فهرست منبع

refactor & feat: 字面量调用

SongZihuan 3 سال پیش
والد
کامیت
8a8db69378
9فایلهای تغییر یافته به همراه88 افزوده شده و 21 حذف شده
  1. 2 0
      include/core/activation.hpp
  2. 1 0
      include/core/core.hpp
  3. 7 3
      include/core/inter.hpp
  4. 8 2
      include/core/value.hpp
  5. 1 1
      include/tool/regex.hpp
  6. 16 9
      src/core/activation.cpp
  7. 19 3
      src/core/inter.cpp
  8. 2 1
      src/tool/regex.cpp
  9. 32 2
      test/src/run-code.cpp

+ 2 - 0
include/core/activation.hpp

@@ -26,6 +26,7 @@ namespace aFuncore {
 
 
         virtual ActivationStatus getCode(Code *&code)=0;
         virtual ActivationStatus getCode(Code *&code)=0;
         virtual void runCode(Code *code);
         virtual void runCode(Code *code);
+        virtual void endRun() {}
 
 
         [[nodiscard]] VarList *getVarlist() const {return varlist;}
         [[nodiscard]] VarList *getVarlist() const {return varlist;}
         [[nodiscard]] Activation *toPrev() const {return prev;}
         [[nodiscard]] Activation *toPrev() const {return prev;}
@@ -69,6 +70,7 @@ namespace aFuncore {
         explicit FuncActivation(Code *code, Inter *inter_) : Activation(inter_), call{code,} {}
         explicit FuncActivation(Code *code, Inter *inter_) : Activation(inter_), call{code,} {}
         ~FuncActivation() override;
         ~FuncActivation() override;
         ActivationStatus getCode(Code *&code) override;
         ActivationStatus getCode(Code *&code) override;
+        void endRun() override;
     };
     };
 }
 }
 
 

+ 1 - 0
include/core/core.hpp

