Browse Source

feat: 实现字符串

SongZihuan 3 years ago
parent
commit
8e2f35ae91

+ 1 - 0
include/core/env.h

@@ -91,6 +91,7 @@ AFUN_CORE_EXPORT af_Object *getGlobal(af_Environment *env);
 AFUN_CORE_EXPORT af_Object *getBelong(af_Environment *env);
 AFUN_CORE_EXPORT FilePath getActivityFile(af_Environment *env);
 AFUN_CORE_EXPORT FileLine getActivityLine(af_Environment *env);
+AFUN_CORE_EXPORT af_VarSpaceListNode *getRunVarSpaceList(af_Environment *env);
 
 /* 消息 属性访问 */
 AFUN_CORE_EXPORT af_Object *getMsgNormalData(af_Message *msg);

+ 1 - 0
include/core/var.h

@@ -17,6 +17,7 @@ AFUN_CORE_EXPORT af_VarSpace *makeVarSpace(af_Object *belong, char p_self, char
 
 /* 变量空间链 创建与释放 */
 AFUN_CORE_EXPORT af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs);
+AFUN_CORE_EXPORT af_VarSpaceListNode *copyVarSpaceList(af_VarSpaceListNode *vsl);
 AFUN_CORE_EXPORT void freeAllVarSpaceList(af_VarSpaceListNode *vsl);
 AFUN_CORE_EXPORT bool freeVarSpaceListCount(size_t count, af_VarSpaceListNode *vsl);
 

+ 1 - 1
include/runtime/aFun_tool.h

@@ -4,7 +4,7 @@
 typedef struct APIFunc APIFunc;
 struct APIFunc {
     char *name;
-    objectAPIFunc *func;
+    void *func;  // objectAPIFunc
     DlcHandle *dlc;  // func 的 来源
     DLC_SYMBOL(objectAPIFunc) func_;  // func_和func二选一, func_时dlc无效
     bool free_func_;  // func_是否需要释放

+ 8 - 1
src/core/env.c

@@ -1449,4 +1449,11 @@ af_Object *getImportObject(af_ImportInfo *ii) {
     ii->obj = NULL;
     gc_delReference(obj);
     return obj;
-}
+}
+
+af_VarSpaceListNode *getRunVarSpaceList(af_Environment *env) {
+    if (env->activity->type == act_gc)
+        return env->activity->var_list;
+    else
+        return env->activity->vsl;
+}

+ 1 - 0
src/core/global_obj.c

