浏览代码

feat: 去除af_Code的count字段

af_Code的count字段可能无法记录所有的元素(嵌套block等)
因此使用elements字段和code_end字段
SongZihuan 3 年之前
父节点
当前提交
6ae2b41b54
共有 6 个文件被更改,包括 40 次插入37 次删除
  1. 0 1
      include/code.h
  2. 1 0
      include/tool.h
  3. 1 1
      src/core/__code.h
  4. 27 32
      src/core/code.c
  5. 3 3
      src/core/env.c
  6. 8 0
      src/tool/string.c

+ 0 - 1
include/code.h

@@ -16,7 +16,6 @@ af_Code *makeElementCode(char *var, char prefix, FileLine line, FilePath path);
 af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, FileLine line, FilePath path, af_Code **next);
 
 /* 代码块释放函数 */
-bool freeCodeWithElement(af_Code *bt, af_Code **next);
 void freeAllCode(af_Code *bt);
 
 /* 代码块操作函数 */

+ 1 - 0
include/tool.h

@@ -39,6 +39,7 @@ time33_t w_time33(wchar_t *str);
 #define NEW_WSTR(size) (wchar_t *)calloc((size) + 1, sizeof(wchar_t))
 #define STR_LEN(p) (((p) == NULL) ? 0 : strlen((p)))
 #define WSTR_LEN(p) (((p) == NULL) ? 0 : wcslen((p)))
+char *charToStr(char ch);
 char *strCopy(const char *str);
 wchar_t *wstrCopy(const wchar_t *str);
 wchar_t *wstrWithWchar(wchar_t *str, size_t size, int free_old, ...);

+ 1 - 1
src/core/__code.h

