Bläddra i källkod

feat: 字面量创建调用API

SongZihuan 3 år sedan
förälder
incheckning
a8fb2ff5fc
6 ändrade filer med 116 tillägg och 21 borttagningar
  1. 3 0
      include/obj_api.h
  2. 5 1
      src/core/__env.h
  3. 12 7
      src/core/code.c
  4. 20 0
      src/core/env.c
  5. 44 12
      src/core/run.c
  6. 32 1
      src/main.c

+ 3 - 0
include/obj_api.h

@@ -35,4 +35,7 @@ typedef bool obj_funcGetArgList(ArgList **al, af_Object *obj, ArgCodeList *acl,
 typedef bool obj_funcGetInfo(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env);  // 获取函数信息
 typedef void obj_funcFreeMask(void *mark);  // 释放mask的函数
 
+/* Object 字面量设定 */
+typedef void obj_literalSetting(char *str, void *data, af_Object *obj, af_Environment *env);
+
 #endif //AFUN__OBJ_API_H

+ 5 - 1
src/core/__env.h

@@ -76,7 +76,7 @@ struct af_Activity {  // 活动记录器
     bool return_first;  // 顺序执行, 获取第一个返回结果
     struct af_Object *return_obj;  // 调用者向被调用者传递信息
 
-    // 函数调用专项
+    /* 函数调用专项 */
     enum af_BlockType call_type;  // 函数调用类型
     struct af_Object *parentheses_call;  // 类前缀调用
     struct ArgCodeList *acl_start;
@@ -84,6 +84,9 @@ struct af_Activity {  // 活动记录器
     struct af_FuncInfo *fi;
     struct af_FuncBody *body_next;
     void *mark;  // 标记 [完全由API管理, 不随activity释放]
+
+    /* 字面量专项 */
+    bool is_literal;  // 处于字面量运算 意味着函数调用结束后会调用指定API
 };
 
 struct af_TopMsgProcess {  // 顶层msg处理器
@@ -124,6 +127,7 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env);
 void popActivity(af_Message *msg, af_Environment *env);
 
 /* 运行时Activity设置函数 (设置Activity) */
+bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env);
 bool setFuncActivityToArg(af_Object *func, af_Environment *env);
 bool setFuncActivityAddVar(bool new_vsl, bool is_protect, af_Environment *env);
 

+ 12 - 7
src/core/code.c

@@ -8,6 +8,16 @@
 #include "tool.h"
 #include "__code.h"
 
+/* Code 创建函数 */
+static af_Code *makeCode(char prefix, FileLine line, FilePath path);
+
+/* Code 操作函数 */
+static void countElement(af_Code *element, CodeUint *elements, CodeUint *count, af_Code **next);
+
+/* Code IO函数 */
+static bool readCode(af_Code **bt, FILE *file);
+static bool writeCode(af_Code *bt, FILE *file);
+
 static af_Code *makeCode(char prefix, FileLine line, FilePath path) {
     af_Code *bt = calloc(1, sizeof(af_Code));
     bt->line = line;
@@ -38,7 +48,7 @@ af_Code *makeVariableCode(char *var, char prefix, FileLine line, FilePath path)
  * 函数名: countElement
  * 目标: 统计元素个数(不包括元素的子元素)
  */
-static bool countElement(af_Code *element, CodeUint *elements, CodeUint *count, af_Code **next) {
+static void countElement(af_Code *element, CodeUint *elements, CodeUint *count, af_Code **next) {
     CodeUint to_next = 0;  // 表示紧接着的元素都不纳入统计(指block的子元素)
 
     for (*elements = 0; element != NULL; *next = element, element = element->next) {
@@ -51,8 +61,6 @@ static bool countElement(af_Code *element, CodeUint *elements, CodeUint *count,
         if (element->type == block)
             to_next += element->block.elements;
     }
-
-    return true;
 }
 
 af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, FileLine line, FilePath path, af_Code **next) {
@@ -64,9 +72,7 @@ af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, Fi
     if (next == NULL)
         next = &tmp;
 
-    if (!countElement(element, &elements, &count, next))
-        return NULL;
-
+    countElement(element, &elements, &count, next);
     bt = makeCode(prefix, line, path);
     bt->type = block;
     bt->block.type = type;
@@ -173,7 +179,6 @@ bool getCodeBlockNext(af_Code *bt, af_Code **next) {
 }
 
 #define Done(write) do{if(!(write)){return false;}}while(0)
-
 static bool writeCode(af_Code *bt, FILE *file) {
     Done(byteWriteUint_8(file, bt->type));
     Done(byteWriteUint_8(file, bt->prefix));

+ 20 - 0
src/core/env.c

@@ -515,6 +515,26 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
     return true;
 }
 
+bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env) {
+    env->activity->bt_next = bt->next;
+    if (bt->next == NULL && env->activity->body_next == NULL) {
+        env->activity->bt_top = bt;
+        env->activity->bt_start = NULL;
+        env->activity->bt_next = NULL;
+        freeMark(env);
+        /* 保持原有的 return_first */
+    } else {
+        af_Activity *activity = makeActivity(bt, NULL, false, env->activity->msg_up, env->activity->var_list,
+                                             env->activity->belong, env->activity->func);
+        activity->prev = env->activity;
+        env->activity = activity;
+    }
+
+    env->activity->is_literal = true;
+    env->activity->call_type = env->activity->bt_top->block.type;
+    return setFuncActivityToArg(func, env);
+}
+
 bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
     obj_funcGetArgCodeList *get_acl = findAPI("obj_funcGetArgCodeList", func->data->api);
     obj_funcGetVarList *get_var_list = findAPI("obj_funcGetVarList", func->data->api);

+ 44 - 12
src/core/run.c

@@ -5,7 +5,7 @@
 
 /* Code 执行函数 */
 static void codeVariable(af_Code *code, af_Environment *env);
-static void codeLiteral(af_Code *code, af_Environment *env);
+static bool codeLiteral(af_Code *code, af_Environment *env);
 static bool codeBlock(af_Code *code, af_Environment *env);
 
 /* 工具函数 */
@@ -31,15 +31,21 @@ static void codeVariable(af_Code *code, af_Environment *env) {
     env->activity->bt_next = env->activity->bt_next->next;
 }
 
-static void codeLiteral(af_Code *code, af_Environment *env) {
-    af_Object *obj = makeObject("Literal", true, makeObjectAPI(), true, NULL, NULL, env);
-    af_Message *msg = makeMessage("NORMAL", sizeof(af_Object *));
-    *((af_Object **)msg->msg) = obj;
-    gc_addReference(obj);
-    pushMessageDown(msg, env);
+static bool codeLiteral(af_Code *code, af_Environment *env) {
+    af_Var *var;
 
-    printf("Literal %s(%s) : %p\n", code->literal.func, code->literal.literal_data, obj);
-    env->activity->bt_next = env->activity->bt_next->next;
+    if (code->literal.in_protect)
+        var = findVarFromVarSpace(code->literal.func, env->core->protect);
+    else
+        var = findVarFromVarList(code->literal.func, env->activity->vsl);
+
+    if (var == NULL) {
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+        printf("Literal not found: %s\n", code->variable.name);
+        return false;
+    }
+
+    return pushLiteralActivity(code, var->vn->obj, env);
 }
 
 static bool codeBlock(af_Code *code, af_Environment *env) {
@@ -84,6 +90,22 @@ static void popLastActivity(af_Message *msg, af_Environment *env) {
     } while (env->activity != NULL && env->activity->bt_next == NULL);
 }
 
+static bool checkLiteral(af_Message **msg, af_Environment *env) {
+    if (!env->activity->is_literal)
+        return true;
+
+    af_Object *obj = *(af_Object **)((*msg)->msg);
+    obj_literalSetting *func = findAPI("obj_literalSetting", obj->data->api);
+    if (func == NULL) {
+        gc_delReference(obj);
+        freeMessage(*msg);
+        *msg = makeMessage("ERROR-STR", 0);
+        return false;
+    }
+    func(env->activity->bt_top->literal.literal_data, obj->data->data, obj, env);
+    return true;
+}
+
 bool iterCode(af_Code *code, af_Environment *env) {
     env->process_msg_first = false;  // 优先处理msg而不是运行代码
     if (!addTopActivity(code, env))
@@ -103,14 +125,15 @@ bool iterCode(af_Code *code, af_Environment *env) {
             if (!env->process_msg_first) {
                 switch (env->activity->bt_next->type) {
                     case literal:
-                        codeLiteral(env->activity->bt_next, env);
+                        if (codeLiteral(env->activity->bt_next, env))
+                            continue;  // 若运行成功则跳转到下一次运行, 该步骤仅为设置Activity
                         break;
                     case variable:
                         codeVariable(env->activity->bt_next, env);
                         break;
                     case block:
                         if (codeBlock(env->activity->bt_next, env))
-                            continue;  // 若运行成功则跳转到下一次运行, 该步骤没有任何实质性运算
+                            continue;  // 若运行成功则跳转到下一次运行, 该步骤仅为设置Activity
                     default:
                         break;  // 错误
                 }
@@ -144,12 +167,21 @@ bool iterCode(af_Code *code, af_Environment *env) {
                 else if (env->activity->bt_next == NULL) { // 执行完成
                     switch (setFuncActivityToNormal(env)) {
                         case -1:  // 已经没有下一步了 (原msg不释放)
+                            checkLiteral(&msg, env);  // 检查是否字面量
                             popLastActivity(msg, env);
                             break;
                         case 0:  // 已经没有下一步了 (但原msg释放)
                             gc_delReference(*(af_Object **)(msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
                             freeMessage(msg);
-                            popLastActivity(NULL, env);
+
+                            if (env->activity->msg_down == NULL)  // 检查是否有msg
+                                msg = makeMessage("ERROR-STR", 0);
+                            else {
+                                msg = getFirstMessage(env);
+                                checkLiteral(&msg, env);  // 检查是否字面量
+                            }
+
+                            popLastActivity(msg, env);
                             break;
                         default:
                         case 1:  // 继续运行

+ 32 - 1
src/main.c

@@ -41,10 +41,23 @@ bool getAl(ArgList **al, af_Object *obj, ArgCodeList *acl, void *mark, af_Enviro
     return true;
 }
 
+void literalSet(char *str, void *data, af_Object *obj, af_Environment *env) {
+    printf("literalSet(): str = %s\n", str);
+}
+
 void testFunc(int *mark, af_Environment *env) {  // 测试用函数
     printf("testFunc(): I am testFunc\n");
+    af_Object *obj;
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) literal_set = MAKE_SYMBOL(literalSet, objectAPIFunc);
+        if (addAPI(literal_set, "obj_literalSetting", api) != 1)
+            return;
+        obj = makeObject("func", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(literal_set);
+    }
 
-    af_Object *obj = makeObject("Literal", true, makeObjectAPI(), true, NULL, NULL, env);
     af_Message *msg = makeMessage("NORMAL", sizeof(af_Object *));
     *((af_Object **)(getMessageData(msg))) = obj;
     gc_addReference(obj);
@@ -136,6 +149,7 @@ int main() {
     }
 
     {  // 正常程序
+        printf("TAG A:\n");
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
         af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
         connectCode(&bt1, bt2);
@@ -153,6 +167,7 @@ int main() {
     }
 
     {  // 尾调递归优化
+        printf("TAG B:\n");
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
         af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
         connectCode(&bt1, bt2);
@@ -166,7 +181,17 @@ int main() {
         printf("\n");
     }
 
+    {  // 尾调递归优化2
+        printf("TAG C:\n");
+        af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
     {  // 测试类前缀调用
+        printf("TAG D:\n");
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
         af_Code *bt2 = makeVariableCode("func", 0, 1, NULL);
         connectCode(&bt1, bt2);
@@ -184,6 +209,7 @@ int main() {
     }
 
     {  // 测试错误 (无函数指定)
+        printf("TAG F: ERROR\n");
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
 
         af_Code *bt5 = makeBlockCode(curly, NULL, 0, 1, NULL, NULL);
@@ -198,6 +224,7 @@ int main() {
     }
 
     {  // 测试错误 (object2 Var not found)
+        printf("TAG G: ERROR\n");
         af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
         af_Code *bt2 = makeVariableCode("object2", 0, 1, NULL);
 
@@ -209,6 +236,7 @@ int main() {
     }
 
     {  // 测试顺序执行 '(xxx)
+        printf("TAG H:\n");
         af_Code *bt3 = makeLiteralCode("data2", "func", false, 0, 0, NULL);
         af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
 
@@ -225,6 +253,7 @@ int main() {
     }
 
     {  // 测试顺序执行 ,[xxx]
+        printf("TAG I:\n");
         af_Code *bt3 = makeLiteralCode("data2", "func", false, 0, 0, NULL);
         af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
 
@@ -241,6 +270,7 @@ int main() {
     }
 
     {  // 测试顺序执行 '(xxx) 【尾调递归优化】
+        printf("TAG J:\n");
         af_Code *bt3 = makeLiteralCode("data2", "func", false, 0, 0, NULL);
         af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
 
@@ -254,6 +284,7 @@ int main() {
     }
 
     {  // 测试顺序执行 ,[xxx] 【尾调递归优化】
+        printf("TAG K:\n");
         af_Code *bt3 = makeLiteralCode("data2", "func", false, 0, 0, NULL);
         af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);