Browse Source

feat: 添加对象函数调用的支持

SongZihuan 3 years ago
parent
commit
275de177a3
7 changed files with 130 additions and 20 deletions
  1. 1 1
      include/func.h
  2. 2 1
      src/core/__env.h
  3. 0 1
      src/core/__func.h
  4. 8 0
      src/core/env.c
  5. 1 2
      src/core/func.c
  6. 19 10
      src/core/run.c
  7. 99 5
      src/main.c

+ 1 - 1
include/func.h

@@ -45,7 +45,7 @@ ArgList **pushNewArgList(ArgList **base, char *name, af_Object *obj);
 bool runArgList(ArgList *al, af_VarSpaceListNode *vsl);
 
 /* FuncInfo 创建与释放 */
-af_FuncInfo *makeFuncInfo(enum af_FuncInfoScope scope, enum af_FuncInfoEmbedded embedded, bool is_macro, bool is_object);
+af_FuncInfo *makeFuncInfo(enum af_FuncInfoScope scope, enum af_FuncInfoEmbedded embedded, bool is_macro);
 
 void freeFuncInfo(af_FuncInfo *fi);
 

+ 2 - 1
src/core/__env.h

@@ -130,8 +130,9 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env);
 void popActivity(af_Message *msg, af_Environment *env);
 
 /* 运行时Activity设置函数 (设置Activity) */
-bool pushMacroFuncActivity(af_Object *func, af_Environment *env);
+bool pushVariableActivity(af_Code *bt, af_Object *func, af_Environment *env);
 bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env);
+bool pushMacroFuncActivity(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);
 

+ 0 - 1
src/core/__func.h

@@ -53,7 +53,6 @@ struct af_FuncInfo {
     enum af_FuncInfoEmbedded embedded;  // 定义在 func.h
 
     bool is_macro;  // 宏函数
-    bool is_object;  // 对象函数
 
     // 函数信息
     struct af_FuncBody *body;

+ 8 - 0
src/core/env.c

@@ -550,6 +550,14 @@ bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env) {
     return setFuncActivityToArg(func, env);
 }
 
