Ver Fonte

feat: run模块添加顺序执行

SongZihuan há 3 anos atrás
pai
commit
eb88a24a9f
4 ficheiros alterados com 71 adições e 7 exclusões
  1. 5 1
      src/core/__env.h
  2. 3 2
      src/core/env.c
  3. 39 4
      src/core/run.c
  4. 24 0
      src/main.c

+ 5 - 1
src/core/__env.h

@@ -69,7 +69,11 @@ struct af_Activity {  // 活动记录器
     struct af_Code *bt_next;  // 指示代码下一步要运行的位置
 
     bool return_first;  // 顺序执行, 获取第一个返回结果
-    struct af_Message *return_msg;  // 调用者向被调用者传递信息
+    struct af_Object *return_obj;  // 调用者向被调用者传递信息
+
+    // 函数调用专项
+    bool must_common_arg;  // 强制普通参数
+    bool not_strict;  // 非严格调用
 };
 
 struct af_TopMsgProcess {  // 顶层msg处理器

+ 3 - 2
src/core/env.c

@@ -165,8 +165,9 @@ static af_Activity *freeActivity(af_Activity *activity) {
     if (activity->func != NULL)
         gc_delReference(activity->func);
 
-    if (activity->return_msg != NULL)
-        freeMessage(activity->return_msg);
+    if (activity->return_obj != NULL)
+        gc_delReference(activity->return_obj);
+
     freeAllMessage(activity->msg_down);  // msg转移后需要将对应成员设置为NULL
     for (int i = activity->msg_up_count; i > 0; i--) {
         if (msg_up == NULL)  // 发生了错误

+ 39 - 4
src/core/run.c

@@ -16,9 +16,10 @@ static af_Code *codeVariable(af_Code *code, af_Environment *env) {
         msg = makeMessage("NORMAL", sizeof(af_Object *));
         *((af_Object **)msg->msg) = obj;
         gc_addReference(obj);
+        printf("Get Variable %s : %p\n", code->variable.name, obj);
     } else {
         msg = makeMessage("ERROR-STR", 0);
-        printf("Var not found: %s\n", code->variable.name);
+        printf("Variable not found: %s\n", code->variable.name);
     }
 
     pushMessageDown(msg, env);
@@ -28,7 +29,7 @@ static af_Code *codeVariable(af_Code *code, af_Environment *env) {
 static af_Code *codeLiteral(af_Code *code, af_Environment *env) {
     af_Message *msg;
     af_Object *obj = makeObject("Literal", 0, true, true, NULL, NULL, env);
-    printf("Literal %s : %s\n", code->literal.func, code->literal.literal_data);
+    printf("Literal %s(%s) : %p\n", code->literal.func, code->literal.literal_data, obj);
     msg = makeMessage("NORMAL", sizeof(af_Object *));
     *((af_Object **)msg->msg) = obj;
     gc_addReference(obj);
@@ -50,11 +51,39 @@ static void popLastActivity(af_Message *msg, af_Environment *env){
     do {  // 如果返回一级后仍是执行完成则继续返回
         if (env->activity->prev == NULL)
             printf("top finished\n");
+        if (env->activity->return_first) {
+            if (msg != NULL) {
+                gc_delReference(*(af_Object **)msg->msg);
+                freeMessage(msg);
+            }
+
+            if (env->activity->return_obj == NULL)
+                msg = makeMessage("ERROR-STR", 0);
+            else {
+                msg = makeMessage("NORMAL", sizeof(af_Object *));
+                *(af_Object **)msg->msg = env->activity->return_obj;  // env->activity->return_obj本来就有一个gc_Reference
+                env->activity->return_obj = NULL;
+            }
+        }
         popActivity(msg, env);
         msg = NULL;  // 随后几次执行popActivity时不需要压入新的msg
     } while (env->activity != NULL && env->activity->bt_next == NULL);
 }
 
+static void codeBlock(af_Code *bt, af_Environment *env) {
+    if (bt->prefix == '\'' && bt->block.type == parentheses)  // 顺序执行, 返回尾项
+        pushExecutionActivity(bt, false, env);
+    else if (bt->prefix == ',' && bt->block.type == brackets)  // 顺序执行, 返回首项
+        pushExecutionActivity(bt, true, env);
+    else {
+        pushFuncActivity(env->activity->bt_next, env);
+        if (bt->prefix == '<')
+            env->activity->must_common_arg = true;
+        else if (bt->prefix == ',')
+            env->activity->not_strict = true;
+    }
+}
+
 bool iterCode(af_Code *code, af_Environment *env) {
     if (!addTopActivity(code, env))
        return false;
@@ -68,8 +97,8 @@ bool iterCode(af_Code *code, af_Environment *env) {
             case variable:
                 env->activity->bt_next = codeVariable(env->activity->bt_next, env);
                 break;
-            case block:  // TODO-szh 考虑前缀
-                pushFuncActivity(env->activity->bt_next, env);
+            case block:
+                codeBlock(env->activity->bt_next, env);
                 continue;  // 该步骤没有任何实质性运算
             default:
                 break;  // 错误
@@ -83,12 +112,18 @@ bool iterCode(af_Code *code, af_Environment *env) {
         if (!EQ_STR(msg->type, "NORMAL")) {
             pushMessageDown(msg, env);
             if (env->activity->status != act_normal || !checkInMsgType(msg->type, env)) {
+                if (env->activity->return_obj != NULL)
+                    gc_delReference(env->activity->return_obj);
+                env->activity->return_obj = NULL;
                 popLastActivity(NULL, env);  // msg 已经 push进去了
                 continue;
             } else {
                 env->activity->bt_next = NULL;
                 // TODO-szh 切换函数
             }
+        } else if (env->activity->return_first && env->activity->return_obj == NULL) {
+            env->activity->return_obj = *(af_Object **)msg->msg;
+            gc_addReference(env->activity->return_obj);
         }
 
         switch (env->activity->status) {

+ 24 - 0
src/main.c

@@ -71,6 +71,30 @@ int main() {
         freeAllCode(bt1);
     }
 
+    {  // 测试顺序执行 '(xxx)
+        af_Code *bt3 = makeLiteralCode("data2", "func", 0, 0, NULL);
+        af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
+
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(parentheses, bt3, '\'', 1, NULL, NULL);
+
+        iterCode(bt5, env);
+        freeAllCode(bt5);
+    }
+
+    {  // 测试顺序执行 ,[xxx]
+        af_Code *bt3 = makeLiteralCode("data2", "func", 0, 0, NULL);
+        af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
+
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(brackets, bt3, ',', 1, NULL, NULL);
+
+        iterCode(bt5, env);
+        freeAllCode(bt5);
+    }
+
     freeEnvironment(env);
     return 0;
 }