Răsfoiți Sursa

feat: 错误回溯时打印代码内容

SongZihuan 3 ani în urmă
părinte
comite
65d282c16f
3 a modificat fișierele cu 43 adăugiri și 7 ștergeri
  1. 1 0
      include/code.h
  2. 22 2
      src/core/code.c
  3. 20 5
      src/core/env.c

+ 1 - 0
include/code.h

@@ -2,6 +2,7 @@
 #define AFUN__BYTECODE_H_PUBLIC
 #include <stdio.h>
 
+#define CODE_STR_MAX_SIZE (50)
 typedef struct af_Code af_Code;
 
 /* 括号类型 */

+ 22 - 2
src/core/code.c

@@ -299,6 +299,20 @@ static char *codeToStr_(af_Code *code, CodeUint *layer, struct af_BlockEnd **bn)
             re = strJoin(re, "| ", true, false);
         } else
             re = strJoin(re, code->element.data, true, false);
+    } else if (code->block.elements == 0) {
+        switch(code->block.type) {
+            case parentheses:
+                re = strJoin(re, "()", true, false);
+                break;
+            case brackets:
+                re = strJoin(re, "[]", true, false);
+                break;
+            case curly:
+                re = strJoin(re, "{}", true, false);
+                break;
+            default:
+                break;
+        }
     } else {
         char ch = NUL;
         switch(code->block.type) {
@@ -333,8 +347,8 @@ static char *codeToStr_(af_Code *code, CodeUint *layer, struct af_BlockEnd **bn)
 static char *codeEndToStr(CodeUint code_end, CodeUint *layer, struct af_BlockEnd **bn) {
     char *re = NEW_STR(code_end);
     for (size_t i = 0; code_end > 0; code_end--, i++) {
-        if ((*layer) <= 0 || *bn == NULL)
-            *layer = -1;
+        if (*bn == NULL)
+            break;
         (*layer)--;
         re[i] = (*bn)->ch;
 
@@ -354,7 +368,13 @@ char *codeToStr(af_Code *code, int n) {
     char *re = strCopy(NULL);
     struct af_BlockEnd *bn = NULL;
     CodeUint layer = 0;
+
     for (NULL; code != NULL && layer >= 0 && (n > 0 || n == -1); code = code->next) {
+        if (strlen(re) >= CODE_STR_MAX_SIZE) {
+            re = strJoin(re, " ...", true, false);  // 限度
+            break;
+        }
+
         char *get = codeToStr_(code, &layer, &bn);
         re = strJoin(re, get, true, true);
         if (code->code_end != 0) {

+ 20 - 5
src/core/env.c

@@ -49,7 +49,7 @@ static af_ErrorBacktracking *freeErrorBacktracking(af_ErrorBacktracking *ebt);
 static void freeAllErrorBacktracking(af_ErrorBacktracking *ebt);
 
 /* af_ErrorBacktracking 相关函数 */
-static char *getActivityInfoToBacktracking(af_Activity *activity);
+static char *getActivityInfoToBacktracking(af_Activity *activity, bool print_bt_top);
 static void fprintfNote(FILE *file, char *note);
 
 /* 内置顶层消息处理器 */
@@ -409,12 +409,12 @@ af_Message *makeNORMALMessage(af_Object *obj) {
 }
 
 af_Message *makeERRORMessage(char *type, char *error, af_Environment *env) {
-    char *info = getActivityInfoToBacktracking(env->activity);
+    char *info = getActivityInfoToBacktracking(env->activity, false);
     af_ErrorInfo *ei = makeErrorInfo(type, error, info, env->activity->line, env->activity->file);
     free(info);
 
     for (af_Activity *activity = env->activity->prev; activity != NULL; activity = activity->prev) {
-        info = getActivityInfoToBacktracking(activity);
+        info = getActivityInfoToBacktracking(activity, true);
         pushErrorBacktracking(activity->line, activity->file, info, ei);
         free(info);
     }
@@ -1111,7 +1111,7 @@ static void fprintfNote(FILE *file, char *note) {
         ent = strchr(note, '\n');
         if (ent != NULL)
             *ent = NUL;
-        fprintf(file, "   #note: %s\n", note);
+        fprintf(file, "   #note %s\n", note);
         if (ent == NULL)  // 意味着是最后一部分`note`
             break;
         *ent = '\n';
@@ -1162,7 +1162,7 @@ void pushErrorBacktracking(FileLine line, FilePath file, char *note, af_ErrorInf
     ei->track = ebt;
 }
 
-static char *getActivityInfoToBacktracking(af_Activity *activity) {
+static char *getActivityInfoToBacktracking(af_Activity *activity, bool print_bt_top){
     char *info = NULL;
     if (activity->type == act_gc) {
         info = strJoin(info, "gc-activity;", true, false);
@@ -1208,5 +1208,20 @@ static char *getActivityInfoToBacktracking(af_Activity *activity) {
     if (activity->optimization)
         info = strJoin(info, "\ntail-call-Optimization;", true, false);
 
+    info = strJoin(info, "\n", true, false);
+    char *print_code = NULL;
+    if (!print_bt_top && activity->bt_next != NULL)
+        print_code = codeToStr(activity->bt_next, 1);
+    else if (activity->bt_top != NULL)
+        print_code = codeToStr(activity->bt_top, 1);
+    else if (activity->prev == NULL && activity->bt_start != NULL)
+        print_code = codeToStr(activity->bt_start, -1);
+
+    if (print_code != NULL) {
+        info = strJoin(info, "code: ", true, false);
+        info = strJoin(info, print_code, true, true);
+    } else
+        info = strJoin(info, "sys-err non-code", true, false);
+
     return info;
 }