+bool pushVariableActivity(af_Code *bt, af_Object *func, af_Environment *env) {
+    env->activity->bt_next = bt->next;
+
+    /* 隐式调用不设置 bt_top */
+    newActivity(bt, bt->next, false, true, env);
+    return setFuncActivityToArg(func, env);
+}
+
 bool pushMacroFuncActivity(af_Object *func, af_Environment *env) {
     /* Macro是隐式调用, bt不移动 */
     /* 沿用activity */

+ 1 - 2
src/core/func.c

@@ -161,12 +161,11 @@ static void pushFuncBody(af_FuncBody **base, af_FuncBody *body) {
     *base = body;
 }
 
-af_FuncInfo *makeFuncInfo(enum af_FuncInfoScope scope, enum af_FuncInfoEmbedded embedded, bool is_macro, bool is_object) {
+af_FuncInfo *makeFuncInfo(enum af_FuncInfoScope scope, enum af_FuncInfoEmbedded embedded, bool is_macro){
     af_FuncInfo *fi = calloc(sizeof(af_FuncInfo), 1);
     fi->scope = scope;
     fi->embedded = embedded;
     fi->is_macro = is_macro;
-    fi->is_object = is_object;
     return fi;
 }
 

+ 19 - 10
src/core/run.c

@@ -4,7 +4,7 @@
 #include "__env.h"
 
 /* Code 执行函数 */
-static void codeVariable(af_Code *code, af_Environment *env);
+static bool codeVariable(af_Code *code, af_Environment *env);
 static bool codeLiteral(af_Code *code, af_Environment *env);
 static bool codeBlock(af_Code *code, af_Environment *env);
 
@@ -12,23 +12,31 @@ static bool 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 void codeVariable(af_Code *code, af_Environment *env) {
+static bool codeVariable(af_Code *code, af_Environment *env) {
     af_Var *var = findVarFromVarList(code->variable.name, env->activity->vsl);
     af_Message *msg;
 
-    if (var != NULL) {
-        af_Object *obj = var->vn->obj;
+    if (var == NULL) {
+        pushMessageDown(makeMessage("ERROR-STR", 0), env);
+        printf("Variable not found: %s\n", code->variable.name);
+        return false;
+    }
+
+    af_Object *obj = var->vn->obj;
+    is_obj_func *func;
+    if (code->prefix == env->core->prefix[V_QUOTE] ||
+        (func = findAPI("is_obj_func", obj->data->api)) == NULL ||
+        !func(obj)) {  // 非对象函数 或 引用调用
         msg = makeMessage("NORMAL", sizeof(af_Object *));
         *((af_Object **)msg->msg) = obj;
         gc_addReference(obj);
+        env->activity->bt_next = env->activity->bt_next->next;
+        pushMessageDown(msg, env);
         printf("Get Variable %s : %p\n", code->variable.name, obj);
-    } else {
-        msg = makeMessage("ERROR-STR", 0);
-        printf("Variable not found: %s\n", code->variable.name);
+        return false;
     }
 
-    pushMessageDown(msg, env);
-    env->activity->bt_next = env->activity->bt_next->next;
+    return pushVariableActivity(code, var->vn->obj, env);
 }
 
 static bool codeLiteral(af_Code *code, af_Environment *env) {
@@ -142,7 +150,8 @@ bool iterCode(af_Code *code, af_Environment *env) {
                             continue;  // 若运行成功则跳转到下一次运行, 该步骤仅为设置Activity
                         break;
                     case variable:
-                        codeVariable(env->activity->bt_next, env);
+                        if (codeVariable(env->activity->bt_next, env))
+                            continue;
                         break;
                     case block:
                         if (codeBlock(env->activity->bt_next, env))

+ 99 - 5
src/main.c

@@ -66,7 +66,7 @@ void testFunc(int *mark, af_Environment *env) {  // 测试用函数
 }
 
 bool getInfo(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
-    *fi = makeFuncInfo(normal_scope, not_embedded, false, false);  // 获取FuncInfo [桩]
+    *fi = makeFuncInfo(normal_scope, not_embedded, false);  // 获取FuncInfo [桩]
     makeCodeFuncBodyToFuncInfo(makeVariableCode("test", NUL, 0, "Unknow"), true, NULL, *fi);
 
     DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc, callFuncBody);
@@ -117,7 +117,7 @@ void testFunc2(int *mark, af_Environment *env) {  // 测试用函数
 }
 
 bool getInfo2(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
-    *fi = makeFuncInfo(normal_scope, not_embedded, true, false);  // 获取FuncInfo [桩]
+    *fi = makeFuncInfo(normal_scope, not_embedded, true);  // 获取FuncInfo [桩]
     makeCodeFuncBodyToFuncInfo(makeVariableCode("test", NUL, 0, "Unknow"), true, NULL, *fi);
     DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc2, callFuncBody);
     makeCFuncBodyToFuncInfo(func, NULL, *fi);
@@ -126,11 +126,42 @@ bool getInfo2(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_En
 }
 
 bool getInfo3(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
-    *fi = makeFuncInfo(normal_scope, not_embedded, false, false);  // 获取FuncInfo [桩]
+    *fi = makeFuncInfo(normal_scope, not_embedded, false);  // 获取FuncInfo [桩]
     makeCodeFuncBodyToFuncInfo(makeLiteralCode("data3", "func", true, NUL, 0, "Unknow"), true, NULL, *fi);
     return true;
 }
 
+void testFunc4(int *mark, af_Environment *env) {  // 测试用函数
+    printf("testFunc4(): I am testFunc4\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_Message *msg = makeMessage("NORMAL", sizeof(af_Object *));
+    *((af_Object **)(getMessageData(msg))) = obj;
+    gc_addReference(obj);
+    pushMessageDown(msg, env);
+}
+
+bool getInfo4(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false);  // 获取FuncInfo [桩]
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc4, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+bool objFunc(af_Object *obj) {
+    return true;
+}
+
 int main() {
     aFunInit();
     printf("Hello World\n");
@@ -240,6 +271,38 @@ int main() {
         FREE_SYMBOL(free_mark);
     }
 
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_alc = MAKE_SYMBOL(getAcl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_al = MAKE_SYMBOL(getAl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info4 = MAKE_SYMBOL(getInfo4, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) obj_func = MAKE_SYMBOL(objFunc, objectAPIFunc);
+        if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
+            return 2;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return 2;
+        if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
+            return 2;
+        if (addAPI(get_info4, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(obj_func, "is_obj_func", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func4", 3, 3,
+                                        makeObject("func", true, api, true, NULL, NULL, env)),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info4);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(obj_func);
+    }
+
     addVarToProtectVarSpace(makeVar("object", 3, 3,
                                     makeObject("object", true, makeObjectAPI(), true, NULL, NULL, env)),
                             env);
@@ -257,8 +320,8 @@ int main() {
 
     {  // 正常程序
         printf("TAG A:\n");
-        af_Code *bt1 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
-        af_Code *bt2 = makeVariableCode("object", 0, 1, NULL);
+        af_Code *bt1 = makeVariableCode("object", 0, 1, NULL);
+        af_Code *bt2 = makeLiteralCode("data", "func", false, ',', 0, "Unknow");
         connectCode(&bt1, bt2);
 
         af_Code *bt3 = makeVariableCode("func", 0, 1, NULL);
@@ -438,6 +501,37 @@ int main() {
         printf("\n");
     }
 
+    {  // 对象函数的调用
+        printf("TAG N:\n");
+        af_Code *bt1 = makeVariableCode("func4", 0, 1, NULL);
+        af_Code *bt2 = makeVariableCode("global", 0, 1, NULL);
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 变量引用调用
+        printf("TAG O:\n");
+        af_Code *bt1 = makeVariableCode("func4", '\'', 1, NULL);
+        af_Code *bt2 = makeVariableCode("global", 0, 1, NULL);
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 对象函数的调用 (尾调递归有啊)
+        printf("TAG P:\n");
+        af_Code *bt1 = makeVariableCode("func4", 0, 1, NULL);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
     freeEnvironment(env);
     return 0;
 }