Ver Fonte

feat: FuncBody添加对act_top_import的支持

SongZihuan há 3 anos atrás
pai
commit
a3ae2cc6d2
8 ficheiros alterados com 167 adições e 34 exclusões
  1. 3 1
      include/core/func.h
  2. 3 0
      include/core/info/runtime_error.h
  3. 1 0
      src/core/__env.h
  4. 2 1
      src/core/__func.h
  5. 59 23
      src/core/env.c
  6. 12 1
      src/core/func.c
  7. 21 8
      src/core/run.c
  8. 66 0
      src/main.c

+ 3 - 1
include/core/func.h

@@ -50,6 +50,7 @@ AFUN_CORE_EXPORT bool runArgList(af_ArgList *al, af_VarSpaceListNode *vsl, af_En
 
 /* FuncBody 创建与释放 */
 AFUN_CORE_EXPORT af_FuncBody *makeCodeFuncBody(af_Code *code, bool free_code, char **msg_type);
+AFUN_CORE_EXPORT af_FuncBody *makeImportFuncBody(af_Code *code, bool free_code, char **msg_type);
 AFUN_CORE_EXPORT af_FuncBody *makeCFuncBody(DLC_SYMBOL(callFuncBody) c_func, char **msg_type);
 AFUN_CORE_EXPORT af_FuncBody *makeDynamicFuncBody(void);
 AFUN_CORE_EXPORT af_FuncBody *freeFuncBody(af_FuncBody *fb);
@@ -57,12 +58,13 @@ AFUN_CORE_EXPORT void freeAllFuncBody(af_FuncBody *fb);
 
 /* FuncInfo 创建与释放 */
 AFUN_CORE_EXPORT af_FuncInfo *makeFuncInfo(enum af_FuncInfoScope scope, enum af_FuncInfoEmbedded embedded,
-        bool is_macro, bool var_this, bool var_func);
+                                           bool is_macro, bool var_this, bool var_func);
 AFUN_CORE_EXPORT void freeFuncInfo(af_FuncInfo *fi);
 
 /* FuncInfo 操作函数 */
 AFUN_CORE_EXPORT void makeCFuncBodyToFuncInfo(DLC_SYMBOL(callFuncBody) c_func, char **msg_type, af_FuncInfo *fi);
 AFUN_CORE_EXPORT void makeCodeFuncBodyToFuncInfo(af_Code *code, bool free_code, char **msg_type, af_FuncInfo *fi);
+AFUN_CORE_EXPORT void makeImportFuncBodyToFuncInfo(af_Code *code, bool free_code, char **msg_type, af_FuncInfo *fi);
 AFUN_CORE_EXPORT void makeDynamicFuncBodyToFuncInfo(af_FuncInfo *fi);
 
 #endif //AFUN_FUNC

+ 3 - 0
include/core/info/runtime_error.h

@@ -19,6 +19,9 @@
 #define NOT_MSG_INFO "Don't get msg after function call."
 #define NOT_NORMAL_MSG_INFO "Don't get normal msg after function call."
 
+#define IMPORT_ERROR "Import-Error"
+#define IMPORT_OBJ_ERROR "Cannot creat an import object."
+
 #define INFIX_PROTECT "Infix-Protect"
 #define LITERAL_ERROR "Literal-Error"
 #define VARIABLE_ERROR "Variable-Error"

+ 1 - 0
src/core/__env.h

