瀏覽代碼

feat: 错误回溯

允许错误层层传递并且回溯
显示错误代码所在行号
inter.data增加error成员用于输出错误
try分支会释放error
finally分支若覆盖原先的错误也会释放error
可以输出错误文件位置
include可以输出语法错误
SongZihuan 4 年之前
父節點
當前提交
8a8511becf
共有 28 個文件被更改,包括 396 次插入258 次删除
  1. 1 0
      include/grammar.h
  2. 1 0
      include/inter.h
  3. 2 1
      include/lexical.h
  4. 2 0
      include/log.h
  5. 1 1
      include/mem.h
  6. 5 2
      include/parameter.h
  7. 18 16
      include/statement.h
  8. 4 3
      include/token.h
  9. 20 2
      include/value.h
  10. 1 0
      main.c
  11. 6 4
      memory/mem.c
  12. 16 12
      parser/__grammar.c
  13. 82 63
      parser/grammar.c
  14. 4 4
      parser/include/__grammar.h
  15. 6 3
      parser/lexical.c
  16. 3 3
      parser/syntax.c
  17. 11 8
      parser/token.c
  18. 2 2
      src/__run.c
  19. 0 1
      src/include/__run.h
  20. 23 13
      src/inter.c
  21. 8 7
      src/operation.c
  22. 42 46
      src/parameter.c
  23. 7 7
      src/run.c
  24. 18 11
      src/runbranch.c
  25. 4 3
      src/runcall.c
  26. 6 5
      src/runfile.c
  27. 40 36
      src/statement.c
  28. 63 5
      src/value.c

+ 1 - 0
include/grammar.h

@@ -14,6 +14,7 @@ struct ParserMessage{
         lexical_error,
     } status;
     char *status_message;
+    char *file;
 };
 
 typedef struct ParserMessage ParserMessage;

+ 1 - 0
include/inter.h

@@ -11,6 +11,7 @@ struct Inter{
     struct VarList *var_list;
     struct InterData{
         FILE *debug;
+        FILE *error;
         char *log_dir;  // 记录log文件夹的位置
         char *var_str_prefix;
         char *var_num_prefix;

+ 2 - 1
include/lexical.h

@@ -8,7 +8,8 @@ struct LexFile{
         bool is_back;
         signed char p;
     } back;
-    int count;
+    long int count;
+    long int line;
 };
 
 struct LexMather{

+ 2 - 0
include/log.h

@@ -52,10 +52,12 @@ fprintf(file, message, __VA_ARGS__); \
 #define PASERS_LOG "/pasers.log"
 #define LEXICAL_LOG "/lexical.log"
 #define INTER_LOG "/inter.log"
+#define INTER_ERROR "/error.log"
 #else
 #define GRAMMAR_LOG "\grammar.log"
 #define PASERS_LOG "\pasers.log"
 #define LEXICAL_LOG "\lexical.log"
 #define INTER_LOG "\inter.log"
+#define INTER_ERROR "\error.log"
 #endif
 #endif //VIRTUALMATH_LOG_H

+ 1 - 1
include/mem.h

@@ -9,7 +9,7 @@ void *memRealloc(void *old, size_t size);
 char *memStrcpy(char *str, size_t nsize, int free_old, int write, ...);
 char *memString(size_t size);
 size_t memStrlen(char *p);
-char *memStrcat(char *first, char *second);
+char *memStrcat(char *first, char *second, bool free_old);
 char *memStrcpySelf(char *str, NUMBER_TYPE times);
 char *memStrrev(char *str);
 

+ 5 - 2
include/parameter.h

@@ -1,5 +1,6 @@
 #ifndef VIRTUALMATH_PARAMETER_H
 #define VIRTUALMATH_PARAMETER_H
+
 #include "__macro.h"
 
 struct Parameter{
@@ -62,8 +63,10 @@ void freeParameter(Parameter *pt, bool free_st);
 Argument *listToArgument(LinkValue *list_value, INTER_FUNCTIONSIG_CORE);
 Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE);
 
-Result setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_CORE);
-Result setParameter(Parameter *call, Parameter *function, VarList *function_var, INTER_FUNCTIONSIG_CORE);
+Result setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, struct Statement *base,
+                        struct Inter *inter, struct VarList *var_list);
+Result setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, struct Statement *base,
+                    struct Inter *inter, struct VarList *var_list);
 Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE);
 Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE);
 

+ 18 - 16
include/statement.h

@@ -121,6 +121,8 @@ struct Statement{
             struct Statement *file;
         } include_file;
     }u;
+    long int line;
+    char *code_file;
     struct Statement *next;
 };
 
@@ -140,30 +142,30 @@ struct StatementList{
 typedef struct Statement Statement;
 typedef struct StatementList StatementList;
 
-Statement *makeStatement();
+Statement *makeStatement(long int line, char *file);
 void freeStatement(Statement *st);
 Statement *copyStatement(Statement *st);
 Statement *copyStatementCore(Statement *st);
 void connectStatement(Statement *base, Statement *new);
 
-Statement *makeOperationStatement(int type);
-Statement *makeBaseValueStatement(LinkValue *value);
-Statement *makeBaseVarStatement(char *name, Statement *times);
+Statement *makeOperationStatement(int type, long int line, char *file);
+Statement *makeBaseValueStatement(LinkValue *value, long int line, char *file);
+Statement *makeBaseVarStatement(char *name, Statement *times, long int line, char *file);
 Statement *makeBaseSVarStatement(Statement *name, Statement *times);
-Statement *makeBaseDictStatement(Parameter *pt);
-Statement *makeTupleStatement(struct Parameter *pt, enum ListType type);
+Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file);
+Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line, char *file);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);
-Statement *makeIfStatement();
-Statement *makeWhileStatement();
-Statement *makeTryStatement();
-Statement *makeBreakStatement(Statement *times);
-Statement *makeContinueStatement(Statement *times);
-Statement *makeRegoStatement(Statement *times);
-Statement *makeRestartStatement(Statement *times);
-Statement *makeReturnStatement(Statement *value);
-Statement *makeRaiseStatement(Statement *value);
-Statement *makeIncludeStatement(Statement *file);
+Statement *makeIfStatement(long int line, char *file);
+Statement *makeWhileStatement(long int line, char *file);
+Statement *makeTryStatement(long int line, char *file);
+Statement *makeBreakStatement(Statement *times, long int line, char *file);
+Statement *makeContinueStatement(Statement *times, long int line, char *file);
+Statement *makeRegoStatement(Statement *times, long int line, char *file);
+Statement *makeRestartStatement(Statement *times, long int line, char *file);
+Statement *makeReturnStatement(Statement *value, long int line, char *file);
+Statement *makeRaiseStatement(Statement *value, long int line, char *file);
+Statement *makeIncludeStatement(Statement *file, long int line, char *file_dir);
 struct Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token *right, int type, bool is_right);
 
 StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code, int type);

+ 4 - 3
include/token.h

@@ -117,6 +117,7 @@ writeLog(debug, type, "\n", NULL); \
 
 struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配
+    long int line;
     struct TokenData{
         char *str;
         char *second_str;  // 针对123.4j这种形式设定的,其中second_str存储j
@@ -145,9 +146,9 @@ typedef struct TokenMessage TokenMessage;
 TokenMessage *makeTokenMessage(char *file_dir, char *debug);
 void freeTokenMessage(TokenMessage *tm, bool self, bool free_st);
 
-Token *makeToken();
-void freeToken(Token *tk, bool self, bool error);
-Token *makeLexToken(int type, char *str, char *second_str);
+Token *makeToken(long int line);
+long freeToken(Token *tk, bool self, bool error);
+Token *makeLexToken(int type, char *str, char *second_str, long int line);
 Token *makeStatementToken(int type, struct Statement *st);
 
 extern Token *getToken(LexFile *file, LexMathers *mathers, FILE *debug);

+ 20 - 2
include/value.h

@@ -1,5 +1,6 @@
 #ifndef VIRTUALMATH_VALUE_H
 #define VIRTUALMATH_VALUE_H
+
 #include "__macro.h"
 
 struct VarList;
@@ -62,12 +63,22 @@ struct Result{
         restart_return,
     } type;
     struct LinkValue *value;
+    struct Error *error;
     int times;
 };
 
+struct Error{
+    char *type;
+    char *messgae;
+    char *file;
+    long int line;
+    struct Error *next;
+};
+
 typedef struct Value Value;
 typedef struct LinkValue LinkValue;
 typedef struct Result Result;
+typedef struct Error Error;
 
 Value *makeValue(Inter *inter);
 void freeValue(Value *value, Inter *inter);
