Przeglądaj źródła

feat: 添加.afb测试文件

SongZihuan 3 lat temu
rodzic
commit
a10ecac5d3

+ 1 - 1
include/core/code.h

@@ -30,7 +30,7 @@ AFUN_CORE_EXPORT void freeAllCode(af_Code *bt);
 AFUN_CORE_EXPORT af_Code *pushCode(af_Code **base, af_Code *next);
 AFUN_CORE_EXPORT af_Code *copyCode(af_Code *base, FilePath *path);
 AFUN_CORE_EXPORT bool writeAllCode(af_Code *bt, FILE *file);
-AFUN_CORE_EXPORT bool readAllCode(af_Code **bt, FILE *file);
+AFUN_CORE_EXPORT bool readAllCode(af_Code **bt, FilePath path, FILE *file);
 
 /* 代码块 属性访问 */
 AFUN_CORE_EXPORT af_Code *getCodeNext(af_Code *bt);

+ 2 - 2
include/runtime/aFunlang.h

@@ -12,10 +12,10 @@ 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 runCodeFromFileSource(FilePath file, FILE *error_file, af_Environment *env);
+AFUN_LANG_EXPORT int runCodeFromFileSource(FilePath file, FILE *error_file, bool save_afb, FilePath save_path, af_Environment *env);
 AFUN_LANG_EXPORT int runCodeFromStdin(char *name, FILE *error_file, af_Environment *env);
 AFUN_LANG_EXPORT int runCodeFromMemory(af_Code *code, af_Environment *env);
 AFUN_LANG_EXPORT int runCodeFromMemoryAsImport(af_Code *code, af_Environment *env);
 AFUN_LANG_EXPORT int runCodeFromFileByte(FilePath file, FILE *error_file, af_Environment *env);
-AFUN_LANG_EXPORT int runCodeFromFile(FilePath file, FILE *error_file, af_Environment *env);
+AFUN_LANG_EXPORT int runCodeFromFile(FilePath file, FILE *error_file, bool save_afb, af_Environment *env);
 #endif //AFUN_AFUNLANG_H

+ 1 - 1
src/__main_run.h

@@ -25,6 +25,6 @@ RunList *makeStringRunList(char *string);
 void freeAllRunList(RunList *rl);
 RunList **pushRunList(RunList *rl, RunList **base);
 
-int runCodeFromRunList(RunList *run_list, RunList **bak, af_Environment *env);
+int runCodeFromRunList(RunList *run_list, RunList **bak, bool save_afb, af_Environment *env);
 
 #endif //AFUN___MAIN_RUN_H

+ 16 - 25
src/core/code.c

