Sfoglia il codice sorgente

feat: runtime封装aFunCore的函数

SongZihuan 3 anni fa
parent
commit
0b655b8059

+ 1 - 1
include/core/parser.h

@@ -17,7 +17,7 @@ AFUN_CORE_EXPORT af_Parser *makeParserByFile(FilePath path, FILE *error);
 AFUN_CORE_EXPORT af_Parser *makeParserByStdin(FILE *error);
 
 /* Parser 相关操作 */
-AFUN_CORE_EXPORT af_Code *parserCode(af_Parser *parser);
+AFUN_CORE_EXPORT af_Code *parserCode(FilePath file, af_Parser *parser);
 AFUN_CORE_EXPORT void initParser(af_Parser *parser);
 
 #endif //AFUN_PARSER_H

+ 9 - 0
include/runtime/aFunlang.h

@@ -1,7 +1,16 @@
 #ifndef AFUN_AFUNLANG_H
 #define AFUN_AFUNLANG_H
 #include "aFunlangExport.h"
+#include "aFunCore.h"
 
 AFUN_LANG_EXPORT void aFunInit();
 
+AFUN_LANG_EXPORT af_Environment *creatAFunEnviroment(void);
+AFUN_LANG_EXPORT void destructAFunEnvironment(af_Environment *env);
+
+/* 源文件运行 */
+AFUN_LANG_EXPORT int runCodeFromString(char *code, char *string_name, FILE *error_file, af_Environment *env);
+AFUN_LANG_EXPORT int runCodeFromFile(FilePath file, FILE *error_file, af_Environment *env);
+AFUN_LANG_EXPORT int runCodeFromStdin(char *name, FILE *error_file, af_Environment *env);
+
 #endif //AFUN_AFUNLANG_H

+ 1 - 1
src/core/__env.h

@@ -20,7 +20,7 @@ typedef struct af_ErrorBacktracking af_ErrorBacktracking;
 #include "__func.h"
 #include "regex.h"
 
-#define DEFAULT_GC_COUNT_MAX (10)
+#define DEFAULT_GC_COUNT_MAX (50)
 #define ENV_VAR_HASH_SIZE (8)
 typedef uint16_t ActivityCount;
 

+ 1 - 0
src/core/__reader.h

@@ -27,6 +27,7 @@ struct af_Reader {
     size_t buf_size;  // buf的长度-1
     char *read;
     bool read_end;
+    FileLine line;
 
     bool init;  // 是否初始化
 };

+ 2 - 2
src/core/env.c

@@ -1366,11 +1366,11 @@ void setGcRun(enum GcRunTime grt, af_Environment *env) {
 }
 
 size_t getGcCount(af_Environment *env) {
-    return env->core->gc_count_max;
+    return env->core->gc_count;
 }
 
 size_t getGcMax(af_Environment *env) {
-    return env->core->gc_count;
+    return env->core->gc_count_max;
 }
 
 enum GcRunTime getGcRun(af_Environment *env) {

+ 4 - 2
src/core/gc.c

@@ -12,13 +12,15 @@ void gc_add##type(af_##type *obj, af_Environment *env) { \
         env->core->gc_##type->gc.prev = obj; \
     }                             \
     obj->gc.next = env->core->gc_##type; \
-    env->core->gc_##type = obj; \
+    env->core->gc_##type = obj;  \
+    env->core->gc_count++;  \
 } \
 void gc_add##type##ByCore(af_##type *obj, af_Core *core) { \
 if (obj->gc.next != NULL || obj->gc.prev != NULL) {return;} \
 obj->gc.prev = NULL; \
 obj->gc.next = core->gc_##type; \
-core->gc_##type = obj; \
+core->gc_##type = obj;        \
+core->gc_count++;  \
 } \
 void gc_add##type##Reference(af_##type *obj) { \
     obj->gc.info.reference++; \

+ 7 - 0
src/core/reader.c

@@ -21,6 +21,7 @@ af_Reader *initReader(af_Reader *reader) {
     char *new = readWord(reader->buf_size, reader);  // 写入数据
     free(new);
     reader->init = true;
+    reader->line = 1;
     return reader;
 }
 
@@ -58,6 +59,12 @@ char *readWord(size_t del_index, af_Reader *reader) {
         *(write + len) = NUL;
     }
 