@@ -19,6 +19,7 @@ enum af_CodeType {
 struct af_Code {  // 一个 Code 的结构体
     enum af_CodeType type;
     char prefix;  // 前缀
+    CodeUint code_end;  // 记录block的end
     union {
         struct {
             char *data;
@@ -26,7 +27,6 @@ struct af_Code {  // 一个 Code 的结构体
 
         struct {
             CodeUint elements;  // 元素个数
-            CodeUint count;  // 总元素个数
             enum af_BlockType type;  // 括号类型
         } block;
     };

+ 27 - 32
src/core/code.c

@@ -13,7 +13,7 @@ static af_Code *makeCode(char prefix, FileLine line, FilePath path);
 static af_Code *freeCode(af_Code *bt);
 
 /* Code 操作函数 */
-static void countElement(af_Code *element, CodeUint *elements, CodeUint *count, af_Code **next);
+static void countElement(af_Code *element, CodeUint *elements, af_Code **next);
 
 /* Code IO函数 */
 static bool readCode(af_Code **bt, FILE *file);
@@ -42,26 +42,24 @@ af_Code *makeElementCode(char *var, char prefix, FileLine line, FilePath path) {
  * 函数名: countElement
  * 目标: 统计元素个数(不包括元素的子元素)
  */
-static void countElement(af_Code *element, CodeUint *elements, CodeUint *count, af_Code **next) {
-    CodeUint to_next = 0;  // 表示紧接着的元素都不纳入统计(指block的子元素)
+static void countElement(af_Code *element, CodeUint *elements, af_Code **next) {
+    CodeUint layer = 0;
 
     for (*elements = 0; element != NULL; *next = element, element = element->next) {
-        (*count)++;
-        if (to_next == 0)
+        if (layer == 0)
             (*elements)++;
-        else
-            to_next--;
 
         if (element->type == code_block)
-            to_next += element->block.elements;
+            layer++;
+        if (element->code_end)
+            layer = layer - element->code_end;
     }
 }
 
 af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, FileLine line, FilePath path, af_Code **next) {
     af_Code *bt = NULL;
-    af_Code *tmp = NULL;
+    af_Code *tmp = NULL;  // 保存最后一个code的地址
     CodeUint elements = 0;
-    CodeUint count = 0;
 
     if (next == NULL)
         next = &tmp;
@@ -69,13 +67,14 @@ af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, Fi
     if (prefix != NUL && strchr(B_PREFIX, prefix) == NULL)
         prefix = NUL;
 
-    countElement(element, &elements, &count, next);
+    countElement(element, &elements, next);
     bt = makeCode(prefix, line, path);
     bt->type = code_block;
     bt->block.type = type;
     bt->block.elements = elements;
-    bt->block.count = count;
     bt->next = element;
+    if (*next != NULL)
+        (*next)->code_end++;
     return bt;
 }
 
@@ -97,12 +96,12 @@ af_Code *copyCode(af_Code *base, FilePath *path) {
     for (NULL; base != NULL; base = base->next) {
         *pdest = makeCode(base->prefix, base->line, base->path);
         (*pdest)->type = base->type;
+        (*pdest)->code_end = base->code_end;
         switch (base->type) {
             case code_element:
                 (*pdest)->element.data = strCopy(base->element.data);
                 break;
             case code_block:
-                (*pdest)->block.count = base->block.count;
                 (*pdest)->block.elements = base->block.elements;
                 (*pdest)->block.type = base->block.type;
                 break;
@@ -134,28 +133,25 @@ static af_Code *freeCode(af_Code *bt) {
     return next;
 }
 
-bool freeCodeWithElement(af_Code *bt, af_Code **next) {
-    CodeUint count = 1 + bt->block.count;  // 要释放的元素个数
-    for (NULL; count != 0; count--) {
-        if (bt == NULL)
-            return false;
-        bt = freeCode(bt);
-    }
-    if (next != NULL)
-        *next = bt;
-    return true;
-}
-
 void freeAllCode(af_Code *bt) {
     while (bt != NULL)
         bt = freeCode(bt);
 }
 
 bool getCodeBlockNext(af_Code *bt, af_Code **next) {
-    CodeUint count = 1 + bt->block.count;
-    for (NULL; count != 0; count--, bt = bt->next) {
+    if (bt->block.elements == 0) {
+        *next = bt->next;
+        return true;
+    }
+
+    CodeUint count = 1;
+    bt = bt->next;
+    for (NULL; count != 0; bt = bt->next) {
         if (bt == NULL)
             return false;
+        if (bt->type == code_block)
+            count++;
+        count = count - bt->code_end;
     }
     *next = bt;
     return true;
@@ -166,6 +162,7 @@ static bool writeCode(af_Code *bt, FILE *file) {
     Done(byteWriteUint_8(file, bt->type));
     Done(byteWriteUint_8(file, bt->prefix));
     Done(byteWriteUint_32(file, bt->line));
+    Done(byteWriteUint_32(file, bt->code_end));
 
     if (bt->path != NULL) {
         Done(byteWriteUint_8(file, true));  // 表示有path
@@ -181,7 +178,6 @@ static bool writeCode(af_Code *bt, FILE *file) {
         case code_block:
             Done(byteWriteUint_8(file, bt->block.type));
             Done(byteWriteUint_32(file, bt->block.elements));
-            Done(byteWriteUint_32(file, bt->block.count));
             break;
         default:
             break;
@@ -217,19 +213,21 @@ static bool readCode(af_Code **bt, FILE *file) {
     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_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);
     (*bt)->type = type;
+    (*bt)->code_end = code_end;
 
     switch (type) {
         case code_element:
@@ -238,13 +236,10 @@ static bool readCode(af_Code **bt, FILE *file) {
         case code_block: {
             uint8_t block_type;
             uint32_t elements;
-            uint32_t count;
             Done(byteReadUint_8(file, &block_type));
             Done(byteReadUint_32(file,&elements));
-            Done(byteReadUint_32(file,&count));
             (*bt)->block.type = block_type;
             (*bt)->block.elements = elements;
-            (*bt)->block.elements = count;
             break;
         }
         default:

+ 3 - 3
src/core/env.c

@@ -636,11 +636,11 @@ static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_
 bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env) {
     af_Code *next;
     if (!getCodeBlockNext(bt, &next)) {
-        pushMessageDown(makeERRORMessage(SYNTAX_ERROR, SYNTAX_ERROR_INFO, env), env);
+        pushMessageDown(makeERRORMessage(SYNTAX_ERROR, SYNTAX_ERROR_INFO"1", env), env);
         return false;
     }
 
-    if (bt->type != code_block || bt->block.count == 0) {
+    if (bt->type != code_block || bt->block.elements == 0) {
         pushMessageDown(makeERRORMessage(SYNTAX_ERROR, NOT_CODE_INFO, env), env);
         return false;
     }
@@ -676,7 +676,7 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
     env->activity->parentheses_call = NULL;
 
     if (!getCodeBlockNext(bt, &next)) {
-        pushMessageDown(makeERRORMessage(SYNTAX_ERROR, SYNTAX_ERROR_INFO, env), env);
+        pushMessageDown(makeERRORMessage(SYNTAX_ERROR, SYNTAX_ERROR_INFO"2", env), env);
         return false;
     }
 

+ 8 - 0
src/tool/string.c

@@ -10,6 +10,14 @@
 #include "tool.h"
 #include "mem.h"
 
+char *charToStr(char ch) {
+    if (ch == NUL)
+        return NULL;
+    char *tmp = NEW_STR(1);
+    *tmp = ch;
+    return tmp;
+}
+
 char *strCopy(const char *str){
     char *tmp = NEW_STR(STR_LEN(str));
     if (str != NULL)