@@ -58,6 +58,7 @@ namespace aFuncore {
     typedef enum ActivationStatus {
     typedef enum ActivationStatus {
         as_run = 0,
         as_run = 0,
         as_end = 1,
         as_end = 1,
+        as_end_run = 2,
     } ActivationStatus;
     } ActivationStatus;
 
 
     class GcList;
     class GcList;

+ 7 - 3
include/core/inter.hpp

@@ -10,6 +10,7 @@ namespace aFuncore {
         friend class Object;
         friend class Object;
         friend class Var;
         friend class Var;
         friend class VarSpace;
         friend class VarSpace;
+        friend class Activation;
 
 
         /* 解释器原信息记录 */
         /* 解释器原信息记录 */
         pthread_mutex_t status_lock;  // status 可能被外部使用, 因此需要用锁保护
         pthread_mutex_t status_lock;  // status 可能被外部使用, 因此需要用锁保护
@@ -28,11 +29,12 @@ namespace aFuncore {
         VarSpace *global;  // 全局变量空间
         VarSpace *global;  // 全局变量空间
         VarList *global_varlist;  // global + protect
         VarList *global_varlist;  // global + protect
         Activation *activation;  // 活动记录
         Activation *activation;  // 活动记录
+        void pushActivation(Activation *new_activation) {activation = new_activation;}
 
 
         struct LiteralRegex {
         struct LiteralRegex {
             Regex *rg;
             Regex *rg;
             std::string pattern;  // 派生 LiteralRegex 时使用
             std::string pattern;  // 派生 LiteralRegex 时使用
-            char *func;  // 调用的函数
+            std::string literaler;  // 调用的函数
             bool in_protect;  // 是否在protect空间
             bool in_protect;  // 是否在protect空间
         };
         };
         std::list<LiteralRegex> *literal;
         std::list<LiteralRegex> *literal;
@@ -61,13 +63,15 @@ namespace aFuncore {
         [[nodiscard]] InterStatus getStatus() const {return status;}
         [[nodiscard]] InterStatus getStatus() const {return status;}
         [[nodiscard]] bool isExit() const {return (status == inter_exit || status == inter_stop);}
         [[nodiscard]] bool isExit() const {return (status == inter_exit || status == inter_stop);}
 
 
+        [[nodiscard]] ProtectVarSpace *getProtectVarSpace() const {return protect;}
+        [[nodiscard]] VarSpace *getGlobalVarSpace() const {return global;}
         [[nodiscard]] VarList *getGlobalVarlist() const {return global_varlist;}
         [[nodiscard]] VarList *getGlobalVarlist() const {return global_varlist;}
         [[nodiscard]] Activation *getActivation() const {return activation;}
         [[nodiscard]] Activation *getActivation() const {return activation;}
         [[nodiscard]] bool checkLiteral(const std::string &element) const;
         [[nodiscard]] bool checkLiteral(const std::string &element) const;
-        [[nodiscard]] bool checkLiteral(const std::string &element, std::string &func, bool &in_protect) const;
+        [[nodiscard]] bool checkLiteral(const std::string &element, std::string &literaler, bool &in_protect) const;
         [[nodiscard]] EnvVarSpace *getEnvVarSpace() const {return envvar;}
         [[nodiscard]] EnvVarSpace *getEnvVarSpace() const {return envvar;}
 
 
-        void pushActivation(Activation *new_activation) {activation = new_activation;}
+        bool pushLiteral(const std::string &pattern, const std::string &literaler, bool in_protect);
 
 
         bool runCode();
         bool runCode();
         bool runCode(Code *code);
         bool runCode(Code *code);

+ 8 - 2
include/core/value.hpp

@@ -18,7 +18,7 @@ namespace aFuncore {
 
 
     class Function : public Object {
     class Function : public Object {
     public:
     public:
-        Function(const std::string &type_, Inter *inter_) : Object(type_, inter_) {}
+        Function(const std::string &type_, Inter *inter_) : Object(type_ + ":Function", inter_) {}
         class CallFunction {
         class CallFunction {
         public:
         public:
             struct ArgCodeList {
             struct ArgCodeList {
@@ -27,11 +27,17 @@ namespace aFuncore {
             };
             };
             virtual ~CallFunction()=default;
             virtual ~CallFunction()=default;
             virtual std::list<ArgCodeList> *getArgCodeList()=0;
             virtual std::list<ArgCodeList> *getArgCodeList()=0;
-            virtual ActivationStatus runFunction()=0;
+            virtual void runFunction()=0;
         };
         };
         virtual CallFunction *getCallFunction(Code *code, Inter *inter)=0;
         virtual CallFunction *getCallFunction(Code *code, Inter *inter)=0;
         virtual bool isInfix() {return false;}
         virtual bool isInfix() {return false;}
     };
     };
+
+    class Literaler : public Object {
+    public:
+        Literaler(const std::string &type_, Inter *inter_) : Object(type_ + ":Literaler", inter_) {}
+        virtual void getObject(const std::string &literal, char prefix)=0;
+    };
 };
 };
 
 
 #endif //AFUN_VALUE_HPP
 #endif //AFUN_VALUE_HPP

+ 1 - 1
include/tool/regex.hpp

@@ -13,7 +13,7 @@ namespace aFuntool {
         pcre2_code *re;  // 正则表达式
         pcre2_code *re;  // 正则表达式
         const std::string pattern;  // 正则表达式的字符串
         const std::string pattern;  // 正则表达式的字符串
     public:
     public:
-        AFUN_TOOL_EXPORT explicit Regex (const std::string &pattern_);
+        AFUN_TOOL_EXPORT explicit Regex(const std::string &pattern_);
         AFUN_TOOL_EXPORT ~Regex ();
         AFUN_TOOL_EXPORT ~Regex ();
         AFUN_TOOL_EXPORT int match(const char *subject);
         AFUN_TOOL_EXPORT int match(const char *subject);
         AFUN_TOOL_EXPORT int match(const std::string &subject) {return match(subject.c_str());}
         AFUN_TOOL_EXPORT int match(const std::string &subject) {return match(subject.c_str());}

+ 16 - 9
src/core/activation.cpp

@@ -51,12 +51,18 @@ void Activation::runCode(Code *code){
         down->pushMessage(new NormalMessage(none));
         down->pushMessage(new NormalMessage(none));
     } else {
     } else {
         if (code_type == code_element) {
         if (code_type == code_element) {
-            std::string func;
+            std::string literaler_name;
             bool in_protect = false;
             bool in_protect = false;
-            if (inter->checkLiteral(code->getElement(), func, in_protect)) {
-                // ...
+            Object *obj = nullptr;
+            if (inter->checkLiteral(code->getElement(), literaler_name, in_protect)) {
+                if (in_protect)
+                    obj = inter->getProtectVarSpace()->findObject(literaler_name);
+                else
+                    obj = varlist->findObject(literaler_name);
+                auto literaler = dynamic_cast<Literaler *>(obj);
+                if (literaler != nullptr)
+                    literaler->getObject(code->getElement(), code->getPrefix());
             } else {
             } else {
-                Object *obj = nullptr;
                 if (varlist != nullptr)
                 if (varlist != nullptr)
                     obj = varlist->findObject(code->getElement());
                     obj = varlist->findObject(code->getElement());
                 trackLog(aFunCoreLogger, "Find Var %s -> %p", code->getElement(), obj);
                 trackLog(aFunCoreLogger, "Find Var %s -> %p", code->getElement(), obj);
@@ -179,8 +185,7 @@ ActivationStatus FuncActivation::getCode(Code *&code){
     auto *msg = down->getMessage<NormalMessage>("NORMAL");
     auto *msg = down->getMessage<NormalMessage>("NORMAL");
     if (msg == nullptr)
     if (msg == nullptr)
         return as_end;
         return as_end;
-    else
-        down->popMessage("NORMAL");
+    down->popMessage("NORMAL");
 
 
     acl_begin->ret = msg->getObject();
     acl_begin->ret = msg->getObject();
     delete msg;
     delete msg;
@@ -192,7 +197,9 @@ ActivationStatus FuncActivation::getCode(Code *&code){
     }
     }
 
 
     on_tail = true;
     on_tail = true;
-    if (call_func->runFunction() == as_run)
-        return inter->getActivation()->getCode(code);
-    return as_end;
+    return as_end_run;
+}
+
+void FuncActivation::endRun(){
+    call_func->runFunction();
 }
 }

+ 19 - 3
src/core/inter.cpp

@@ -61,6 +61,9 @@ Inter::~Inter(){
         Var::destruct(gc->var);
         Var::destruct(gc->var);
         VarSpace::destruct(gc->varspace);
         VarSpace::destruct(gc->varspace);
 
 
+        for (auto &it : *literal)
+            delete it.rg;
+
         delete literal;
         delete literal;
         delete gc;
         delete gc;
         delete son_inter;
         delete son_inter;
@@ -105,6 +108,9 @@ bool Inter::runCode(){
             case as_run:
             case as_run:
                 activation->runCode(code);
                 activation->runCode(code);
                 break;
                 break;
+            case as_end_run:
+                activation->endRun();
+                break;
             default:
             default:
                 errorLog(aFunCoreLogger, "Error activation status.");
                 errorLog(aFunCoreLogger, "Error activation status.");
                 break;
                 break;
@@ -155,11 +161,11 @@ bool Inter::checkLiteral(const std::string &element) const {
 /**
 /**
  * 检查字面量正则匹配
  * 检查字面量正则匹配
  * @param element 字面量
  * @param element 字面量
- * @param func 函数
+ * @param literaler 函数
  * @param in_protect 是否保护空间
  * @param in_protect 是否保护空间
  * @return
  * @return
  */
  */
-bool Inter::checkLiteral(const std::string &element, std::string &func, bool &in_protect) const {
+bool Inter::checkLiteral(const std::string &element, std::string &literaler, bool &in_protect) const {
     if (literal->empty())
     if (literal->empty())
         return false;
         return false;
 
 
@@ -170,7 +176,7 @@ bool Inter::checkLiteral(const std::string &element, std::string &func, bool &in
         try {
         try {
             if (it->rg->match(element) != 1)
             if (it->rg->match(element) != 1)
                 continue;
                 continue;
-            func = it->func;
+            literaler = it->literaler;
             in_protect = it->in_protect;
             in_protect = it->in_protect;
             return true;
             return true;
         } catch (RegexException &e) {
         } catch (RegexException &e) {
@@ -180,3 +186,13 @@ bool Inter::checkLiteral(const std::string &element, std::string &func, bool &in
     return false;
     return false;
 }
 }
 
 
+bool Inter::pushLiteral(const std::string &pattern, const std::string &literaler, bool in_protect){
+    try {
+        Regex *rg =  new Regex(pattern);
+        literal->push_front({rg, pattern, literaler, in_protect});
+    } catch (RegexException &e) {
+        return false;
+    }
+    return true;
+}
+

+ 2 - 1
src/tool/regex.cpp

@@ -24,7 +24,8 @@ aFuntool::Regex::Regex(const std::string &pattern_) : pattern {pattern_} {
 }
 }
 
 
 aFuntool::Regex::~Regex() {
 aFuntool::Regex::~Regex() {
-    pcre2_code_free(re);
+    if (re != nullptr)
+        pcre2_code_free(re);
 }
 }
 
 
 /*
 /*

+ 32 - 2
test/src/run-code.cpp

@@ -25,10 +25,9 @@ class Func1 : public Function {
             return acl;
             return acl;
         }
         }
 
 
-        ActivationStatus runFunction() override {
+        void runFunction() override {
             printf_stdout(0, "runFunction : %p\n", acl->begin()->ret);
             printf_stdout(0, "runFunction : %p\n", acl->begin()->ret);
             new ExeActivation(func_code, inter);
             new ExeActivation(func_code, inter);
-            return aFuncore::as_run;
         }
         }
 
 
         ~CallFunc1() override {
         ~CallFunc1() override {
@@ -54,8 +53,27 @@ public:
     bool isInfix() override {return true;}
     bool isInfix() override {return true;}
 };
 };
 
 
+class Literaler1 : public Literaler {
+    Code *func_code;
+public:
+    explicit Literaler1(Inter *inter_) : Literaler("Data", inter_) {
+        func_code = (new Code(0, "run-code.aun"));
+        func_code->connect(new Code(block_p, new Code("test-var", 1), 0));
+    }
+
+    ~Literaler1() override {
+        func_code->destructAll();
+    }
+
+    void getObject(const std::string &literal, char prefix) override {
+        printf("Literaler1: %s %c\n", literal.c_str(), prefix);
+        new ExeActivation(func_code, inter);
+    }
+};
+
 int main() {
 int main() {
     auto *inter = new Inter();
     auto *inter = new Inter();
+
     auto *obj = new Object("Object", inter);
     auto *obj = new Object("Object", inter);
     inter->getGlobalVarlist()->defineVar("test-var", obj);
     inter->getGlobalVarlist()->defineVar("test-var", obj);
     printf_stdout(0, "obj: %p\n", obj);
     printf_stdout(0, "obj: %p\n", obj);
@@ -64,6 +82,10 @@ int main() {
     inter->getGlobalVarlist()->defineVar("test-func", func);
     inter->getGlobalVarlist()->defineVar("test-func", func);
     printf_stdout(0, "func: %p\n", func);
     printf_stdout(0, "func: %p\n", func);
 
 
+    auto literaler = new Literaler1(inter);
+    inter->getGlobalVarlist()->defineVar("test-literaler", literaler);
+    printf_stdout(0, "literaler: %p\n", literaler);
+
     {
     {
         auto code = (new Code(0, "run-code.aun"));
         auto code = (new Code(0, "run-code.aun"));
         code->connect(new Code(block_p, new Code("test-var", 1), 0));
         code->connect(new Code(block_p, new Code("test-var", 1), 0));
@@ -91,6 +113,14 @@ int main() {
         code->destructAll();
         code->destructAll();
     }
     }
 
 
+    {
+        inter->pushLiteral("data[0-9]", "test-literaler", false);
+        auto code = (new Code(0, "run-code.aun"));
+        code->connect(new Code("data3", 1));
+        inter->runCode(code);
+        code->destructAll();
+    }
+
     delete inter;
     delete inter;
     return 0;
     return 0;
 }
 }