瀏覽代碼

feat: 函数调用添加了参数处理函数

SongZihuan 3 年之前
父節點
當前提交
ebd7ef8157
共有 5 個文件被更改,包括 173 次插入86 次删除
  1. 1 5
      include/prefix_macro.h
  2. 12 3
      src/core/__env.h
  3. 40 13
      src/core/env.c
  4. 102 64
      src/core/run.c
  5. 18 1
      src/main.c

+ 1 - 5
include/prefix_macro.h

@@ -14,10 +14,6 @@
 #define B_MUST_COMMON_ARG (4)  /* 括号前缀: 强制普通参数调用 */
 #define B_NOT_STRICT      (5)  /* 括号前缀: 非严格参数匹配调用 */
 
-// 作为函数实参
-#define B_ARG_CUL         (6)  /* 括号前缀: 表示实际计算 */
-#define B_ARG_EXEC        (7)  /* 括号前缀: 表示顺序执行 */
-
-#define PREFIX_SIZE       (8)  /* 前缀总数 */
+#define PREFIX_SIZE       (6)  /* 前缀总数 */
 
 #endif //AFUN__PREFIX_MACRO_H

+ 12 - 3
src/core/__env.h

@@ -14,6 +14,7 @@ typedef struct af_TopMsgProcess af_TopMsgProcess;
 #include "__var.h"
 #include "__code.h"
 #include "__gc.h"
+#include "__arg.h"
 
 #define ENV_VAR_HASH_SIZE (8)
 typedef uint16_t ActivityCount;
@@ -60,7 +61,10 @@ struct af_Activity {  // 活动记录器
     ActivityCount msg_up_count;  // msg_up 添加的个数
     char **msg_type;  // 一个包含字符串的列表, 记录了需要处理的`msg`类型的数组
 
-    struct af_VarSpaceListNode *var_list;  // 变量空间
+    bool run_in_func;  // 在函数变量空间内运行 (act_arg用)
+    struct af_VarSpaceListNode *vsl;  // 变量空间
+    struct af_VarSpaceListNode *func_var_list;  // 函数内部变量空间 (运行函数体时会设置为 主变量空间)
+    struct af_VarSpaceListNode *var_list;  // 主变量空间
     ActivityCount new_vs_count;  // 需要释放的空间数
 
     struct af_Object *belong;  // 属对象 (belong通常为func的belong)
@@ -74,8 +78,13 @@ struct af_Activity {  // 活动记录器
     struct af_Object *return_obj;  // 调用者向被调用者传递信息
 
     // 函数调用专项
+    enum af_BlockType call_type;  // 函数调用类型
     bool must_common_arg;  // 强制普通参数
     bool not_strict;  // 非严格调用
+    af_Object *parentheses_call;  // 类前缀调用
+    ArgCodeList *acl_start;
+    ArgCodeList *acl_next;
+    bool is_last;  // 最后一个函数体 (允许尾调递归优化)
 };
 
 struct af_TopMsgProcess {  // 顶层msg处理器
@@ -114,6 +123,6 @@ void popActivity(af_Message *msg, af_Environment *env);
 
 /* 运行时Activity设置函数 (设置Activity) */
 bool setFuncActivityToArg(af_Object *func, af_Environment *env);
-bool setFuncActivityAddVar(af_VarSpaceListNode *vsl, bool new_vsl, bool is_protect, char **msg_type, af_Environment *env);
-bool setFuncActivityToNormal(af_Code *bt, af_Environment *env);
+bool setFuncActivityAddVar(bool new_vsl, bool is_protect, char **msg_type, af_Environment *env);
+bool setFuncActivityToNormal(bool is_first, af_Environment *env);
 #endif //AFUN__ENV_H

+ 40 - 13
src/core/env.c

@@ -45,9 +45,6 @@ static af_Core *makeCore(void) {
     core->prefix[B_MUST_COMMON_ARG] = '<';
     core->prefix[B_NOT_STRICT] = ',';
 
-    core->prefix[B_ARG_CUL] = '\'';
-    core->prefix[B_ARG_EXEC] = '\'';
-
     return core;
 }
 
@@ -207,12 +204,15 @@ static af_Activity *freeActivity(af_Activity *activity) {
         msg_up = freeMessage(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);
     }
 
+    freeAllArgCodeList(activity->acl_start);
     free(activity);
     return prev;
 }
@@ -393,6 +393,7 @@ bool addTopActivity(af_Code *code, af_Environment *env) {
     env->activity->var_list = makeVarSpaceList(env->core->global->data->var_space);
     env->activity->var_list->next = makeVarSpaceList(env->core->protect);
     env->activity->status = act_normal;
+    env->activity->is_last = true;
     return true;
 }
 
@@ -484,7 +485,16 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
     env->activity->bt_next = next;
     activity->prev = env->activity;
     env->activity = activity;
-    env->activity->status = act_func;
+    env->activity->call_type = env->activity->bt_top->block.type;
+    env->activity->func_var_list = env->activity->var_list;  // 设置为函数变量空间 [桩]
+
+    if (env->activity->call_type == parentheses) {  // 对于类前缀调用, 已经获得func的实际值了
+        setFuncActivityToArg(env->activity->prev->parentheses_call, env);
+        gc_delReference(env->activity->prev->parentheses_call);
+        env->activity->prev->parentheses_call = NULL;
+    } else
+        env->activity->status = act_func;
+
     return true;
 }
 
