Parcourir la source

feat: 添加activity新类型

添加top和import类型
SongZihuan il y a 3 ans
Parent
commit
b2bd85b63b
4 fichiers modifiés avec 81 ajouts et 46 suppressions
  1. 8 9
      src/core/__env.h
  2. 47 18
      src/core/env.c
  3. 24 17
      src/core/run.c
  4. 2 2
      src/main.c

+ 8 - 9
src/core/__env.h

@@ -29,7 +29,7 @@ struct af_Core {  // 解释器核心
         core_creat = 0,
         core_init,  // 执行.i.af
         core_normal,  // 正常执行
-        core_srop,  // 当前运算退出
+        core_stop,  // 当前运算退出
         core_exit,  // 解释器退出
     } status;
 
@@ -71,8 +71,10 @@ struct af_Activity {  // 活动记录器
     struct af_Activity *prev;  // 上一个活动记录器
 
     enum af_ActivityType {
-        act_func,
-        act_gc,
+        act_top = 0,  /* 顶层 永远存在第一层 */
+        act_func,  /* 函数调用 */
+        act_top_import,  /* 导入 运算结束后global进入msg反 */
+        act_gc,  /* gc机制 只存在一层 */
     } type;
 
     struct af_Object *belong;  // 属对象 (belong通常为func的belong)
@@ -88,13 +90,13 @@ struct af_Activity {  // 活动记录器
     FileLine line;
 
     union {
-        struct {
+        struct {  // 仅gc使用
             struct gc_DestructList *dl;
             struct gc_DestructList **pdl;  // 执行dl的最末端
             struct gc_DestructList *dl_next;  // dl执行的位置
         };
 
-        struct {
+        struct {  // gc以外的其他内容使用
             enum af_ActivityStatus {
                 act_func_get = 0,
                 act_func_arg,
@@ -130,7 +132,7 @@ struct af_Activity {  // 活动记录器
             struct af_VarSpaceListNode *macro_vsl;  // 宏函数执行的vsl
             ActivityCount macro_vs_count;
 
-            /* 函数调用: 析构函数 */
+            /* 函数调用: 析构函数 在错误回溯时使用, 是个标记*/
             bool is_gc_call;
 
             /* 字面量 */
@@ -200,9 +202,6 @@ struct af_ErrorInfo {
 /* Core 管理函数 */
 AFUN_CORE_NO_EXPORT af_Object *getBaseObjectFromCore(char *name, af_Core *core);
 
-/* Activity 运行初始化函数 */
-AFUN_CORE_NO_EXPORT bool addTopActivity(af_Code *code, af_Environment *env);
-
 /* 运行时Activity设置函数 (新增Activity) */
 AFUN_CORE_NO_EXPORT bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env);
 AFUN_CORE_NO_EXPORT bool pushFuncActivity(af_Code *bt, af_Environment *env);

+ 47 - 18
src/core/env.c

@@ -11,8 +11,11 @@ static void freeCore(af_Environment *env);
 static af_Activity *makeActivity(af_Message *msg_up, af_VarSpaceListNode *vsl, af_Object *belong);
 static af_Activity *makeFuncActivity(af_Code *bt_top, af_Code *bt_start, bool return_first, af_Message *msg_up,
                                      af_VarSpaceListNode *vsl, af_Object *belong, af_Object *func);
+static af_Activity *makeTopActivity(af_Code *bt_top, af_Code *bt_start, af_VarSpace *protect, af_Object *belong);
+static af_Activity *makeTopImportActivity(af_Code *bt_top, af_Code *bt_start, af_VarSpace *protect, af_Object *belong);
 static af_Activity *makeGcActivity(gc_DestructList *dl, gc_DestructList **pdl, af_Environment *env);
 static af_Activity *freeActivity(af_Activity *activity);
+static void freeActivityTop(af_Activity *activity);
 static void freeAllActivity(af_Activity *activity);
 static void clearActivity(af_Activity *activity);
 
@@ -137,7 +140,7 @@ af_Object *getBaseObject(char *name, af_Environment *env) {
 
 void setCoreStop(af_Environment *env) {
     if (env->core->status != core_exit)
-        env->core->status = core_srop;
+        env->core->status = core_stop;
 }
 
 void setCoreExit(int exit_code, af_Environment *env) {
@@ -146,7 +149,7 @@ void setCoreExit(int exit_code, af_Environment *env) {
 }
 
 void setCoreNormal(af_Environment *env) {
-    if (env->core->status == core_exit || env->core->status == core_srop) {
+    if (env->core->status == core_exit || env->core->status == core_stop) {
         env->core->status = core_normal;
         env->core->exit_code = 0;
     }
@@ -177,6 +180,29 @@ static af_Activity *makeFuncActivity(af_Code *bt_top, af_Code *bt_start, bool re
     return activity;
 }
 
+static af_Activity *makeTopActivity(af_Code *bt_top, af_Code *bt_start, af_VarSpace *protect, af_Object *belong) {
+    af_Activity *activity = makeActivity(NULL, NULL, belong);
+
+    activity->type = act_top;
+    activity->status = act_func_normal;
+
+    activity->new_vs_count = 2;
+    activity->var_list = makeVarSpaceList(belong->data->var_space);
+    activity->var_list->next = makeVarSpaceList(protect);
+
+    setActivityBtTop(bt_top, activity);
+    setActivityBtStart(bt_start, activity);
+
+    return activity;
+}
+
+static af_Activity *makeTopImportActivity(af_Code *bt_top, af_Code *bt_start, af_VarSpace *protect, af_Object *belong) {
+    af_Activity *activity = makeTopActivity(bt_top, bt_start, protect, belong);
+
+    activity->type = act_top_import;
+    return activity;
+}
+
 static af_Activity *makeGcActivity(gc_DestructList *dl, gc_DestructList **pdl, af_Environment *env) {
     af_Activity *activity = makeActivity(NULL, NULL, env->core->global);
     activity->type = act_gc;
@@ -219,6 +245,17 @@ static af_Activity *freeActivity(af_Activity *activity) {
     return prev;
 }
 
+static void freeActivityTop(af_Activity *activity) {
+    freeAllMessage(activity->msg_down);  // msg转移后需要将对应成员设置为NULL
+    freeMessageCount(activity->msg_up_count, activity->msg_up);
+    free(activity->file);
+    activity->line = 0;
+
+    activity->bt_top = NULL;
+    activity->bt_start = NULL;
+    activity->bt_next = NULL;
+}
+
 static void freeAllActivity(af_Activity *activity) {
     while (activity != NULL)
         activity = freeActivity(activity);
@@ -553,21 +590,10 @@ af_Environment *makeEnvironment(enum GcRunTime grt) {
     FREE_SYMBOL(func2);
 
     env->core->status = core_init;
+    env->activity = makeTopActivity(NULL, NULL, env->core->protect, env->core->global);
     return env;
 }
 
-bool addTopActivity(af_Code *code, af_Environment *env) {
-    if (env->activity != NULL)
-        return false;
-
-    env->activity = makeFuncActivity(NULL, code, false, NULL, NULL, env->core->global, NULL);
-    env->activity->new_vs_count = 2;
-    env->activity->var_list = makeVarSpaceList(env->core->global->data->var_space);
-    env->activity->var_list->next = makeVarSpaceList(env->core->protect);
-    env->activity->status = act_func_normal;
-    return true;
-}
-
 void enableEnvironment(af_Environment *env) {
     env->core->protect->is_protect = true;
     env->core->status = core_normal;
@@ -576,8 +602,8 @@ void enableEnvironment(af_Environment *env) {
 void freeEnvironment(af_Environment *env) {
     if (env->core->status != core_creat)
         iterDestruct(10, env);
-    freeCore(env);
     freeAllActivity(env->activity);
+    freeCore(env);
     freeEnvVarSpace(env->esv);
     freeAllTopMsgProcess(env->process);
     free(env);
@@ -1014,7 +1040,7 @@ static void freeMark(af_Environment *env) {
 }
 
 void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
-    if (env->activity->type == act_func) {
+    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 (EQ_STR(msg->type, "NORMAL")) {
                 gc_delReference(*(af_Object **) msg->msg);
@@ -1043,7 +1069,7 @@ void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
     if (!is_normal)
         freeMark(env);  // 遇到非正常退出时, 释放`mark`
 
-    if (env->activity->prev == NULL || env->activity->type == act_gc)  // 顶层或gc层
+    if (env->activity->type == act_top || env->activity->type == act_top_import || env->activity->type == act_gc)  // 顶层或gc层
         runTopMessageProcess((env->activity->type == act_gc), env);
     else {
         connectMessage(&(env->activity->msg_down), env->activity->prev->msg_down);
@@ -1052,7 +1078,10 @@ void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
         env->activity->prev->process_msg_first++;  // 优先处理通过msg_down返回的结果
     }
 
-    env->activity = freeActivity(env->activity);
+    if (env->activity->type != act_top)  // TODO-szh 处理act_top_import
+        env->activity = freeActivity(env->activity);
+    else
+        freeActivityTop(env->activity);  // activity不被释放
 }
 
 static af_LiteralRegex *makeLiteralRegex(char *pattern, char *func, bool in_protect) {

+ 24 - 17
src/core/run.c

@@ -107,14 +107,12 @@ static bool checkRunGC(af_Environment *env) {
  * 目标: 初始化activity和environment (若environment中未存在activity则通过code新增一个TopActivity, 否则沿用原activity)
  */
 static bool iterCodeInit(af_Code *code, af_Environment *env) {
-    if (env == NULL || env->core == NULL || env->core->status == core_exit)
+    if (env == NULL || env->core == NULL || env->activity == NULL || env->core->status == core_exit)
         return false;
-    if (env->core->status == core_srop)
+    if (env->core->status == core_stop)
         env->core->status = core_normal;
-    if (env->activity == NULL && code == NULL || env->activity != NULL && code != NULL)
-        return false;
-    if (code != NULL && !addTopActivity(code, env))  // 初始化环境
-        return false;
+    setActivityBtTop(code, env->activity);
+    setActivityBtStart(code, env->activity);
     return true;
 }
 
@@ -163,7 +161,7 @@ static bool codeElement(af_Code *code, af_Environment *env) {
     if (code->prefix != getPrefix(E_QUOTE, env)) {
         if ((is_obj = findAPI("obj_isObjFunc", obj->data->api)) != NULL && is_obj(obj))
             return pushVariableActivity(code, var->vn->obj, env);  // 对象函数
-        else if (env->activity->status != act_func_get && // 在act_func模式时关闭保护
+        else if (env->activity->status != act_func_get && // 在act_func_get 模式下不检查是否为is_infix函数 因为本来就要将其作为函数调用
                  (is_infix = findAPI("obj_isInfixFunc", obj->data->api)) != NULL && is_infix(obj)) {
             pushMessageDown(makeERRORMessageFormate(INFIX_PROTECT, env,
                                                     "Infix protect variable: %s.", code->element.data), env);
@@ -387,28 +385,37 @@ static void processMsg(af_Message *msg, bool run_code, af_Environment *env) {
  * 函数名: iterCode
  * 目标: 运行代码 (代码可通过code参数传入, 或通过env->activity传入)
  */
-bool iterCode(af_Code *code, af_Environment *env) {
+bool iterCode(af_Code *code, af_Environment *env){
     if (!iterCodeInit(code, env))
         return false;
 
-    for (NULL; env->activity != NULL; ) {
-        af_Message *msg = NULL;
-        bool run_code = false;
-        if (env->core->status == core_srop || env->core->status == core_exit) {
-            for (NULL; env->activity != NULL;)
+    /* destruct模式下则以activity为NULL作为判断 */
+    /* 普通模式则以是否释放到顶层作为判断 */
+    while (env->activity->type != act_top ||
+          env->activity->bt_next != NULL  ||
+          env->activity->process_msg_first != 0) {
+
+        /* 检查是否需要退出执行 */
+        if (env->core->status == core_stop || env->core->status == core_exit) {
+            while (env->activity->type != act_top || env->activity->prev != NULL)
                 popActivity(false, NULL, env);  // is_normal=false, 非正常退出, 释放mark
+            popActivity(false, NULL, env);  // 在释放 act_top
             return false;
         }
 
+        /* 检查gc机制 */
         checkRunGC(env);
+
+        /* 检查是否gc状态 */
         if (env->activity->type == act_gc) {  // gc 模式
             if (env->activity->dl_next == NULL)
                 popActivity(true, NULL, env);  // 结束运行
-            else {
-                printf("env->activity->dl_next.obj = %p, %d\n", env->activity->dl_next->obj->data, env->activity->dl_next->obj->data->gc.done_destruct);
+            else
                 pushDestructActivity(env->activity->dl_next, env);
-            }
-        } else {
+        } else {  // 普通运行模式
+            af_Message *msg = NULL;
+            bool run_code = false;
+
             setRunVarSpaceList(env);
             if (runCode(&msg, &run_code, env))
                 continue;  // 若未获得msg (未进行实质性运算) 则再次运算

+ 2 - 2
src/main.c

@@ -824,7 +824,7 @@ int main() {
 
     {  // 正常程序
         printf("TAG A:\n");
-        af_Code *bt1 = makeElementCode("object", 0, 1, NULL);
+        af_Code *bt1 = makeElementCode("object", 0, 1, "Unknown");
         af_Code *bt2 = makeElementCode("data", ',', 0, "Unknown");
         connectCode(&bt1, bt2);
 
@@ -867,7 +867,7 @@ int main() {
         af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
         connectCode(&bt2, bt5);
 
-        iterCode(bt1, env);
+        iterCode(bt5, env);
         freeAllCode(bt1);
         printf("\n");
     }