Browse Source

refactor & feat: 基础框架

SongZihuan 3 years ago
parent
commit
3f74e78d09

+ 20 - 11
include/core/activation.hpp

@@ -17,31 +17,40 @@ namespace aFuncore {
     class Activation {
     protected:
         Activation *prev;
-        Inter *inter;
-
-        UpMessage *up;
-        DownMessage *down;
 
         VarList *varlist;
         VarList *old_varlist;
 
+        UpMessage *up;
+        DownMessage *down;
+    public:
+        Inter *const inter;
+
         StringFilePath path;
         FileLine line;
-    public:
-        Activation(Inter *inter_, Activation *prev_);
+
+        explicit Activation(Inter *inter_);
         virtual ~Activation();
+
         virtual Code *getCode()=0;
-        [[nodiscard]] StringFilePath getFilePath() const {return path;}
-        [[nodiscard]] FileLine getFileLine() const {return line;}
+        virtual bool onTail()=0;
+
+        [[nodiscard]] VarList *getVarlist() const {return varlist;}
+        [[nodiscard]] Activation *toPrev() const {return prev;}
+        [[nodiscard]] UpMessage *getUpStream() const {return up;}
+        [[nodiscard]] DownMessage *getDownStream() const {return down;}
     };
 
-    class TopActivation {
+    class TopActivation : public Activation {
         Code *start;
         Code *next;
     public:
-        Code *getCode();
-    };
+        explicit TopActivation(Code *code, Inter *inter_);
+        ~TopActivation() override;
 
+        Code *getCode() override;
+        bool onTail() override {return false;}
+    };
 }
 
 #endif //AFUN_ACTIVATION_HPP

+ 4 - 7
include/core/env-var.hpp

