2
0
Эх сурвалжийг харах

refactor & feat: 函数调用

SongZihuan 3 жил өмнө
parent
commit
b4f0992a58

+ 25 - 15
include/core/activation.hpp

@@ -2,21 +2,8 @@
 #define AFUN_ACTIVATION_HPP
 #include "tool.hpp"
 #include "aFunCoreExport.h"
-
-namespace aFuncore {
-    class Activation;
-    class TopActivation;
-
-    typedef enum ActivationStatus {
-        as_run = 0,
-        as_end = 1,
-    } ActivationStatus;
-}
-
-#include "msg.hpp"
-#include "code.hpp"
-#include "inter.hpp"
-#include "var.hpp"
+#include "core.hpp"
+#include "value.hpp"
 
 namespace aFuncore {
     class Activation {
@@ -64,6 +51,29 @@ namespace aFuncore {
         ~TopActivation() override;
         bool onTail() override {return false;}
     };
+
+    class FuncActivation : public Activation {
+        enum {
+            func_first = 0,
+            func_get_func = 1,
+            func_get_arg = 2,
+        } status = func_first;
+
+        bool on_tail = false;
+        Code *call;
+
+        Function *func = nullptr;
+        Function::CallFunction *call_func = nullptr;
+
+        std::list<Function::CallFunction::ArgCodeList> *acl = nullptr;
+        std::list<Function::CallFunction::ArgCodeList>::iterator acl_begin;
+        std::list<Function::CallFunction::ArgCodeList>::iterator acl_end;
+    public:
+        explicit FuncActivation(Code *code, Inter *inter_) : Activation(inter_), call{code,} {}
+        ~FuncActivation() override;
+        ActivationStatus getCode(Code *&code) override;
+        bool onTail() override {return on_tail;}
+    };
 }
 
 #endif //AFUN_ACTIVATION_HPP

+ 3 - 16
include/core/code.hpp

@@ -2,29 +2,16 @@
 #define AFUN_CODE_HPP
 #include "tool.hpp"
 #include "aFunCoreExport.h"
+#include "core.hpp"
 
 namespace aFuncore {
-    typedef enum CodeType {
-        code_start = 0,
-        code_element = 1,
-        code_block = 2,
-    } CodeType;
-
-    typedef enum BlockType {
-        block_p = '(',
-        block_b = '[',
-        block_c = '{',
-    } BlockType;
-
-    typedef class Code Code;
     class Code {
         CodeType type;
         char prefix=NUL;
 
         union {
-            char *element;  // union 内不使用 std::string
-
-            struct {
+            char *element = nullptr;  // union 内不使用 std::string
+            struct {  // NOLINT 不需要初始化
                 BlockType block_type;
                 Code *son;
             };

+ 75 - 0
include/core/core.hpp

@@ -2,4 +2,79 @@
 #define AFUN_CORE_HPP
 #include "tool.hpp"
 
+namespace aFuncore {
+    typedef enum CodeType {
+        code_start = 0,
+        code_element = 1,
+        code_block = 2,
+    } CodeType;
+    typedef enum BlockType {
+        block_p = '(',
+        block_b = '[',
+        block_c = '{',
+    } BlockType;
+    typedef class Code Code;
+
+    class EnvVarSpace;
+
+    class Inter;
+    enum InterStatus {
+        inter_creat = 0,
+        inter_init = 1,  // 执行初始化程序
+        inter_normal = 2,  // 正常执行
+        inter_stop = 3,  // 当前运算退出
+        inter_exit = 4,  // 解释器退出
+    };
+    typedef enum InterStatus InterStatus;
+    typedef enum ExitFlat {
+        ef_activity = 0,  // 主动退出
+        ef_passive = 1,  // 被动退出
+        ef_none = 2,
+    } ExitFlat;
+    typedef enum ExitMode {
+        em_activity = ef_activity,  // 主动退出
+        em_passive = ef_passive,  // 被动退出
+    } ExitMode;
+
+    static const int PrefixCount = 2;
+    typedef enum Prefix {
+        prefix_quote = 0,  // 变量引用
+        prefix_exec_first = 1,
+    } Prefix;
+    static const std::string E_PREFIX = "$`'";  /* NOLINT element前缀 */
+    static const std::string B_PREFIX = "$`'%^&<?>";  /* NOLINT block前缀 */
+
+    class Message;
+    class NormalMessage;
+
+    class MessageStream;
+    class UpMessage;
+    class DownMessage;
+
+    class Activation;
+    class ExeActivation;
+    class TopActivation;
+    class FuncActivation;
+    typedef enum ActivationStatus {
+        as_run = 0,
+        as_end = 1,
+    } ActivationStatus;
+
+    class GcList;
+
+    class Object;
+    class Function;
+
+    class Var;
+    class VarSpace;
+    class VarList;
+    class ProtectVarSpace;
+    typedef enum VarOperationFlat {
+        vof_success = 0,  // 成功
+        vof_not_var = 1,  // 变量不存在
+        vof_redefine_var = 2,  // 变量重复定义
+        vof_fail = 3,  // 存在其他错误
+    } VarOperationFlat;
+}
+
 #endif //AFUN_CORE_HPP

+ 1 - 45
include/core/inter.hpp

@@ -3,45 +3,7 @@
 #include <list>
 #include "tool.hpp"
 #include "aFunCoreExport.h"
-
-namespace aFuncore {
-    class Inter;
-
-    enum InterStatus {
-        inter_creat = 0,
-        inter_init = 1,  // 执行初始化程序
-        inter_normal = 2,  // 正常执行
-        inter_stop = 3,  // 当前运算退出
-        inter_exit = 4,  // 解释器退出
-    };
-    typedef enum InterStatus InterStatus;
-
-    typedef enum ExitFlat {
-        ef_activity = 0,  // 主动退出
-        ef_passive = 1,  // 被动退出
-        ef_none = 2,
-    } ExitFlat;
-
-    typedef enum ExitMode {
-        em_activity = ef_activity,  // 主动退出
-        em_passive = ef_passive,  // 被动退出
-    } ExitMode;
-
-    static const int PrefixCount = 2;
-    typedef enum Prefix {
-        prefix_quote = 0,  // 变量引用
-        prefix_exec_first = 1,
-    } Prefix;
-    static const std::string E_PREFIX = "$`'";  /* NOLINT element前缀 */
-    static const std::string B_PREFIX = "$`'%^&<?>";  /* NOLINT block前缀 */
-
-}
-
-#include "env-var.hpp"
-#include "code.hpp"
-#include "var.hpp"
-#include "value.hpp"
-#include "activation.hpp"
+#include "core.hpp"
 
 namespace aFuncore {
     class Inter {
@@ -102,13 +64,7 @@ namespace aFuncore {
         [[nodiscard]] VarList *getGlobalVarlist() const {return global_varlist;}
         [[nodiscard]] Activation *getActivation() const {return activation;}
         [[nodiscard]] bool checkLiteral(const std::string &element, std::string &func, bool &in_protect) const;
-
         [[nodiscard]] EnvVarSpace *getEnvVarSpace() const {return envvar;}
-        [[nodiscard]] int getGcRuntime() const {return gc_runtime->num;}
-        [[nodiscard]] char getPrefx(enum Prefix pre) const {return prefix->str[pre];}
-        [[nodiscard]] int getExitCode() const {return exit_code->num;}
-        [[nodiscard]] int getArgc() const {return argc->num;}
-        [[nodiscard]] int getErrorStd() const {return error_std->num == 1;}
 
         void pushActivation(Activation *new_activation) {activation = new_activation;}
 

+ 2 - 10
include/core/msg.hpp

@@ -2,16 +2,7 @@
 #define AFUN_MSG_HPP
 #include "tool.hpp"
 #include "aFunCoreExport.h"
-
-namespace aFuncore {
-    class MessageStream;
-    class Message;
-    class NormalMessage;
-    class UpMessage;
-    class DownMessage;
-}
-
-#include "value.hpp"
+#include "core.hpp"
 
 namespace aFuncore {
     class Message {
@@ -38,6 +29,7 @@ namespace aFuncore {
         AFUN_CORE_EXPORT explicit NormalMessage(Object *obj);
         AFUN_CORE_EXPORT ~NormalMessage() override;
         void topProgress() override;
+        Object *getObject() {return obj;}
     };
 
     class MessageStream {

+ 18 - 6
include/core/value.hpp

@@ -2,13 +2,9 @@
 #define AFUN_VALUE_HPP
 #include "tool.hpp"
 #include "aFunCoreExport.h"
-
-namespace aFuncore {
-    class Object;
-};
-
+#include "list"
+#include "core.hpp"
 #include "gc.hpp"
-#include "inter.hpp"
 
 namespace aFuncore {
     class Object : public GcObject<class Object> {
@@ -19,6 +15,22 @@ namespace aFuncore {
         AFUN_CORE_EXPORT explicit Object(const std::string &type_, Inter *inter_);
         AFUN_CORE_EXPORT ~Object() override =default;
     };
+
+    class Function : public Object {
+    public:
+        Function(const std::string &type_, Inter *inter_) : Object(type_, inter_) {}
+        class CallFunction {
+        public:
+            struct ArgCodeList {
+                Code *code = nullptr;
+                Object *ret = nullptr;
+            };
+            virtual ~CallFunction()=default;
+            virtual std::list<ArgCodeList> *getArgCodeList()=0;
+            virtual ActivationStatus runFunction()=0;
+        };
+        virtual CallFunction *getCallFunction(Code *code, Inter *inter)=0;
+    };
 };
 
 #endif //AFUN_VALUE_HPP

+ 1 - 16
include/core/var.hpp

@@ -2,23 +2,8 @@
 #define AFUN_VAR_HPP
 #include "tool.hpp"
 #include "aFunCoreExport.h"
-
-namespace aFuncore {
-    typedef enum VarOperationFlat {
-        vof_success = 0,  // 成功
-        vof_not_var = 1,  // 变量不存在
-        vof_redefine_var = 2,  // 变量重复定义
-        vof_fail = 3,  // 存在其他错误
-    } VarOperationFlat;
-
-    class Var;
-    class VarSpace;
-    class VarList;
-    class ProtectVarSpace;
-}
-
+#include "core.hpp"
 #include "gc.hpp"
-#include "value.hpp"
 
 namespace aFuncore {
     class Var : public GcObject<class Var> {

+ 89 - 5
src/core/activation.cpp

@@ -1,10 +1,21 @@
 #include "activation.hpp"
 #include "value.hpp"
+#include "inter.hpp"
 #include "init.hpp"
+#include "msg.hpp"
+#include "var.hpp"
+#include "code.hpp"
 
 using namespace aFuncore;
 using namespace aFuntool;
 
+/**
+ * 创建基本Activation
+ * 若上层Activation已到结尾则尾调用优化
+ * 自动继承上层VarList和UpMessage
+ * 自动压入inter
+ * @param inter_
+ */
 Activation::Activation(Inter *inter_) : inter{inter_}, line{0} {
     Activation *prev_ = inter->getActivation();
     if (prev_ != nullptr && prev_->onTail()) {
@@ -29,6 +40,11 @@ Activation::Activation(Inter *inter_) : inter{inter_}, line{0} {
     inter->pushActivation(this);
 }
 
+/**
+ * 析构Activation
+ * 注意: 不会自动从inter中弹出
+ * 释放Varlist并且将DownMessage压入上层
+ */
 Activation::~Activation(){
     if (varlist != nullptr && old_varlist != nullptr)
         varlist->disconnect(old_varlist);
@@ -38,6 +54,10 @@ Activation::~Activation(){
     delete down;
 }
 
+/**
+ * 运行代码
+ * @param code
+ */
 void Activation::runCode(Code *code){
     auto code_type = code->getType();
     if (code_type == code_start) {  // start 不处理 msg
@@ -53,6 +73,7 @@ void Activation::runCode(Code *code){
                 Object *obj = nullptr;
                 if (varlist != nullptr)
                     obj = varlist->findObject(code->getElement());
+                trackLog(aFunCoreLogger, "Find Var %s -> %p", code->getElement(), obj);
                 if (obj != nullptr)
                     down->pushMessage(new NormalMessage(obj));
             }
@@ -61,8 +82,8 @@ void Activation::runCode(Code *code){
                 new ExeActivation(code->getSon(), inter);
                 break;
             case block_b:
-                break;
             case block_c:
+                new FuncActivation(code, inter);
                 break;
             default:
                 errorLog(aFunCoreLogger, "Error block type.");
@@ -77,11 +98,11 @@ ActivationStatus ExeActivation::getCode(Code *&code){
         return as_end;
 
     if (!first) {
-        Message *msg = down->getMessage<NormalMessage>("NORMAL");
-        if (msg == nullptr) {
+        auto msg = down->getMessage<NormalMessage>("NORMAL");
+        if (msg == nullptr)
             return as_end;
-        } else
-            msg = down->popMessage("NORMAL");
+        else
+            down->popMessage("NORMAL");
         delete msg;
     }
 
@@ -104,3 +125,66 @@ static void ActivationTopProgress(Message *msg, void *) {
 TopActivation::~TopActivation() {
     down->forEach<void *>(ActivationTopProgress, nullptr);
 }
+
+FuncActivation::~FuncActivation(){
+    delete call_func;
+}
+
+ActivationStatus FuncActivation::getCode(Code *&code){
+    if (on_tail)
+        return as_end;
+
+    if (status == func_first) {
+        status = func_get_func;
+        switch (call->getBlockType()) {
+            case block_c:
+                code = call->getSon();
+                return as_run;
+            case block_b:
+                break;
+            default:
+                errorLog(aFunCoreLogger, "Error FuncActivation block type");
+                return as_end;
+        }
+    }
+
+    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;
+
+        call_func = func->getCallFunction(call, inter);
+        acl = call_func->getArgCodeList();
+        acl_begin = acl->begin();
+        acl_end = acl->end();
+        if (acl_begin != acl_end) {
+            code = acl_begin->code;
+            return as_run;
+        }
+    }
+
+    auto *msg = down->getMessage<NormalMessage>("NORMAL");
+    if (msg == nullptr)
+        return as_end;
+    else
+        down->popMessage("NORMAL");
+
+    acl_begin->ret = msg->getObject();
+    delete msg;
+
+    acl_begin++;
+    if (acl_begin != acl_end) {
+        code = acl_begin->code;
+        return as_run;
+    }
+
+    on_tail = true;
+    return call_func->runFunction();
+}

+ 4 - 0
src/core/inter.cpp

@@ -1,6 +1,10 @@
 #include "inter.hpp"
+#include "activation.hpp"
 #include "init.hpp"
+#include "env-var.hpp"
+#include "var.hpp"
 #include "__gc.hpp"
+
 using namespace aFuncore;
 using namespace aFuntool;
 

+ 62 - 4
test/src/run-code.cpp

@@ -1,17 +1,75 @@
 #include "inter.hpp"
 #include "value.hpp"
+#include "var.hpp"
+#include "code.hpp"
+#include "msg.hpp"
+#include "activation.hpp"
+
 using namespace aFuncore;
 using namespace aFuntool;
 
+class Func1 : public Function {
+    class CallFunc1 : public CallFunction {
+        Code *code;
+        Inter *inter;
+        std::list<ArgCodeList> *acl;
+    public:
+        CallFunc1(Code *code_, Inter *inter_) : code{code_}, inter{inter_} {
+            acl = new std::list<ArgCodeList>;
+            ArgCodeList agr1 = {code_->getSon()->toNext()};
+            acl->push_front(agr1);
+        }
+
+        std::list<ArgCodeList> *getArgCodeList() override {
+            return acl;
+        }
+
+        ActivationStatus runFunction() override {
+            printf_stdout(0, "runFunction : %p\n", acl->begin()->ret);
+            auto *none = new Object("None", inter);
+            inter->getActivation()->getDownStream()->pushMessage(new NormalMessage(none));
+            return aFuncore::as_end;
+        }
+
+        ~CallFunc1() override {
+            delete acl;
+        }
+    };
+
+public:
+    explicit Func1(Inter *inter_) : Function("Function", inter_) {}
+    CallFunction *getCallFunction(Code *code, Inter *inter) override {
+        return dynamic_cast<CallFunction *>(new CallFunc1(code, inter));
+    }
+};
+
 int main() {
     auto *inter = new Inter();
     auto *obj = new Object("Object", inter);
     inter->getGlobalVarlist()->defineVar("test-var", obj);
+    printf_stdout(0, "obj: %p\n", obj);
+
+    auto func = new Func1(inter);
+    inter->getGlobalVarlist()->defineVar("test-func", func);
+    printf_stdout(0, "func: %p\n", func);
+
+    {
+        auto code = (new Code(0, "run-code.aun"));
+        code->connect(new Code(block_p, new Code("test-var", 1), 0));
+        inter->runCode(code);
+        code->destructAll();
+    }
+
+    {
+        auto arg = new Code("test-func", 1);
+        arg->connect(new Code("test-var", 1));
+
+        auto code = (new Code(0, "run-code.aun"));
+        code->connect(new Code(block_c, arg, 0));
+        inter->runCode(code);
+        code->destructAll();
+    }
 
-    auto *code = (new Code(0, "run-code.aun"));
-    code->connect(new Code(block_p, new Code("test-var", 1), 0));
-    inter->runCode(code);
-    code->destructAll();
     delete inter;
     return 0;
 }