Bladeren bron

feat: runtime添加tool工具包

SongZihuan 3 jaren geleden
bovenliggende
commit
00ab596b23

+ 0 - 1
include/core/env.h

@@ -48,7 +48,6 @@ AFUN_CORE_EXPORT void enableEnvironment(af_Environment *env);
 AFUN_CORE_EXPORT void setGcMax(size_t max, af_Environment *env);
 AFUN_CORE_EXPORT void setGcRun(enum GcRunTime grt, af_Environment *env);
 AFUN_CORE_EXPORT char setPrefix(size_t name, char prefix, af_Environment *env);
-AFUN_CORE_EXPORT bool addVarToProtectVarSpace(af_Var *var, af_Environment *env);
 AFUN_CORE_EXPORT void setCoreStop(af_Environment *env);
 AFUN_CORE_EXPORT void setCoreExit(int exit_code, af_Environment *env);
 AFUN_CORE_EXPORT void setCoreNormal(af_Environment *env);

+ 1 - 0
include/core/var.h

@@ -39,6 +39,7 @@ AFUN_CORE_EXPORT bool makeVarToVarSpaceList(char *name, char p_self, char p_post
                                             af_VarSpaceListNode *vsl, af_Object *visitor, af_Environment *env);
 AFUN_CORE_EXPORT bool makeVarToProtectVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj,
                                                af_Environment *env);
+AFUN_CORE_EXPORT bool addVarToProtectVarSpace(af_Var *var, af_Environment *env);
 AFUN_CORE_EXPORT bool delVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *vsl);
 AFUN_CORE_EXPORT bool setVarToVarList(char *name, af_Object *obj, af_Object *visitor, af_VarSpaceListNode *vsl);
 AFUN_CORE_EXPORT af_VarSpaceListNode *pushNewVarList(af_Object *belong, af_VarSpaceListNode *base, af_Environment *env);

+ 6 - 0
include/runtime/aFun_tool.h

@@ -0,0 +1,6 @@
+#ifndef AFUN_AFUN_TOOL_H
+#define AFUN_AFUN_TOOL_H
+
+AFUN_LANG_EXPORT int aFunTool(char *name, af_Code **code, af_Object *visitor, af_VarSpace *vs, af_Environment *env);
+
+#endif //AFUN_AFUN_TOOL_H

+ 2 - 0
include/runtime/aFunlang.h

@@ -3,6 +3,8 @@
 #include "aFunlangExport.h"
 #include "aFunCore.h"
 
+#include "aFun_tool.h"
+
 AFUN_LANG_EXPORT void aFunInit();
 
 AFUN_LANG_EXPORT af_Environment *creatAFunEnviroment(void);

+ 0 - 4
src/core/env.c

@@ -647,10 +647,6 @@ void freeEnvironment(af_Environment *env) {
     free(env);
 }
 
-bool addVarToProtectVarSpace(af_Var *var, af_Environment *env) {
-    return addVarToVarSpace(var, NULL, env->core->protect);
-}
-
 static af_TopMsgProcess *makeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func) {
     af_TopMsgProcess *mp = calloc(1, sizeof(af_TopMsgProcess));
     mp->type = strCopy(type);

+ 15 - 0
src/core/var.c

@@ -281,6 +281,21 @@ bool makeVarToProtectVarSpace(char *name, char p_self, char p_posterity, char p_
     return re;
 }
 
+/*
+ * 函数名: addVarToProtectVarSpace
+ * 目标: 添加一个var变量添加到保护空间中
+ * 若已存在同名Var则返回false不作修改
+ * 否则返回true
+ * 调用 addVarToVarSpace
+ */
+bool addVarToProtectVarSpace(af_Var *var, af_Environment *env) {
+    env->core->protect->is_protect = false;
+    bool re = addVarToVarSpace(var, NULL, env->core->protect);
+    env->core->protect->is_protect = true;
+    return re;
+}
+
+
 static bool checkVarSpaceDelPermissions(af_Object *visitor, af_VarSpace *vs) {
     char p = vs->permissions[2];  // 默认外部权限
 

+ 0 - 1
src/main.c

@@ -871,7 +871,6 @@ int main() {
     }
 
     printf("\n");
-    enableEnvironment(env);
 
     {  // 正常程序
         printf("TAG A:\n");

+ 8 - 1
src/runtime/CMakeLists.txt

@@ -2,6 +2,10 @@
      LIST_DIRECTORIES FALSE
      ${CMAKE_CURRENT_LIST_DIR}/*.c)
 
+file(GLOB source_tool
+     LIST_DIRECTORIES FALSE
+     ${CMAKE_CURRENT_LIST_DIR}/aFunTool/*.c)
+
 file(GLOB private_h
      LIST_DIRECTORIES FALSE
      ${CMAKE_CURRENT_LIST_DIR}/*.h)
@@ -33,10 +37,13 @@ add_library(aFun-cx-libs SHARED "")  # cx表示仅core动态链接 core-share-c
 add_library(aFun-ct-libs SHARED "")  # ct表示均静态链接 core-static-s
 
 foreach(tgt aFun-xx-libs aFun-cx-libs aFun-ct-libs)
-    target_sources(${tgt} PRIVATE ${source} ${private_h} ${private_h_core} PUBLIC ${public_h_build} ${public_h_install})
+    target_sources(${tgt}
+                   PRIVATE ${source} ${source_tool} ${private_h} ${private_h_core}
+                   PUBLIC ${public_h_build} ${public_h_install})
     target_include_directories(${tgt}
                                PRIVATE
                                    "${CMAKE_CURRENT_LIST_DIR}/../core"
+                                   "${CMAKE_CURRENT_LIST_DIR}"  # aFunTool内的程序需要使用
                                PUBLIC
                                    $<BUILD_INTERFACE:${build_include_runtime}>
                                    $<INSTALL_INTERFACE:${install_include_runtime}>)

+ 61 - 0
src/runtime/__aFun_tool.h

@@ -0,0 +1,61 @@
+#ifndef AFUN_AFUN_TOOL_H_
+#define AFUN_AFUN_TOOL_H_
+#include "aFunlang.h"
+#include "aFun_tool.h"
+#include "__env.h"
+
+/*
+ * 返回 (0/1) 执行正常
+ * 返回 其他执行错误
+ */
+typedef int aFunToolFunction(af_Code **code, af_Object *visitor, af_VarSpace *vs, af_Environment *env);
+
+typedef struct ToolFunc ToolFunc;
+struct ToolFunc {
+    char *name;
+    aFunToolFunction *func;
+};
+
+typedef struct APIFunc APIFunc;
+struct APIFunc {
+    char *name;
+    objectAPIFunc *func;
+};
+
+typedef struct ObjectDefine ObjectDefine;
+struct ObjectDefine {
+    char *id;
+
+    bool free_api;
+    af_ObjectAPI *api;
+    struct APIFunc *api_list;  // api和api_list只能二选一
+
+    bool allow_inherit;
+    af_Object *belong;
+    af_Inherit *inherit;  // TODO-szh 继承表生成工具
+
+    char *var_name;
+    char p_self, p_posterity, p_external;
+
+    af_Object **save;  // obj保存位置
+};
+
+typedef struct LiteralFunc LiteralFunc;
+struct LiteralFunc {
+    char *pattern;
+    char *func;
+    bool in_protect;
+};
+
+typedef struct TopMsgFunc TopMsgFunc;
+struct TopMsgFunc {
+    char *type;
+    TopMsgProcessFunc *func;
+};
+
+AFUN_LANG_NO_EXPORT af_ObjectAPI *makeAPIFromList(const APIFunc api_list[]);
+AFUN_LANG_NO_EXPORT void makeObjectFromList(const ObjectDefine obj_def[], af_Object *visitor, af_VarSpace *vs, af_Environment *env);
+AFUN_LANG_NO_EXPORT void makeLiteralRegexFromList(const LiteralFunc literal_list[], af_Environment *env);
+AFUN_LANG_NO_EXPORT void makeTopMsgProcessFromList(const TopMsgFunc top_msg_list[], af_Environment *env);
+
+#endif //AFUN_AFUN_TOOL_H_

+ 6 - 0
src/runtime/__rt_tool.h

@@ -0,0 +1,6 @@
+#ifndef AFUN___RT_TOOL_H
+#define AFUN___RT_TOOL_H
+
+AFUN_LANG_NO_EXPORT int aFunTool_base(af_Code **code, af_Object *visitor, af_VarSpace *vs, af_Environment *env);
+
+#endif //AFUN___RT_TOOL_H

+ 7 - 0
src/runtime/aFunTool/base.c

@@ -0,0 +1,7 @@
+#include "__aFun_tool.h"
+
+// 桩函数
+int aFunTool_base(af_Code **code, af_Object *visitor, af_VarSpace *vs, af_Environment *env) {
+    printf("Run aFunTool-Base %p\n", vs);
+    return 0;
+}

+ 86 - 0
src/runtime/aFun_tool.c

@@ -0,0 +1,86 @@
+#include "__aFun_tool.h"
+#include "__rt_tool.h"
+
+/* 数组为只读的内容 */
+static const ToolFunc global_tool_list[] = {
+        {.name="base", .func=aFunTool_base},
+        {.name=NULL, .func=NULL},
+};
+
+/*
+ * 返回 (0)   执行正常
+ * 返回 (1)  库不存在
+ *
+ * 必须传入: code
+ */
+int aFunTool(char *name, af_Code **code, af_Object *visitor, af_VarSpace *vs, af_Environment *env) {
+    if (code == NULL || env == NULL || vs == NULL)
+        return 1;
+    *code = NULL;
+    for (const ToolFunc *tf = global_tool_list; global_tool_list->name != NULL; tf++) {
+        if (EQ_STR(tf->name, name)) {
+            int exit_code = tf->func(code, visitor, vs, env);
+            if (exit_code == 1)  // 将 exit_code 映射到0
+                return 0;
+            return exit_code;
+        }
+    }
+    return 1;
+}
+
+/*
+ * 函数名: makeAPIFromList
+ * 目标: 根据APIFunc生成api表并写入数据
+ */
+af_ObjectAPI *makeAPIFromList(const APIFunc api_list[]) {
+    af_ObjectAPI *api = makeObjectAPI();
+
+    for (const APIFunc *af = api_list; af->name != NULL; af++) {
+        DLC_SYMBOL(objectAPIFunc) func = MAKE_SYMBOL(af->func, objectAPIFunc);
+        addAPI(func, af->name, api);
+        FREE_SYMBOL(func);
+    }
+
+    return api;
+}
+
+/*
+ * 函数名: makeObjectFromList
+ * 目标: 根据ObjectDefine生成Object, 并保存到对应位置和变量空间中
+ */
+void makeObjectFromList(const ObjectDefine obj_def[], af_Object *visitor, af_VarSpace *vs, af_Environment *env) {
+    for (const ObjectDefine *od = obj_def; od->id != NULL; od++) {
+        af_ObjectAPI *api = od->api;
+        if (api == NULL)
+            api = makeAPIFromList(od->api_list);
+
+        af_Object *obj = makeObject(od->id, od->free_api, api, od->allow_inherit, od->belong, od->inherit, env);
+        if (od->save != NULL)
+            *(od->save) = obj;
+        if (vs != NULL && od->var_name != NULL) {
+            if (!makeVarToVarSpace(od->var_name, od->p_self, od->p_posterity, od->p_external, obj, vs, visitor, env))
+                setVarToVarSpace(od->var_name, obj, visitor, vs);  // 若失败则尝试直接设定变量
+        }
+    }
+}
+
+/*
+ * 函数名: makeLiteralRegexFromList
+ * 目标: 根据LiteralFunc压入新的字面量处理器
+ */
+void makeLiteralRegexFromList(const LiteralFunc literal_list[], af_Environment *env) {
+    for (const LiteralFunc *lt = literal_list; lt->pattern != NULL; lt++)
+        pushLiteralRegex(lt->pattern, lt->func, lt->in_protect, env);
+}
+
+/*
+ * 函数名: makeTopMsgProcessFromList
+ * 目标: 根据TopMsgFunc压入新的字面量处理器
+ */
+void makeTopMsgProcessFromList(const TopMsgFunc top_msg_list[], af_Environment *env) {
+    for (const TopMsgFunc *tml = top_msg_list; tml->type != NULL; tml++) {
+        DLC_SYMBOL(TopMsgProcessFunc) func = MAKE_SYMBOL(tml->func, TopMsgProcessFunc);
+        addTopMsgProcess(tml->type, func, env);
+        FREE_SYMBOL(func);
+    }
+}

+ 14 - 1
src/runtime/aFunlang.c

@@ -8,7 +8,20 @@ void aFunInit() {
 
 af_Environment *creatAFunEnviroment(void) {
     af_Environment *env = makeEnvironment(grt_count);
-    /* 内置量操作 */
+    af_Code *code;
+
+    aFunTool("base", &code, NULL, env->core->protect, env);
+
+    if (code != NULL) {
+        bool res = iterCode(code, 0, env);
+        freeAllCode(code);
+        if (!res) {
+            freeEnvironment(env);
+            return NULL;
+        }
+    }
+
+    enableEnvironment(env);
     return env;
 }