@@ -4,28 +4,25 @@
 #include "aFunCoreExport.h"
 
 namespace aFuncore {
-    static const size_t ENV_VAR_HASH_SIZE = 100;  // 环境变量哈希表大小
     class EnvVarSpace {  // 环境变量
-        friend class Inter;
-
+    public:
+        static const size_t ENV_VAR_HASH_SIZE = 100;  // 环境变量哈希表大小
         struct EnvVar {  // 环境变量
             std::string name;
             std::string str;
             int32_t num = 0;  // 可以同时记录字符串和数字
             struct EnvVar *next = nullptr;
         };
-
+    private:
         size_t count;
         EnvVar *var[ENV_VAR_HASH_SIZE] {};
         pthread_rwlock_t lock;
-
-        EnvVar *findVar(const std::string &name);
     public:
         AFUN_CORE_EXPORT EnvVarSpace();
         AFUN_CORE_EXPORT ~EnvVarSpace();
 
         [[nodiscard]] size_t getCount() const {return count;}
-
+        [[nodiscard]] EnvVar *findVar(const std::string &name);
         AFUN_CORE_EXPORT bool findString(const std::string &name, std::string &str) const;
         AFUN_CORE_EXPORT bool findNumber(const std::string &name, int32_t &num) const;
 

+ 0 - 1
include/core/init.hpp

@@ -6,7 +6,6 @@
 namespace aFuncore {
     struct InitInfo {
         const std::string &base_dir;
-
         bool log_asyn;
         aFuntool::LogLevel level;
     };

+ 32 - 11
include/core/inter.hpp

@@ -26,6 +26,15 @@ namespace aFuncore {
         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"
@@ -36,11 +45,11 @@ namespace aFuncore {
 
 namespace aFuncore {
     class Inter {
-        /* 解释器原信息记录 */
         friend class Object;
         friend class Var;
         friend class VarSpace;
 
+        /* 解释器原信息记录 */
         pthread_mutex_t status_lock;  // status 可能被外部使用, 因此需要用锁保护
         InterStatus status;
 
@@ -50,6 +59,7 @@ namespace aFuncore {
             Var *var;
             VarSpace *varspace;
         } *gc;
+        [[nodiscard]] struct GcRecord *getGcRecord() const {return gc;}
 
         /* 运行相关 */
         ProtectVarSpace *protect;  // 保护变量空间
@@ -63,7 +73,7 @@ namespace aFuncore {
             char *func;  // 调用的函数
             bool in_protect;  // 是否在protect空间
         };
-        std::list<LiteralRegex *> *literal;
+        std::list<LiteralRegex> *literal;
 
         /* 配置信息记录器 */
         EnvVarSpace *envvar;
@@ -74,13 +84,14 @@ namespace aFuncore {
         EnvVarSpace::EnvVar *error_std;  // Error输出的位置 0-stdout 其他-stderr
 
         /* 线程信息 */
-        bool is_derive;  // 是否派生
-        Inter *base;  // 主线程
+    public:
+        const bool is_derive;  // 是否派生
+        Inter *const base;  // 主线程
+    private:
         Object *result;  // 线程执行的结果
         std::list<Inter *> *son_inter;  // 派生线程链表, 由主线程负责管理
 
         pthread_t monitor;  // 守护线程
-
         ExitFlat exit_flat;  // 外部设置退出
         ExitMode exit_mode;  // 退出模式
         pthread_mutex_t monitor_lock;
@@ -90,13 +101,23 @@ namespace aFuncore {
         ~Inter();
         void enable();
 
-        Var *findGlobalVar(const std::string &name);
-        VarOperationFlat defineGlobalVar(const std::string &name, Object *data);
-        VarOperationFlat defineGlobalVar(const std::string &name, Var *data);
-        VarOperationFlat setGlobalVar(const std::string &name, Object *data);
-        VarOperationFlat delGlobalVar(const std::string &name);
-        Object *findGlobalObject(const std::string &name);
+        [[nodiscard]] InterStatus getStatus() const {return status;}
+        [[nodiscard]] bool isExit() const {return (status == inter_exit || status == inter_stop);}
+
+        [[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;}
 
+        bool runCode();
         bool runCode(Code *code);
     };
 }

+ 34 - 7
include/core/msg.hpp

@@ -5,19 +5,39 @@
 
 namespace aFuncore {
     class MessageStream;
+    class Message;
+    class NormalMessage;
+    class UpMessage;
+    class DownMessage;
+}
+
+#include "value.hpp"
 
+namespace aFuncore {
     class Message {
-        std::string type;  // 消息类型标注
+        friend class MessageStream;
+        friend class UpMessage;
+        friend class DownMessage;
+
         Message *next;  // 下一条消息
+    public:
+        const std::string type;  // 消息类型标注
+        AFUN_CORE_EXPORT explicit Message(const std::string &type_) : type {type_}, next {nullptr} {}
+        AFUN_CORE_EXPORT virtual ~Message() = default;
+    };
 
-    friend class MessageStream;
-    friend class UpMessage;
-    friend class DownMessage;
+    class TopMessage : public Message {
+    public:
+        explicit TopMessage(const std::string &type_) : Message(type_) {}
+        virtual void topProgress()=0;
+    };
 
+    class NormalMessage : public TopMessage {
+        Object *obj;
     public:
-        AFUN_CORE_EXPORT explicit Message(const std::string &type_) : type {type_}, next {nullptr} {};
-        AFUN_CORE_EXPORT virtual ~Message() = default;
-        [[nodiscard]] const std::string &getType() const {return type;}
+        AFUN_CORE_EXPORT explicit NormalMessage(Object *obj);
+        AFUN_CORE_EXPORT ~NormalMessage() override;
+        void topProgress() override;
     };
 
     class MessageStream {
@@ -38,6 +58,13 @@ namespace aFuncore {
 
         virtual AFUN_CORE_EXPORT Message *popMessage(const std::string &type);
         AFUN_CORE_EXPORT void pushMessage(Message *msg);
+
+        template <typename T>
+        AFUN_CORE_EXPORT void forEach(void (*func)(Message *, T), T arg) {
+            for (Message *msg = stream; msg != nullptr; msg = msg->next) {
+                func(msg, arg);
+            }
+        }
     };
 
     class UpMessage : public MessageStream {

+ 2 - 2
include/core/value.hpp

@@ -12,10 +12,10 @@ namespace aFuncore {
 
 namespace aFuncore {
     class Object : public GcObject<class Object> {
-        friend class Inter;
-        Inter *inter;
     public:
+        Inter *const inter;
         const std::string type;  // 标识 Object 的字符串
+
         AFUN_CORE_EXPORT explicit Object(const std::string &type, Inter *inter_);
         AFUN_CORE_EXPORT ~Object() override =default;
     };

+ 18 - 13
include/core/var.hpp

@@ -4,8 +4,6 @@
 #include "aFunCoreExport.h"
 
 namespace aFuncore {
-    static const size_t VAR_HASH_SIZE = 100;  // 环境变量哈希表大小
-
     typedef enum VarOperationFlat {
         vof_success = 0,  // 成功
         vof_not_var = 1,  // 变量不存在
@@ -24,20 +22,21 @@ namespace aFuncore {
 
 namespace aFuncore {
     class Var : public GcObject<class Var> {
-        friend class Inter;
-        Inter *inter;
         Object *data;
     public:
+        Inter *const inter;
+
         Var(Object *data_, Inter *inter_);
         ~Var() override =default;
 
-        virtual Object *getData() {return data;}
+        [[nodiscard]] virtual Object *getData() {return data;}
         virtual void setData(Object *data_) {data = data_;}
     };
 
     class VarSpace : public GcObject<class VarSpace> {
-        friend class Inter;
-        Inter *inter;
+    public:
+        static const size_t VAR_HASH_SIZE = 100;  // 环境变量哈希表大小
+    private:
         struct VarCup {
             std::string name;
             Var *var;
@@ -46,16 +45,18 @@ namespace aFuncore {
         size_t count;
         VarCup *var[VAR_HASH_SIZE];
     public:
+        Inter *const inter;
         explicit VarSpace(Inter *inter_);
         ~VarSpace() override;
 
-        virtual Var *findVar(const std::string &name);
+        [[nodiscard]] size_t getCount() const {return count;}
+        [[nodiscard]] virtual Var *findVar(const std::string &name);
         virtual VarOperationFlat defineVar(const std::string &name, Object *data);
         virtual VarOperationFlat defineVar(const std::string &name, Var *data);
         virtual VarOperationFlat setVar(const std::string &name, Object *data);
         virtual VarOperationFlat delVar(const std::string &name);
 
-        Object *findObject(const std::string &name) {
+        [[nodiscard]] Object *findObject(const std::string &name) {
             Var *ret = findVar(name);
             return ret ? ret->getData() : nullptr;
         }
@@ -65,8 +66,10 @@ namespace aFuncore {
         bool is_protect;
     public:
         explicit ProtectVarSpace(Inter *inter_) : VarSpace(inter_), is_protect{false} {}
+
         [[nodiscard]]bool getProtect() const {return is_protect;};
         bool setProtect(bool protect) {bool ret = is_protect; is_protect = protect; return ret;}
+
         VarOperationFlat defineVar(const std::string &name, Object *data) override;
         VarOperationFlat defineVar(const std::string &name, Var *data) override;
         VarOperationFlat setVar(const std::string &name, Object *data) override;
@@ -74,25 +77,27 @@ namespace aFuncore {
     };
 
     class VarList {
-        VarSpace *const varspace;
         VarList *next;
     public:
+        VarSpace *const varspace;
+
         explicit VarList(VarSpace *vs) : varspace {vs}, next {nullptr} {};
         void destructAll();
 
-        virtual Var *findVar(const std::string &name);
+        [[nodiscard]] virtual Var *findVar(const std::string &name);
         virtual bool defineVar(const std::string &name, Object *data);
         virtual bool defineVar(const std::string &name, Var *data);
         virtual bool setVar(const std::string &name, Object *data);
         virtual bool delVar(const std::string &name);
-        Object *findObject(const std::string &name) {
+        [[nodiscard]] Object *findObject(const std::string &name) {
             Var *var = findVar(name);
             return var ? var->getData() : nullptr;
         }
 
-        VarList *toNext() {return next;}
+        [[nodiscard]] VarList *toNext() const {return next;}
         VarList *connect(VarList *varlist) {next = varlist; return this;}
         void disconnect(VarList *varlist);
+        void disconnectNext() {next = nullptr;}
     };
 }
 

+ 1 - 0
include/tool/regex.hpp

@@ -16,6 +16,7 @@ namespace aFuntool {
         AFUN_TOOL_EXPORT explicit Regex (const std::string &pattern_);
         AFUN_TOOL_EXPORT ~Regex ();
         AFUN_TOOL_EXPORT int match(const char *subject);
+        AFUN_TOOL_EXPORT int match(const std::string &subject) {return match(subject.c_str());}
     };
 }
 

+ 44 - 8
src/core/activation.cpp

@@ -1,25 +1,61 @@
 #include "activation.hpp"
-
 using namespace aFuncore;
 using namespace aFuntool;
 
-Activation::Activation(Inter *inter_, Activation *prev_)
-        : inter{inter_}, prev{prev_}, old_varlist{prev_->varlist},
-          varlist{}, line{0}{
-    up = new UpMessage(prev ? prev->up : nullptr);
-    down = new DownMessage();
+Activation::Activation(Inter *inter_) : inter{inter_}, line{0} {
+    Activation *prev_ = inter->getActivation();
+    if (prev_ != nullptr && prev_->onTail()) {
+        prev = prev_->prev;
+        up = prev_->up;
+        down = prev_->down;
+        old_varlist = prev_->old_varlist;
+        varlist = prev_->varlist;
+
+        prev_->up = nullptr;
+        prev_->down = nullptr;
+        prev_->old_varlist = nullptr;
+        prev_->varlist = nullptr;
+        delete prev_;
+    } else {
+        prev = prev_;
+        old_varlist = prev ? prev->varlist : nullptr;
+        varlist = old_varlist;
+        down = new DownMessage();
+        up = new UpMessage(prev ? prev->up : nullptr);
+    }
+    inter->pushActivation(this);
 }
 
 Activation::~Activation(){
-    varlist->disconnect(old_varlist);
-    if (prev)
+    if (varlist != nullptr && old_varlist != nullptr)
+        varlist->disconnect(old_varlist);
+    if (prev && down != nullptr)
         down->joinMsg(prev->down);
     delete up;
     delete down;
 }
 
+TopActivation::TopActivation(Code *code, Inter *inter_)
+    : Activation(inter_), start{code}, next{code} {
+    varlist = inter_->getGlobalVarlist();
+    old_varlist = varlist;
+}
+
+static void ActivationTopProgress(Message *msg, void *) {
+    auto *t = dynamic_cast<TopMessage *>(msg);
+    if (t)
+        t->topProgress();
+};
+
+TopActivation::~TopActivation() {
+    down->forEach<void *>(ActivationTopProgress, nullptr);
+}
+
 Code *TopActivation::getCode(){
     Code *ret = next;
+    if (ret == nullptr)
+        return nullptr;
+
     next = ret->toNext();
     return ret;
 }

+ 86 - 21
src/core/inter.cpp

@@ -1,11 +1,12 @@
 #include "inter.hpp"
+#include "init.hpp"
 #include "__gc.hpp"
 
 using namespace aFuncore;
 using namespace aFuntool;
 
 
-Inter::Inter(int argc, char **argv, ExitMode em) : status_lock{}, monitor_lock{}, monitor_cond{} {
+Inter::Inter(int argc, char **argv, ExitMode em) : status_lock{}, monitor{}, monitor_lock{}, monitor_cond{} {
     status = inter_creat;
     pthread_mutex_init(&status_lock, nullptr);
 
@@ -15,6 +16,7 @@ Inter::Inter(int argc, char **argv, ExitMode em) : status_lock{}, monitor_lock{}
     gc->varspace = nullptr;
 
     activation = nullptr;
+    literal = new std::list<LiteralRegex>;
 
     envvar = new EnvVarSpace();
     gc_runtime = envvar->findVar("sys:gc-runtime");
@@ -39,8 +41,6 @@ Inter::Inter(int argc, char **argv, ExitMode em) : status_lock{}, monitor_lock{}
     result = nullptr;
     son_inter = new std::list<Inter *>;
 
-    monitor = 0;
-
     exit_flat = ef_none;
     exit_mode = em;
 
@@ -65,6 +65,7 @@ Inter::~Inter(){
         Var::destruct(gc->var);
         VarSpace::destruct(gc->varspace);
 
+        delete literal;
         delete gc;
         delete son_inter;
         delete envvar;
@@ -78,30 +79,94 @@ void Inter::enable(){
     }
 }
 
-Var *Inter::findGlobalVar(const std::string &name) {
-    return global->findVar(name);
-}
-
-VarOperationFlat Inter::defineGlobalVar(const std::string &name, Object *data) {
-    return global->defineVar(name, data);
+bool Inter::isExit() const{
+    bool ret = (status == inter_exit || status == inter_stop);
+    return ret;
 }
 
-VarOperationFlat Inter::defineGlobalVar(const std::string &name, Var *data) {
-    return global->defineVar(name, data);
+bool Inter::runCode(){
+    while (activation != nullptr) {
+        if (isExit()) {
+            // TODO-szh 弹出所有activation
+            return false;
+        }
+
+        Code *code = activation->getCode();
+        if (code == nullptr) {  // activation 执行完成
+            Activation *prev = activation->toPrev();
+            delete activation;
+            activation = prev;
+            continue;
+        }
+
+        auto code_type = code->getType();
+        if (code_type == code_start)
+            continue;
+
+        Message *msg = activation->getDownStream()->popMessage("NORMAL");
+        if (msg == nullptr) {
+            // ... 出现异常
+        }
+
+        delete msg;
+
+        if (code_type == code_element) {
+            std::string func;
+            bool in_protect = false;
+            if (checkLiteral(code->getElement(), func, in_protect)) {
+                // ...
+            } else {
+                auto varlist = activation->getVarlist();
+                Object *obj = nullptr;
+                if (varlist != nullptr)
+                    obj = varlist->findObject(code->getElement());
+                if (obj != nullptr)
+                    activation->getDownStream()->pushMessage(new NormalMessage(obj));
+            }
+
+        } else switch (code->getBlockType()) {
+            case block_p:
+                break;
+            case block_b:
+                break;
+            case block_c:
+                break;
+            default:
+                errorLog(aFunCoreLogger, "Error block type.");
+                break;
+        }
+    }
+    return true;
 }
 
-VarOperationFlat Inter::setGlobalVar(const std::string &name, Object *data) {
-    return global->setVar(name, data);
-}
+bool Inter::runCode(Code *code){
+    if (activation != nullptr) {
+        errorLog(aFunCoreLogger, "Run code with activation");
+        return false;
+    }
 
-VarOperationFlat Inter::delGlobalVar(const std::string &name) {
-    return global->delVar(name);
+    new TopActivation(code, this);
+    return runCode();
 }
 
-Object *Inter::findGlobalObject(const std::string &name) {
-    return global->findObject(name);
+bool Inter::checkLiteral(const std::string &element, std::string &func, bool &in_protect) 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;
+            func = it->func;
+            in_protect = it->in_protect;
+            return true;
+        } catch (RegexException &e) {
+            continue;
+        }
+    }
+    return false;
 }
 
-bool Inter::runCode(Code *code){
-    return 0;
-}

+ 12 - 0
src/core/msg.cpp

@@ -2,6 +2,18 @@
 using namespace aFuncore;
 using namespace aFuntool;
 
+NormalMessage::NormalMessage(Object *obj) : TopMessage("NORMAL") {
+    this->obj = obj;
+}
+
+NormalMessage::~NormalMessage(){
+    this->obj = nullptr;
+}
+
+void NormalMessage::topProgress(){
+    printf_stdout(0, "NORMAL: %p\n", obj);
+}
+
 MessageStream::MessageStream(){
     stream = nullptr;
 }

+ 1 - 1
src/core/value.cpp

@@ -6,6 +6,6 @@ using namespace aFuncore;
 using namespace aFuntool;
 
 aFuncore::Object::Object(const std::string &type_, Inter *inter_)
-    : type{type_}, inter{inter_->base} {
+        : type{type_}, inter{inter_->base} {
     this->addObject(inter->gc->obj);
 }

+ 4 - 1
src/core/var.cpp

@@ -33,6 +33,7 @@ VarOperationFlat aFuncore::VarSpace::defineVar(const std::string &name, Object *
     (*tmp) = new VarCup;
     (*tmp)->name = name;
     (*tmp)->var = new Var(data, inter);
+    count++;
     return vof_success;
 }
 
@@ -46,6 +47,7 @@ VarOperationFlat aFuncore::VarSpace::defineVar(const std::string &name, Var *dat
     (*tmp) = new VarCup;
     (*tmp)->name = name;
     (*tmp)->var = data;
+    count++;
     return vof_success;
 }
 
@@ -67,6 +69,7 @@ VarOperationFlat aFuncore::VarSpace::delVar(const std::string &name){
             auto del = tmp->next;
             tmp->next = del->next;
             delete del;  // 删除 VarCup
+            count--;
             return vof_success;
         }
     }
@@ -111,7 +114,7 @@ Var *aFuncore::VarList::findVar(const std::string &name){
     Var *ret = nullptr;
     for (auto tmp = this; tmp != nullptr && ret == nullptr; tmp = tmp->next)
         ret = tmp->varspace->findVar(name);
-    return nullptr;
+    return ret;
 }
 
 bool aFuncore::VarList::defineVar(const std::string &name, Object *data){

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

@@ -6,16 +6,11 @@ using namespace aFuntool;
 int main() {
     auto *inter = new Inter();
     auto *obj = new Object("Object", inter);
-    inter->defineGlobalVar("test-var", obj);
-
-    std::cout << "test-var = " << inter->findGlobalObject("test-var")
-              << " non-var = " << inter->findGlobalObject("non-var")
-              << " obj = " << obj
-              << std::endl;
+    inter->getGlobalVarlist()->defineVar("test-var", obj);
 
     auto *code = (new Code(0, "run-code.aun"));
     code->connect(new Code("test-var", 1));
-
+    inter->runCode(code);
     code->destructAll();
     delete inter;
     return 0;