+    /* 计算行号 */
+    for (char *tmp = re; *tmp != NUL; tmp ++) {
+        if (*tmp == '\n')
+            reader->line++;
+    }
+
     return re;
 }
 

+ 1 - 0
src/core/run.c

@@ -96,6 +96,7 @@ static int checkMacro(af_Message *msg, af_Environment *env) {
 static bool checkRunGC(af_Environment *env) {
     if (env->core->gc_run == grt_always ||
         env->core->gc_run == grt_count && env->core->gc_count >= env->core->gc_count_max) {
+        env->core->gc_count = 0;  // 清零
         gc_RunGC(env);
         return true;
     }

+ 10 - 5
src/core/syntactic.c

@@ -45,7 +45,7 @@ static af_Code *code(size_t deep, char prefix, af_Parser *parser) {
     switch (parser->syntactic->token) {
         case TK_ELEMENT_SHORT:
         case TK_ELEMENT_LONG:
-            re = makeElementCode(parser->syntactic->text, prefix, 0, NULL);
+            re = makeElementCode(parser->syntactic->text, prefix, parser->reader->line, NULL);
             free(parser->syntactic->text);
             break;
         case TK_LP:
@@ -67,7 +67,7 @@ static af_Code *code(size_t deep, char prefix, af_Parser *parser) {
                     break;
             }
 
-            re = makeBlockCode(parentheses, code_list, prefix, 0, NULL, NULL);
+            re = makeBlockCode(parentheses, code_list, prefix, parser->reader->line, NULL, NULL);
             break;
         case TK_LB:
             if (deep <= SYNTACTIC_MAX_DEEP)
@@ -88,7 +88,7 @@ static af_Code *code(size_t deep, char prefix, af_Parser *parser) {
                     break;
             }
 
-            re = makeBlockCode(brackets, code_list, prefix, 0, NULL, NULL);
+            re = makeBlockCode(brackets, code_list, prefix, parser->reader->line, NULL, NULL);
             break;
         case TK_LC:
             if (deep <= SYNTACTIC_MAX_DEEP)
@@ -109,7 +109,7 @@ static af_Code *code(size_t deep, char prefix, af_Parser *parser) {
                     break;
             }
 
-            re = makeBlockCode(curly, code_list, prefix, 0, NULL, NULL);
+            re = makeBlockCode(curly, code_list, prefix, parser->reader->line, NULL, NULL);
             break;
         case TK_ERROR:
             return NULL;
@@ -217,12 +217,17 @@ static af_Code *codeListEnd(af_Parser *parser) {
     return re;
 }
 
-af_Code *parserCode(af_Parser *parser) {
+af_Code *parserCode(FilePath file, af_Parser *parser) {
     af_Code *code = codeListEnd(parser);
+    if (file == NULL)
+        return NULL;
+
     if (parser->is_error) {
         freeAllCode(code);
         return NULL;
     }
 
+    if (code != NULL)
+        code->path = pathCopy(file);
     return code;
 }

+ 17 - 2
src/main.c

@@ -373,7 +373,7 @@ int main() {
     aFunInit();
     printf("Hello World\n");
 
-    af_Environment *env = makeEnvironment(grt_always);
+    af_Environment *env = creatAFunEnviroment();
     if(!pushLiteralRegex("data.*", "func", true, env)) {
         fprintf(stderr, "pushLiteralRegex Error\n");
         goto RETURN_1;
@@ -1147,6 +1147,21 @@ int main() {
         printf("\n");
     }
 
+    {
+        printf("TAG S: STRING\n");
+        int exit_code = runCodeFromString("object\ndata\n{func}\nglobal\n", "tags-string.af", NULL, env);
+        printf("exit code = %d\n\n", exit_code);
+    }
+
+#ifndef IN_CTEST
+    {
+        printf("TAG T: [stdin]\n");
+        int exit_code = runCodeFromStdin(NULL, NULL, env);
+        printf("exit code = %d\n\n", exit_code);
+        getc(stdin);
+    }
+#endif
+
     /* 错误用例 */
 
     {  // 中缀调用测试
@@ -1218,7 +1233,7 @@ int main() {
     }
 
     printf("freeEnvironment:\n");
-    freeEnvironment(env);
+    destructAFunEnvironment(env);
 
     printf("Exit at 0.");
 #ifndef IN_CTEST

+ 61 - 1
src/runtime/aFunlang.c

@@ -4,4 +4,64 @@
 
 void aFunInit() {
     aFunCoreInit();
-}
+}
+
+af_Environment *creatAFunEnviroment(void) {
+    af_Environment *env = makeEnvironment(grt_count);
+    /* 内置量操作 */
+    return env;
+}
+
+void destructAFunEnvironment(af_Environment *env) {
+    freeEnvironment(env);
+}
+
+static int runCode_(FilePath name, af_Parser *parser, int mode, af_Environment *env) {
+    af_Code *bt_code = parserCode(name, parser);
+    freeParser(parser);
+    if (bt_code == NULL)
+        return -2;
+
+    bool res = iterCode(bt_code, mode, env);
+    freeAllCode(bt_code);
+    if (!res)
+        return env->core->exit_code;
+    return 0;
+}
+
+
+int runCodeFromString(char *code, char *string_name, FILE *error_file, af_Environment *env) {
+    if (env == NULL || code == NULL)
+        return -1;
+
+    if (string_name == NULL)
+        string_name = "string-code.af";
+
+    if (error_file == NULL)
+        error_file = stderr;
+    af_Parser *parser = makeParserByString(code, false, error_file);
+    return runCode_(string_name, parser, 1, env);
+}
+
+int runCodeFromFile(FilePath file, FILE *error_file, af_Environment *env) {
+    if (env == NULL || file == NULL)
+        return -1;
+
+    if (error_file == NULL)
+        error_file = stderr;
+    af_Parser *parser = makeParserByFile(file, error_file);
+    return runCode_(file, parser, 1, env);
+}
+
+int runCodeFromStdin(char *name, FILE *error_file, af_Environment *env) {
+    if (env == NULL || feof(stdin) || ferror(stdin))
+        return -1;
+
+    if (name == NULL)
+        name = "sys-stdin.af";
+
+    if (error_file == NULL)
+        error_file = stderr;
+    af_Parser *parser = makeParserByStdin(error_file);
+    return runCode_(name, parser, 0, env);
+}

+ 17 - 2
test/src/run_code.c

@@ -373,7 +373,7 @@ int main() {
     aFunInit();
     printf("Hello World\n");
 
-    af_Environment *env = makeEnvironment(grt_always);
+    af_Environment *env = creatAFunEnviroment();
     if(!pushLiteralRegex("data.*", "func", true, env)) {
         fprintf(stderr, "pushLiteralRegex Error\n");
         goto RETURN_1;
@@ -1147,6 +1147,21 @@ int main() {
         printf("\n");
     }
 
+    {
+        printf("TAG S: STRING\n");
+        int exit_code = runCodeFromString("object\ndata\n{func}\nglobal\n", "tags-string.af", NULL, env);
+        printf("exit code = %d\n\n", exit_code);
+    }
+
+#ifndef IN_CTEST
+    {
+        printf("TAG T: [stdin]\n");
+        int exit_code = runCodeFromStdin(NULL, NULL, env);
+        printf("exit code = %d\n\n", exit_code);
+        getc(stdin);
+    }
+#endif
+
     /* 错误用例 */
 
     {  // 中缀调用测试
@@ -1218,7 +1233,7 @@ int main() {
     }
 
     printf("freeEnvironment:\n");
-    freeEnvironment(env);
+    destructAFunEnvironment(env);
 
     printf("Exit at 0.");
 #ifndef IN_CTEST

+ 2 - 2
test/src/syntactic.c

@@ -21,7 +21,7 @@ int main() {
 
 void test1(void) {
     af_Parser *parser = makeParserByString(str, false, stderr);
-    af_Code *code = parserCode(parser);
+    af_Code *code = parserCode("test1.af", parser);
     freeParser(parser);
     freeAllCode(code);
 }
@@ -41,7 +41,7 @@ void test2(void) {
     fclose(file);
 
     af_Parser *parser = makeParserByFile(path, stderr);
-    af_Code *code = parserCode(parser);
+    af_Code *code = parserCode("test2.af", parser);
     printCode(code);
     freeParser(parser);
     freeAllCode(code);