@@ -16,6 +16,7 @@ static GlobalObjectData *initGOD(af_Object  *obj, af_Environment *env) {
 
 static void freeGOD(GlobalObjectData *god, af_Object  *obj, af_Environment *env) {
     god->share = NULL;
+    free(god);
 }
 
 static size_t getSize(char *id, af_Object *obj) {

+ 1 - 1
src/core/run.c

@@ -174,7 +174,7 @@ static bool codeElement(af_Code *code, af_Environment *env) {
             var = findVarFromVarList(func, env->activity->belong, env->activity->vsl);
 
         if (var == NULL) {
-            pushMessageDown(makeERRORMessageFormat(LITERAL_ERROR, env, "Literal not found: %s.", code->element.data), env);
+            pushMessageDown(makeERRORMessageFormat(LITERAL_ERROR, env, "Literal not found: %s: %s.", code->element.data, func), env);
             return false;
         }
 

+ 10 - 1
src/core/var.c

@@ -168,6 +168,14 @@ af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs) {
     return vsl;
 }
 
+af_VarSpaceListNode *copyVarSpaceList(af_VarSpaceListNode *vsl) {
+    af_VarSpaceListNode *base = NULL;
+    af_VarSpaceListNode **pvsl = &base;
+    for (NULL; vsl != NULL; vsl = vsl->next, pvsl = &((*pvsl)->next))
+        *pvsl = makeVarSpaceList(vsl->vs);
+    return base;
+}
+
 static af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl){
     af_VarSpaceListNode *next = vsl->next;
     free(vsl);
@@ -289,9 +297,10 @@ bool makeVarToProtectVarSpace(char *name, char p_self, char p_posterity, char p_
  * 调用 addVarToVarSpace
  */
 bool addVarToProtectVarSpace(af_Var *var, af_Environment *env) {
+    bool is_protect = env->core->protect->is_protect;
     env->core->protect->is_protect = false;
     bool re = addVarToVarSpace(var, NULL, env->core->protect);
-    env->core->protect->is_protect = true;
+    env->core->protect->is_protect = is_protect;
     return re;
 }
 

+ 6 - 2
src/runtime/CMakeLists.txt

@@ -4,12 +4,16 @@
 
 file(GLOB source_tool
      LIST_DIRECTORIES FALSE
-     ${CMAKE_CURRENT_LIST_DIR}/aFunTool/*.c)
+     ${CMAKE_CURRENT_LIST_DIR}/aFunTool/*/*.c)
 
 file(GLOB private_h
      LIST_DIRECTORIES FALSE
      ${CMAKE_CURRENT_LIST_DIR}/*.h)
 
+file(GLOB private_tool_h
+     LIST_DIRECTORIES FALSE
+     ${CMAKE_CURRENT_LIST_DIR}/aFunTool/*/*.h)
+
 file(GLOB private_h_core
      LIST_DIRECTORIES FALSE
      ${CMAKE_CURRENT_LIST_DIR}/../core/*.h)  # 需要使用 core 的特定头文件 (高级开发)
@@ -38,7 +42,7 @@ add_library(aFun-ct-libs SHARED "")  # ct表示均静态链接 core-static-s
 
 foreach(tgt aFun-xx-libs aFun-cx-libs aFun-ct-libs)
     target_sources(${tgt}
-                   PRIVATE ${source} ${source_tool} ${private_h} ${private_h_core}
+                   PRIVATE ${source} ${source_tool} ${private_h} ${private_tool_h} ${private_h_core}
                    PUBLIC ${public_h_build} ${public_h_install})
     target_include_directories(${tgt}
                                PRIVATE

+ 29 - 0
src/runtime/aFunTool/base/__base.h

@@ -0,0 +1,29 @@
+#ifndef AFUN___BASE_H
+#define AFUN___BASE_H
+#include "__aFun_tool.h"
+#include "__env.h"
+#include "__var.h"
+
+static char *const string_id = "string";
+static char *const string_func_id = "string-maker";
+
+static const LiteralFunc literal[] = {
+        /* 字符串匹配:\"[\s\S]*\" */
+        {.pattern="\\\"[\\s\\S]*\\\"", .func="str", .in_protect=true},
+};
+
+typedef struct ObjectString ObjectString;
+struct ObjectString{
+    char *str;
+};
+
+typedef struct ObjectStrFunc ObjectStrFunc;
+struct ObjectStrFunc {
+    af_ObjectAPI *api;
+    af_VarSpace *share_vs;
+    af_VarSpaceListNode *func_var_list;
+};
+
+AFUN_LANG_NO_EXPORT void makeStrFunc(af_Object *visitor, af_VarSpace *vs, af_Environment *env);
+
+#endif //AFUN___BASE_H

+ 3 - 1
src/runtime/aFunTool/base.c → src/runtime/aFunTool/base/base.c

@@ -1,7 +1,9 @@
-#include "__aFun_tool.h"
+#include "__base.h"
 
 // 桩函数
 int aFunTool_base(af_Code **code, af_Object *visitor, af_VarSpace *vs, af_Environment *env) {
     printf("Run aFunTool-Base %p\n", vs);
+    makeLiteralRegexFromList(literal, env);
+    makeStrFunc(visitor, vs, env);
     return 0;
 }

+ 118 - 0
src/runtime/aFunTool/base/str_obj.c

@@ -0,0 +1,118 @@
+#include "__base.h"
+
+static size_t strGetSize(char *id, af_Object *obj) {
+    return sizeof(ObjectString);
+}
+
+static void strInit(char *id, af_Object *obj, ObjectString *data, af_Environment *env) {
+    if (EQ_STR(id, string_id))
+        data->str = NULL;
+}
+
+static void strDestruct(char *id, af_Object *obj, ObjectString *data, af_Environment *env) {
+    if (EQ_STR(id, string_id)) {
+        free(data->str);
+    }
+}
+
+static void strLiteral(char *id, af_Object *obj, ObjectString *data, char *str, af_Environment *env) {
+    if (!EQ_STR(id, string_id) || data->str != NULL)
+        return;
+    data->str = NEW_STR(STR_LEN(str) - 2);  // 取出两个引号
+    memcpy(data->str, str + 1, (STR_LEN(str) - 2) * sizeof(char));
+}
+
+static size_t strFuncGetSize(char *id, af_Object *obj) {
+    return sizeof(ObjectStrFunc);
+}
+
+static void strFuncInit(char *id, af_Object *obj, ObjectStrFunc *data, af_Environment *env) {
+    static const APIFunc api_list[] = {
+            {.name="obj_getDataSize", .func=strGetSize, .dlc=NULL},
+            {.name="obj_initData", .func=strInit, .dlc=NULL},
+            {.name="obj_destructData", .func=strDestruct, .dlc=NULL},
+            {.name="obj_literalSetting", .func=strLiteral, .dlc=NULL},
+            {.name=NULL}
+    };
+
+    if (!EQ_STR(id, string_func_id))
+        return;
+    data->func_var_list = copyVarSpaceList(getRunVarSpaceList(env));
+    data->share_vs = makeVarSpace(obj, 3, 2, 0, env);
+    data->api = makeAPIFromList(api_list);
+}
+
+typedef struct strFuncMark strFuncMark;
+struct strFuncMark {
+    af_Object *obj;
+};
+
+static bool strFuncArgCodeList(char *id, af_Object *obj, af_ArgCodeList **acl, af_Code *code, void **mark, af_Environment *env) {
+    *acl = NULL;
+    *mark = calloc(1, sizeof(strFuncMark));
+
+    strFuncMark *sfm = *mark;
+    sfm->obj = obj;
+    return true;
+}
+
+static bool strFuncArgList(char *id, af_Object *obj, af_ArgList **al, af_ArgCodeList *acl, void *mark, af_Environment *env) {
+    *al = NULL;
+    return true;
+}
+
+static bool strFuncVarList(char *id, af_Object *obj, af_VarSpaceListNode **vsl, void *mark, af_Environment *env) {
+    ObjectStrFunc *sf = getObjectData(obj);
+    *vsl = sf->func_var_list;
+    return true;
+}
+
+static af_FuncBody *strFuncBody(strFuncMark *mark, af_Environment *env) {
+    af_Object *obj = mark->obj;
+    ObjectStrFunc *osf = getObjectData(obj);
+    af_Object *str = makeObject((char *)string_id, false, osf->api, false, NULL, makeInherit(obj), env);
+    af_Message *msg = makeNORMALMessage(str);
+    pushMessageDown(msg, env);
+    return NULL;
+}
+
+static bool strFuncGetInfo(char *id, af_Object *obj, af_FuncInfo **fi, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, false, false);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(strFuncBody, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+static void strFuncFreeMark(char *id, af_Object *obj, strFuncMark *mark) {
+    free(mark);
+}
+
+static void strFuncDestruct(char *id, af_Object *obj, ObjectStrFunc *data, af_Environment *env) {
+    if (EQ_STR(id, string_func_id)) {
+        freeObjectAPI(data->api);
+        freeAllVarSpaceList(data->func_var_list);
+    }
+}
+
+void makeStrFunc(af_Object *visitor, af_VarSpace *vs, af_Environment *env) {
+    static APIFunc api_list[] = {
+            {.name="obj_getDataSize", .func=strFuncGetSize, .dlc=NULL},
+            {.name="obj_initData", .func=strFuncInit, .dlc=NULL},
+            {.name="obj_destructData", .func=strFuncDestruct, .dlc=NULL},
+            {.name="obj_funcGetArgCodeList", .func=strFuncArgCodeList, .dlc=NULL},
+            {.name="obj_funcGetVarList", .func=strFuncVarList, .dlc=NULL},
+            {.name="obj_funcGetArgList", .func=strFuncArgList, .dlc=NULL},
+            {.name="obj_funcGetInfo", .func=strFuncGetInfo, .dlc=NULL},
+            {.name="obj_funcFreeMask", .func=strFuncFreeMark, .dlc=NULL},
+            {.name=NULL}
+    };
+
+    static ObjectDefine obj_def[] = {
+            {.id=string_func_id, .free_api=true, .api_list=api_list, .allow_inherit=true,
+                    .var_name="str", .p_self=3, .p_posterity=3, .p_external=3},
+            {.id=NULL}
+    };
+
+    makeObjectFromList(obj_def, visitor, vs, env);
+}

+ 9 - 7
src/tool/dlc.c

@@ -75,13 +75,6 @@ static bool freeLibary_(struct DlcHandle *dlc, bool f) {
     return true;
 }
 
-struct DlcSymbol_ *makeSymbol_(void *symbol) {
-    struct DlcSymbol_ *ds = calloc(1, sizeof(struct DlcSymbol_));
-    ds->symbol = symbol;
-    ds->dlc = NULL;
-    return ds;
-}
-
 static void blindSymbol(struct DlcSymbol_ *ds, struct DlcHandle *dlc) {
     if (ds->dlc != NULL)
         ds->dlc->link--;
@@ -90,6 +83,15 @@ static void blindSymbol(struct DlcSymbol_ *ds, struct DlcHandle *dlc) {
     dlc->link++;
 }
 
+struct DlcSymbol_ *makeSymbol_(DlcHandle *dlc, void *symbol) {
+    struct DlcSymbol_ *ds = calloc(1, sizeof(struct DlcSymbol_));
+    ds->symbol = symbol;
+
+    if (dlc != NULL)
+        blindSymbol(ds, dlc);
+    return ds;
+}
+
 struct DlcSymbol_ *copySymbol_(struct DlcSymbol_ *ds) {
     if (ds == NULL)
         return NULL;