@@ -499,31 +509,48 @@ bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
     env->activity->func = func;
     env->activity->belong = belong;
     env->activity->status = act_arg;
-    // TODO-szh 参数处理(计算)
+
+    env->activity->acl_start = NULL;  // 设置acl [桩]
+    env->activity->acl_next = env->activity->acl_start;
+    env->activity->bt_next = NULL;
     return true;
 }
 
-bool setFuncActivityAddVar(af_VarSpaceListNode *vsl, bool new_vsl, bool is_protect, char **msg_type, af_Environment *env) {
-    if (env->activity->new_vs_count != 0 || !new_vsl && is_protect)
+bool setFuncActivityAddVar(bool new_vsl, bool is_protect, char **msg_type, af_Environment *env) {
+    if (!new_vsl && is_protect)
         return false;
 
-    if (vsl != NULL)
-        env->activity->var_list = vsl;
+    // 桩函数: 目前func_var_list引用自var_list, 故var_list不释放
+    //af_VarSpaceListNode *vs = env->activity->var_list;
+    //for (int i = env->activity->new_vs_count; i > 0; i--) {
+    //    if (vs == NULL)  // 发生了错误
+    //        return false;
+    //    vs = popLastVarList(vs);
+    //}
+
+    env->activity->var_list = env->activity->func_var_list;
+    env->activity->func_var_list = NULL;
+    env->activity->new_vs_count = 0;
     if (new_vsl) {
         env->activity->var_list = pushNewVarList(env->activity->var_list);
         env->activity->new_vs_count = 1;
     }
 
     env->activity->msg_type = msg_type;
-    // TODO-szh 参数处理(赋值)
+    runArgList(NULL, env->activity->var_list);
     env->activity->var_list->vs->is_protect = is_protect;
     return true;
 }
 
-bool setFuncActivityToNormal(af_Code *bt, af_Environment *env) {
-    env->activity->bt_start = bt;
-    env->activity->bt_next = bt;
+bool setFuncActivityToNormal(bool is_first, af_Environment *env) {  // 获取函数的函数体
     env->activity->status = act_normal;
+    env->activity->bt_next = NULL;
+    if (env->activity->is_last)
+        return false;
+
+    env->activity->bt_start = env->activity->bt_start;
+    env->activity->bt_next = env->activity->bt_start;
+    env->activity->is_last = true;
     return true;
 }
 

+ 102 - 64
src/core/run.c

@@ -8,16 +8,16 @@
 #include "__code.h"
 
 /* Code 执行函数 */
-static af_Code *codeVariable(af_Code *code, af_Environment *env);
-static af_Code *codeLiteral(af_Code *code, af_Environment *env);
-static void codeBlock(af_Code *bt, af_Environment *env);
+static void codeVariable(af_Code *code, af_Environment *env);
+static void codeLiteral(af_Code *code, af_Environment *env);
+static void codeBlock(af_Code *code, af_Environment *env);
 
 /* 工具函数 */
 static bool checkInMsgType(char *type, af_Environment *env);
 static void popLastActivity(af_Message *msg, af_Environment *env) ;
 
-static af_Code *codeVariable(af_Code *code, af_Environment *env) {
-    af_Var *var = findVarFromVarList(code->variable.name, env->activity->var_list);
+static void codeVariable(af_Code *code, af_Environment *env) {
+    af_Var *var = findVarFromVarList(code->variable.name, env->activity->vsl);
     af_Message *msg;
 
     if (var != NULL) {
@@ -32,32 +32,34 @@ static af_Code *codeVariable(af_Code *code, af_Environment *env) {
     }
 
     pushMessageDown(msg, env);
-    return code->next;
+    env->activity->bt_next = env->activity->bt_next->next;
 }
 
-static af_Code *codeLiteral(af_Code *code, af_Environment *env) {
-    af_Message *msg;
+static void codeLiteral(af_Code *code, af_Environment *env) {
     af_Object *obj = makeObject("Literal", 0, true, true, NULL, NULL, env);
-    printf("Literal %s(%s) : %p\n", code->literal.func, code->literal.literal_data, obj);
-    msg = makeMessage("NORMAL", sizeof(af_Object *));
+    af_Message *msg = makeMessage("NORMAL", sizeof(af_Object *));
     *((af_Object **)msg->msg) = obj;
     gc_addReference(obj);
     pushMessageDown(msg, env);
-    return code->next;
+
+    printf("Literal %s(%s) : %p\n", code->literal.func, code->literal.literal_data, obj);
+    env->activity->bt_next = env->activity->bt_next->next;
 }
 
-static void codeBlock(af_Code *bt, af_Environment *env) {
-    if (bt->prefix == env->core->prefix[B_EXEC] && bt->block.type == parentheses)  // 顺序执行, 返回尾项
-        pushExecutionActivity(bt, false, env);
-    else if (bt->prefix == env->core->prefix[B_EXEC_FIRST] && bt->block.type == brackets)  // 顺序执行, 返回首项
-        pushExecutionActivity(bt, true, env);
-    else {
+static void codeBlock(af_Code *code, af_Environment *env) {
+    if (code->prefix == env->core->prefix[B_EXEC] && code->block.type == parentheses)  // 顺序执行, 返回尾项
+        pushExecutionActivity(code, false, env);
+    else if (code->prefix == env->core->prefix[B_EXEC_FIRST] && code->block.type == brackets)  // 顺序执行, 返回首项
+        pushExecutionActivity(code, true, env);
+    else if (code->prefix == NUL) {
         pushFuncActivity(env->activity->bt_next, env);
-        if (bt->prefix == env->core->prefix[B_MUST_COMMON_ARG])
+        if (code->prefix == env->core->prefix[B_MUST_COMMON_ARG])
             env->activity->must_common_arg = true;
-        else if (bt->prefix == env->core->prefix[B_NOT_STRICT])
+        else if (code->prefix == env->core->prefix[B_NOT_STRICT])
             env->activity->not_strict = true;
-    }
+    } else
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+
 }
 
 static bool checkInMsgType(char *type, af_Environment *env) {
@@ -95,67 +97,102 @@ static void popLastActivity(af_Message *msg, af_Environment *env) {
 
 bool iterCode(af_Code *code, af_Environment *env) {
     if (!addTopActivity(code, env))
-       return false;
+        return false;
 
     while (env->activity != NULL) {
-        af_Message *msg;
-        switch (env->activity->bt_next->type) {
-            case literal:
-                env->activity->bt_next = codeLiteral(env->activity->bt_next, env);
-                break;
-            case variable:
-                env->activity->bt_next = codeVariable(env->activity->bt_next, env);
-                break;
-            case block:
-                codeBlock(env->activity->bt_next, env);
-                continue;  // 该步骤没有任何实质性运算
-            default:
-                break;  // 错误
-        }
-
-        if (env->activity->msg_down == NULL) {
-            msg = makeMessage("ERROR-STR", 0);
-        } else
-            msg = getFirstMessage(env);
+        af_Message *msg = NULL;
+        bool run_code = false;
+
+        if (env->activity->status == act_arg && env->activity->run_in_func && env->activity->func_var_list != NULL)
+            env->activity->vsl = env->activity->func_var_list;
+        else
+            env->activity->vsl = env->activity->var_list;
+
+        if (env->activity->bt_next != NULL) {
+            run_code = true;
+            switch (env->activity->bt_next->type) {
+                case literal:
+                    codeLiteral(env->activity->bt_next, env);
+                    break;
+                case variable:
+                    codeVariable(env->activity->bt_next, env);
+                    break;
+                case block:
+                    codeBlock(env->activity->bt_next, env);
+                    continue;  // 该步骤没有任何实质性运算
+                default:
+                    break;  // 错误
+            }
 
-        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 切换函数
+            if (env->activity->msg_down == NULL)  // 若未获得 msg
+                msg = makeMessage("ERROR-STR", 0);
+            else
+                msg = getFirstMessage(env);
+
+            if (!EQ_STR(msg->type, "NORMAL")) {  // 若msg为非正常值
+                pushMessageDown(msg, env);  // msg不弹出
+                if (env->activity->status != act_normal || !checkInMsgType(msg->type, env)) {  // 非normal模式, 或normal模式不匹配该msg
+                    if (env->activity->return_obj != NULL)
+                        gc_delReference(env->activity->return_obj);
+                    env->activity->return_obj = NULL;
+                    popLastActivity(NULL, env);  // msg 已经 push进去了
+                    continue;
+                }
+            } else if (env->activity->return_first && env->activity->return_obj == NULL) {  // 设置return_first
+                env->activity->return_obj = *(af_Object **)msg->msg;
+                gc_addReference(env->activity->return_obj);
             }
-        } 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) {
             case act_normal:
-                if (env->activity->bt_next == NULL) { // 执行完成
+                if (!run_code) {
+                    msg = makeMessage("ERROR-STR", 0);  // 无代码可运行
                     popLastActivity(msg, env);
+                } else if (env->activity->bt_next == NULL) { // 执行完成
+                    if (setFuncActivityToNormal(true, env))
+                        goto run_continue;  // 继续运行
+                    else
+                        popLastActivity(msg, env);
+                } else if (env->activity->bt_next->type == block && env->activity->bt_next->block.type == parentheses
+                           && env->activity->bt_next->prefix == NUL) {  // 类前缀调用
+                    env->activity->parentheses_call = *(af_Object **)(msg->msg);
+                    freeMessage(msg);
                 } else {
+                    run_continue:
                     gc_delReference(*(af_Object **)(msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
                     freeMessage(msg);
                 }
                 break;
             case act_func: {
-                af_Object *func = *(af_Object **)(msg->msg);  // func仍保留了msg的gc计数
-                freeMessage(msg);
-                setFuncActivityToArg(func, env);  // 该函数会设定bt_next到arg计算的bt上
-                gc_delReference(func);  // 释放计数
+                if (!run_code) {
+                    msg = makeMessage("ERROR-STR", 0);  // 无代码可运行
+                    popLastActivity(msg, env);
+                } else {
+                    af_Object *func = *(af_Object **)(msg->msg);  // func仍保留了msg的gc计数
+                    freeMessage(msg);
+                    setFuncActivityToArg(func, env);  // 该函数会设定bt_next到arg计算的bt上
+                    gc_delReference(func);  // 释放计数
+                }
                 break;
             }
-            case act_arg: {  // TODO-szh 暂时跳过参数设定
-                setFuncActivityAddVar(NULL, true, false, NULL, env);
-                setFuncActivityToNormal(env->activity->bt_next, env);
-                gc_delReference(*(af_Object **)(msg->msg));  // 释放计数
-                freeMessage(msg);
+            case act_arg: {
+                if (!run_code) {
+                    act_arg_end:
+                    setFuncActivityAddVar(true, false, NULL, env);
+                    if (!setFuncActivityToNormal(true, env)) {
+                        msg = makeMessage("ERROR-STR", 0);  // 无代码可运行
+                        popLastActivity(msg, env);
+                    }
+                } else {
+                    env->activity->acl_next->result = *(af_Object **)(msg->msg);
+                    freeMessage(msg);
+                    if (env->activity->acl_next->next == NULL)
+                        goto act_arg_end;  // 参数设定结束
+
+                    env->activity->acl_next = env->activity->acl_next->next;
+                    env->activity->bt_next = env->activity->acl_next->code;
+                }
                 break;
             }
             default:
@@ -163,5 +200,6 @@ bool iterCode(af_Code *code, af_Environment *env) {
         }
 
     }
+
     return true;
 }

+ 18 - 1
src/main.c

@@ -38,7 +38,7 @@ int main() {
         af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
 
         af_Code *bt3 = makeLiteralCode("data2", "func", false, 0, 0, NULL);
-        af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
+        af_Code *bt4 = makeVariableCode("object", 0, 1, NULL);
         af_Code *bt6 = makeVariableCode("object", 0, 1, NULL);
 
         connectCode(&bt1, bt2);
@@ -52,6 +52,23 @@ int main() {
         freeAllCode(bt1);
     }
 
+    {  // 测试类前缀调用
+        af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
+        af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
+
+        af_Code *bt3 = makeLiteralCode("data2", "func", false, 0, 0, NULL);
+        af_Code *bt4 = makeVariableCode("object", 0, 1, NULL);
+
+        connectCode(&bt1, bt2);
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(parentheses, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt2, bt5);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+    }
+
     {  // 测试错误 (object2 Var not found)
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
         af_Code *bt2 = makeVariableCode("object2", 0, 1, NULL);