فهرست منبع

refactor & feat: 添加Exit函数

SongZihuan 3 سال پیش
والد
کامیت
4fee0c9836

+ 2 - 4
include/core/inter.h

@@ -21,8 +21,6 @@ namespace aFuncore {
 
     class AFUN_CORE_EXPORT Environment {
         friend class Object;
-        friend class Var;
-        friend class VarSpace;
         friend class Inter;
 
     public:
@@ -43,13 +41,13 @@ namespace aFuncore {
         std::list<Object *> gc;
         Inter &gc_inter;  /* 需要在lock和reference后初始化 */
         std::thread gc_thread;
+        void gcThread();
 
+    protected:  // 位于 mutex 之下
         ProtectVarSpace *const protect;  // 保护变量空间
         VarSpace *const global;  // 全局变量空间
         VarList *const global_varlist;  // global + protect
         EnvVarSpace envvar;
-
-        void gcThread();
     };
 
     class AFUN_CORE_EXPORT Inter {

+ 8 - 2
include/core/object-value.h

@@ -89,7 +89,7 @@ namespace aFuncore {
 
     class AFUN_CORE_EXPORT Function::CallFunction {
     public:
-        struct ArgCodeList;
+        class ArgCodeList;
 
         CallFunction() = default;
         virtual ~CallFunction() = default;
@@ -100,8 +100,14 @@ namespace aFuncore {
         virtual void runFunction() = 0;
     };
 
-    struct Function::CallFunction::ArgCodeList {
+    class Function::CallFunction::ArgCodeList {
+    public:
         const Code::ByteCode *code = nullptr;
+        inline explicit ArgCodeList(const Code::ByteCode *code = nullptr);
+        inline ~ArgCodeList();
+        inline Object *setObject(Object *res);
+        inline Object *getObject();
+    private:
         Object *ret = nullptr;
     };
 

+ 21 - 0
include/core/object-value.inline.h

@@ -28,6 +28,27 @@ namespace aFuncore {
     inline bool ProtectVarSpace::setProtect(bool protect) {
         bool ret = is_protect; is_protect = protect; return ret;
     }
+
+    inline Function::CallFunction::ArgCodeList::ArgCodeList(const Code::ByteCode *code_) : code{code_}, ret{nullptr} {
+
+    }
+
+    inline Function::CallFunction::ArgCodeList::~ArgCodeList() {
+        if (ret != nullptr)
+            ret->delReference();
+    }
+
+    Object *Function::CallFunction::ArgCodeList::setObject(Object *res) {
+        Object *obj = ret;
+        ret = res;
+        if (ret != nullptr)
+            ret->addReference();
+        return obj;
+    }
+
+    Object *Function::CallFunction::ArgCodeList::getObject() {
+        return ret;
+    }
 };
 
 #endif //AFUN_OBJECT_VALUE_INLINE_H

+ 3 - 0
include/runtime/aFunrt.h

@@ -1,6 +1,9 @@
 #ifndef AFUN_AFUNRT_H
 #define AFUN_AFUNRT_H
 
+#include "rt-init.h"
 #include "rt-reader.h"
+#include "rt-inter.h"
+#include "rt-exception.h"
 
 #endif //AFUN_AFUNRT_H

+ 33 - 0
include/runtime/func-exit.h

@@ -0,0 +1,33 @@
+#ifndef AFUN_FUNC_EXIT_H
+#define AFUN_FUNC_EXIT_H
+#include "aFunlangExport.h"
+#include "aFuncore.h"
+
+namespace aFunrt {
+    class ExitFunction : public aFuncore::Function {
+        class CallFunc : public CallFunction {
+            const aFuncore::Code::ByteCode *call_code;
+            aFuncore::Inter &inter;
+            std::list<ArgCodeList> *acl;
+        public:
+            CallFunc(const aFuncore::Code::ByteCode *code_, aFuncore::Inter &inter_);
+            std::list<ArgCodeList> *getArgCodeList(aFuncore::Inter &inter_,
+                                                   aFuncore:: Activation &activation,
+                                                   const aFuncore::Code::ByteCode *call) override;
+
+            void runFunction() override;
+            ~CallFunc() override;
+        };
+
+    public:
+        inline explicit ExitFunction(aFuncore::Inter &inter_);
+        inline explicit ExitFunction(aFuncore::Environment &env_);
+        ~ExitFunction() override = default;
+
+        CallFunction *getCallFunction(const aFuncore::Code::ByteCode *code, aFuncore::Inter &inter) override;
+    };
+}
+
+#include "func-exit.inline.h"
+
+#endif //AFUN_FUNC_EXIT_H

+ 16 - 0
include/runtime/func-exit.inline.h

@@ -0,0 +1,16 @@
+#ifndef AFUN_FUNC_EXIT_INLINE_H
+#define AFUN_FUNC_EXIT_INLINE_H
+
+#include "func-exit.h"
+
+namespace aFunrt {
+    inline ExitFunction::ExitFunction(aFuncore::Inter &inter_) : Object("Function", inter_) {
+
+    }
+
+    inline ExitFunction::ExitFunction(aFuncore::Environment &env_) : Object("Function", env_) {
+
+    }
+}
+
+#endif //AFUN_FUNC_EXIT_INLINE_H

+ 14 - 0
include/runtime/rt-inter.h

@@ -0,0 +1,14 @@
+#ifndef AFUN_RT_INTER_H
+#define AFUN_RT_INTER_H
+#include "aFunlangExport.h"
+#include "aFuncore.h"
+
+namespace aFunrt {
+    class aFunEnvironment : public aFuncore::Environment {
+    public:
+        explicit aFunEnvironment(int argc = 0, char **argv = nullptr);
+    };
+}
+
+
+#endif //AFUN_RT_INTER_H

+ 1 - 1
src/core/activation.cpp

@@ -250,7 +250,7 @@ namespace aFuncore {
                 return as_end;
             down.popMessage("NORMAL");
 
-            acl_begin->ret = msg->getObject();
+            acl_begin->setObject(msg->getObject());
             delete msg;
 
             acl_begin++;

+ 40 - 0
src/runtime/func-exit.cpp

@@ -0,0 +1,40 @@
+#include "func-exit.h"
+
+namespace aFunrt {
+    aFuncore::Function::CallFunction *ExitFunction::getCallFunction(const aFuncore::Code::ByteCode *code, aFuncore::Inter &inter) {
+        return dynamic_cast<CallFunction *>(new CallFunc(code, inter));
+    }
+
+    ExitFunction::CallFunc::CallFunc(const aFuncore::Code::ByteCode *code_, aFuncore::Inter &inter_) : call_code{code_}, inter{inter_} {
+        acl = new std::list<ArgCodeList>;
+        if (code_ != nullptr) {
+            auto arg_code = code_->getSon()->toNext();
+            if (arg_code != nullptr) {
+                ArgCodeList agr1{code_->getSon()->toNext()};
+                acl->push_front(agr1);
+            }
+        }
+    }
+
+    std::list<aFuncore::Function::CallFunction::ArgCodeList> *ExitFunction::CallFunc::getArgCodeList(aFuncore::Inter &inter_,
+                                                                                                     aFuncore:: Activation &activation,
+                                                                                                     const aFuncore::Code::ByteCode *call) {
+        return acl;
+    }
+
+    void ExitFunction::CallFunc::runFunction() {
+        inter.setInterExit();
+        auto &stream = inter.getActivation()->getDownStream();
+        if (acl->empty()) {
+            auto none = new aFuncore::Object("None", inter);
+            stream.pushMessage("NORMAL", new aFuncore::NormalMessage(none));
+            none->delReference();
+        } else
+            stream.pushMessage("NORMAL", new aFuncore::NormalMessage(acl->begin()->getObject()));
+
+    }
+
+    ExitFunction::CallFunc::~CallFunc() {
+        delete acl;
+    }
+}

+ 16 - 0
src/runtime/rt-inter.cpp

@@ -0,0 +1,16 @@
+#include "rt-inter.h"
+#include "func-exit.h"
+
+namespace aFunrt {
+    aFunEnvironment::aFunEnvironment(int argc, char **argv) : Environment(argc, argv)  {
+        {  // 退出函数
+            auto exit = new ExitFunction(*this);
+            protect->defineVar("exit", exit);
+            exit->delReference();
+        }
+
+        {  // 导入函数
+
+        }
+    }
+}

+ 15 - 6
test/src/run-code.cpp

@@ -1,5 +1,6 @@
-#include "aFuncore.h"
+#include "aFunrt.h"
 
+using namespace aFunrt;
 using namespace aFuncore;
 using namespace aFuntool;
 
@@ -15,7 +16,7 @@ class Func1 : public Function {
         CallFunc1(Code &func_code_, const Code::ByteCode *code_, Inter &inter_) : func_code{func_code_}, call_code{code_}, inter{inter_} {
             acl = new std::list<ArgCodeList>;
             if (code_ != nullptr) {
-                ArgCodeList agr1 = {code_->getSon()->toNext()};
+                ArgCodeList agr1 {code_->getSon()->toNext()};
                 acl->push_front(agr1);
             }
         }
@@ -28,7 +29,7 @@ class Func1 : public Function {
             if (acl->empty())
                 printf_stdout(0, "runFunction No AegCodeList\n");
             else
-                printf_stdout(0, "runFunction : %p\n", acl->begin()->ret);
+                printf_stdout(0, "runFunction : %p\n", acl->begin()->getObject());
             new ExeActivation(func_code, inter);
         }
 
@@ -141,7 +142,7 @@ void thread_test(Inter &son) {
 }
 
 int Main() {
-    Environment env {};
+    aFunEnvironment env{};
     Inter inter {env};
 
     auto obj = new Object("Object", inter);
@@ -260,6 +261,7 @@ int Main() {
 
     /* 执行错误的代码 */
     {
+        fputs_stdout("Test-a: error not var\n");
         auto code = Code("run-code.aun");
         code.getByteCode()->connect(new Code::ByteCode(code, "test-not-var", 1));
         inter.runCode(code);
@@ -267,8 +269,15 @@ int Main() {
         fputs_stdout("\n");
     }
 
-    /* 不会执行的代码 */
-    inter.setInterExit();
+    {
+        fputs_stdout("Test-last: {exit}\n");
+        auto code = Code("run-code.aun");
+        code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_c,
+                                                       new Code::ByteCode(code, "exit", 1), 0));
+        inter.runCode(code);
+        printInterEvent(inter);
+        fputs_stdout("\n");
+    }
 
     {
         auto code = Code("run-code.aun");