Jelajahi Sumber

feat & fix: 添加了run中处理msg->type的程序

run可以处理msg->type
修复了部分bug
SongZihuan 3 tahun lalu
induk
melakukan
256d5ead56
5 mengubah file dengan 85 tambahan dan 23 penghapusan
  1. 1 0
      include/object.h
  2. 4 3
      src/core/env.c
  3. 10 0
      src/core/object.c
  4. 36 8
      src/core/run.c
  5. 34 12
      src/main.c

+ 1 - 0
include/object.h

@@ -10,6 +10,7 @@ typedef struct af_Inherit af_Inherit;
 af_Object *makeObject(char *id, size_t data_size, bool inherit_api, bool allow_iherit, af_Object *belong,
                       af_Inherit *iherit, af_Environment *env);
 void freeObject(af_Object *obj);
+af_Object *getBelongObject(af_Object *object, af_Environment *env);
 
 af_Inherit *makeIherit(af_Object *obj);
 af_Inherit *freeIherit(af_Inherit *ih);

+ 4 - 3
src/core/env.c

@@ -380,14 +380,15 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
 }
 
 bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
+    af_Object *belong = getBelongObject(func, env);
     gc_delReference(env->activity->belong);
     if (env->activity->func != NULL)
         gc_delReference(env->activity->func);
     gc_addReference(func);
-    gc_addReference(func->belong);  // TODO-szh 处理belong为NULL的情况 (global的belong)
+    gc_addReference(belong);
 
     env->activity->func = func;
-    env->activity->belong = func->belong;
+    env->activity->belong = belong;
     env->activity->status = act_arg;
     // TODO-szh 参数处理(计算)
     return true;
@@ -424,7 +425,7 @@ void popActivity(af_Message *msg, af_Environment *env) {
             new_msg = msg;
             msg->next = env->activity->msg_down;
         } else
-            msg = env->activity->msg_down;
+            new_msg = env->activity->msg_down;
         env->activity->msg_down = NULL;
         connectMessage(&new_msg, env->activity->prev->msg_down);
         env->activity->prev->msg_down = new_msg;

+ 10 - 0
src/core/object.c

@@ -96,6 +96,16 @@ void freeObject(af_Object *obj) {
     free(obj);
 }
 
+af_Object *getBelongObject(af_Object *object, af_Environment *env) {
+    af_Object *belong = object->belong;
+    if (belong == NULL){
+        if (object != env->core->global)
+            object->belong = env->core->global;
+        return env->core->global;
+    }
+    return belong;
+}
+
 af_Inherit *makeIherit(af_Object *obj) {
     af_Inherit *ih = calloc(sizeof(af_Inherit), 1);
     ih->obj = obj;

+ 36 - 8
src/core/run.c

@@ -36,8 +36,27 @@ static af_Code *codeLiteral(af_Code *code, af_Environment *env) {
     return code->next;
 }
 
+static bool checkInMsgType(char *type, af_Environment *env) {
+    if (env->activity->msg_type == NULL)
+        return false;
+    for (char *msg_type_node = *env->activity->msg_type; msg_type_node != NULL; msg_type_node++) {
+        if (EQ_STR(type, msg_type_node))
+            return true;
+    }
+    return false;
+}
+
+static void popLastActivity(af_Message *msg, af_Environment *env){
+    do {  // 如果返回一级后仍是执行完成则继续返回
+        if (env->activity->prev == NULL)
+            printf("top finished\n");
+        popActivity(msg, env);
+        msg = NULL;  // 随后几次执行popActivity时不需要压入新的msg
+    } while (env->activity != NULL && env->activity->bt_next == NULL);
+}
+
 bool iterCode(af_Code *code, af_Environment *env) {
-   if (!addTopActivity(code, env))
+    if (!addTopActivity(code, env))
        return false;
 
     while (env->activity != NULL) {
@@ -56,17 +75,26 @@ bool iterCode(af_Code *code, af_Environment *env) {
                 break;  // 错误
         }
 
-        msg = getFirstMessage(env);  // TODO-szh 检查是否为 NORMAL
+        if (env->activity->msg_down == NULL) {
+            msg = makeMessage("ERROR-STR", 0);
+        } else
+            msg = getFirstMessage(env);
+
+        if (!EQ_STR(msg->type, "NORMAL")) {
+            pushMessageDown(msg, env);
+            if (env->activity->status != act_normal || !checkInMsgType(msg->type, env)) {
+                popLastActivity(NULL, env);  // msg 已经 push进去了
+                continue;
+            } else {
+                env->activity->bt_next = NULL;
+                // TODO-szh 切换函数
+            }
+        }
 
         switch (env->activity->status) {
             case act_normal:
                 if (env->activity->bt_next == NULL) { // 执行完成
-                    do {  // 如果返回一级后仍是执行完成则继续返回
-                        if (env->activity->prev == NULL)
-                            printf("top finished\n");
-                        popActivity(msg, env);
-                        msg = NULL;  // 随后几次执行popActivity时不需要压入新的msg
-                    } while (env->activity != NULL && env->activity->bt_next == NULL);
+                    popLastActivity(msg, env);
                 } else {
                     gc_delReference(*(af_Object **)(msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
                     freeMessage(msg);

+ 34 - 12
src/main.c

@@ -17,22 +17,44 @@ int main() {
         exit(EXIT_FAILURE);
     }
 
-    af_Code *bt1 = makeLiteralCode("data", "func", ',', 0, "Unknow");
-    af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
+    {  // 正常程序
+        af_Code *bt1 = makeLiteralCode("data", "func", ',', 0, "Unknow");
+        af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
 
-    af_Code *bt3 = makeLiteralCode("data2", "func", 0, 0, NULL);
-    af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
-    af_Code *bt6 = makeVariableCode("object", 0, 1, NULL);
+        af_Code *bt3 = makeLiteralCode("data2", "func", 0, 0, NULL);
+        af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
+        af_Code *bt6 = makeVariableCode("object", 0, 1, NULL);
 
-    connectCode(&bt1, bt2);
-    connectCode(&bt3, bt4);
-    connectCode(&bt4, bt6);
+        connectCode(&bt1, bt2);
+        connectCode(&bt3, bt4);
+        connectCode(&bt4, bt6);
 
-    af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
-    connectCode(&bt2, bt5);
+        af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt2, bt5);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+    }
+
+    {  // 测试错误 (object2 Var not found)
+        af_Code *bt1 = makeLiteralCode("data", "func", ',', 0, "Unknow");
+        af_Code *bt2 = makeVariableCode("object2", 0, 1, NULL);
+
+        af_Code *bt3 = makeLiteralCode("data2", "func", 0, 0, NULL);
+        af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
+        af_Code *bt6 = makeVariableCode("object", 0, 1, NULL);
+
+        connectCode(&bt1, bt2);
+        connectCode(&bt3, bt4);
+        connectCode(&bt4, bt6);
+
+        af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt2, bt5);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+    }
 
-    iterCode(bt1, env);
-    freeAllCode(bt1);
     freeEnvironment(env);
     return 0;
 }