소스 검색

refactor & feat: 添加Import函数

SongZihuan 3 년 전
부모
커밋
a4cdae2d98

+ 12 - 0
include/core/core-exception.h

@@ -13,6 +13,18 @@ namespace aFuncore {
         inline EnvironmentDestructException();
     };
 
+    class RuntimeError : public aFuncoreException {
+        std::string type;
+    public:
+        inline RuntimeError(const std::string &msg, std::string type);
+        inline const std::string &getType() const;
+    };
+
+    class ArgumentError : public RuntimeError {
+        std::string type;
+    public:
+        inline ArgumentError();
+    };
 }
 
 #include "core-exception.inline.h"

+ 14 - 0
include/core/core-exception.inline.h

@@ -1,5 +1,7 @@
 #ifndef AFUN_CORE_EXCEPTION_INLINE_H
 #define AFUN_CORE_EXCEPTION_INLINE_H
+#include <utility>
+
 #include "core-exception.h"
 
 namespace aFuncore {
@@ -10,6 +12,18 @@ namespace aFuncore {
     inline EnvironmentDestructException::EnvironmentDestructException() : aFuncoreException("Environment Destruct Error") {
 
     }
+
+    inline RuntimeError::RuntimeError(const std::string &msg, std::string type_) : aFuncoreException(msg), type{std::move(type_)} {
+
+    }
+
+    inline const std::string &RuntimeError::getType() const {
+        return type;
+    }
+
+    inline ArgumentError::ArgumentError() : RuntimeError("Argument mismatch", "ArgumentError") {
+
+    }
 }
 
 #endif //AFUN_CORE_EXCEPTION_INLINE_H

+ 34 - 0
include/runtime/func-import.h

@@ -0,0 +1,34 @@
+#ifndef AFUN_FUNC_IMPORT_H
+#define AFUN_FUNC_IMPORT_H
+#include "aFunlangExport.h"
+#include "aFuncore.h"
+
+namespace aFunrt {
+    class ImportFunction : public aFuncore::Function {
+        class CallFunc : public CallFunction {
+            const aFuncore::Code::ByteCode *call_code;
+            aFuncore::Inter &inter;
+            std::list<ArgCodeList> *acl;
+            std::string import;
+        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 ImportFunction(aFuncore::Inter &inter_);
+        inline explicit ImportFunction(aFuncore::Environment &env_);
+        ~ImportFunction() override = default;
+
+        CallFunction *getCallFunction(const aFuncore::Code::ByteCode *code, aFuncore::Inter &inter) override;
+    };
+}
+
+#include "func-import.inline.h"
+
+#endif //AFUN_FUNC_IMPORT_H

+ 15 - 0
include/runtime/func-import.inline.h

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

+ 1 - 0
include/tool/tool-exception.h

@@ -8,6 +8,7 @@ namespace aFuntool {
     public:
         inline explicit aFunException(std::string msg);
         virtual const char *what();
+        inline const std::string &getMessage() const;
     };
 
     class aFuntoolException : public aFunException {

+ 4 - 0
include/tool/tool-exception.inline.h

@@ -8,6 +8,10 @@ namespace aFuntool {
 
     }
 
+    inline const std::string &aFunException::getMessage() const {
+        return message;
+    }
+
     inline aFuntoolException::aFuntoolException(const std::string &msg) : aFunException{msg} {
 
     }

+ 8 - 2
src/core/activation.cpp

@@ -3,6 +3,7 @@
 #include "core-init.h"
 #include "msg.h"
 #include "code.h"
+#include "core-exception.h"
 
 namespace aFuncore {
     /**
@@ -232,8 +233,13 @@ namespace aFuncore {
 
             /* Label: 执行变量获取前的准备 */
             status = func_get_arg;
-            call_func = func->getCallFunction(call, inter);
-            acl = call_func->getArgCodeList(inter, *this, call);
+            try {
+                call_func = func->getCallFunction(call, inter);
+                acl = call_func->getArgCodeList(inter, *this, call);
+            } catch (RuntimeError &e) {
+                down.pushMessage("ERROR", new ErrorMessage(e.getType(), e.getMessage(), this));
+                return as_end;
+            }
             acl_begin = acl->begin();
             acl_end = acl->end();
             if (acl_begin != acl_end) {  // 如果有参数需要计算

+ 35 - 0
src/runtime/func-import.cpp

@@ -0,0 +1,35 @@
+#include "func-import.h"
+
+namespace aFunrt {
+    aFuncore::Function::CallFunction *ImportFunction::getCallFunction(const aFuncore::Code::ByteCode *code, aFuncore::Inter &inter) {
+        return dynamic_cast<CallFunction *>(new CallFunc(code, inter));
+    }
+
+    ImportFunction::CallFunc::CallFunc(const aFuncore::Code::ByteCode *code_, aFuncore::Inter &inter_) : call_code{code_}, inter{inter_} {
+        if (code_ == nullptr ||
+            code_->getSon() == nullptr ||
+            code_->getSon()->toNext() == nullptr ||
+            code_->getSon()->toNext()->getType() != aFuncore::Code::ByteCode::code_element)
+            throw aFuncore::ArgumentError();
+        acl = new std::list<ArgCodeList>;
+        import = code_->getSon()->toNext()->getElement();
+    }
+
+    std::list<aFuncore::Function::CallFunction::ArgCodeList> *ImportFunction::CallFunc::getArgCodeList(aFuncore::Inter &inter_,
+                                                                                                       aFuncore:: Activation &activation,
+                                                                                                       const aFuncore::Code::ByteCode *call) {
+        return acl;
+    }
+
+    void ImportFunction::CallFunc::runFunction() {
+        auto &stream = inter.getActivation()->getDownStream();
+        auto none = new aFuncore::Object("None", inter);
+        stream.pushMessage("NORMAL", new aFuncore::NormalMessage(none));
+        none->delReference();
+        aFuntool::cout << "Import " << import << "\n";
+    }
+
+    ImportFunction::CallFunc::~CallFunc() {
+        delete acl;
+    }
+}

+ 4 - 1
src/runtime/rt-inter.cpp

@@ -1,5 +1,6 @@
 #include "rt-inter.h"
 #include "func-exit.h"
+#include "func-import.h"
 
 namespace aFunrt {
     aFunEnvironment::aFunEnvironment(int argc, char **argv) : Environment(argc, argv)  {
@@ -10,7 +11,9 @@ namespace aFunrt {
         }
 
         {  // 导入函数
-
+            auto import = new ImportFunction(*this);
+            protect->defineVar("import", import);
+            import->delReference();
         }
     }
 }

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

@@ -241,9 +241,23 @@ int Main() {
         fputs_stdout("\n");
     }
 
+    {
+        fputs_stdout("Test-7: {import test}\n");
+        auto code = Code("run-code.aun");
+
+        auto arg = new Code::ByteCode(code, "import", 1);
+        arg->connect(new Code::ByteCode(code, "test", 1));
+
+        code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_c, arg, 0));
+
+        inter.runCode(code);
+        printInterEvent(inter);
+        fputs_stdout("\n");
+    }
+
     {
         /* 多线程 */
-        fputs_stdout("Test-7: thread\n");
+        fputs_stdout("Test-8: thread\n");
         Inter son{inter};
         std::thread thread{thread_test, std::ref(son)};