소스 검색

feat: af_Code改动

af_Code转换为双向链表
env新增bt_done字段
错误回溯时显示bt_done的字符串
SongZihuan 3 년 전
부모
커밋
2dae3a9fca
5개의 변경된 파일41개의 추가작업 그리고 22개의 파일을 삭제
  1. 1 0
      src/core/__code.h
  2. 1 0
      src/core/__env.h
  3. 20 8
      src/core/code.c
  4. 15 11
      src/core/env.c
  5. 4 3
      src/core/run.c

+ 1 - 0
src/core/__code.h

@@ -26,6 +26,7 @@ struct af_Code {  // 一个 Code 的结构体
     FileLine line;
     FilePath path;  // path == NULL表示沿用上层地址
 
+    struct af_Code *prev;
     struct af_Code *next;
 };
 

+ 1 - 0
src/core/__env.h

@@ -124,6 +124,7 @@ struct af_Activity {  // 活动记录器
 
             struct af_Code *bt_top;  // 最顶层设置为NULL, 函数调用设置为block, (bt_start的上一个元素) [只在函数调用的非NORMAL期有用]
             struct af_Code *bt_start;  // 代码的起始位置 (block的第一个元素)
+            struct af_Code *bt_done;  // 当前正在执行的代码
             struct af_Code *bt_next;  // 指示代码下一步要运行的位置 [总是超前当前执行的code]
 
             /* 返回值 */

+ 20 - 8
src/core/code.c

@@ -17,7 +17,7 @@ static af_Code *freeCode(af_Code *bt);
 static int countElement(af_Code *element, CodeUInt *elements, af_Code **next);
 
 /* Code IO函数 */
-static bool readCode(af_Code **bt, FILE *file);
+static bool readCode(af_Code **bt, af_Code *prev, FILE *file);
 static bool writeCode(af_Code *bt, FILE *file);
 
 /* Code 转换STR函数 */
@@ -113,8 +113,12 @@ af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, Fi
 }
 
 af_Code *pushCode(af_Code **base, af_Code *next) {
-    while ((*base) != NULL)
-        base = &((*base)->next);
+    af_Code *prev = NULL;
+    while ((*base) != NULL) {
+        prev = *base;
+        base = &(prev->next);
+    }
+    next->prev = prev;
     *base = next;
 
     while (next != NULL && next->next != NULL)
@@ -126,11 +130,14 @@ af_Code *pushCode(af_Code **base, af_Code *next) {
 af_Code *copyAllCode(af_Code *base, FilePath *path) {
     af_Code *dest = NULL;
     af_Code **pdest = &dest;
+    af_Code *prev = NULL;
 
-    for (NULL; base != NULL; base = base->next) {
+    for (NULL; base != NULL; base = base->next, prev = *pdest, pdest = &(prev->next)) {
         *pdest = makeCode(base->prefix, base->line, base->path);
         (*pdest)->type = base->type;
         (*pdest)->code_end = base->code_end;
+        (*pdest)->prev = prev;
+
         switch (base->type) {
             case code_element:
                 (*pdest)->element.data = strCopy(base->element.data);
@@ -159,11 +166,14 @@ af_Code *copyAllCode(af_Code *base, FilePath *path) {
 af_Code *copyCode(af_Code *base, FilePath *path) {
     af_Code *dest = NULL;
     af_Code **pdest = &dest;
+    af_Code *prev = NULL;
 
     CodeUInt layer = 0;
-    for (NULL; base != NULL; base = base->next) {
+    for (NULL; base != NULL; base = base->next, prev = *pdest, pdest = &(prev->next)) {
         *pdest = makeCode(base->prefix, base->line, base->path);
         (*pdest)->type = base->type;
+        (*pdest)->prev = prev;
+
         switch (base->type) {
             case code_element:
                 (*pdest)->element.data = strCopy(base->element.data);
@@ -291,7 +301,7 @@ RETURN_FALSE:
     return false;
 }
 
-static bool readCode(af_Code **bt, FILE *file) {
+static bool readCode(af_Code **bt, af_Code *prev, FILE *file) {
     uint8_t type;
     uint8_t prefix;
     uint32_t line;
@@ -305,6 +315,7 @@ static bool readCode(af_Code **bt, FILE *file) {
     *bt = makeCode((char)prefix, line, NULL);
     (*bt)->type = type;
     (*bt)->code_end = (CodeUInt)code_end;
+    (*bt)->prev = prev;
 
     switch (type) {
         case code_element:
@@ -327,10 +338,11 @@ static bool readCode(af_Code **bt, FILE *file) {
 
 bool readAllCode(af_Code **bt, FilePath path, FILE *file) {
     af_Code **base = bt;
+    af_Code *prev = NULL;
     *bt = NULL;
 
-    for (NULL; true;bt = &((*bt)->next)) {
-        if(!readCode(bt, file))
+    for (NULL; true;prev = *bt, bt = &(prev->next)) {
+        if(!readCode(bt, prev, file))
             goto RETURN_FALSE;
         if (CLEAR_FERROR(stdin))
             goto RETURN_FALSE;

+ 15 - 11
src/core/env.c

@@ -576,19 +576,15 @@ af_Message *makeNORMALMessage(af_Object *obj) {
 }
 
 af_Message *makeERRORMessage(char *type, char *error, af_Environment *env) {
-    char *info = getActivityInfoToBacktracking(env->activity);
-    af_ErrorInfo *ei = makeErrorInfo(type, error, info, env->activity->line, env->activity->file);
-    free(info);
+    char *info = NULL;
+    af_ErrorInfo *ei = NULL;
 
-    for (af_ActivityTrackBack *atb = env->activity->tb; atb != NULL; atb = atb->next) {
-        info = getActivityTrackBackInfoToBacktracking(atb);
-        pushErrorBacktracking(atb->line, atb->file, info, ei);
-        free(info);
-    }
-
-    for (af_Activity *activity = env->activity->prev; activity != NULL; activity = activity->prev) {
+    for (af_Activity *activity = env->activity; activity != NULL; activity = activity->prev) {
         info = getActivityInfoToBacktracking(activity);
-        pushErrorBacktracking(activity->line, activity->file, info, ei);
+        if (ei == NULL)
+            ei = makeErrorInfo(type, error, info, env->activity->line, env->activity->file);
+        else
+            pushErrorBacktracking(activity->line, activity->file, info, ei);
         free(info);
 
         for (af_ActivityTrackBack *atb = activity->tb; atb != NULL; atb = atb->next) {
@@ -1709,6 +1705,14 @@ static char *getActivityInfoToBacktracking(af_Activity *activity){
     if (activity->optimization)
         strcat(info, "\ntail-call-optimization;");
 
+    if (activity->bt_done != NULL) {
+        char *code = codeToStr(activity->bt_done, 1);
+        if (code != NULL) {
+            strcat(info, "\ncode: ");
+            strcat(info, code);
+        }
+    }
+
     return strCopy(info);
 }
 

+ 4 - 3
src/core/run.c

@@ -418,13 +418,14 @@ bool iterCode(af_Code *code, int mode, af_Environment *env){
         /* 有代码运行 */
         bool pass_msg = false;  // 表示不处理msg
         if (env->activity->process_msg_first == 0) {  /* 运行实际代码 */
-            switch (env->activity->bt_next->type) {
+            env->activity->bt_done = env->activity->bt_next;
+            switch (env->activity->bt_done->type) {
                 case code_element:
-                    if (codeElement(env->activity->bt_next, env))
+                    if (codeElement(env->activity->bt_done, env))
                         pass_msg = true;
                     break;
                 case code_block:
-                    if (codeBlock(env->activity->bt_next, env))
+                    if (codeBlock(env->activity->bt_done, env))
                         pass_msg = true;  // 若运行成功则跳转到下一次运行, 该步骤仅为设置Activity
                     break;
                 default: