瀏覽代碼

feat: 添加宏函数的执行

SongZihuan 3 年之前
父節點
當前提交
41a74e42ed
共有 7 個文件被更改,包括 221 次插入62 次删除
  1. 3 2
      include/env.h
  2. 1 0
      include/var.h
  3. 3 0
      src/core/__env.h
  4. 101 60
      src/core/env.c
  5. 15 0
      src/core/run.c
  6. 9 0
      src/core/var.c
  7. 89 0
      src/main.c

+ 3 - 2
include/env.h

@@ -32,13 +32,14 @@ af_Object *getBaseObject(char *name, af_Environment *env);
 af_Message *makeMessage(char *type, size_t size);
 af_Message *freeMessage(af_Message *msg);
 void freeAllMessage(af_Message *msg);
-void *getMessageData(af_Message *msg);
-void connectMessage(af_Message **base, af_Message *msg);
+bool freeMessageCount(size_t count, af_Message *msg);
 
 /* 消息管理函数 */
 void pushMessageUp(af_Message *msg, af_Environment *env);
 void *popMessageUpData(char *type, af_Environment *env);
 af_Message *popMessageUp(af_Environment *env);
+void *getMessageData(af_Message *msg);
+void connectMessage(af_Message **base, af_Message *msg);
 
 /* 下行消息表管理函数 */
 void pushMessageDown(af_Message *msg, af_Environment *env);

+ 1 - 0
include/var.h

@@ -42,6 +42,7 @@ af_Var *findVarFromVarList(char *name, af_VarSpaceListNode *vsl);
 af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs);
 af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl);
 void freeAllVarSpaceList(af_VarSpaceListNode *vsl);
+bool freeVarSpaceListCount(size_t count, af_VarSpaceListNode *vsl);
 
 /* 变量空间链管理 */
 af_VarSpaceListNode *pushNewVarList(af_VarSpaceListNode *base);

+ 3 - 0
src/core/__env.h

@@ -84,6 +84,8 @@ struct af_Activity {  // 活动记录器
     struct af_FuncInfo *fi;
     struct af_FuncBody *body_next;
     void *mark;  // 标记 [完全由API管理, 不随activity释放]
+    struct af_VarSpaceListNode *macro_vsl;  // 宏函数执行的vsl
+    ActivityCount macro_vs_count;
 
     /* 字面量专项 */
     bool is_literal;  // 处于字面量运算 意味着函数调用结束后会调用指定API
@@ -127,6 +129,7 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env);
 void popActivity(af_Message *msg, af_Environment *env);
 
 /* 运行时Activity设置函数 (设置Activity) */
+bool pushMacroFuncActivity(af_Object *func, af_Environment *env);
 bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env);
 bool setFuncActivityToArg(af_Object *func, af_Environment *env);
 bool setFuncActivityAddVar(bool new_vsl, bool is_protect, af_Environment *env);

+ 101 - 60
src/core/env.c

@@ -13,9 +13,12 @@ static af_Activity *makeActivity(af_Code *bt_top, af_Code *bt_start, bool return
                                  af_VarSpaceListNode *vsl, af_Object *belong, af_Object *func);
 static af_Activity *freeActivity(af_Activity *activity);
 static void freeAllActivity(af_Activity *activity);
+static void clearActivity(af_Activity *activity);
 
 /* 活动记录器相关处理函数 */
 static void freeMark(af_Environment *env);
+static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_Environment *env);
+static void freeMarkByActivity(af_Activity *activity);
 
 /* 环境变量创建与释放 */
 static af_EnvVar *makeEnvVar(char *name, char *data);