@@ -213,6 +213,7 @@ AFUN_CORE_NO_EXPORT void pushGCActivity(gc_DestructList *dl, gc_DestructList **p
 AFUN_CORE_NO_EXPORT bool pushVariableActivity(af_Code *bt, af_Object *func, af_Environment *env);
 AFUN_CORE_NO_EXPORT bool pushLiteralActivity(af_Code *bt, char *data, af_Object *func, af_Environment *env);
 AFUN_CORE_NO_EXPORT bool pushMacroFuncActivity(af_Object *func, af_Environment *env);
+AFUN_CORE_NO_EXPORT bool pushImportActivity(af_Code *bt, af_Environment *env);
 AFUN_CORE_NO_EXPORT bool setFuncActivityToArg(af_Object *func, af_Environment *env);
 AFUN_CORE_NO_EXPORT bool setFuncActivityAddVar(af_Environment *env);
 AFUN_CORE_NO_EXPORT int setFuncActivityToNormal(af_Environment *env);

+ 2 - 1
src/core/__func.h

@@ -29,8 +29,9 @@ NEW_DLC_SYMBOL(callFuncBody, callFuncBody);
 
 struct af_FuncBody {
     enum af_FuncBodyType {
-        func_body_c,  // 回调C函数
+        func_body_c = 0,  // 回调C函数
         func_body_code,  // 执行af_Code
+        func_body_import,  // import内容
         func_body_dynamic,
     } type;
 

+ 59 - 23
src/core/env.c

@@ -59,6 +59,9 @@ static void fprintfNote(FILE *file, char *note);
 static void mp_NORMAL(af_Message *msg, bool is_gc, af_Environment *env);
 static void mp_ERROR(af_Message *msg, bool is_gc, af_Environment *env);
 
+/* 变量检查函数 */
+static bool isInfixFunc(af_Code *code, af_Environment *env);
+
 static af_Core *makeCore(enum GcRunTime grt) {
     af_Core *core = calloc(1, sizeof(af_Core));
     core->status = core_creat;
@@ -676,6 +679,25 @@ static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_
     }
 }
 
+/*
+ * 函数名: isInfixFunc
+ * 目标: 检查是否中缀调用函数
+ */
+static bool isInfixFunc(af_Code *code, af_Environment *env) {
+    if (code == NULL || code->type != code_element || code->prefix == getPrefix(E_QUOTE, env))
+        return false;
+
+    // TODO-szh 检查是否变量
+    af_Var *var = findVarFromVarList(code->element.data, env->activity->belong, env->activity->var_list);
+    if (var == NULL)
+        return false;
+
+    obj_isInfixFunc *func = findAPI("obj_isInfixFunc", var->vn->obj->data->api);
+    if (func == NULL)
+        return false;
+    return func(var->vn->obj);
+}
+
 bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env) {
     af_Code *next;
     if (!getCodeBlockNext(bt, &next)) {
@@ -698,20 +720,6 @@ bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env)
     return true;
 }
 
