Procházet zdrojové kódy

refactor & feat: 中缀函数调用

SongZihuan před 3 roky
rodič
revize
1237eb2f46

+ 1 - 1
include/core/core.hpp

@@ -36,7 +36,7 @@ namespace aFuncore {
         em_passive = ef_passive,  // 被动退出
     } ExitMode;
 
-    static const int PrefixCount = 2;
+    static const int PREFIX_COUNT = 2;
     typedef enum Prefix {
         prefix_quote = 0,  // 变量引用
         prefix_exec_first = 1,

+ 1 - 0
include/core/inter.hpp

@@ -63,6 +63,7 @@ namespace aFuncore {
 
         [[nodiscard]] VarList *getGlobalVarlist() const {return global_varlist;}
         [[nodiscard]] Activation *getActivation() const {return activation;}
+        [[nodiscard]] bool checkLiteral(const std::string &element) const;
         [[nodiscard]] bool checkLiteral(const std::string &element, std::string &func, bool &in_protect) const;
         [[nodiscard]] EnvVarSpace *getEnvVarSpace() const {return envvar;}
 

+ 1 - 0
include/core/value.hpp

@@ -30,6 +30,7 @@ namespace aFuncore {
             virtual ActivationStatus runFunction()=0;
         };
         virtual CallFunction *getCallFunction(Code *code, Inter *inter)=0;
+        virtual bool isInfix() {return false;}
     };
 };
 

+ 32 - 11
src/core/activation.cpp

@@ -5,6 +5,7 @@
 #include "msg.hpp"
 #include "var.hpp"
 #include "code.hpp"
+#include "env-var.hpp"
 
 using namespace aFuncore;
 using namespace aFuntool;
@@ -125,8 +126,25 @@ ActivationStatus FuncActivation::getCode(Code *&code){
             case block_c:
                 code = call->getSon();
                 return as_run;
-            case block_b:
+            case block_b: {
+                std::string prefix;
+                if (!inter->getEnvVarSpace()->findString("sys:prefix", prefix) || prefix.size() != PREFIX_COUNT)
+                    prefix = "''";
+                char quote = prefix[prefix_quote];
+                for (Code *var = call->getSon(); var != nullptr; var = var->toNext()) {
+                    if (var->getType() != code_element || var->getPrefix() == quote || inter->checkLiteral(var->getElement()))
+                        continue;
+                    Object *obj = varlist->findObject(var->getElement());
+                    if (obj == nullptr || !dynamic_cast<Function *>(obj) || !dynamic_cast<Function *>(obj)->isInfix())
+                        continue;
+                    func = dynamic_cast<Function *>(obj);
+                    if (func == nullptr || !func->isInfix())
+                        continue;
+                    status = func_get_func;
+                    break;  /* 跳转到: 执行变量获取前的准备 */
+                }
                 break;
+            }
             default:
                 errorLog(aFunCoreLogger, "Error FuncActivation block type");
                 return as_end;
@@ -134,17 +152,20 @@ ActivationStatus FuncActivation::getCode(Code *&code){
     }
 
     if (status == func_get_func) {
-        status = func_get_arg;
-        auto *msg = down->getMessage<NormalMessage>("NORMAL");
-        if (msg == nullptr)
-            return as_end;
-        else
-            down->popMessage("NORMAL");
-        func = dynamic_cast<Function *>(msg->getObject());
-        delete msg;
-        if (func == nullptr)
-            return as_end;
+        if (func == nullptr) {
+            auto *msg = down->getMessage<NormalMessage>("NORMAL");
+            if (msg == nullptr)
+                return as_end;
+            else
+                down->popMessage("NORMAL");
+            func = dynamic_cast<Function *>(msg->getObject());
+            delete msg;
+            if (func == nullptr)
+                return as_end;
+        }
 
+        /* Label: 执行变量获取前的准备 */
+        status = func_get_arg;
         call_func = func->getCallFunction(call, inter);
         acl = call_func->getArgCodeList();
         acl_begin = acl->begin();

+ 24 - 0
src/core/inter.cpp

@@ -128,6 +128,30 @@ bool Inter::runCode(Code *code){
     return runCode();
 }
 
+/**
+ * 检查字面量是否匹配
+ * @param element 字面量
+ * @return
+ */
+bool Inter::checkLiteral(const std::string &element) const {
+    if (literal->empty())
+        return false;
+
+    auto it = literal->begin();
+    auto end = literal->end();
+
+    for(NULL;it != end;it++){
+        try {
+            if (it->rg->match(element) != 1)
+                continue;
+            return true;
+        } catch (RegexException &e) {
+            continue;
+        }
+    }
+    return false;
+}
+
 /**
  * 检查字面量正则匹配
  * @param element 字面量

+ 13 - 1
test/src/run-code.cpp

@@ -43,13 +43,15 @@ public:
         func_code->connect(new Code(block_p, new Code("test-var", 1), 0));
     }
 
-    ~Func1() {
+    ~Func1() override {
         func_code->destructAll();
     }
 
     CallFunction *getCallFunction(Code *code, Inter *inter) override {
         return dynamic_cast<CallFunction *>(new CallFunc1(func_code, code, inter));
     }
+
+    bool isInfix() override {return true;}
 };
 
 int main() {
@@ -79,6 +81,16 @@ int main() {
         code->destructAll();
     }
 
+    {
+        auto arg = new Code("test-var", 1);
+        arg->connect(new Code("test-func", 1));
+
+        auto code = (new Code(0, "run-code.aun"));
+        code->connect(new Code(block_b, arg, 0));
+        inter->runCode(code);
+        code->destructAll();
+    }
+
     delete inter;
     return 0;
 }