@@ -185,13 +185,6 @@ static bool writeCode(af_Code *bt, FILE *file) {
     Done(byteWriteUint_32(file, bt->line));
     Done(byteWriteUint_32(file, bt->code_end));
 
-    if (bt->path != NULL) {
-        Done(byteWriteUint_8(file, true));  // 表示有path
-        Done(byteWriteStr(file, bt->path));
-    } else {
-        Done(byteWriteUint_8(file, false));  // 表示无path
-    }
-
     switch (bt->type) {
         case code_element:
             Done(byteWriteStr(file, bt->element.data));
@@ -212,18 +205,13 @@ static bool writeCode(af_Code *bt, FILE *file) {
  * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可
  */
 bool writeAllCode(af_Code *bt, FILE *file) {
-    uint32_t count = 0;
-
     if (bt == NULL || bt->path == NULL)
         return false;
 
-    for (af_Code *tmp = bt; tmp != NULL; tmp = tmp->next)  // 统计个数
-        count++;
-
-    Done(byteWriteUint_32(file,count));
     for (NULL; bt != NULL; bt = bt->next) {
         if (!writeCode(bt, file))
             return false;
+        Done(byteWriteUint_8(file, (bt->next == NULL)));  // 记录是否为最后一位
     }
 
     return true;
@@ -233,20 +221,14 @@ static bool readCode(af_Code **bt, FILE *file) {
     uint8_t type;
     uint8_t prefix;
     uint32_t line;
-    uint8_t have_path;
     uint32_t code_end;
-    char *path = NULL;
 
     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));
 
-    *bt = makeCode((char)prefix, line, path);
-    free(path);
+    *bt = makeCode((char)prefix, line, NULL);
     (*bt)->type = type;
     (*bt)->code_end = (CodeInt)code_end;
 
@@ -269,14 +251,23 @@ static bool readCode(af_Code **bt, FILE *file) {
     return true;
 }
 
-bool readAllCode(af_Code **bt, FILE *file) {
-    uint32_t count;
-    Done(byteReadUint_32(file,&count));
-
-    for (NULL; count != 0; count--, bt = &((*bt)->next)) {
+bool readAllCode(af_Code **bt, FilePath path, FILE *file) {
+    af_Code **base = bt;
+    *bt = NULL;
+    for (NULL; true;bt = &((*bt)->next)) {
         if(!readCode(bt, file))
             return false;
+        if (ferror(stdin))
+            return false;
+
+        uint8_t last;
+        Done(byteReadUint_8(file, &last));
+        if (last)
+            break;
     }
+
+    if (*base != NULL)
+        (*base)->path = strCopy(path);
     return true;
 }
 

+ 11 - 3
src/main.c

@@ -12,6 +12,7 @@ ff_defArg(run, false)
                 ff_argRule('f', file, must, 'f')
                 ff_argRule('s', source, must, 's')
                 ff_argRule('b', byte, must, 'b')
+                ff_argRule(NUL, no-afb, not, 'a')
                 ff_argRule(NUL, no-cl, not, 'n')
 ff_endArg(run, false);
 
@@ -107,12 +108,15 @@ out:
     return EXIT_SUCCESS;
 }
 
-static RunList *getRunList(ff_FFlags *ff, bool *command_line) {
+static RunList *getRunList(ff_FFlags *ff, bool *command_line, bool *save_afb) {
     char *text = NULL;
     RunList *run_list = NULL;
     RunList **prl = &run_list;
     int mark;
 
+    *command_line = true;
+    *save_afb = true;
+
     while (1) {
         mark = ff_getopt(&text, ff);
         switch (mark) {
@@ -131,6 +135,9 @@ static RunList *getRunList(ff_FFlags *ff, bool *command_line) {
             case 'n':
                 *command_line = false;
                 break;
+            case 'a':
+                *save_afb = false;
+                break;
             case -1:
                 goto out;
             default:
@@ -148,12 +155,13 @@ out:
 
 static int mainRun(ff_FFlags *ff) {
     bool command_line = true;
+    bool save_afb = true;
     int exit_code;
-    RunList *rl = getRunList(ff, &command_line);
+    RunList *rl = getRunList(ff, &command_line, &save_afb);
 
     af_Environment *env = creatAFunEnviroment();
     if (rl != NULL)
-        exit_code = runCodeFromRunList(rl, NULL, env);
+        exit_code = runCodeFromRunList(rl, NULL, save_afb, env);
     else if (!command_line) {
         fprintf(stderr, "Not code to run.\n");
         printHelp();

+ 3 - 3
src/main_run.c

@@ -57,7 +57,7 @@ RunList **pushRunList(RunList *rl, RunList **base) {
     return base;
 }
 
-int runCodeFromRunList(RunList *run_list, RunList **bak, af_Environment *env) {
+int runCodeFromRunList(RunList *run_list, RunList **bak, bool save_afb, af_Environment *env) {
     int exit_code = 0;
 
     for (NULL; run_list != NULL; run_list = run_list->next) {
@@ -66,13 +66,13 @@ int runCodeFromRunList(RunList *run_list, RunList **bak, af_Environment *env) {
                 exit_code = runCodeFromString(run_list->string, "command-line-eval", stderr, env);
                 break;
             case rl_file:
-                exit_code = runCodeFromFile(run_list->file, stderr, env);
+                exit_code = runCodeFromFile(run_list->file, stderr, save_afb, env);
                 break;
             case rl_file_b:
                 exit_code = runCodeFromFileByte(run_list->file, stderr, env);
                 break;
             case rl_file_s:
-                exit_code = runCodeFromFileSource(run_list->file, stderr, env);
+                exit_code = runCodeFromFileSource(run_list->file, stderr, save_afb, NULL, env);
                 break;
             default:
                 break;

+ 28 - 9
src/runtime/aFunlang.c

@@ -2,7 +2,7 @@
 #include "aFunCore.h"
 #include "__env.h"
 
-static int runCode_(FilePath name, af_Parser *parser, int mode, af_Environment *env);
+static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env);
 
 void aFunInit() {
     aFunCoreInit();
@@ -31,7 +31,7 @@ void destructAFunEnvironment(af_Environment *env) {
     freeEnvironment(env);
 }
 
-static int runCode_(FilePath name, af_Parser *parser, int mode, af_Environment *env) {
+static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env){
     if (parser == NULL)
         return -1;
 
@@ -40,6 +40,13 @@ static int runCode_(FilePath name, af_Parser *parser, int mode, af_Environment *
     if (bt_code == NULL)
         return -2;
 
+    /* 写入文件 */
+    if (save_path != NULL) {
+        FILE *file_ = fopen(save_path, "wb");
+        if (file_ != NULL)
+            writeAllCode(bt_code, file_);
+    }
+
     bool res = iterCode(bt_code, mode, env);
     freeAllCode(bt_code);
     if (!res)
@@ -62,14 +69,14 @@ int runCodeFromString(char *code, char *string_name, FILE *error_file, af_Enviro
     if (error_file == NULL)
         error_file = stderr;
     af_Parser *parser = makeParserByString(code, false, error_file);
-    return runCode_(string_name, parser, 1, env);
+    return runCode_(string_name, parser, 1, NULL, env);
 }
 
 /*
  * 函数名: runCodeFromFileSource
  * 目标: 运行文件中的程序 (源码形式)
  */
-int runCodeFromFileSource(FilePath file, FILE *error_file, af_Environment *env) {
+int runCodeFromFileSource(FilePath file, FILE *error_file, bool save_afb, FilePath save_path, af_Environment *env) {
     if (env == NULL || file == NULL)
         return -1;
 
@@ -77,10 +84,22 @@ int runCodeFromFileSource(FilePath file, FILE *error_file, af_Environment *env)
     if (sufix == NULL || !EQ_STR(".af", sufix))
         return -2;
 
+    /* 若文件不存在则自动生成 */
+    bool free_save_path = false;
+    if (save_afb && !save_path) {
+        char *path = getFileNameWithPath(file);
+        save_path = strJoin(path, ".afb", true, false);
+        free_save_path = true;
+    } else if (!save_afb)
+        save_path = NULL;
+
     if (error_file == NULL)
         error_file = stderr;
     af_Parser *parser = makeParserByFile(file, error_file);
-    return runCode_(file, parser, 1, env);
+    int exit_code = runCode_(file, parser, 1, save_path, env);
+    if (free_save_path)
+        free(save_path);
+    return exit_code;
 }
 
 /*
@@ -97,7 +116,7 @@ int runCodeFromStdin(char *name, FILE *error_file, af_Environment *env) {
     if (error_file == NULL)
         error_file = stderr;
     af_Parser *parser = makeParserByStdin(error_file);
-    return runCode_(name, parser, 0, env);
+    return runCode_(name, parser, 0, NULL, env);
 }
 
 /*
@@ -142,7 +161,7 @@ int runCodeFromFileByte(FilePath file, FILE *error_file, af_Environment *env) {
         return -3;
     }
 
-    if(!readAllCode(&code, file_)) {
+    if(!readAllCode(&code, file, file_)) {
         freeAllCode(code);
         return -2;
     }
@@ -158,7 +177,7 @@ int runCodeFromFileByte(FilePath file, FILE *error_file, af_Environment *env) {
  * 目标: 运行文件中的程序 (字节码/源码形式)
  * 注意: 必须传入.af文件
  */
-int runCodeFromFile(FilePath file, FILE *error_file, af_Environment *env) {
+int runCodeFromFile(FilePath file, FILE *error_file, bool save_afb, af_Environment *env) {
     if (env == NULL || file == NULL)
         return -1;
 
@@ -180,7 +199,7 @@ int runCodeFromFile(FilePath file, FILE *error_file, af_Environment *env) {
     if (time_2 >= time_1)
         exit_code = runCodeFromFileByte(path_2, error_file, env);
     else
-        exit_code = runCodeFromFileSource(path_1, error_file, env);
+        exit_code = runCodeFromFileSource(path_1, error_file, save_afb, path_2, env);
 
     free(path_1);
     free(path_2);

+ 1 - 4
test/af/test1.af

@@ -1,5 +1,2 @@
 global
-{str}
-str()
-"Hello"
-str
+{str}

BIN
test/af/test1.afb


BIN
test/af/test2.afb


+ 1 - 1
test/src/byte_code.c

@@ -35,7 +35,7 @@ int main() {
         return EXIT_FAILURE;
     }
 
-    if(!readAllCode(&get, file)) {
+    if(!readAllCode(&get, "test.afb", file)) {
         fprintf(stderr, "Read test.afb error.\n");
         return EXIT_FAILURE;
     }