-static bool isInfixFunc(af_Code *code, af_Environment *env) {
-    if (code == NULL || code->type != code_element || code->prefix == getPrefix(E_QUOTE, env))
-        return false;
-
-    af_Var *var = findVarFromVarList(code->element.data, env->activity->belong, env->activity->var_list);
-    if (var == NULL)
-        return false;
-
-    obj_isInfixFunc *func = findAPI("obj_isInfixFunc", var->vn->obj->data->api);
-    if (func == NULL)
-        return false;
-    return func(var->vn->obj);
-}
-
 bool pushFuncActivity(af_Code *bt, af_Environment *env) {
     af_Code *next;
     af_Code *func;
@@ -827,6 +835,17 @@ void pushGCActivity(gc_DestructList *dl, gc_DestructList **pdl, af_Environment *
     env->activity = activity;
 }
 
+bool pushImportActivity(af_Code *bt, af_Environment *env) {
+    af_Object *obj = makeGlobalObject(env);
+    if (obj == NULL)
+        return false;
+
+    af_Activity *activity = makeTopImportActivity(bt, bt, env->core->protect, obj);
+    activity->prev = env->activity;
+    env->activity = activity;
+    return true;
+}
+
 bool pushDestructActivity(gc_DestructList *dl, af_Environment *env) {
     env->activity->dl_next = dl->next;
 
@@ -965,7 +984,7 @@ bool setFuncActivityAddVar(af_Environment *env){
     env->activity->acl_done = NULL;
 
     if (setFuncActivityToNormal(env) == 0)
-        return false;
+        return false;  // 运行结束, 且已写入msg
     return true;
 }
 
@@ -974,7 +993,7 @@ bool setFuncActivityAddVar(af_Environment *env){
  * 目标: 获取下一步需要运行的结果
  * 返回  (0) 表示无下一步
  * 返回 (-1) 表示运行C函数, 并且设置了 process_msg_first
- * 返回  (1) 表示下一步运Code
+ * 返回  (1) 表示下一步运Code
  * 返回  (2) 表示遇到未被替换的动态代码块
  */
 int setFuncActivityToNormal(af_Environment *env){  // 获取函数的函数体
@@ -989,14 +1008,22 @@ int setFuncActivityToNormal(af_Environment *env){  // 获取函数的函数体
     env->activity->body_next = body->next;
     switch (body->type) {
         case func_body_c: {
-            af_FuncBody *new;
-            new = GET_SYMBOL(body->c_func)(env->activity->mark, env);
+            af_FuncBody *new = GET_SYMBOL(body->c_func)(env->activity->mark, env);
             env->activity->process_msg_first++;  // 处理C函数通过msg_down返回的结果
             pushDynamicFuncBody(new, body);
             env->activity->body_next = body->next;  // 添加新元素后要重新设定body_next的位置
             re = -1;
             break;
         }
+        case func_body_import:
+            if (!pushImportActivity(body->code, env)) {
+                pushMessageDown(makeERRORMessage(IMPORT_ERROR, IMPORT_OBJ_ERROR, env), env);
+                env->activity->process_msg_first++;  // 处理C函数通过msg_down返回的结果
+                re = 2;
+                break;
+            }
+            re = 1;
+            break;
         case func_body_code:
             setActivityBtStart(body->code, env->activity);
             re = 1;
@@ -1041,13 +1068,13 @@ static void freeMark(af_Environment *env) {
 
 void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
     if (env->activity->type == act_func || env->activity->type == act_top || env->activity->type == act_top_import) {
-        if (msg != NULL && env->activity->return_first) {
+        if (msg != NULL && env->activity->return_first) {  // msg有内容, 并且设定了返回首位, 则清除msg内容, 并压入首位(压入的代码在下面)
             if (EQ_STR(msg->type, "NORMAL")) {
                 gc_delReference(*(af_Object **) msg->msg);
                 freeMessage(msg);
                 msg = NULL;
             }
-        } else if (env->activity->return_first) {  // msg == NULL
+        } else if (env->activity->return_first) {  // msg无内容, 并且设定了返回首位, 则检查msg_down是否有normal, 有则清除
             if (env->activity->msg_down != NULL && EQ_STR(env->activity->msg_down->type, "NORMAL")) {
                 af_Message *tmp = getFirstMessage(env);
                 gc_delReference(*(af_Object **) (tmp->msg));
@@ -1055,7 +1082,7 @@ void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
             }
         }
 
-        if (msg == NULL && env->activity->return_first) {
+        if (msg == NULL && env->activity->return_first) {  // 如果首位
             if (env->activity->return_obj == NULL)
                 msg = makeERRORMessage(RUN_ERROR, RETURN_OBJ_NOT_FOUND_INFO, env);
             else
@@ -1066,10 +1093,19 @@ void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
     if (msg != NULL)
         pushMessageDown(msg, env);
 
+    if (env->activity->type == act_top_import && /* import模式, 并且msg_down中有normal, 则把normal替换为belong */
+        env->activity->msg_down != NULL && EQ_STR(env->activity->msg_down->type, "NORMAL")) {
+        af_Message *tmp = getFirstMessage(env);
+        gc_delReference(*(af_Object **) (tmp->msg));
+        freeMessage(tmp);
+
+        pushMessageDown(makeNORMALMessage(env->activity->belong), env);  // 压入belong作为msg
+    }
+
     if (!is_normal)
         freeMark(env);  // 遇到非正常退出时, 释放`mark`
 
-    if (env->activity->type == act_top || env->activity->type == act_top_import || env->activity->type == act_gc)  // 顶层或gc层
+    if (env->activity->type == act_top || env->activity->type == act_gc) // 顶层或gc层
         runTopMessageProcess((env->activity->type == act_gc), env);
     else {
         connectMessage(&(env->activity->msg_down), env->activity->prev->msg_down);
@@ -1078,7 +1114,7 @@ void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
         env->activity->prev->process_msg_first++;  // 优先处理通过msg_down返回的结果
     }
 
-    if (env->activity->type != act_top)  // TODO-szh 处理act_top_import
+    if (env->activity->type != act_top)
         env->activity = freeActivity(env->activity);
     else
         freeActivityTop(env->activity);  // activity不被释放

+ 12 - 1
src/core/func.c

@@ -122,6 +122,13 @@ af_FuncBody *makeCodeFuncBody(af_Code *code, bool free_code, char **msg_type) {
     return fb;
 }
 
+af_FuncBody *makeImportFuncBody(af_Code *code, bool free_code, char **msg_type) {
+    af_FuncBody *fb = makeFuncBody(func_body_import, msg_type);
+    fb->code = code;
+    fb->free_code = free_code;
+    return fb;
+}
+
 af_FuncBody *makeDynamicFuncBody(void) {
     af_FuncBody *fb = makeFuncBody(func_body_dynamic, NULL);
     return fb;
@@ -141,7 +148,7 @@ static void freeMsgType(char **msg_type) {
 
 af_FuncBody *freeFuncBody(af_FuncBody *fb) {
     af_FuncBody *next = fb->next;
-    if (fb->type == func_body_code && fb->free_code)
+    if ((fb->type == func_body_code || fb->type == func_body_import) && fb->free_code)
         freeAllCode(fb->code);
     else if (fb->type == func_body_c)
         FREE_SYMBOL(fb->c_func);
@@ -186,6 +193,10 @@ void makeCodeFuncBodyToFuncInfo(af_Code *code, bool free_code, char **msg_type,
     pushFuncBody(&fi->body, makeCodeFuncBody(code, free_code, msg_type));
 }
 
+void makeImportFuncBodyToFuncInfo(af_Code *code, bool free_code, char **msg_type, af_FuncInfo *fi) {
+    pushFuncBody(&fi->body, makeImportFuncBody(code, free_code, msg_type));
+}
+
 void makeDynamicFuncBodyToFuncInfo(af_FuncInfo *fi) {
     pushFuncBody(&fi->body, makeDynamicFuncBody());
 }

+ 21 - 8
src/core/run.c

@@ -13,7 +13,7 @@ static af_Message *getTopMsg(af_Environment *env);
 /* 工具函数: 检查类型 */
 static bool checkInMsgType(char *type, af_Environment *env);
 static bool checkLiteral(af_Message **msg, af_Environment *env);
-static bool checkMacro(af_Message *msg, af_Environment *env);
+static int checkMacro(af_Message *msg, af_Environment *env);
 static bool checkRunGC(af_Environment *env);
 static int checkMsg(af_Message *msg, af_Environment *env);
 bool checkNormalEnd(af_Message *msg, af_Environment *env);
@@ -69,18 +69,24 @@ static bool checkLiteral(af_Message **msg, af_Environment *env) {
 /*
  * 函数名: checkMacro
  * 目标: 检查是否宏函数调用, 若是则返回true并修改activity隐式调用(activity继续执行时则会执行该调用), 否则返回false不做修改
+ * 返回值:
+ * -1 非宏函数
+ *  0 错误
+ *  1 宏函数
  */
-static bool checkMacro(af_Message *msg, af_Environment *env) {
+static int checkMacro(af_Message *msg, af_Environment *env) {
     if (env->activity->fi == NULL || !env->activity->fi->is_macro)  // 非宏函数
-        return false;
+        return -1;
     if (!EQ_STR(msg->type, "NORMAL"))  // msg非正常值
-        return false;
+        return -1;
 
     af_Object *obj = *(af_Object **)(msg->msg);
-    pushMacroFuncActivity(obj, env);
+    bool re = pushMacroFuncActivity(obj, env);
     gc_delReference(obj);
     freeMessage(msg);
-    return true;
+    if (re)
+        return 1;
+    return 0;
 }
 
 /*
@@ -229,8 +235,15 @@ bool checkNormalEnd(af_Message *msg, af_Environment *env) {
                 return true;
             }
 
-            if (checkMacro(msg, env))  // 检查是否宏函数
-                return false;  // 继续执行
+            switch (checkMacro(msg, env)) {
+                case 0:
+                    return true;  // 错误
+                case 1:
+                    return false;  // 宏函数
+                case -1:
+                default:
+                    break;  // 非宏函数
+            }
 
             checkLiteral(&msg, env);  // 检查是否字面量
             pushMessageDown(msg, env);

+ 66 - 0
src/main.c

@@ -356,6 +356,12 @@ bool getInfo10(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_E
     return true;
 }
 
+bool getInfo11(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    makeImportFuncBodyToFuncInfo(makeElementCode("global", NUL, 1, "func9.info.af"), true, NULL, *fi);
+    return true;
+}
+
 bool objFunc(af_Object *obj) {
     return true;
 }
@@ -819,6 +825,52 @@ int main() {
         printf("func9(%p)\n", obj);
     }
 
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info11 = MAKE_SYMBOL(getInfo11, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            goto RETURN_2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            goto RETURN_2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            goto RETURN_2;
+        if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
+            goto RETURN_2;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            goto RETURN_2;
+        if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
+            goto RETURN_2;
+        if (addAPI(get_info11, "obj_funcGetInfo", api) != 1)
+            goto RETURN_2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            goto RETURN_2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            goto RETURN_2;
+
+        addVarToProtectVarSpace(makeVar("func10", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info11);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func9(%p)\n", obj);
+    }
+
     printf("\n");
     enableEnvironment(env);
 
@@ -1064,6 +1116,20 @@ int main() {
         printf("\n");
     }
 
+    {  // func_body_import 测试
+        printf("TAG X:\n");
+
+        af_Code *bt2 = makeElementCode("func10", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, "TagX.af", NULL);
+        af_Code *bt3 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
     /* 错误用例 */
 
     {  // 中缀调用测试