Browse Source

feat: 添加Reader模块

SongZihuan 3 năm trước cách đây
mục cha
commit
41336b1bf9
7 tập tin đã thay đổi với 1391 bổ sung28 xóa
  1. 43 0
      src/core/__reader.h
  2. 1 1
      src/core/code.c
  3. 89 0
      src/core/reader.c
  4. 29 27
      src/main.c
  5. 2 0
      test/CMakeLists.txt
  6. 87 0
      test/test_reader.c
  7. 1140 0
      test/test_run.c

+ 43 - 0
src/core/__reader.h

@@ -0,0 +1,43 @@
+#ifndef AFUN__READER_H
+#define AFUN__READER_H
+#include <stdio.h>
+#include "macro.h"
+#include "tool.h"
+
+#define DEFAULT_BUF_SIZE (1024)
+#define NEW_BUF_SIZE (512)
+
+typedef struct af_Reader af_Reader;
+
+typedef size_t readerFunc(void *data, char *dest, size_t len);
+NEW_DLC_SYMBOL(readerFunc, readerFunc);
+
+typedef void destructReaderDataFunc(void *data);
+NEW_DLC_SYMBOL(destructReaderDataFunc, destructReaderDataFunc);
+
+struct af_Reader {
+    DLC_SYMBOL(readerFunc) read_func;
+    DLC_SYMBOL(destructReaderDataFunc) destruct;
+    void *data;
+    size_t data_size;
+
+    char *buf;
+    char *buf_end;  // buf的尾部位置[NUL的位置]
+    size_t buf_size;  // buf的长度-1
+    char *read;
+    bool read_end;
+};
+
+/* Reader 创建与释放 */
+af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderDataFunc) destruct_func, size_t data_size);
+void freeReader(af_Reader *reader);
+
+/* Reader 初始化函数 */
+af_Reader *initReader(af_Reader *reader);
+
+/* Reader 操作哈桑 */
+char *readWord(size_t del_index, af_Reader *reader);
+char getChar(af_Reader *reader);
+void *getReaderData(af_Reader *reader);
+
+#endif //AFUN__READER_H

+ 1 - 1
src/core/code.c

@@ -234,10 +234,10 @@ static bool readCode(af_Code **bt, FILE *file) {
     Done(byteReadUint_8(file, &type));
     Done(byteReadUint_8(file, &prefix));
     Done(byteReadUint_32(file,&line));
+    Done(byteReadUint_32(file, &code_end));
     Done(byteReadUint_8(file, &(have_path)));
     if (have_path)
         Done(byteReadStr(file, &path));
-    Done(byteReadUint_32(file, &code_end));
 
     *bt = makeCode((char)prefix, line, path);
     free(path);

+ 89 - 0
src/core/reader.c

@@ -0,0 +1,89 @@
+#include "__reader.h"
+
+af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderDataFunc) destruct_func, size_t data_size) {
+    af_Reader *reader = calloc(1, sizeof(af_Reader));
+    reader->read_func = COPY_SYMBOL(read_func, readerFunc);
+    reader->destruct = COPY_SYMBOL(destruct_func, destructReaderDataFunc);
+
+    reader->data = calloc(1, data_size);
+    reader->data_size = data_size;
+
+    reader->buf = NEW_STR(DEFAULT_BUF_SIZE);
+    reader->buf_size = DEFAULT_BUF_SIZE;
+    reader->buf_end = reader->buf + DEFAULT_BUF_SIZE;  // 执行buf[DEFAULT_BUF_SIZE], 即NUL
+    reader->read = reader->buf;
+    return reader;
+}
+
+af_Reader *initReader(af_Reader *reader) {
+    char *new = readWord(reader->buf_size, reader);  // 写入数据
+    free(new);
+    return reader;
+}
+
+void freeReader(af_Reader *reader) {
+    if (reader->destruct != NULL)
+        GET_SYMBOL(reader->destruct)(reader->data);
+    free(reader->data);
+    free(reader->buf);
+    FREE_SYMBOL(reader->read_func);
+    FREE_SYMBOL(reader->destruct);
+    free(reader);
+}
+
+void *getReaderData(af_Reader *reader) {
+    return reader->data;
+}
+
+char *readWord(size_t del_index, af_Reader *reader) {
+    char *re;
+    char *write = reader->buf_end - del_index;  // 数据写入的位置
+    reader->read = reader->buf;  // 重置指针
+
+    if (del_index == 0)
+        return strCopy(NULL);  // 返回空字符串
+
+    re = NEW_STR(del_index);
+    memcpy(re, reader->buf, del_index);  // 复制旧字符串
+    memmove(reader->buf, reader->buf + del_index, reader->buf_size - del_index + 1);  // +1是为了涵盖NUL
+    if (!reader->read_end) { // 没到尾部, 则写入数据
+        size_t len = GET_SYMBOL(reader->read_func)(reader->data, write, del_index);
+        if (len > del_index)
+            len = del_index;
+        else if (len < del_index)
+            reader->read_end = true;
+        *(write + len) = NUL;
+    }
+
+    return re;
+}
+
+char getChar(af_Reader *reader) {
+    char ch = *(reader->read);
+    if (ch != NUL) {  // 未读取到末尾
+        reader->read++;
+        return ch;
+    } else if (reader->read_end)  // 读取到末尾, 且无新内容
+        return NUL;
+
+    char *new_buf = NEW_STR(reader->buf_size + NEW_BUF_SIZE);
+    memcpy(new_buf, reader->buf, reader->buf_size);
+
+    size_t len = GET_SYMBOL(reader->read_func)(reader->data, new_buf + reader->buf_size, NEW_BUF_SIZE);
+    if (len > NEW_BUF_SIZE)
+        len = NEW_BUF_SIZE;
+    else if (len < NEW_BUF_SIZE)
+        reader->read_end = true;
+    *(new_buf + reader->buf_size + len + 1) = NUL;
+
+    free(reader->buf);
+    reader->buf = new_buf;
+    reader->buf_size = reader->buf_size + NEW_BUF_SIZE;
+    reader->buf_end = reader->buf + reader->buf_size;
+    reader->read = reader->buf + reader->buf_size - NEW_BUF_SIZE;
+
+    ch = *(reader->read);
+    if (ch != NUL)
+        reader->read++;
+    return ch;
+}