@@ -79,10 +90,17 @@ Value *makeFunctionValue(struct Statement *st, struct Parameter *pt, struct VarL
 Value *makeListValue(struct Argument **arg_ad, Inter *inter, enum ListType type);
 Value *makeDictValue(struct Argument **arg_ad, bool new_hash, Inter *inter);
 
-void setResult(Result *ru, bool link, Inter *inter);
-void setResultError(Result *ru, Inter *inter);
+void setResultCore(Result *ru);
+void setResult(Result *ru, Inter *inter);
+void setResultError(Result *ru, Inter *inter, char *error_type, char *error_message, struct Statement *st, bool new);
+void setResultErrorCore(Result *ru, Inter *inter, char *error_type, char *error_message, long line, char *file, bool new);
 void setResultOperation(Result *ru, Inter *inter);
 
+Error *makeError(char *type, char *message, long int line, char *file);
+void freeError(Error *base);
+Error *connectError(Error *new, Error *base);
+void printError(Error *error, Inter *inter, bool free);
+
 void printValue(Value *value, FILE *debug);
 void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug);
 

+ 1 - 0
main.c

@@ -20,4 +20,5 @@ int main(int argc, char *argv[]) {
  * TODO-szh import和include语句
  * TODO-szh 错误回溯
  * TODO-szh 检查文件是否为目录和目录是否为目录
+ * TODO-szh 生成语法树
  */

+ 6 - 4
memory/mem.c

@@ -61,19 +61,21 @@ char *memStrcpy(char *str, size_t nsize, bool free_old, bool write, ...) {  // 
     return tmp;
 }
 
-char *memStrcat(char *first, char *second){
-    if (first == NULL && second == NULL){
+char *memStrcat(char *first, char *second, bool free_old) {
+    if (first == NULL && second == NULL)
         return NULL;
-    }
     else if (first == NULL){
         first = second;
         second = NULL;
+        free_old = false;
     }
 
     char *new = memStrcpy(first, memStrlen(second), false, false);
     if (second != NULL){
         strcat(new, second);
     }
+    if (free_old)
+        memFree(first);
     return new;
 }
 
@@ -86,7 +88,7 @@ char *memStrcpySelf(char *str, NUMBER_TYPE times){
     }
     char *new_str = memStrcpy(str, 0, false, false), *tmp;
     for (NUMBER_TYPE i=0; i < times - 1; i++){
-        tmp = memStrcat(new_str, str);
+        tmp = memStrcat(new_str, str, false);
         memFree(new_str);
         new_str = tmp;
     }

+ 16 - 12
parser/__grammar.c

@@ -20,6 +20,7 @@ inline void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBac
         Token *left_token = NULL;
         Token *right_token = NULL;
         Statement *st = NULL;
+        long int line = 0;
 
         if (readBackToken(pm) != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
@@ -31,6 +32,7 @@ inline void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBac
             continue;
         }
         left_token = popAheadToken(pm);
+        line = left_token->line;
 
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
         if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st))