@@ -164,27 +167,18 @@ static af_Activity *makeActivity(af_Code *bt_top, af_Code *bt_start, bool return
 
 static af_Activity *freeActivity(af_Activity *activity) {
     af_Activity *prev = activity->prev;
-    af_VarSpaceListNode *vs = activity->var_list;
-    af_Message *msg_up = activity->msg_up;
 
     gc_delReference(activity->belong);
     if (activity->func != NULL)
         gc_delReference(activity->func);
 
     freeAllMessage(activity->msg_down);  // msg转移后需要将对应成员设置为NULL
-    for (int i = activity->msg_up_count; i > 0; i--) {
-        if (msg_up == NULL)  // 发生了错误
-            break;
-        msg_up = freeMessage(msg_up);
-    }
+    freeMessageCount(activity->msg_up_count, activity->msg_up);
 
     // vsl 是引用自 var_list和func_var_list的 故不释放
     // func_var_list 是引用自函数的 故不释放
-    for (int i = activity->new_vs_count; i > 0; i--) {
-        if (vs == NULL)  // 发生了错误
-            break;
-        vs = popLastVarList(vs);
-    }
+    freeVarSpaceListCount(activity->new_vs_count, activity->var_list);
+    freeVarSpaceListCount(activity->macro_vs_count, activity->macro_vsl);
 
     if (activity->return_obj != NULL)
         gc_delReference(activity->return_obj);
@@ -204,6 +198,28 @@ static void freeAllActivity(af_Activity *activity) {
         activity = freeActivity(activity);
 }
 
+static void clearActivity(af_Activity *activity) {
+    freeMarkByActivity(activity);
+    freeVarSpaceListCount(activity->macro_vs_count, activity->macro_vsl);
+    freeAllArgCodeList(activity->acl_start);
+    if (activity->fi != NULL)
+        freeFuncInfo(activity->fi);
+    if (activity->parentheses_call != NULL) {
+        gc_delReference(activity->parentheses_call);
+        activity->parentheses_call = NULL;
+    }
+
+    activity->func_var_list = NULL;
+    activity->bt_top = NULL;
+    activity->bt_start = NULL;
+    activity->bt_next = NULL;
+
+    activity->acl_start = NULL;
+    activity->acl_next = NULL;
+    activity->fi = NULL;
+    activity->body_next = NULL;
+}
+
 af_Message *makeMessage(char *type, size_t size) {
     af_Message *msg = calloc(sizeof(af_Message), 1);
     msg->type = strCopy(type);
@@ -226,6 +242,15 @@ void freeAllMessage(af_Message *msg) {
         msg = freeMessage(msg);
 }
 
+bool freeMessageCount(size_t count, af_Message *msg) {
+    for (size_t i = count; i > 0; i--) {
+        if (msg == NULL)  // 发生了错误
+            return false;
+        msg = freeMessage(msg);
+    }
+    return true;
+}
+
 void pushMessageUp(af_Message *msg, af_Environment *env) {
     msg->next = env->activity->msg_up;
     env->activity->msg_up = msg;
@@ -246,13 +271,13 @@ void *popMessageUpData(char *type, af_Environment *env) {
 }
 
 af_Message *popMessageUp(af_Environment *env) {
-    if (env->activity->new_vs_count == 0 || env->activity->msg_up == NULL)
+    if (env->activity->msg_up_count == 0 || env->activity->msg_up == NULL)
         return NULL;
 
     af_Message *msg = env->activity->msg_up;
     env->activity->msg_up = msg->next;
     msg->next = NULL;
-    env->activity->new_vs_count--;
+    env->activity->msg_up_count--;
     return msg;
 }
 
@@ -440,29 +465,34 @@ bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
     return true;
 }
 
-bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env) {
-    af_Code *next;
-    if (!getCodeBlockNext(bt, &next)) {
-        pushMessageDown(makeMessage("ERROR-STR", 0), env);
-        return false;
-    }
-
-    env->activity->bt_next = next;
+static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_Environment *env){
     if (next == NULL && env->activity->body_next == NULL) {
         printf("Tail tone recursive optimization\n");
+        clearActivity(env->activity);
         env->activity->bt_top = bt;
-        env->activity->bt_start = bt->next;
-        env->activity->bt_next = bt->next;
         if (!env->activity->return_first)  // 若原本就有设置 return_first 则没有在设置的必要了, 因为该执行不会被返回
             env->activity->return_first = return_first;
-        freeMark(env);
     } else {
-        af_Activity *activity = makeActivity(bt, bt->next, return_first, env->activity->msg_up,
+        af_Activity *activity = makeActivity(bt, NULL, return_first, env->activity->msg_up,
                                              env->activity->var_list, env->activity->belong,
                                              env->activity->func);
         activity->prev = env->activity;
         env->activity = activity;
     }
+}
+
+bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env) {
+    af_Code *next;
+    if (!getCodeBlockNext(bt, &next)) {
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+        return false;
+    }
+
+    env->activity->bt_next = next;
+
+    newActivity(bt, next, return_first, env);
+    env->activity->bt_start = bt->next;
+    env->activity->bt_next = bt->next;
 
     env->activity->status = act_normal;
     return true;
@@ -473,9 +503,9 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
     af_Code *func;
     af_Object *parentheses_call = env->activity->parentheses_call;
 
-    env->activity->parentheses_call = false;
     if (parentheses_call != NULL)
         gc_delReference(parentheses_call);
+    env->activity->parentheses_call = NULL;
 
     if (!getCodeBlockNext(bt, &next)) {
         pushMessageDown(makeMessage("ERROR-STR", 0), env);
@@ -495,18 +525,10 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
         func = NULL;  // 小括号则不在需要匹配
 
     env->activity->bt_next = next;
-    if (next == NULL && env->activity->body_next == NULL) {
-        env->activity->bt_top = bt;
-        env->activity->bt_start = func;
-        env->activity->bt_next = func;
-        freeMark(env);
-        /* 保持原有的 return_first */
-    } else {
-        af_Activity *activity = makeActivity(bt, func, false, env->activity->msg_up, env->activity->var_list,
-                                             env->activity->belong, env->activity->func);
-        activity->prev = env->activity;
-        env->activity = activity;
-    }
+
+    newActivity(bt, next, false, env);
+    env->activity->bt_start = func;
+    env->activity->bt_next = func;
 
     env->activity->call_type = env->activity->bt_top->block.type;
     env->activity->status = act_func;
@@ -517,21 +539,28 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
 
 bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env) {
     env->activity->bt_next = bt->next;
-    if (bt->next == NULL && env->activity->body_next == NULL) {
-        env->activity->bt_top = bt;
-        env->activity->bt_start = NULL;
-        env->activity->bt_next = NULL;
-        freeMark(env);
-        /* 保持原有的 return_first */
-    } else {
-        af_Activity *activity = makeActivity(bt, NULL, false, env->activity->msg_up, env->activity->var_list,
-                                             env->activity->belong, env->activity->func);
-        activity->prev = env->activity;
-        env->activity = activity;
-    }
 
+    newActivity(bt, bt->next, false, env);
     env->activity->is_literal = true;
-    env->activity->call_type = env->activity->bt_top->block.type;
+    return setFuncActivityToArg(func, env);
+}
+
+bool pushMacroFuncActivity(af_Object *func, af_Environment *env) {
+    /* Macro是隐式调用, bt不移动 */
+    /* 沿用activity */
+
+    printf("Run macro\n");
+    if (!freeVarSpaceListCount(env->activity->new_vs_count, env->activity->var_list)) { // 释放外部变量空间
+        env->activity->new_vs_count = 0;
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+        return false;
+    }
+
+    env->activity->var_list = env->activity->macro_vsl;
+    env->activity->new_vs_count = env->activity->macro_vs_count;
+    env->activity->macro_vs_count = 0;
+
+    clearActivity(env->activity);
     return setFuncActivityToArg(func, env);
 }
 
@@ -583,15 +612,18 @@ bool setFuncActivityAddVar(bool new_vsl, bool is_protect, af_Environment *env){
 
     if (!get_info(&env->activity->fi, env->activity->func, env->activity->bt_top, env->activity->mark, env))
         return false;
+    if (env->activity->fi == NULL) {
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+        return false;
+    }
     env->activity->body_next = env->activity->fi->body;
 
-    af_VarSpaceListNode *vs = env->activity->var_list;
-    for (int i = env->activity->new_vs_count; i > 0; i--) {
-        if (vs == NULL) {  // 发生了错误
-            pushMessageDown(makeMessage("ERROR-STR", 0), env);
-            return false;
-        }
-        vs = popLastVarList(vs);
+    if (env->activity->fi->is_macro) {  // 是宏函数则保存变量空间
+        env->activity->macro_vsl = env->activity->var_list;
+        env->activity->macro_vs_count = env->activity->new_vs_count;
+    } else if (!freeVarSpaceListCount(env->activity->new_vs_count, env->activity->var_list)) { // 不是宏函数则释放外部变量空间
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+        return false;
     }
 
     env->activity->var_list = env->activity->func_var_list;
@@ -651,6 +683,15 @@ static void runTopMessageProcess(af_Environment *env) {
     }
 }
 
+static void freeMarkByActivity(af_Activity *activity) {
+    if (activity->func != NULL) {
+        obj_funcFreeMask *func = findAPI("obj_funcFreeMask", activity->func->data->api);
+        if (func != NULL)
+            func(activity->mark);
+        activity->mark = NULL;
+    }
+}
+
 static void freeMark(af_Environment *env) {
     if (env->activity->func != NULL) {
         obj_funcFreeMask *func = findAPI("obj_funcFreeMask", env->activity->func->data->api);
@@ -661,6 +702,7 @@ static void freeMark(af_Environment *env) {
 }
 
 void popActivity(af_Message *msg, af_Environment *env) {
+    freeMark(env);
     if (env->activity->prev != NULL) {
         af_Message *new_msg;
         if (msg != NULL) {
@@ -678,6 +720,5 @@ void popActivity(af_Message *msg, af_Environment *env) {
         }
         runTopMessageProcess(env);
     }
-    freeMark(env);
     env->activity = freeActivity(env->activity);
 }

+ 15 - 0
src/core/run.c

@@ -106,6 +106,17 @@ static bool checkLiteral(af_Message **msg, af_Environment *env) {
     return true;
 }
 
+static bool checkMacro(af_Message *msg, af_Environment *env) {
+    if (env->activity->fi == NULL || !env->activity->fi->is_macro)  // 非宏函数
+        return false;
+
+    af_Object *obj = *(af_Object **)(msg->msg);
+    pushMacroFuncActivity(obj, env);
+    gc_delReference(obj);
+    freeMessage(msg);
+    return true;
+}
+
 bool iterCode(af_Code *code, af_Environment *env) {
     env->process_msg_first = false;  // 优先处理msg而不是运行代码
     if (!addTopActivity(code, env))
@@ -167,6 +178,8 @@ bool iterCode(af_Code *code, af_Environment *env) {
                 else if (env->activity->bt_next == NULL) { // 执行完成
                     switch (setFuncActivityToNormal(env)) {
                         case -1:  // 已经没有下一步了 (原msg不释放)
+                            if (checkMacro(msg, env))  // 检查是否宏函数
+                                break;  // 继续执行
                             checkLiteral(&msg, env);  // 检查是否字面量
                             popLastActivity(msg, env);
                             break;
@@ -178,6 +191,8 @@ bool iterCode(af_Code *code, af_Environment *env) {
                                 msg = makeMessage("ERROR-STR", 0);
                             else {
                                 msg = getFirstMessage(env);
+                                if (checkMacro(msg, env))  // 检查是否宏函数
+                                    break;  // 继续执行
                                 checkLiteral(&msg, env);  // 检查是否字面量
                             }
 

+ 9 - 0
src/core/var.c

@@ -112,6 +112,15 @@ void freeAllVarSpaceList(af_VarSpaceListNode *vsl) {
         vsl = freeVarSpaceList(vsl);
 }
 
+bool freeVarSpaceListCount(size_t count, af_VarSpaceListNode *vsl) {
+    for (size_t i = count; i > 0; i--) {
+        if (vsl == NULL)  // 发生了错误
+            return false;
+        vsl = popLastVarList(vsl);
+    }
+    return true;
+}
+
 void addVarSpaceGCByCore(af_VarSpace *vs, af_Core *core) {
     if (vs->gc.info.start_gc)
         return;

+ 89 - 0
src/main.c

@@ -79,6 +79,50 @@ void freeMark(int *mark) {
     free(mark);
 }
 
+void testFunc2(int *mark, af_Environment *env) {  // 测试用函数
+    printf("testFunc2(): I am testFunc2\n");
+    af_Object *obj;
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_alc = MAKE_SYMBOL(getAcl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_al = MAKE_SYMBOL(getAl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info = MAKE_SYMBOL(getInfo, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
+            return;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return;
+        if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
+            return;
+        if (addAPI(get_info, "obj_funcGetInfo", api) != 1)
+            return;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return;
+
+        obj = makeObject("func", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info);
+        FREE_SYMBOL(free_mark);
+    }
+
+    af_Message *msg = makeMessage("NORMAL", sizeof(af_Object *));
+    *((af_Object **)(getMessageData(msg))) = obj;
+    gc_addReference(obj);
+    pushMessageDown(msg, env);
+}
+
+bool getInfo2(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, true, false);  // 获取FuncInfo [桩]
+    makeCodeFuncBodyToFuncInfo(makeVariableCode("test", NUL, 0, "Unknow"), true, NULL, *fi);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc2, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
 
 int main() {
     aFunInit();
@@ -133,6 +177,34 @@ int main() {
         FREE_SYMBOL(free_mark);
     }
 
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_alc = MAKE_SYMBOL(getAcl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_al = MAKE_SYMBOL(getAl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info2 = MAKE_SYMBOL(getInfo2, objectAPIFunc);  // 宏函数
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
+            return 2;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return 2;
+        if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
+            return 2;
+        if (addAPI(get_info2, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func2", 3, 3,
+                                        makeObject("func", true, api, true, NULL, NULL, env)),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info2);
+        FREE_SYMBOL(free_mark);
+    }
+
     addVarToProtectVarSpace(makeVar("object", 3, 3,
                                     makeObject("object", true, makeObjectAPI(), true, NULL, NULL, env)),
                             env);
@@ -166,6 +238,23 @@ int main() {
         printf("\n");
     }
 
+    {  // 宏函数
+        printf("TAG L:\n");
+        af_Code *bt1 = makeVariableCode("object", 0, 1, NULL);
+
+        af_Code *bt3 = makeVariableCode("func2", 0, 1, NULL);
+        af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt1, bt5);
+
+        af_Code *bt6 = makeVariableCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+
     {  // 尾调递归优化
         printf("TAG B:\n");
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");