+ 29 - 27
src/main.c

@@ -899,33 +899,6 @@ int main() {
         printf("\n");
     }
 
-    {  // 测试错误 (无函数指定)
-        printf("TAG F: ERROR\n");
-        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
-
-        af_Code *bt5 = makeBlockCode(curly, NULL, 0, 1, NULL, NULL);
-        connectCode(&bt1, bt5);
-
-        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
-        connectCode(&bt5, bt6);
-
-        iterCode(bt1, env);
-        freeAllCode(bt1);
-        printf("\n");
-    }
-
-    {  // 测试错误 (object2 Var not found)
-        printf("TAG G: ERROR\n");
-        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
-        af_Code *bt2 = makeElementCode("object2", 0, 1, NULL);
-
-        connectCode(&bt1, bt2);
-
-        iterCode(bt1, env);
-        freeAllCode(bt1);
-        printf("\n");
-    }
-
     {  // 测试顺序执行 '(xxx)
         printf("TAG H:\n");
         af_Code *bt3 = makeElementCode("data2", 0, 0, NULL);
@@ -1091,6 +1064,8 @@ int main() {
         printf("\n");
     }
 
+    /* 错误用例 */
+
     {  // 中缀调用测试
         printf("TAG T: ERROR\n");
 
@@ -1105,6 +1080,33 @@ int main() {
         printf("\n");
     }
 
+    {  // 测试错误 (无函数指定)
+        printf("TAG F: ERROR\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+
+        af_Code *bt5 = makeBlockCode(curly, NULL, 0, 1, NULL, NULL);
+        connectCode(&bt1, bt5);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 测试错误 (object2 Var not found)
+        printf("TAG G: ERROR\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+        af_Code *bt2 = makeElementCode("object2", 0, 1, NULL);
+
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
     {  // 中缀保护测试
         printf("TAG V: ERROR\n");
 

+ 2 - 0
test/CMakeLists.txt

@@ -29,6 +29,8 @@ ADD_aFunTest(byte test_byte.c)
 ADD_aFunTest(byte_code test_byte_code.c)
 ADD_aFunTest(env test_env.c)
 ADD_aFunTest(regex test_regex.c)
+ADD_aFunTest(run test_run.c)
+ADD_aFunTest(reader test_reader.c)
 
 SET_LINK(lib lib_Test1)  # 链接测试程序需要的动态库
 

+ 87 - 0
test/test_reader.c

@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include "aFun.h"
+
+/* 测试程序, 直接调用内部函数 */
+typedef struct af_Reader af_Reader;
+
+typedef size_t readerFunc(void *data, char *dest, size_t len);
+DEFINE_DLC_SYMBOL(readerFunc);
+
+typedef void destructReaderDataFunc(void *data);
+DEFINE_DLC_SYMBOL(destructReaderDataFunc);
+
+af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderDataFunc) destruct_func, size_t data_size);
+void freeReader(af_Reader *reader);
+af_Reader *initReader(af_Reader *reader);
+void *getReaderData(af_Reader *reader);
+char *readWord(size_t del_index, af_Reader *reader);
+char getChar(af_Reader *reader);
+
+size_t readTest(int *data, char *dest, size_t len) {
+    *data = *data + 1;
+    if (*data == 1) {
+        memset(dest, 's', len);
+        return len;
+    } else if (*data == 2) {
+        memset(dest, 'w', len - 5);
+        return len - 5;
+    }
+    return 0;
+}
+
+void destructTest(const int *data) {
+    printf("destructTest data = %d\n", *data);
+}
+
+int main() {
+    printf("HelloWorld\n");
+
+    {
+        DLC_SYMBOL(readerFunc) read_func = MAKE_SYMBOL(readTest, readerFunc);
+        DLC_SYMBOL(destructReaderDataFunc) destruct_func = MAKE_SYMBOL(destructTest, destructReaderDataFunc);
+        af_Reader *reader = makeReader(read_func, destruct_func, sizeof(int));
+        *(int *) getReaderData(reader) = 0;
+        initReader(reader);
+        FREE_SYMBOL(read_func);
+        FREE_SYMBOL(destruct_func);
+
+        char ch;
+        size_t count = 0;
+        do {
+            ch = getChar(reader);
+            printf("%zu\t\tch = %c\n", count, ch);
+            count++;
+        } while (ch != NUL);
+
+        freeReader(reader);
+    }
+
+    {
+        DLC_SYMBOL(readerFunc) read_func = MAKE_SYMBOL(readTest, readerFunc);
+        DLC_SYMBOL(destructReaderDataFunc) destruct_func = MAKE_SYMBOL(destructTest, destructReaderDataFunc);
+        af_Reader *reader = makeReader(read_func, destruct_func, sizeof(int));
+        *(int *) getReaderData(reader) = 0;
+        initReader(reader);
+        FREE_SYMBOL(read_func);
+        FREE_SYMBOL(destruct_func);
+
+        char ch;
+        for (size_t i = 0; i < 1000; i++) {
+            ch = getChar(reader);
+            printf("%zu\t\tch = %c\n", i, ch);
+        }
+        char *new = readWord(100, reader);  // 提取前面100个值
+        free(new);
+
+        size_t count = 0;
+        do {
+            ch = getChar(reader);
+            printf("%zu\t\tch = %c\n", count, ch);  // 923-s 1019-w
+            count++;
+        } while (ch != NUL);
+
+        freeReader(reader);
+    }
+
+    return 0;
+}

+ 1140 - 0
test/test_run.c

@@ -0,0 +1,1140 @@
+#include <stdio.h>
+#include "aFun.h"
+
+size_t getSize(af_Object *obj) {
+    return sizeof(int *);
+}
+
+void initData(af_Object *obj, int **data, af_Environment *env) {
+    *data = calloc(1, sizeof(int));
+    **data = 100;
+}
+
+void freeData(af_Object *obj, int **data, af_Environment *env) {
+    printf("freeData(): **data = %d\n", **data);
+    free(*data);
+}
+
+size_t getSize2(af_Object *obj) {
+    return sizeof(af_VarSpaceListNode *);
+}
+
+void initData2(af_Object *obj, af_VarSpaceListNode **data, af_Environment *env) {
+    *data = makeVarSpaceList(getProtectVarSpace(env));
+}
+
+void freeData2(af_Object *obj, af_VarSpaceListNode **data, af_Environment *env) {
+    printf("freeData2(): vsl = %p\n", *data);
+    freeAllVarSpaceList(*data);
+}
+
+size_t getSize3(af_Object *obj) {
+    return sizeof(af_VarSpace *);
+}
+
+void initData3(af_Object *obj, af_VarSpace **data, af_Environment *env) {
+    *data = makeVarSpace(obj, env);
+}
+
+void freeData3(af_Object *obj, af_VarSpace **data, af_Environment *env) {
+    printf("freeData(): *data = %p\n", *data);
+    freeVarSpace(*data, env);
+}
+
+af_GcList *getGcList3(char *id, void *data) {
+    af_GcList *gl = pushGcList(glt_vs, *(af_VarSpace **)data, NULL);
+    return gl;
+}
+
+
+af_VarSpace *getShareVS(af_Object *obj) {
+    return *(af_VarSpace **)getObjectData(obj);
+}
+
+bool getAcl(af_ArgCodeList **acl, af_Object *obj, af_Code *code, int **mark, af_Environment *env) {
+    *acl = makeArgCodeList(makeElementCode("object", NUL, 0, "Unknown"), 0, true, false);
+    *mark = calloc(1, sizeof(int));
+    **mark = 100;
+    return true;
+}
+
+bool getVsl(af_VarSpaceListNode **vsl, af_Object *obj, void *mark, af_Environment *env) {
+    *vsl = *(af_VarSpaceListNode **)getObjectData(obj);
+    return true;
+}
+
+af_GcList *getGcList(char *id, void *data) {
+    af_GcList *gl = pushGcList(glt_vsl, *(af_VarSpaceListNode **)data, NULL);
+    return gl;
+}
+
+bool getAl(af_ArgList **al, af_Object *obj, af_ArgCodeList *acl, void *mark, af_Environment *env) {
+    *al = makeArgList("test", getArgCodeListResult(acl));
+    return true;
+}
+
+void literalSet(char *str, void *data, af_Object *obj, af_Environment *env) {
+    printf("literalSet(): str = %s\n", str);
+}
+
+af_FuncBody *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 NULL;
+        obj = makeObject("func", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(literal_set);
+    }
+
+    pushMessageDown(makeNORMALMessage(obj), env);
+    return NULL;
+}
+
+bool getInfo(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    makeCodeFuncBodyToFuncInfo(makeElementCode("test", NUL, 0, "Unknown"), true, NULL, *fi);
+
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+void freeMark(int *mark) {
+    printf("freeMark(): mark = %d\n", *mark);
+    free(mark);
+}
+
+af_FuncBody *testFunc2(int *mark, af_Environment *env) {  // 测试用函数
+    printf("testFunc2(): I am testFunc2\n");
+    af_Object *obj;
+
+    {
+        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_info = MAKE_SYMBOL(getInfo, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return NULL;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return NULL;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return NULL;
+        if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
+            return NULL;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return NULL;
+        if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
+            return NULL;
+        if (addAPI(get_info, "obj_funcGetInfo", api) != 1)
+            return NULL;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return NULL;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return NULL;
+
+        obj = makeObject("func", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+    }
+
+    pushMessageDown(makeNORMALMessage(obj), env);
+    return NULL;
+}
+
+bool getInfo2(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, true, true, true);
+    makeCodeFuncBodyToFuncInfo(makeElementCode("test", NUL, 0, "Unknown"), true, NULL, *fi);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc2, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+bool getInfo3(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    makeCodeFuncBodyToFuncInfo(makeElementCode("data3", NUL, 0, "Unknown"), true, NULL, *fi);
+    return true;
+}
+
+af_FuncBody *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 NULL;
+        obj = makeObject("func", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(literal_set);
+    }
+
+    pushMessageDown(makeNORMALMessage(obj), env);
+    return NULL;
+}
+
+bool getInfo4(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc4, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+af_FuncBody *testFunc9(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    af_FuncBody *fb;
+    obj = makeObject("obj", true, makeObjectAPI(), true, NULL, NULL, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc9(%p): I am testFunc9\n", obj);
+
+    DLC_SYMBOL(callFuncBody) func1 = MAKE_SYMBOL(testFunc9, callFuncBody);
+    fb = makeCFuncBody(func1, NULL);
+    FREE_SYMBOL(func1);
+
+    return fb;
+}
+
+bool getInfo9(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func1 = MAKE_SYMBOL(testFunc9, callFuncBody);
+    makeCFuncBodyToFuncInfo(func1, NULL, *fi);
+    FREE_SYMBOL(func1);
+
+    makeDynamicFuncBodyToFuncInfo(*fi);
+    return true;
+}
+
+af_FuncBody *testFunc8(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    obj = makeObject("obj", true, makeObjectAPI(), true, NULL, NULL, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc8(%p): I am testFunc8\n", obj);
+    fflush(stdout);
+    return NULL;
+}
+
+af_FuncBody *testFunc7(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc7[des](%p): I am testFunc7\n", obj);
+    fflush(stdout);
+    return NULL;
+}
+
+bool getInfo7(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc7, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+af_FuncBody *testFunc6(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    af_Object *des;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info7 = MAKE_SYMBOL(getInfo7, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return NULL;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return NULL;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return NULL;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return NULL;
+        if (addAPI(get_info7, "obj_funcGetInfo", api) != 1)
+            return NULL;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return NULL;
+        des = makeObject("func-des", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_info7);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+    }
+
+    setObjectAttributes(mg_gc_destruct, 3, 3, 3, des, obj, obj, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc6[des](%p, %p): I am testFunc6\n", obj, des);
+    return NULL;
+}
+
+bool getInfo6(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func1 = MAKE_SYMBOL(testFunc6, callFuncBody);
+    makeCFuncBodyToFuncInfo(func1, NULL, *fi);
+    FREE_SYMBOL(func1);
+
+    DLC_SYMBOL(callFuncBody) func2 = MAKE_SYMBOL(testFunc8, callFuncBody);
+    makeCFuncBodyToFuncInfo(func2, NULL, *fi);
+    FREE_SYMBOL(func2);
+    return true;
+}
+
+af_FuncBody *testFunc5(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    af_Object *des;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info6 = MAKE_SYMBOL(getInfo6, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return NULL;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return NULL;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return NULL;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return NULL;
+        if (addAPI(get_info6, "obj_funcGetInfo", api) != 1)
+            return NULL;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return NULL;
+        des = makeObject("func-des", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_info6);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+    }
+
+    setObjectAttributes(mg_gc_destruct, 3, 3, 3, des, obj, obj, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc5(%p, %p): I am testFunc5\n", obj, des);
+    return NULL;
+}
+
+bool getInfo5(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc5, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    makeCodeFuncBodyToFuncInfo(makeElementCode("test", NUL, 0, "Unknown"), true, NULL, *fi);
+    return true;
+}
+
+bool getInfo10(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, true, true, true);
+    makeCodeFuncBodyToFuncInfo(makeElementCode("no-var", NUL, 1, "func9.info.af"), true, NULL, *fi);
+    return true;
+}
+
+bool objFunc(af_Object *obj) {
+    return true;
+}
+
+bool infixFunc(af_Object *obj) {
+    return true;
+}
+
+int main() {
+    aFunInit();
+    printf("Hello World\n");
+
+    af_Environment *env = makeEnvironment(grt_always);
+    if(!pushLiteralRegex("data.*", "func", true, env)) {
+        fprintf(stderr, "pushLiteralRegex Error\n");
+        return 1;
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        DLC_SYMBOL(objectAPIFunc) getSize_3 = MAKE_SYMBOL(getSize3, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_3 = MAKE_SYMBOL(initData3, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_3 = MAKE_SYMBOL(freeData3, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getShareVS_ = MAKE_SYMBOL(getShareVS, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl3 = MAKE_SYMBOL(getGcList3, objectAPIFunc);
+        if (addAPI(getSize_3, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_3, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_3, "obj_destructData", api) != 1)
+            return 2;
+        if (addAPI(getShareVS_, "obj_getShareVarSpace", api) != 1)
+            return 2;
+        if (addAPI(get_gl3, "obj_getGcList", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("object", 3, 3, 3,
+                                        (obj = makeObject("object", true, api, true, NULL, NULL, env)),
+                                        env),
+                                env);
+        FREE_SYMBOL(getSize_3);
+        FREE_SYMBOL(initData_3);
+        FREE_SYMBOL(freeData_3);
+        FREE_SYMBOL(getShareVS_);
+        FREE_SYMBOL(get_gl3);
+        printf("object(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info = MAKE_SYMBOL(getInfo, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        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_info, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info2 = MAKE_SYMBOL(getInfo2, objectAPIFunc);  // 宏函数
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+        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_info2, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func2", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info2);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func2(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info3 = MAKE_SYMBOL(getInfo3, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+        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_info3, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func3", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info3);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func3(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+        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, "obj_isObjFunc", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func4", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), 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);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func4(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info5 = MAKE_SYMBOL(getInfo5, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        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_info5, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func5", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info5);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func5(%p)\n", obj);
+    }
+
+    {
+        af_Object *obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+        af_Object *des;
+
+        {
+            af_ObjectAPI *api = makeObjectAPI();
+            DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) get_info6 = MAKE_SYMBOL(getInfo6, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+            if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+                return 2;
+            if (addAPI(initData_2, "obj_initData", api) != 1)
+                return 2;
+            if (addAPI(freeData_2, "obj_destructData", api) != 1)
+                return 2;
+            if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+                return 2;
+            if (addAPI(get_info6, "obj_funcGetInfo", api) != 1)
+                return 2;
+            if (addAPI(get_gl, "obj_getGcList", api) != 1)
+                return 2;
+            des = makeObject("func-des", true, api, true, NULL, NULL, env);
+            FREE_SYMBOL(get_vsl);
+            FREE_SYMBOL(get_info6);
+            FREE_SYMBOL(get_gl);
+            FREE_SYMBOL(getSize_2);
+            FREE_SYMBOL(initData_2);
+            FREE_SYMBOL(freeData_2);
+        }
+
+        setObjectAttributes(mg_gc_destruct, 3, 3, 3, des, obj, obj, env);
+        addVarToProtectVarSpace(makeVar("func6", 3, 3, 3, obj, env), env);
+        printf("func6(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info9 = MAKE_SYMBOL(getInfo9, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        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_info9, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func7", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info9);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func7(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info = MAKE_SYMBOL(getInfo, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) infix_func = MAKE_SYMBOL(infixFunc, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        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_info, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+        if (addAPI(infix_func, "obj_isInfixFunc", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func8", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        FREE_SYMBOL(infix_func);
+        printf("func8(%p)\n", obj);
+    }
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        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_info10 = MAKE_SYMBOL(getInfo10, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        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_info10, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func9", 3, 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info10);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func9(%p)\n", obj);
+    }
+
+    printf("\n");
+    enableEnvironment(env);
+
+    {  // 正常程序
+        printf("TAG A:\n");
+        af_Code *bt1 = makeElementCode("object", 0, 1, NULL);
+        af_Code *bt2 = makeElementCode("data", ',', 0, "Unknown");
+        connectCode(&bt1, bt2);
+
+        af_Code *bt3 = makeElementCode("func", 0, 1, NULL);
+        af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt2, bt5);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 宏函数
+        printf("TAG L:\n");
+        af_Code *bt1 = makeElementCode("object", 0, 1, NULL);
+
+        af_Code *bt3 = makeElementCode("func2", 0, 1, NULL);
+        af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt1, bt5);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+
+    {  // 尾调递归优化
+        printf("TAG B:\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+        af_Code *bt2 = makeElementCode("object", 0, 1, NULL);
+        connectCode(&bt1, bt2);
+
+        af_Code *bt3 = makeElementCode("func", 0, 1, NULL);
+        af_Code *bt5 = makeBlockCode(curly, bt3, 0, 1, NULL, NULL);
+        connectCode(&bt2, bt5);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 尾调递归优化2
+        printf("TAG C:\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 测试类前缀调用
+        printf("TAG D:\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+        af_Code *bt2 = makeElementCode("func", 0, 1, NULL);
+        connectCode(&bt1, bt2);
+
+        af_Code *bt5 = makeBlockCode(parentheses, NULL, 0, 1, NULL, NULL);
+        connectCode(&bt2, bt5);
+
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 测试顺序执行 '(xxx)
+        printf("TAG H:\n");
+        af_Code *bt3 = makeElementCode("data2", 0, 0, NULL);
+        af_Code *bt4 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(parentheses, bt3, '\'', 1, NULL, NULL);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt5, env);
+        freeAllCode(bt5);
+        printf("\n");
+    }
+
+    {  // 测试顺序执行 ,[xxx]
+        printf("TAG I:\n");
+        af_Code *bt3 = makeElementCode("data2", 0, 0, NULL);
+        af_Code *bt4 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(brackets, bt3, ',', 1, NULL, NULL);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt5, env);
+        freeAllCode(bt5);
+        printf("\n");
+    }
+
+    {  // 测试顺序执行 '(xxx) 【尾调递归优化】
+        printf("TAG J:\n");
+        af_Code *bt3 = makeElementCode("data2", 0, 0, NULL);
+        af_Code *bt4 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(parentheses, bt3, '\'', 1, NULL, NULL);
+
+        iterCode(bt5, env);
+        freeAllCode(bt5);
+        printf("\n");
+    }
+
+    {  // 测试顺序执行 ,[xxx] 【尾调递归优化】
+        printf("TAG K:\n");
+        af_Code *bt3 = makeElementCode("data2", 0, 0, NULL);
+        af_Code *bt4 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt3, bt4);
+
+        af_Code *bt5 = makeBlockCode(brackets, bt3, ',', 1, NULL, NULL);
+
+        iterCode(bt5, env);
+        freeAllCode(bt5);
+        printf("\n");
+    }
+
+    {  // 双层尾调递归优化 (函数内调用函数)
+        printf("TAG M:\n");
+        af_Code *bt2 = makeElementCode("func3", 0, 1, NULL);
+        af_Code *bt3 = makeBlockCode(curly, bt2, 0, 1, NULL, NULL);
+
+        af_Code *bt4 = makeElementCode("func3", 0, 1, NULL);
+        af_Code *bt5 = makeBlockCode(curly, bt4, 0, 1, NULL, NULL);
+        connectCode(&bt3, bt5);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt3, env);
+        freeAllCode(bt3);
+        printf("\n");
+    }
+
+    {  // 对象函数的调用
+        printf("TAG N:\n");
+        af_Code *bt1 = makeElementCode("func4", 0, 1, NULL);
+        af_Code *bt2 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 变量引用调用
+        printf("TAG O:\n");
+        af_Code *bt1 = makeElementCode("func4", '\'', 1, NULL);
+        af_Code *bt2 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 对象函数的调用 (尾调递归优化)
+        printf("TAG P:\n");
+        af_Code *bt1 = makeElementCode("func4", 0, 1, "TagP.af");
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 函数调用
+        printf("TAG U:\n");
+
+        af_Code *bt2 = makeElementCode("func", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, "TagU.af", NULL);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // gc测试
+        printf("TAG Q:\n");
+
+        af_Code *bt2 = makeElementCode("func5", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, "TagQ.af", NULL);
+        af_Code *bt3 = makeElementCode("global", 0, 1, NULL);
+        af_Code *bt4 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+        connectCode(&bt3, bt4);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // func_body_dynamic 测试
+        printf("TAG R:\n");
+
+        af_Code *bt2 = makeElementCode("func7", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, "TagR.af", NULL);
+        af_Code *bt3 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 中缀调用测试
+        printf("TAG S:\n");
+
+        af_Code *bt2 = makeElementCode("func8", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(brackets, bt2, 0, 1, "TagS.af", NULL);
+        af_Code *bt3 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    /* 错误用例 */
+
+    {  // 中缀调用测试
+        printf("TAG T: ERROR\n");
+
+        af_Code *bt2 = makeElementCode("func", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(brackets, bt2, 0, 1, "TagT.error.af", NULL);
+        af_Code *bt3 = makeElementCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 测试错误 (无函数指定)
+        printf("TAG F: ERROR\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+
+        af_Code *bt5 = makeBlockCode(curly, NULL, 0, 1, NULL, NULL);
+        connectCode(&bt1, bt5);
+
+        af_Code *bt6 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt5, bt6);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 测试错误 (object2 Var not found)
+        printf("TAG G: ERROR\n");
+        af_Code *bt1 = makeElementCode("data", ',', 0, "Unknown");
+        af_Code *bt2 = makeElementCode("object2", 0, 1, NULL);
+
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 中缀保护测试
+        printf("TAG V: ERROR\n");
+
+        af_Code *bt2 = makeElementCode("func8", 0, 2, NULL);
+        af_Code *bt1 = makeElementCode("global", 0, 1, "TagV.error.af");
+
+        connectCode(&bt1, bt2);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    {  // 错误回溯测试
+        printf("TAG W: ERROR\n");
+
+        af_Code *bt2 = makeElementCode("func9", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, "TagW.error.af", NULL);
+
+        af_Code *bt3 = makeElementCode("global", 0, 1, NULL);
+        connectCode(&bt1, bt3);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    printf("freeEnvironment:\n");
+    freeEnvironment(env);
+    return 0;
+}