@@ -49,7 +51,7 @@ inline void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBac
             goto return_;
         }
         if (readBackToken(pm) != call_type){  // 若非正确数值
-            syntaxError(pm, syntax_error, 3, "ERROR from ", self_name, "(get right)");
+            syntaxError(pm, syntax_error, line, 3, "ERROR from ", self_name, "(get right)");
             freeToken(left_token, true, true);
             freeStatement(st);
             goto return_;
@@ -118,26 +120,27 @@ inline void tailOperation(PASERSSIGNATURE, PasersFunction callBack, TailFunction
  * @param message 错误信息
  * @param status 错误类型
  */
-void syntaxError(ParserMessage *pm, int status, int num, ...) {
+void syntaxError(ParserMessage *pm, int status, long int line, int num, ...) {
     char *message = NULL;
 
     if (pm->status != success)
         return;
     if (status <= 0){
-        message = memStrcpy("Not message", 0, false, false);
+        message = memStrcpy("Not Message", 0, false, false);
         goto not_message;
     }
 
     va_list message_args;
     va_start(message_args, num);
-    for (int i=0; i < num; i++) {
-        char *new_message;
-        new_message = memStrcat(message, va_arg(message_args, char *));
-        memFree(message);
-        message = new_message;
-    }
+    for (int i=0; i < num; i++)
+        message = memStrcat(message, va_arg(message_args, char *), true);
     va_end(message_args);
 
+    char info[100];
+    snprintf(info, 100, "\non line %ld\nin file ", line);
+    message = memStrcat(message, info, true);
+    message = memStrcat(message, pm->file, true);
+
     not_message:
     pm->status = status;
     pm->status_message = message;
@@ -150,7 +153,7 @@ int readBackToken(ParserMessage *pm){
     Token *tmp = popNewToken(pm->tm, pm->paser_debug);
     if (tmp->token_type == -2){
         freeToken(tmp, true, false);
-        syntaxError(pm, lexical_error, 1, "lexical make some error");
+        syntaxError(pm, lexical_error, tmp->line, 1, "lexical make some error");
     }
     addBackToken(pm->tm->ts, tmp, pm->paser_debug);
     return tmp->token_type;
@@ -215,7 +218,7 @@ bool callChildToken(ParserMessage *pm, Inter *inter, PasersFunction callBack, in
         return false;
     if (readBackToken(pm) != type) {
         if (message != NULL)
-            syntaxError(pm, error_type, 1, message);
+            syntaxError(pm, error_type, (*tmp)->line, 1, message);
         return false;
     }
     *tmp = popAheadToken(pm);
@@ -290,7 +293,8 @@ bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_fo
             goto error_;
         if (readBackToken(pm) != POLYNOMIAL) {
             if (status == s_3) {
-                syntaxError(pm, syntax_error, 1, "Don't get a parameter after *");
+                long int line = pm->tm->ts->token_list->line;
+                syntaxError(pm, syntax_error, line, 1, "Don't get a parameter after *");
                 goto error_;
             }
             break;

+ 82 - 63
parser/grammar.c

@@ -2,13 +2,14 @@
 
 ParserMessage *makeParserMessage(char *file_dir, char *debug){
     ParserMessage *tmp = memCalloc(1, sizeof(ParserMessage));
+    tmp->file = file_dir;
     tmp->tm = makeTokenMessage(file_dir, debug);
     tmp->status = success;
     tmp->status_message = NULL;
     tmp->count = 0;
 #if OUT_LOG
     if (debug != NULL){
-        char *debug_dir = memStrcat(debug, PASERS_LOG), *grammar_dir = memStrcat(debug, GRAMMAR_LOG);
+        char *debug_dir = memStrcat(debug, PASERS_LOG, false), *grammar_dir = memStrcat(debug, GRAMMAR_LOG, false);
         if (access(debug_dir, F_OK) != 0 || access(debug_dir, W_OK) == 0)
             tmp->paser_debug = fopen(debug_dir, "w");
         if (access(grammar_dir, F_OK) != 0 || access(debug_dir, W_OK) == 0)
@@ -84,7 +85,7 @@ void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
                 if (global) {
                     freeToken(command_token, true, true);
                     printf("stop = %d\n", stop);
-                    syntaxError(pm, command_list_error, 1, "ERROR from parserCommand list(get stop)");
+                    syntaxError(pm, command_list_error, command_token->line, 1, "ERROR from parserCommand list(get stop)");
                 }
                 else{
                     connectStatement(st, command_token->data.st);
@@ -195,7 +196,8 @@ void parserControl(ParserMessage *pm, Inter *inter, MakeControlFunction callBack
                    char *message) {
     Statement *times = NULL;
     Statement *st = NULL;
-    delToken(pm);
+    long int line = 0;
+    line = delToken(pm);
     parserOperation(CALLPASERSSIGNATURE);
     if (!call_success(pm))
         goto return_;
@@ -206,10 +208,10 @@ void parserControl(ParserMessage *pm, Inter *inter, MakeControlFunction callBack
         freeToken(tmp, true, false);
     }
     else if (must_operation){
-        syntaxError(pm, syntax_error, 1, message);
+        syntaxError(pm, syntax_error, line, 1, message);
         goto return_;
     }
-    st = callBack(times);
+    st = callBack(times, line, pm->file);
     addStatementToken(type, st, pm);
     return_:
     return;
@@ -236,6 +238,7 @@ void parserIf(PASERSSIGNATURE){
     Statement *finally_st = NULL;
     StatementList *sl = NULL;
     bool have_if = false;
+    long int line = 0;
     again:
     switch (readBackToken(pm)) {
         case MATHER_IF:
@@ -243,14 +246,19 @@ void parserIf(PASERSSIGNATURE){
                 goto default_;
             else
                 have_if = true;
+            line = delToken(pm);
+            goto not_del;
         case MATHER_ELIF: {
+            Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
+            long int tmo_line = delToken(pm);
             if (else_st != NULL) {
-                syntaxError(pm, syntax_error, 1, "get elif after else\n");
+                syntaxError(pm, syntax_error, tmo_line, 1, "get elif after else");
                 goto error_;
             }
-            Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
-            delToken(pm);
-            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, "Don't get a if condition"))
+
+            not_del:
+            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp,
+                                    "Don't get a if condition"))
                 goto error_;
 
             if (!callParserAs(CALLPASERSSIGNATURE, &var_tmp, "Don't get a while var")) {
@@ -276,15 +284,16 @@ void parserIf(PASERSSIGNATURE){
             sl = makeConnectStatementList(sl, NULL, NULL, code_tmp, do_b);
             goto again;
         }
-        case MATHER_ELSE:
-            if (else_st != NULL){
-                syntaxError(pm, syntax_error, 1, "get else after else\n");
+        case MATHER_ELSE: {
+            long int tmp_line = delToken(pm);
+            if (else_st != NULL) {
+                syntaxError(pm, syntax_error, tmp_line, 1, "get else after else");
                 goto error_;
             }
-            delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a if...else code"))
                 goto error_;
             goto again;
+        }
         case MATHER_FINALLY:
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a if...else code"))
@@ -302,7 +311,7 @@ void parserIf(PASERSSIGNATURE){
         }
     }
 
-    st = makeIfStatement();
+    st = makeIfStatement(line, pm->file);
     st->u.if_branch.if_list = sl;
     st->u.if_branch.else_list = else_st;
     st->u.if_branch.finally = finally_st;
@@ -335,7 +344,7 @@ void parserWhile(PASERSSIGNATURE){
     Statement *do_st = NULL;
     StatementList *sl = NULL;
     bool have_while = false;
-
+    long int line = 0;
     again:
     switch (readBackToken(pm)) {
         case MATHER_WHILE: {
@@ -345,7 +354,7 @@ void parserWhile(PASERSSIGNATURE){
                 have_while = true;
 
             Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
-            delToken(pm);
+            line = delToken(pm);
             if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, "Don't get a while condition"))
                 goto error_;
 
@@ -370,15 +379,16 @@ void parserWhile(PASERSSIGNATURE){
             if (!callParserCode(CALLPASERSSIGNATURE, &do_st, "Don't get a while...do code"))
                 goto error_;
             goto again;
-        case MATHER_ELSE:
+        case MATHER_ELSE: {
+            long int tmp_line = delToken(pm);
             if (else_st != NULL) {
-                syntaxError(pm, syntax_error, 1, "get else after else\n");
+                syntaxError(pm, syntax_error, tmp_line, 1, "get else after else\n");
                 goto error_;
             }
-            delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a while...else code"))
                 goto error_;
             goto again;
+        }
         case MATHER_FINALLY:
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a while...finally code"))
@@ -396,7 +406,7 @@ void parserWhile(PASERSSIGNATURE){
         }
     }
 
-    st = makeWhileStatement();
+    st = makeWhileStatement(line, pm->file);
     st->u.while_branch.while_list = sl;
     st->u.while_branch.else_list = else_st;
     st->u.while_branch.finally = finally_st;
@@ -430,25 +440,26 @@ void parserTry(PASERSSIGNATURE){
     Statement *else_st = NULL;
     Statement *finally_st = NULL;
     StatementList *sl = NULL;
-
+    long int line = 0;
     again:
     switch (readBackToken(pm)) {
         case MATHER_TRY:{
             if (try_st != NULL)
                 goto default_;
-            delToken(pm);
+            line = delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &try_st, "Don't get a try code"))
                 goto error_;
             goto again;
         }
         case MATHER_EXCEPT: {
+            Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
+            long int tmp_line = delToken(pm);
             if (else_st != NULL) {
-                syntaxError(pm, syntax_error, 1, "get except after else\n");
+                syntaxError(pm, syntax_error, tmp_line, 1, "get except after else");
                 goto error_;
             }
-            Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
-            delToken(pm);
-            callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, NULL);
+            if (readBackToken(pm) != MATHER_LC)
+                callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, NULL);
 
             if (!callParserAs(CALLPASERSSIGNATURE, &var_tmp, "Don't get a except var")){
                 freeStatement(condition_tmp);
@@ -462,15 +473,16 @@ void parserTry(PASERSSIGNATURE){
             sl = makeConnectStatementList(sl, condition_tmp, var_tmp, code_tmp, except_b);
             goto again;
         }
-        case MATHER_ELSE:
+        case MATHER_ELSE: {
+            long int tmp_line = delToken(pm);
             if (else_st != NULL) {
-                syntaxError(pm, syntax_error, 1, "get else after else\n");
+                syntaxError(pm, syntax_error, tmp_line, 1, "get else after else");
                 goto error_;
             }
-            delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a try...else code"))
                 goto error_;
             goto again;
+        }
         case MATHER_FINALLY:
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a try...finally code"))
@@ -488,7 +500,7 @@ void parserTry(PASERSSIGNATURE){
         }
     }
 
-    st = makeTryStatement();
+    st = makeTryStatement(line, pm->file);
     st->u.try_branch.try = try_st;
     st->u.try_branch.except_list = sl;
     st->u.try_branch.else_list = else_st;
@@ -517,29 +529,29 @@ void parserDef(PASERSSIGNATURE){
     Statement *name_tmp = NULL;
     Statement *code_tmp = NULL;
     Parameter *pt = NULL;
-    delToken(pm);
+    long int line = delToken(pm);
 
     if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &name_tmp,
                             "Don't get a function name"))
         goto error_;
 
     if (!checkToken_(pm, MATHER_LP)) {
-        syntaxError(pm, syntax_error, 1, "Don't get a function ( before parameter");
+        syntaxError(pm, syntax_error, line, 1, "Don't get a function ( before parameter");
         goto error_;
     }
     if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
-        syntaxError(pm, syntax_error, 1, "Don't get a function parameter");
+        syntaxError(pm, syntax_error, line, 1, "Don't get a function parameter");
         goto error_;
     }
     if (!checkToken_(pm, MATHER_RP)) {
-        syntaxError(pm, syntax_error, 1, "Don't get a function ) after parameter");
+        syntaxError(pm, syntax_error, line, 1, "Don't get a function ) after parameter");
         goto error_;
     }
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserDef: get function title success\n", NULL);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserDef: call parserCode\n", NULL);
 
     if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code")) {
-        syntaxError(pm, syntax_error, 1, "Don't get a function code");
+        syntaxError(pm, syntax_error, line, 1, "Don't get a function code");
         goto error_;
     }
 
@@ -564,10 +576,13 @@ void parserDef(PASERSSIGNATURE){
  * @param inter
  */
 void parserCode(PASERSSIGNATURE){
-    Statement *st = makeStatement();
+    Statement *st = makeStatement(0, NULL);  // TODO-szh 设置Line
+    long int line = 0;
     while (true){
-        if (!checkToken_(pm, MATHER_LC))
+        if (readBackToken(pm) == MATHER_LC){
+            line = delToken(pm);
             goto again_;
+        }
         break;
         again_:
         if (!checkToken_(pm, MATHER_ENTER))
@@ -580,7 +595,7 @@ void parserCode(PASERSSIGNATURE){
 
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList success\n", NULL);
     if (!checkToken_(pm, MATHER_RC)) {
-        syntaxError(pm, syntax_error, 1, "Don't get the }");
+        syntaxError(pm, syntax_error, line, 1, "Don't get the }");  // 使用{的行号
         goto error_;
     }
 
@@ -622,7 +637,7 @@ void parserOperation(PASERSSIGNATURE){
 bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_ASSIGNMENT:
-            *st = makeOperationStatement(ASS);
+            *st = makeOperationStatement(ASS, 0, pm->file);
             break;
         default:
             return false;
@@ -646,8 +661,11 @@ void parserTuple(PASERSSIGNATURE){
     Parameter *pt = NULL;
     Statement *st = NULL;
     Token *tmp = NULL;
-    if (readBackToken(pm) == MATHER_MUL)
+    long int line = 0;
+    if (readBackToken(pm) == MATHER_MUL) {
+        line = pm->tm->ts->token_list->line;
         goto parserPt;
+    }
 
     if (!callChildToken(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp, NULL, syntax_error))
         goto return_;
@@ -656,14 +674,15 @@ void parserTuple(PASERSSIGNATURE){
         addToken_(pm ,tmp);
         goto return_;
     }
+    line = tmp->line;
     addToken_(pm ,tmp);
 
     parserPt:
     if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, true, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
-        syntaxError(pm, syntax_error, 1, "Don't get tuple element");
+        syntaxError(pm, syntax_error, line, 1, "Don't get tuple element");
         goto return_;
     }
-    st = makeTupleStatement(pt, value_tuple);
+    st = makeTupleStatement(pt, value_tuple, pt->data.value->line, pm->file);
     addStatementToken(TUPLE, st, pm);
 
     return_:
@@ -680,10 +699,10 @@ void parserTuple(PASERSSIGNATURE){
 bool switchPolynomial(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_ADD:
-            *st = makeOperationStatement(ADD);
+            *st = makeOperationStatement(ADD, 0, pm->file);
             break;
         case MATHER_SUB:
-            *st = makeOperationStatement(SUB);
+            *st = makeOperationStatement(SUB, 0, pm->file);
             break;
         default:
             return false;
@@ -705,10 +724,10 @@ void parserPolynomial(PASERSSIGNATURE){
 bool switchFactor(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_MUL:
-            *st = makeOperationStatement(MUL);
+            *st = makeOperationStatement(MUL, 0, pm->file);
             break;
         case MATHER_DIV:
-            *st = makeOperationStatement(DIV);
+            *st = makeOperationStatement(DIV, 0, pm->file);
             break;
         default:
             return false;
@@ -730,18 +749,18 @@ int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
     Parameter *pt = NULL;
     if (readBackToken(pm) != MATHER_LP)
         return -1;
-    delToken(pm);
+    long int line = delToken(pm);
 
     if (checkToken_(pm, MATHER_RP))
         goto not_pt;
 
     if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
-        syntaxError(pm, syntax_error, 1, "Don't get call parameter");
+        syntaxError(pm, syntax_error, line, 1, "Don't get call parameter");
         return 0;
     }
     if (!checkToken_(pm, MATHER_RP)){
         freeParameter(pt, true);
-        syntaxError(pm, syntax_error, 1, "Don't get ) from call back");
+        syntaxError(pm, syntax_error, line, 1, "Don't get ) from call back");
         return 0;
     }
 
@@ -783,23 +802,23 @@ void parserBaseValue(PASERSSIGNATURE){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get number [%s]\n", value_token->data.str);
         char *stop;
         Value *tmp_value = makeNumberValue(strtol(value_token->data.str, &stop, 10), inter);
-        st = makeBaseValueStatement(makeLinkValue(tmp_value, NULL, inter));
+        st = makeBaseValueStatement(makeLinkValue(tmp_value, NULL, inter), value_token->line, pm->file);
     }
     else if (MATHER_STRING == value_token->token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get string [%s]\n", value_token->data.str);
         Value *tmp_value = makeStringValue(value_token->data.str, inter);
-        st = makeBaseValueStatement(makeLinkValue(tmp_value, NULL, inter));
+        st = makeBaseValueStatement(makeLinkValue(tmp_value, NULL, inter), value_token->line, pm->file);
     }
     else if (MATHER_VAR == value_token->token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get var [%s]\n", value_token->data.str);
-        st = makeBaseVarStatement(value_token->data.str, NULL);
+        st = makeBaseVarStatement(value_token->data.str, NULL, value_token->line, pm->file);
     }
     else if (MATHER_SVAR == value_token->token_type){
         Statement *svar_st = NULL;
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get super var\n", NULL);
         if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &svar_st, NULL)){
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get super var after $");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get super var after $");
             goto return_;
         }
         st = makeBaseSVarStatement(svar_st, NULL);
@@ -812,12 +831,12 @@ void parserBaseValue(PASERSSIGNATURE){
         tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RB, &tmp_st, "base value");
         if (tmp == 0){
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get operation from Base Value");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get operation from Base Value");
             goto return_;
         }
         else if(tmp == -1){
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get ] from list/var");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get ] from list/var");
             goto return_;
         }
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation success\n", NULL);
@@ -825,18 +844,18 @@ void parserBaseValue(PASERSSIGNATURE){
         if (MATHER_VAR == readBackToken(pm)){
             Token *var_token;
             var_token = popAheadToken(pm);
-            st = makeBaseVarStatement(var_token->data.str, tmp_st);
+            st = makeBaseVarStatement(var_token->data.str, tmp_st, var_token->line, pm->file);
             freeToken(var_token, true, false);
         }
         else{
             if (tmp_st == NULL)
-                st = makeTupleStatement(NULL, value_list);
+                st = makeTupleStatement(NULL, value_list, value_token->line, pm->file);
             else if (tmp_st->type == base_list && tmp_st->u.base_list.type == value_tuple){
                 tmp_st->u.base_list.type = value_list;
                 st = tmp_st;
             }
             else
-                st = makeTupleStatement(makeValueParameter(tmp_st), value_list);
+                st = makeTupleStatement(makeValueParameter(tmp_st), value_list, value_token->token_type, pm->file);
         }
     }
     else if (MATHER_LP == value_token->token_type){
@@ -844,12 +863,12 @@ void parserBaseValue(PASERSSIGNATURE){
         int tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RP, &st, "base value");
         if (tmp == 0){
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get operation from Base Value");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get operation from Base Value");
             goto return_;
         }
         else if(tmp == -1){
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get ) from Base Value");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get ) from Base Value");
             goto return_;
         }
     }
@@ -858,16 +877,16 @@ void parserBaseValue(PASERSSIGNATURE){
         Parameter *pt = NULL;
         if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, true, MATHER_COMMA, MATHER_COLON)) {
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get a dict parameter");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a dict parameter");
             goto return_;
         }
         if (!checkToken_(pm, MATHER_RC)) {
             freeToken(value_token, true, true);
             freeParameter(pt, true);
-            syntaxError(pm, syntax_error, 1, "Don't get a } after dict");
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a } after dict");
             goto return_;
         }
-        st = makeBaseDictStatement(pt);
+        st = makeBaseDictStatement(pt, value_token->line, pm->file);
     }
     else{
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: else\n", NULL);

+ 4 - 4
parser/include/__grammar.h

@@ -21,15 +21,15 @@ writeLog(pm->paser_debug, pasers_level, "\n"message, __VA_ARGS__); \
 #endif
 
 #define addStatementToken(type, st, pm) addBackToken(pm->tm->ts, makeStatementToken(type, st), pm->paser_debug)
-#define delToken(pm) freeToken(popAheadToken(pm), true, false)
+#define delToken(pm) (freeToken(popAheadToken(pm), true, false))
 #define backToken_(pm, token) addBackToken(pm->tm->ts, (token), pm->paser_debug)
-#define addLexToken(pm, type) backToken_(pm, makeLexToken(type, NULL, NULL))
+#define addLexToken(pm, type) backToken_(pm, makeLexToken(type, NULL, NULL, 0))
 #define addToken_ backToken_
 #define call_success(pm) (pm->status == success)
 
 typedef void (*PasersFunction)(PASERSSIGNATURE);
 typedef int (*GetSymbolFunction)(PASERSSIGNATURE, int, Statement **);
-typedef Statement *(*MakeControlFunction)(Statement *);
+typedef Statement *(*MakeControlFunction)(Statement *, long int, char *);
 typedef int (*TailFunction)(PASERSSIGNATURE, Token *, Statement **);
 
 void parserCommand(PASERSSIGNATURE);
@@ -48,7 +48,7 @@ void parserFactor(PASERSSIGNATURE);
 void parserAssignment(PASERSSIGNATURE);
 void parserTuple(PASERSSIGNATURE);
 
-void syntaxError(ParserMessage *pm, int status, int num, ...);
+void syntaxError(ParserMessage *pm, int status,long int line , int num, ...);
 
 int readBackToken(ParserMessage *pm);
 Token *popAheadToken(ParserMessage *pm);

+ 6 - 3
parser/lexical.c

@@ -7,11 +7,13 @@
  * @return 返回一个字符,若为EOF则返回-1
  */
 signed char readChar(LexFile *file){
-    if (file->back.is_back){
+    if (file->back.is_back)
         file->back.is_back = false;
+    else {
+        file->back.p = (char) fgetc(file->file);
+        if (file->back.p == '\n')
+            file->line ++;
     }
-    else
-        file->back.p = (char)fgetc(file->file);
     return file->back.p;
 }
 
@@ -29,6 +31,7 @@ LexFile *makeLexFile(char *dir){
     tmp->back.is_back = false;
     tmp->back.p = EOF;
     tmp->count = 0;
+    tmp->line = 1;
     return tmp;
 }
 

+ 3 - 3
parser/syntax.c

@@ -295,7 +295,7 @@ int getMatherStatus(LexFile *file, LexMathers *mathers, FILE *debug) {
  * @return
  */
 Token *getToken(LexFile *file, LexMathers *mathers, FILE *debug) {
-    writeLog_(debug, DEBUG, "get token: [%d]\n", file->count);
+    writeLog_(debug, DEBUG, "get token: [%ld]\n", file->count);
     int status = MATHER_SPACE;
     while (status == MATHER_SPACE){
         status = getMatherStatus(file, mathers, debug);
@@ -303,10 +303,10 @@ Token *getToken(LexFile *file, LexMathers *mathers, FILE *debug) {
     Token *tmp;
     if (status == -2){
         writeLog_(debug, ERROR, "lexical ERROR\n", NULL);
-        tmp = makeLexToken(MATHER_ERROR_, NULL, NULL);
+        tmp = makeLexToken(MATHER_ERROR_, NULL, NULL, file->line);
         goto return_;
     }
-    tmp = makeLexToken(status, mathers->mathers[status]->str, mathers->mathers[status]->second_str);
+    tmp = makeLexToken(status, mathers->mathers[status]->str, mathers->mathers[status]->second_str, file->line);
     printTokenEnter(tmp, debug, DEBUG, "new token: ");
     writeLog_(debug, DEBUG, "\n", NULL);
     return_:

+ 11 - 8
parser/token.c

@@ -1,18 +1,19 @@
 #include "__token.h"
 
-Token *makeToken(){
+Token *makeToken(long int line) {
     Token *tmp = memCalloc(1, sizeof(Token));
     tmp->token_type = 0;
     tmp->data.str = NULL;
     tmp->data.st = NULL;
     tmp->data.second_str = NULL;
+    tmp->line = line;
     tmp->next = NULL;
     tmp->last = NULL;
     return tmp;
 }
 
-Token *makeLexToken(int type, char *str, char *second_str) {
-    Token *tmp = makeToken();
+Token *makeLexToken(int type, char *str, char *second_str, long int line) {
+    Token *tmp = makeToken(line);
     tmp->token_type = type;
     tmp->data.str = memStrcpy(str, 0, false, false);
     tmp->data.second_str = memStrcpy(second_str, 0, false, false);
@@ -20,14 +21,16 @@ Token *makeLexToken(int type, char *str, char *second_str) {
 }
 
 Token *makeStatementToken(int type, struct Statement *st){
-    Token *tmp = makeToken();
+    Token *tmp = makeToken(st->line);
     tmp->token_type = type;
     tmp->data.st = st;
     return tmp;
 }
 
-void freeToken(Token *tk, bool self, bool error) {
+long freeToken(Token *tk, bool self, bool error) {
+    long int line = 0;
     freeBase(tk, return_);
+    line = tk->line;
     memFree(tk->data.str);
     memFree(tk->data.second_str);
     if (error){
@@ -37,7 +40,7 @@ void freeToken(Token *tk, bool self, bool error) {
         memFree(tk);
     }
     return_:
-    return;
+    return line;
 }
 
 TokenStream *makeTokenStream(){
@@ -69,7 +72,7 @@ TokenMessage *makeTokenMessage(char *file_dir, char *debug) {
     tm->ts = makeTokenStream();
 #if OUT_LOG
     if (debug != NULL){
-        char *debug_dir = memStrcat(debug, LEXICAL_LOG);
+        char *debug_dir = memStrcat(debug, LEXICAL_LOG, false);
         if (access(debug_dir, F_OK) != 0 || access(debug_dir, W_OK) == 0)
             tm->debug = fopen(debug_dir, "w");
         memFree(debug_dir);
@@ -141,7 +144,7 @@ Token *popNewToken(TokenMessage *tm, FILE *debug) {
     else{
         tmp = popToken(tm->ts, debug);
     }
-    writeLog_(debug, DEBUG, "get token: %d\nnew token: ", tm->file->count);
+    writeLog_(debug, DEBUG, "get token: %ld\nnew token: ", tm->file->count);
     printToken(tmp, debug, DEBUG);
     writeLog_(debug, DEBUG, "\n", NULL);
     return tmp;

+ 2 - 2
src/__run.c

@@ -57,7 +57,7 @@ Result getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
 }
 
 char *setStrVarName(char *old, bool free_old, INTER_FUNCTIONSIG_CORE) {
-    char *name = memStrcat(inter->data.var_str_prefix, old);
+    char *name = memStrcat(inter->data.var_str_prefix, old, false);
     if (free_old)
         memFree(old);
     return name;
@@ -66,7 +66,7 @@ char *setStrVarName(char *old, bool free_old, INTER_FUNCTIONSIG_CORE) {
 char *setNumVarName(NUMBER_TYPE num, INTER_FUNCTIONSIG_CORE) {
     char name[50];
     snprintf(name, 50, "%"NUMBER_FORMAT, num);
-    return memStrcat(inter->data.var_num_prefix, name);
+    return memStrcat(inter->data.var_num_prefix, name, false);
 }
 
 char *getNameFromValue(Value *value, INTER_FUNCTIONSIG_CORE) {

+ 0 - 1
src/include/__run.h

@@ -1,6 +1,5 @@
 #ifndef VIRTUALMATH___RUN_H
 #define VIRTUALMATH___RUN_H
-
 #include "__virtualmath.h"
 
 #if OUT_INTER_LOG && OUT_INTER_LOG

+ 23 - 13
src/inter.c

@@ -33,10 +33,8 @@ Inter *newInter(char *code_file, char *debug_dir, Result *global_result, int *st
     global_inter->statement = tmp;
 
     *global_result = globalIterStatement(global_inter);
-    if (global_result->type == error_return){
-        writeLog(global_inter->data.debug, ERROR, "Run Error\n", NULL);
-        writeLog(stderr, ERROR, "Run Error\n", NULL);
-    }
+    if (global_result->type == error_return)
+        printError(global_result->error, global_inter, true);
 
     return_:
     freeParserMessage(pm, true);
@@ -48,26 +46,30 @@ Inter *makeInter(char *debug){
     setBaseInterData(tmp);
     tmp->base = NULL;
     tmp->link_base = NULL;
-    tmp->statement = makeStatement();
+    tmp->statement = makeStatement(0, NULL);  // TODO-szh 设置文件
     tmp->var_list = makeVarList(tmp);
     tmp->data.log_dir = memStrcpy(debug, 0, false, false);
 
     if (debug != NULL && !args.stdout_inter){
-        char *debug_dir = memStrcat(debug, INTER_LOG);
+        char *debug_dir = memStrcat(debug, INTER_LOG, false), *error_dir = memStrcat(debug, INTER_ERROR, false);
         tmp->data.debug = fopen(debug_dir, "w");
+        tmp->data.error = fopen(error_dir, "w");
         memFree(debug_dir);
+        memFree(error_dir);
     }
-    else
+    else {
         tmp->data.debug = stdout;
+        tmp->data.error = stderr;
+    }
 
     makeValue(tmp);  // 注册None值
     return tmp;
 }
 
 void setBaseInterData(struct Inter *inter){
-    inter->data.var_str_prefix = "str_";
-    inter->data.var_num_prefix = "num_";
-    inter->data.var_defualt = "default_var";
+    inter->data.var_str_prefix = memStrcpy("str_", 0, false, false);
+    inter->data.var_num_prefix = memStrcpy("num_", 0, false, false);
+    inter->data.var_defualt = memStrcpy("default_var", 0, false, false);
     inter->data.debug = NULL;
     inter->data.log_dir = NULL;
 }
@@ -85,12 +87,20 @@ void freeInter(Inter *inter, bool self){
 
     freeStatement(inter->statement);
     freeVarList(inter->var_list, true);
+
+    memFree(inter->data.var_defualt);
+    memFree(inter->data.var_num_prefix);
+    memFree(inter->data.var_str_prefix);
+
     memFree(inter->data.log_dir);
-    if (inter->data.log_dir != NULL)
+
+    if (inter->data.log_dir != NULL) {
         fclose(inter->data.debug);
-    if (self){
-        memFree(inter);
+        fclose(inter->data.error);
     }
+
+    if (self)
+        memFree(inter);
     return_:
     return;
 }

+ 8 - 7
src/operation.c

@@ -51,7 +51,7 @@ Result operationStatement(INTER_FUNCTIONSIG) {
             result = assOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
         default:
-            setResult(&result, true, inter);
+            setResult(&result, inter);
             break;
     }
     return result;
@@ -68,7 +68,7 @@ Result addOperation(INTER_FUNCTIONSIG) {
         valueToResult(result, (operationValue(left, right, num.num, +)), Number, inter);
     }
     else if(viewtype(left, right, string)){
-        char *new_string = memStrcat(left.value->value->data.str.str, right.value->value->data.str.str);
+        char *new_string = memStrcat(left.value->value->data.str.str, right.value->value->data.str.str, false);
         valueToResult(result, new_string, String, inter);
         memFree(new_string);
     }
@@ -147,7 +147,7 @@ Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
     int int_times;
     if (name->type == base_list && name->u.base_list.type == value_tuple){
         Result tmp_result;
-        Statement *tmp_st = makeStatement();
+        Statement *tmp_st = makeStatement(name->line, name->code_file);
         tmp_st->type = base_value;
         tmp_st->u.base_value.value = value;
         Parameter *pt = makeArgsParameter(tmp_st);
@@ -157,7 +157,7 @@ Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
             freeParameter(pt, true);
             return tmp_result;
         }
-        tmp_result = setParameterCore(call, name->u.base_list.list, var_list, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        tmp_result = setParameterCore(call, name->u.base_list.list, var_list, name, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (!run_continue(tmp_result))
             result = tmp_result;
         else{
@@ -197,15 +197,16 @@ Result getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
     result.value = findFromVarList(name, var_list, int_times, false);
     memFree(name);
     if (result.value == NULL){
-        writeLog_(inter->data.debug, WARNING, "var not found[%s]\n", st->u.base_var.name);
-        setResultError(&result, inter);
+        char *info = memStrcat("Name Not Found: ", st->u.base_var.name, false);
+        setResultError(&result, inter, "NameException", info, st, true);
+        memFree(info);
     }
     return result;
 }
 
 Result getBaseValue(INTER_FUNCTIONSIG) {
     Result result;
-    setResult(&result, true, inter);
+    setResult(&result, inter);
     result.value = st->u.base_value.value;
     result.type = operation_return;
     return result;

+ 42 - 46
src/parameter.c

@@ -207,22 +207,21 @@ Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list
     Result result;
     *num = 0;
     while (function != NULL && function->type == name_par){
-        Result tmp, tmp_ass;
-        if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list))) {
-            *function_ad = function;
-            return tmp;
-        }
+        LinkValue *value = NULL;
+        if(operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(function->data.value, var_list)))
+            goto return_;
+
+        value = result.value;
+        result = assCore(function->data.name, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        if (!run_continue(result))
+            goto return_;
 
-        tmp_ass = assCore(function->data.name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-        if (!run_continue(tmp_ass)) {
-            *function_ad = function;
-            return tmp_ass;
-        }
         (*num)++;
         function = function->next;
     }
-    setResult(&result, true, inter);
+    setResult(&result, inter);
 
+    return_:
     *function_ad = function;
     return result;
 }
@@ -240,23 +239,21 @@ Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *va
     Result result;
     *num = 0;
     while (call != NULL && call->type == name_arg){
-        Result tmp_ass;
         if (call->name_type == name_char){
             addFromVarList(call->data.name_, var_list, 0, call->data.value, call->data.name_value);
             goto next;
         }
-        tmp_ass = assCore(call->data.name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-        if (!run_continue(tmp_ass)) {
-            *call_ad = call;
-            return tmp_ass;
-        }
+        result = assCore(call->data.name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        if (!run_continue(result))
+            goto return_;
 
         next:
         (*num)++;
         call = call->next;
     }
-    setResult(&result, true, inter);
 
+    setResult(&result, inter);
+    return_:
     *call_ad = call;
     return result;
 }
@@ -272,9 +269,8 @@ Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *va
  */
 Result parameterFromVar(Parameter **function_ad, VarList *function_var, struct Inter *inter, struct VarList *var_list,
                         NUMBER_TYPE *num, NUMBER_TYPE max, bool *status) {
-    Parameter *function = *function_ad;
     Result result;
-    setResultOperation(&result, inter);
+    Parameter *function = *function_ad;
     bool get;
     *num = 0;
     *status = false;
@@ -308,7 +304,7 @@ Result parameterFromVar(Parameter **function_ad, VarList *function_var, struct I
                 value = tmp.value;
                 goto not_return;
             }
-            setResultError(&tmp, inter);
+            setResultError(&tmp, inter, "ArgumentException", "Too less Argument", name, true);
             *function_ad = function;
             return tmp;
         }
@@ -323,8 +319,8 @@ Result parameterFromVar(Parameter **function_ad, VarList *function_var, struct I
             (*num)++;
         function = function->next;
     }
-    setResult(&result, true, inter);
 
+    setResult(&result, inter);
     *function_ad = function;
     return result;
 }
@@ -342,20 +338,19 @@ Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList
     Argument *call = *call_ad;
     Parameter *function = *function_ad;
     Result result;
+
     while (call != NULL && function != NULL && (call->type == value_arg) && function->type != args_par){
-        Result tmp_ass;
         Statement *name = function->type == value_par ? function->data.value : function->data.name;
-        tmp_ass = assCore(name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
-        if (!run_continue(tmp_ass)) {
-            *call_ad = call;
-            *function_ad = function;
-            return tmp_ass;
-        }
+        result = assCore(name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
+        if (!run_continue(result))
+            goto return_;
 
         call = call->next;
         function = function->next;
     }
-    setResult(&result, true, inter);
+
+    setResult(&result, inter);
+    return_:
     *call_ad = call;
     *function_ad = function;
     return result;
@@ -372,27 +367,26 @@ Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE
     Result result;
     Argument *base = *base_ad;
     while (call != NULL){
-        Result tmp;
-        if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(call->data.value, var_list))) {
-            *base_ad = base;
-            return tmp;
-        }
+        if(operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(call->data.value, var_list)))
+            goto return_;
 
         if (call->type == value_par)
-            base = connectValueArgument(tmp.value, base);
+            base = connectValueArgument(result.value, base);
         else if (call->type == name_par)
-            base = connectStatementNameArgument(tmp.value, call->data.name, base);
+            base = connectStatementNameArgument(result.value, call->data.name, base);
         else if (call->type == args_par){
-            Argument *tmp_at = listToArgument(tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            Argument *tmp_at = listToArgument(result.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
             base = connectArgument(tmp_at, base);
         }
         else if (call->type == kwargs_par){
-            Argument *tmp_at = dictToArgument(tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            Argument *tmp_at = dictToArgument(result.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
             base = connectArgument(tmp_at, base);
         }
         call = call->next;
     }
-    setResult(&result, true, inter);
+    setResult(&result, inter);
+
+    return_:
     *base_ad = base;
     return result;
 }
@@ -419,7 +413,8 @@ Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE){
  * @param var_list
  * @return
  */
-Result setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_CORE) {
+Result setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, Statement *base,
+                    struct Inter *inter, struct VarList *var_list) {
     Result result;
     Argument *call;
     call = getArgument(call_base, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
@@ -427,12 +422,13 @@ Result setParameter(Parameter *call_base, Parameter *function_base, VarList *fun
         freeArgument(call, false);
         return result;
     }
-    result = setParameterCore(call, function_base, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    result = setParameterCore(call, function_base, function_var, base, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     freeArgument(call, false);
     return result;
 }
 
-Result setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_CORE){
+Result setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, Statement *base,
+                        struct Inter *inter, struct VarList *var_list) {
     Result result;
     Parameter *function = copyParameter(function_base), *tmp_function = function;  // 释放使用
     enum {
@@ -511,16 +507,16 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
                 break;
             }
             case error:
-            error_:
+            error_:  // Statement 处理
                 writeLog(inter->data.debug, ERROR, "setParameter error\n", NULL);
-                setResultError(&result, inter);
+                setResultError(&result, inter, "ArgumentException", "Set Argument error", 0, true);
                 goto return_;
             default:
                 goto break_;
         }
     }
     break_:
-    setResult(&result, true ,inter);
+    setResult(&result, inter);
 
     return_:
     freeParameter(tmp_function, true);

+ 7 - 7
src/run.c

@@ -27,7 +27,8 @@ Result runStatement(INTER_FUNCTIONSIG) {
             break;
         case operation:
             result = operationStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
-            printLinkValue(result.value, "operation result = ", "\n", inter->data.debug);
+            if (run_continue(result))
+                printLinkValue(result.value, "operation result = ", "\n", inter->data.debug);
             break;
         case set_function:
             result = setFunction(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -66,7 +67,7 @@ Result runStatement(INTER_FUNCTIONSIG) {
             result = includeFile(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
         default:
-            setResult(&result, true, inter);
+            setResult(&result, inter);
             break;
     }
     return result;
@@ -82,7 +83,7 @@ Result runStatement(INTER_FUNCTIONSIG) {
 Result iterStatement(INTER_FUNCTIONSIG) {
     Result result;
     if (st == NULL){
-        setResult(&result, true, inter);
+        setResult(&result, inter);
         return result;
     }
     Statement *base_st = NULL;
@@ -92,7 +93,7 @@ Result iterStatement(INTER_FUNCTIONSIG) {
         while (base_st != NULL) {
             result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
             if (!run_continue(result))
-                break;
+                goto return_;
             base_st = base_st->next;
         }
 
@@ -102,7 +103,7 @@ Result iterStatement(INTER_FUNCTIONSIG) {
 
     if (result.type == not_return)
         setResultOperation(&result, inter);
-    return result;
+    return_: return result;
 }
 
 /**
@@ -183,9 +184,8 @@ bool tryBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 
 bool functionSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
-    if (result->type == error_return){
+    if (result->type == error_return)
         return true;
-    }
     else if (result->type == function_return){
         result->type = operation_return;
         return true;

+ 18 - 11
src/runbranch.c

@@ -66,13 +66,15 @@ Result ifBranch(INTER_FUNCTIONSIG) {
     not_else:
 
     if (st->u.if_branch.finally != NULL && ifBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.if_branch.finally, var_list))){
+        if (!set_result)
+            freeError(result.error);
         set_result = false;
         result = finally_tmp;
     }
 
     var_list = popVarList(var_list);
     if (set_result)
-        setResult(&result, true, inter);
+        setResult(&result, inter);
     return result;
 }
 
@@ -129,13 +131,15 @@ Result whileBranch(INTER_FUNCTIONSIG) {
     not_else:
 
     if (st->u.while_branch.finally != NULL && cycleBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.finally, var_list))){
+        if (!set_result)
+            freeError(result.error);
         set_result = false;
         result = finally_tmp;
     }
 
     var_list = popVarList(var_list);
     if (set_result)
-        setResult(&result, true, inter);
+        setResult(&result, inter);
     return result;
 }
 
@@ -149,9 +153,8 @@ Result tryBranch(INTER_FUNCTIONSIG) {
     bool set_result = true;
 
     var_list = pushVarList(var_list, inter);
-    if (!tryBranchSafeInterStatement(&try_result, CALL_INTER_FUNCTIONSIG(st->u.try_branch.try, var_list))){
+    if (!tryBranchSafeInterStatement(&try_result, CALL_INTER_FUNCTIONSIG(st->u.try_branch.try, var_list)))
         goto not_except;
-    }
     if (except_list == NULL) {
         result = try_result;
         set_result = false;
@@ -159,6 +162,8 @@ Result tryBranch(INTER_FUNCTIONSIG) {
     }
     if (except_list->var != NULL)
         assCore(except_list->var, try_result.value, inter, var_list);
+    freeError(try_result.error);
+
     if (tryBranchSafeInterStatement(&except_result, CALL_INTER_FUNCTIONSIG(except_list->code, var_list))){
         result = except_result;
         set_result = false;
@@ -173,13 +178,15 @@ Result tryBranch(INTER_FUNCTIONSIG) {
 
     not_else:
     if (st->u.try_branch.finally != NULL && tryBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.try_branch.finally, var_list))){
+        if (!set_result)
+            freeError(result.error);
         set_result = false;
         result = finally_tmp;
     }
 
     var_list = popVarList(var_list);
     if (set_result)
-        setResult(&result, true, inter);
+        setResult(&result, inter);
     return result;
 }
 
@@ -194,7 +201,7 @@ Result breakCycle(INTER_FUNCTIONSIG){
     // TODO-szh 类型检查处理
     times_int = (int)times.value->value->data.num.num;
     not_times:
-    setResult(&result, true, inter);
+    setResult(&result, inter);
     if (times_int >= 0) {
         result.type = break_return;
         result.times = times_int;
@@ -212,7 +219,7 @@ Result continueCycle(INTER_FUNCTIONSIG){
         return times;
     times_int = (int)times.value->value->data.num.num;
     not_times:
-    setResult(&result, true, inter);
+    setResult(&result, inter);
     if (times_int >= 0) {
         result.type = continue_return;
         result.times = times_int;
@@ -230,7 +237,7 @@ Result regoIf(INTER_FUNCTIONSIG){
         return times;
     times_int = (int)times.value->value->data.num.num;
     not_times:
-    setResult(&result, true, inter);
+    setResult(&result, inter);
     if (times_int >= 0) {
         result.type = rego_return;
         result.times = times_int;
@@ -248,7 +255,7 @@ Result restartCode(INTER_FUNCTIONSIG){
         return times;
     times_int = (int)times.value->value->data.num.num;
     not_times:
-    setResult(&result, true, inter);
+    setResult(&result, inter);
     if (times_int >= 0) {
         result.type = restart_return;
         result.times = times_int;
@@ -259,7 +266,7 @@ Result restartCode(INTER_FUNCTIONSIG){
 Result returnCode(INTER_FUNCTIONSIG){
     Result result;
     if (st->u.return_code.value == NULL) {
-        setResult(&result, true, inter);
+        setResult(&result, inter);
         goto set_result;
     }
     if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st->u.return_code.value, var_list)))
@@ -273,7 +280,7 @@ Result returnCode(INTER_FUNCTIONSIG){
 Result raiseCode(INTER_FUNCTIONSIG){
     Result result;
     if (st->u.raise_code.value == NULL) {
-        setResult(&result, true, inter);
+        setResult(&result, inter);
         goto set_result;
     }
     if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st->u.raise_code.value, var_list)))

+ 4 - 3
src/runcall.c

@@ -18,19 +18,20 @@ Result callFunction(INTER_FUNCTIONSIG) {
         return call_function;
 
     if (call_function.value->value->type != function){
-        writeLog_(inter->data.debug, WARNING, "call not function[%d]\n", call_function.type);
-        setResultError(&result, inter);
+        setResultError(&result, inter, "TypeException", "Object is not callable", st, true);
         result.type = error_return;
         goto return_;
     }
     VarList *function_var = call_function.value->value->data.function.var;
     Result set_tmp;
-    set_tmp = setParameter(st->u.call_function.parameter, call_function.value->value->data.function.pt, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    set_tmp = setParameter(st->u.call_function.parameter, call_function.value->value->data.function.pt, function_var,
+                           st, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (set_tmp.type == error_return)
         return set_tmp;
     function_var = pushVarList(function_var, inter);
     functionSafeInterStatement(&result,
                                CALL_INTER_FUNCTIONSIG(call_function.value->value->data.function.function, function_var));
+    setResultError(&result, inter, NULL, NULL, st, false);
     popVarList(function_var);
 
     return_:

+ 6 - 5
src/runfile.c

@@ -5,7 +5,7 @@ Result includeFile(INTER_FUNCTIONSIG) {
     Result file;
     char *file_dir = NULL;
     ParserMessage *pm = NULL;
-    Statement *new_st = makeStatement();
+    Statement *new_st = NULL;
 
     if (operationSafeInterStatement(&file, CALL_INTER_FUNCTIONSIG(st->u.include_file.file, var_list)))
         return file;
@@ -13,20 +13,21 @@ Result includeFile(INTER_FUNCTIONSIG) {
     // TODO-szh 类型检查
     file_dir = file.value->value->data.str.str;
     if (access(file_dir, R_OK) != 0){
-        setResultError(&result, inter);
+        setResultError(&result, inter, "IncludeException", "File is not readable", st, true);
         printf("tag 1\n");
         goto return_;
     }
-
+    new_st = makeStatement(0, file_dir);
     pm = makeParserMessage(file_dir, NULL);
     parserCommandList(pm, inter, true, new_st);
     if (pm->status != success){
-        writeLog(pm->paser_debug, ERROR, "Syntax Error: %s\n", pm->status_message);
-        setResultError(&result, inter);
+        setResultError(&result, inter, "IncludeException", pm->status_message, st, true);
         goto return_;
     }
 
     functionSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(new_st, var_list));
+    if (!run_continue(result))
+        setResultError(&result, inter, NULL, NULL, st, false);
 
     return_:
     freeStatement(new_st);

+ 40 - 36
src/statement.c

@@ -1,9 +1,11 @@
 #include "__virtualmath.h"
 
-Statement *makeStatement(){
+Statement *makeStatement(long int line, char *file) {
     Statement *tmp = memCalloc(1, sizeof(Statement));
     tmp->type = start;
     tmp->next = NULL;
+    tmp->line = line;
+    tmp->code_file = memStrcpy(file, 0, false, false);
     return tmp;
 }
 
@@ -22,9 +24,10 @@ Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token
         st->u.operation.left = left_st;
         st->u.operation.right = right->data.st;
     }
-    new_token = makeToken();
+    new_token = makeToken(0);
     new_token->token_type = type;
     new_token->data.st = st;
+    st->line = left->line;
 
     freeToken(left, true, false);
     freeToken(right, true, false);
@@ -32,15 +35,15 @@ Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token
     return new_token;
 }
 
-Statement *makeBaseValueStatement(LinkValue *value){
-    Statement *tmp = makeStatement();
+Statement *makeBaseValueStatement(LinkValue *value, long int line, char *file) { 
+    Statement *tmp = makeStatement(line, file);
     tmp->type = base_value;
     tmp->u.base_value.value = value;
     return tmp;
 }
 
-Statement *makeBaseVarStatement(char *name, Statement *times){
-    Statement *tmp = makeStatement();
+Statement *makeBaseVarStatement(char *name, Statement *times, long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = base_var;
     tmp->u.base_var.name = memStrcpy(name, 0, false, false);
     tmp->u.base_var.times = times;
@@ -48,22 +51,22 @@ Statement *makeBaseVarStatement(char *name, Statement *times){
 }
 
 Statement *makeBaseSVarStatement(Statement *name, Statement *times){
-    Statement *tmp = makeStatement();
+    Statement *tmp = makeStatement(name->line, name->code_file);
     tmp->type = base_svar;
     tmp->u.base_svar.name = name;
     tmp->u.base_svar.times = times;
     return tmp;
 }
 
-Statement *makeBaseDictStatement(Parameter *pt){
-    Statement *tmp = makeStatement();
+Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = base_dict;
     tmp->u.base_dict.dict = pt;
     return tmp;
 }
 
-Statement *makeOperationStatement(int type){
-    Statement *tmp = makeStatement();
+Statement *makeOperationStatement(int type, long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = operation;
     tmp->u.operation.OperationType = type;
     tmp->u.operation.left = NULL;
@@ -71,8 +74,8 @@ Statement *makeOperationStatement(int type){
     return tmp;
 }
 
-Statement *makeTupleStatement(Parameter *pt, enum ListType type) {
-    Statement *tmp = makeStatement();
+Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = base_list;
     tmp->u.base_list.type = type;
     tmp->u.base_list.list = pt;
@@ -80,7 +83,7 @@ Statement *makeTupleStatement(Parameter *pt, enum ListType type) {
 }
 
 Statement *makeFunctionStatement(Statement *name, Statement *function, Parameter *pt) {
-    Statement *tmp = makeStatement();
+    Statement *tmp = makeStatement(name->line, name->code_file);
     tmp->type = set_function;
     tmp->u.set_function.name = name;
     tmp->u.set_function.function = function;
@@ -89,15 +92,15 @@ Statement *makeFunctionStatement(Statement *name, Statement *function, Parameter
 }
 
 Statement *makeCallStatement(Statement *function, Parameter *pt) {
-    Statement *tmp = makeStatement();
+    Statement *tmp = makeStatement(function->line, function->code_file);
     tmp->type = call_function;
     tmp->u.call_function.function = function;
     tmp->u.call_function.parameter = pt;
     return tmp;
 }
 
-Statement *makeIfStatement(){
-    Statement *tmp = makeStatement();
+Statement *makeIfStatement(long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = if_branch;
     tmp->u.if_branch.if_list = NULL;
     tmp->u.if_branch.else_list = NULL;
@@ -105,8 +108,8 @@ Statement *makeIfStatement(){
     return tmp;
 }
 
-Statement *makeWhileStatement(){
-    Statement *tmp = makeStatement();
+Statement *makeWhileStatement(long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = while_branch;
     tmp->u.while_branch.type = while_;
     tmp->u.while_branch.while_list = NULL;
@@ -117,8 +120,8 @@ Statement *makeWhileStatement(){
     return tmp;
 }
 
-Statement *makeTryStatement(){
-    Statement *tmp = makeStatement();
+Statement *makeTryStatement(long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
     tmp->type = try_branch;
     tmp->u.try_branch.except_list = NULL;
     tmp->u.try_branch.else_list = NULL;
@@ -127,50 +130,50 @@ Statement *makeTryStatement(){
     return tmp;
 }
 
-Statement *makeBreakStatement(Statement *times){
-    Statement *tmp = makeStatement();
+Statement *makeBreakStatement(Statement *times, long int line, char *file){
+    Statement *tmp = makeStatement(line, file);
     tmp->type = break_cycle;
     tmp->u.break_cycle.times = times;
     return tmp;
 }
 
-Statement *makeContinueStatement(Statement *times){
-    Statement *tmp = makeStatement();
+Statement *makeContinueStatement(Statement *times, long int line, char *file){
+    Statement *tmp = makeStatement(line, file);
     tmp->type = continue_cycle;
     tmp->u.continue_cycle.times = times;
     return tmp;
 }
 
-Statement *makeRegoStatement(Statement *times){
-    Statement *tmp = makeStatement();
+Statement *makeRegoStatement(Statement *times, long int line, char *file){
+    Statement *tmp = makeStatement(line, file);
     tmp->type = rego_if;
     tmp->u.rego_if.times = times;
     return tmp;
 }
 
-Statement *makeRestartStatement(Statement *times){
-    Statement *tmp = makeStatement();
+Statement *makeRestartStatement(Statement *times, long int line, char *file){
+    Statement *tmp = makeStatement(line, file);
     tmp->type = restart;
     tmp->u.restart.times = times;
     return tmp;
 }
 
-Statement *makeReturnStatement(Statement *value){
-    Statement *tmp = makeStatement();
+Statement *makeReturnStatement(Statement *value, long int line, char *file){
+    Statement *tmp = makeStatement(line, file);
     tmp->type = return_code;
     tmp->u.return_code.value = value;
     return tmp;
 }
 
-Statement *makeRaiseStatement(Statement *value){
-    Statement *tmp = makeStatement();
+Statement *makeRaiseStatement(Statement *value, long int line, char *file){
+    Statement *tmp = makeStatement(line, file);
     tmp->type = raise_code;
     tmp->u.raise_code.value = value;
     return tmp;
 }
 
-Statement *makeIncludeStatement(Statement *file){
-    Statement *tmp = makeStatement();
+Statement *makeIncludeStatement(Statement *file, long int line, char *file_dir){
+    Statement *tmp = makeStatement(line, file_dir);
     tmp->type = include_file;
     tmp->u.include_file.file = file;
     return tmp;
@@ -269,6 +272,7 @@ void freeStatement(Statement *st){
             default:
                 break;
         }
+        memFree(st->code_file);
         next_tmp = st->next;
         memFree(st);
         st = next_tmp;
@@ -293,7 +297,7 @@ Statement *copyStatement(Statement *st){
 }
 
 Statement *copyStatementCore(Statement *st){
-    Statement *new = makeStatement();
+    Statement *new = makeStatement(st->line, st->code_file);
     new->type = st->type;
     new->next = NULL;
     switch (st->type) {

+ 63 - 5
src/value.c

@@ -1,5 +1,6 @@
 #include "__virtualmath.h"
 
+
 Value *makeValue(Inter *inter) {
     Value *tmp, *list_tmp = inter->base;
     tmp = memCalloc(1, sizeof(Value));
@@ -151,18 +152,35 @@ void freeLinkValue(LinkValue *value, Inter *inter){
     return;
 }
 
-void setResult(Result *ru, bool link, Inter *inter) {
+void setResultCore(Result *ru) {
     ru->type = not_return;
-    if (link)
-        ru->value = makeLinkValue(inter->base, NULL, inter);
+    ru->times = 0;
+    ru->error = NULL;
+    ru->value = NULL;
 }
 
-void setResultError(Result *ru, Inter *inter) {
-    ru->type = error_return;
+void setResult(Result *ru, Inter *inter) {
+    setResultCore(ru);
     ru->value = makeLinkValue(inter->base, NULL, inter);
 }
 
+void setResultError(Result *ru, Inter *inter, char *error_type, char *error_message, Statement *st, bool new) {
+    if (!new && ru->type != error_return)
+        return;
+    if (new) {
+        setResultCore(ru);
+        ru->type = error_return;
+        ru->value = makeLinkValue(inter->base, NULL, inter);
+    }
+    else{
+        error_type = NULL;
+        error_message = NULL;
+    }
+    ru->error = connectError(makeError(error_type, error_message, st->line, st->code_file), ru->error);
+}
+
 void setResultOperation(Result *ru, Inter *inter) {
+    setResultCore(ru);
     ru->type = operation_return;
     ru->value = makeLinkValue(inter->base, NULL, inter);
 }
@@ -226,3 +244,43 @@ void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug){
     writeLog(debug, INFO, "%s", last);
 }
 
+Error *makeError(char *type, char *message, long int line, char *file) {
+    Error *tmp = memCalloc(1, sizeof(Error));
+    tmp->line = line;
+    tmp->type = memStrcpy(type, 0, false, false);
+    tmp->messgae = memStrcpy(message, 0, false, false);
+    tmp->file = memStrcpy(file, 0, false, false);
+    tmp->next = NULL;
+    return tmp;
+}
+
+Error *connectError(Error *new, Error *base){
+    new->next = base;
+    return new;
+}
+
+void freeError(Error *base){
+    while (base != NULL){
+        memFree(base->messgae);
+        memFree(base->type);
+        memFree(base->file);
+        Error *tmp = base->next;
+        memFree(base);
+        base = tmp;
+    }
+}
+
+void printError(Error *error, Inter *inter, bool free) {
+    Error *base = error;
+    while (error != NULL){
+        if (error->next != NULL){
+            writeLog(inter->data.error, ERROR, "Error Backtracking:  On Line: %ld In file: %s Error ID: %p\n", error->line, error->file, error);
+        }
+        else{
+            writeLog(inter->data.error, ERROR, "%s\n%s\nOn Line: %ld\nIn File: %s\nError ID: %p\n", error->type, error->messgae, error->line, error->file, error);
+        }
+        error = error->next;
+    }
+    if (free)
+        freeError(base);
+}