소스 검색

feat: 增加了类型检查

对break等语句的值进行了类型检查
raise语句可以回溯
SongZihuan 4 년 전
부모
커밋
bfb99cdf54
15개의 변경된 파일119개의 추가작업 그리고 85개의 파일을 삭제
  1. 1 1
      include/inter.h
  2. 5 5
      include/statement.h
  3. 1 1
      include/token.h
  4. 2 0
      include/value.h
  5. 1 2
      main.c
  6. 16 10
      parser/__grammar.c
  7. 42 37
      parser/grammar.c
  8. 6 6
      parser/include/__grammar.h
  9. 3 5
      parser/token.c
  10. 12 4
      src/__run.c
  11. 3 3
      src/inter.c
  12. 5 5
      src/operation.c
  13. 11 2
      src/runbranch.c
  14. 7 4
      src/runfile.c
  15. 4 0
      src/value.c

+ 1 - 1
include/inter.h

@@ -21,7 +21,7 @@ struct Inter{
 
 typedef struct Inter Inter;
 
-Inter *makeInter(char *debug);
+Inter *makeInter(char *code_file, char *debug);
 void freeInter(Inter *inter, bool self);
 void setBaseInterData(struct Inter *inter);
 Inter *newInter(char *code_file, char *debug_dir,struct Result *global_result, int *status);

+ 5 - 5
include/statement.h

@@ -47,11 +47,11 @@ struct Statement{
         } base_dict;
         struct operation{
             enum OperationType{
-                ADD = 1,
-                SUB,
-                MUL,
-                DIV,
-                ASS,
+                OPT_ADD = 1,
+                OPT_SUB,
+                OPT_MUL,
+                OPT_DIV,
+                OPT_ASS,
             } OperationType;
             struct Statement *left;
             struct Statement *right;

+ 1 - 1
include/token.h

@@ -147,7 +147,7 @@ TokenMessage *makeTokenMessage(char *file_dir, char *debug);
 void freeTokenMessage(TokenMessage *tm, bool self, bool free_st);
 
 Token *makeToken(long int line);
-long freeToken(Token *tk, bool self, bool error);
+long freeToken(Token *tk, bool self, bool free_st);
 Token *makeLexToken(int type, char *str, char *second_str, long int line);
 Token *makeStatementToken(int type, struct Statement *st);
 

+ 2 - 0
include/value.h

@@ -104,4 +104,6 @@ void printError(Error *error, Inter *inter, bool free);
 void printValue(Value *value, FILE *debug);
 void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug);
 
+bool isType(Value *value, enum ValueType type);
+
 #endif //VIRTUALMATH_VALUE_H

+ 1 - 2
main.c

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

+ 16 - 10
parser/__grammar.c

@@ -13,7 +13,7 @@
  * @param self_name 输出值名称(log)
  * @param is_right 表达式是否从右运算到左
  */
-inline void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBack, GetSymbolFunction getSymbol,
+inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol,
                          int call_type, int self_type, char *call_name, char *self_name, bool is_right) {
     bool is_right_ = false;
     while(true){
@@ -171,7 +171,7 @@ bool checkToken_(ParserMessage *pm, int type){
     return true;
 }
 
-bool commandCallControl_(ParserMessage *pm, Inter *inter, MakeControlFunction callBack, int type, Statement **st,
+bool commandCallControl_(PASERSSIGNATURE, MakeControlFunction callBack, int type, Statement **st,
                          char *log_message, bool must_operation, char *error_message) {
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, log_message, NULL);
     Token *tmp_token = NULL;
@@ -190,14 +190,20 @@ inline bool commandCallBack_(PASERSSIGNATURE, PasersFunction callBack, int type,
     return callChildStatement(CALLPASERSSIGNATURE, callBack, type, st, NULL);
 }
 
-bool callParserCode(PASERSSIGNATURE, Statement **st,char *message){
-    Statement *new_st = NULL;
+bool callParserCode(PASERSSIGNATURE, Statement **st, char *message, long int line) {
+    Token *tmp;
     *st = NULL;
-    if(!callChildStatement(CALLPASERSSIGNATURE, parserCode, CODE, &new_st, message))
+    parserCode(CALLPASERSSIGNATURE);
+    if (!call_success(pm))
+        return false;
+    if (readBackToken(pm) != CODE) {
+        if (message != NULL)
+            syntaxError(pm, syntax_error, line, 1, message);
         return false;
-    if (*st != NULL)
-        freeStatement(*st);
-    *st = new_st;
+    }
+    tmp = popAheadToken(pm);
+    *st = tmp->data.st;
+    freeToken(tmp, true, false);
     return true;
 }
 
@@ -210,7 +216,7 @@ bool callParserAs(PASERSSIGNATURE, Statement **st,char *message){
     return true;
 }
 
-bool callChildToken(ParserMessage *pm, Inter *inter, PasersFunction callBack, int type, Token **tmp, char *message,
+bool callChildToken(PASERSSIGNATURE, PasersFunction callBack, int type, Token **tmp, char *message,
                     int error_type) {
     *tmp = NULL;
     callBack(CALLPASERSSIGNATURE);
@@ -264,7 +270,7 @@ bool callChildStatement(PASERSSIGNATURE, PasersFunction callBack, int type, Stat
  * @param ass 设定赋值符号
  * @return
  */
-bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_formal, bool is_list, bool is_dict, int sep,
+bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_list, bool is_dict, int sep,
                      int ass) {
     Parameter *new_pt = NULL;
     Token *tmp;

+ 42 - 37
parser/grammar.c

@@ -55,7 +55,7 @@ void freeParserMessage(ParserMessage *pm, bool self) {
  * | parserCommand MATHER_SEMICOLON
  * | parserCommand MATHER_EOF
  */
-void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st) {
+void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
     int token_type;
     char *command_message = global ? "ERROR from command list(get parserCommand)" : NULL;
 
@@ -192,7 +192,7 @@ void parserCommand(PASERSSIGNATURE){
  * @param type 输出token的类型
  * @param must_operation 必须匹配 operation
  */
-void parserControl(ParserMessage *pm, Inter *inter, MakeControlFunction callBack, int type, bool must_operation,
+void parserControl(PASERSSIGNATURE, MakeControlFunction callBack, int type, bool must_operation,
                    char *message) {
     Statement *times = NULL;
     Statement *st = NULL;
@@ -250,9 +250,9 @@ void parserIf(PASERSSIGNATURE){
             goto not_del;
         case MATHER_ELIF: {
             Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
-            long int tmo_line = delToken(pm);
+            long int tmp_line = delToken(pm);
             if (else_st != NULL) {
-                syntaxError(pm, syntax_error, tmo_line, 1, "get elif after else");
+                syntaxError(pm, syntax_error, tmp_line, 1, "get elif after else");
                 goto error_;
             }
 
@@ -266,7 +266,7 @@ void parserIf(PASERSSIGNATURE){
                 goto error_;
             }
 
-            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if code")) {
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if code", tmp_line)) {
                 freeStatement(condition_tmp);
                 freeStatement(var_tmp);
                 goto error_;
@@ -278,8 +278,8 @@ void parserIf(PASERSSIGNATURE){
             if (else_st != NULL)
                 goto default_;
             Statement *code_tmp = NULL;
-            delToken(pm);
-            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if...do code"))
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if...do code", tmp_line))
                 goto error_;
             sl = makeConnectStatementList(sl, NULL, NULL, code_tmp, do_b);
             goto again;
@@ -290,15 +290,16 @@ void parserIf(PASERSSIGNATURE){
                 syntaxError(pm, syntax_error, tmp_line, 1, "get else after else");
                 goto error_;
             }
-            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a if...else code"))
+            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a if...else code", tmp_line))
                 goto error_;
             goto again;
         }
-        case MATHER_FINALLY:
-            delToken(pm);
-            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a if...else code"))
+        case MATHER_FINALLY: {
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a if...else code", tmp_line))
                 goto error_;
             break;
+        }
         case MATHER_ENTER:
             delToken(pm);
             goto again;
@@ -362,7 +363,7 @@ void parserWhile(PASERSSIGNATURE){
                 freeStatement(condition_tmp);
                 goto error_;
             }
-            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a while code")) {
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a while code", line)) {
                 freeStatement(condition_tmp);
                 freeStatement(var_tmp);
                 goto error_;
@@ -372,28 +373,30 @@ void parserWhile(PASERSSIGNATURE){
             sl = makeStatementList(condition_tmp, var_tmp, code_tmp, while_b);
             goto again;
         }
-        case MATHER_DO:
+        case MATHER_DO: {
             if (do_st != NULL || else_st != NULL)
                 goto default_;
-            delToken(pm);
-            if (!callParserCode(CALLPASERSSIGNATURE, &do_st, "Don't get a while...do code"))
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &do_st, "Don't get a while...do code", tmp_line))
                 goto error_;
             goto again;
+        }
         case MATHER_ELSE: {
             long int tmp_line = delToken(pm);
             if (else_st != NULL) {
                 syntaxError(pm, syntax_error, tmp_line, 1, "get else after else\n");
                 goto error_;
             }
-            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a while...else code"))
+            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a while...else code", tmp_line))
                 goto error_;
             goto again;
         }
-        case MATHER_FINALLY:
-            delToken(pm);
-            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a while...finally code"))
+        case MATHER_FINALLY: {
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a while...finally code", tmp_line))
                 goto error_;
             break;
+        }
         case MATHER_ENTER:
             delToken(pm);
             goto again;
@@ -447,7 +450,7 @@ void parserTry(PASERSSIGNATURE){
             if (try_st != NULL)
                 goto default_;
             line = delToken(pm);
-            if (!callParserCode(CALLPASERSSIGNATURE, &try_st, "Don't get a try code"))
+            if (!callParserCode(CALLPASERSSIGNATURE, &try_st, "Don't get a try code", line))
                 goto error_;
             goto again;
         }
@@ -465,7 +468,7 @@ void parserTry(PASERSSIGNATURE){
                 freeStatement(condition_tmp);
                 goto error_;
             }
-            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a except code")) {
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a except code", tmp_line)) {
                 freeStatement(condition_tmp);
                 freeStatement(var_tmp);
                 goto error_;
@@ -479,15 +482,16 @@ void parserTry(PASERSSIGNATURE){
                 syntaxError(pm, syntax_error, tmp_line, 1, "get else after else");
                 goto error_;
             }
-            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a try...else code"))
+            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a try...else code", tmp_line))
                 goto error_;
             goto again;
         }
-        case MATHER_FINALLY:
-            delToken(pm);
-            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a try...finally code"))
+        case MATHER_FINALLY: {
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a try...finally code", tmp_line))
                 goto error_;
             break;
+        }
         case MATHER_ENTER:
             delToken(pm);
             goto again;
@@ -550,7 +554,7 @@ void parserDef(PASERSSIGNATURE){
     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")) {
+    if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code", line)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get a function code");
         goto error_;
     }
@@ -575,9 +579,9 @@ void parserDef(PASERSSIGNATURE){
  * @param pm
  * @param inter
  */
-void parserCode(PASERSSIGNATURE){
-    Statement *st = makeStatement(0, NULL);  // TODO-szh 设置Line
+void parserCode(PASERSSIGNATURE) {
     long int line = 0;
+    Statement *st = NULL;
     while (true){
         if (readBackToken(pm) == MATHER_LC){
             line = delToken(pm);
@@ -588,6 +592,7 @@ void parserCode(PASERSSIGNATURE){
         if (!checkToken_(pm, MATHER_ENTER))
             goto return_;
     }
+    st = makeStatement(line, pm->file);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList\n", NULL);
     parserCommandList(CALLPASERSSIGNATURE, false, st);
     if (!call_success(pm))
@@ -637,7 +642,7 @@ void parserOperation(PASERSSIGNATURE){
 bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_ASSIGNMENT:
-            *st = makeOperationStatement(ASS, 0, pm->file);
+            *st = makeOperationStatement(OPT_ASS, 0, pm->file);
             break;
         default:
             return false;
@@ -693,16 +698,16 @@ void parserTuple(PASERSSIGNATURE){
  * 多项式匹配
  * parserPolynomial:
  * | parserBaseValue
- * | parserPolynomial ADD parserFactor
- * | parserPolynomial SUB parserFactor
+ * | parserPolynomial OPT_ADD parserFactor
+ * | parserPolynomial OPT_SUB parserFactor
  */
 bool switchPolynomial(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_ADD:
-            *st = makeOperationStatement(ADD, 0, pm->file);
+            *st = makeOperationStatement(OPT_ADD, 0, pm->file);
             break;
         case MATHER_SUB:
-            *st = makeOperationStatement(SUB, 0, pm->file);
+            *st = makeOperationStatement(OPT_SUB, 0, pm->file);
             break;
         default:
             return false;
@@ -718,16 +723,16 @@ void parserPolynomial(PASERSSIGNATURE){
  * 因式匹配
  * parserFactor:
  * | parserCallBack
- * | switchFactor ADD parserCallBack
- * | switchFactor SUB parserCallBack
+ * | switchFactor OPT_ADD parserCallBack
+ * | switchFactor OPT_SUB parserCallBack
  */
 bool switchFactor(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_MUL:
-            *st = makeOperationStatement(MUL, 0, pm->file);
+            *st = makeOperationStatement(OPT_MUL, 0, pm->file);
             break;
         case MATHER_DIV:
-            *st = makeOperationStatement(DIV, 0, pm->file);
+            *st = makeOperationStatement(OPT_DIV, 0, pm->file);
             break;
         default:
             return false;

+ 6 - 6
parser/include/__grammar.h

@@ -33,7 +33,7 @@ typedef Statement *(*MakeControlFunction)(Statement *, long int, char *);
 typedef int (*TailFunction)(PASERSSIGNATURE, Token *, Statement **);
 
 void parserCommand(PASERSSIGNATURE);
-void parserControl(ParserMessage *pm, Inter *inter, MakeControlFunction callBack, int type, bool must_operation,
+void parserControl(PASERSSIGNATURE, MakeControlFunction callBack, int type, bool must_operation,
                    char *message);
 void parserDef(PASERSSIGNATURE);
 void parserIf(PASERSSIGNATURE);
@@ -54,19 +54,19 @@ int readBackToken(ParserMessage *pm);
 Token *popAheadToken(ParserMessage *pm);
 bool checkToken_(ParserMessage *pm, int type);
 
-bool commandCallControl_(ParserMessage *pm, Inter *inter, MakeControlFunction callBack, int type, Statement **st,
+bool commandCallControl_(PASERSSIGNATURE, MakeControlFunction callBack, int type, Statement **st,
                          char *log_message, bool must_operation, char *error_message);
 bool commandCallBack_(PASERSSIGNATURE, PasersFunction callBack, int type, Statement **st, char *message);
 
-bool callParserCode(PASERSSIGNATURE, Statement **st,char *message);
+bool callParserCode(PASERSSIGNATURE, Statement **st, char *message, long int line);
 bool callParserAs(PASERSSIGNATURE, Statement **st,char *message);
 bool callChildStatement(PASERSSIGNATURE, PasersFunction callBack, int type, Statement **st, char *message);
-bool callChildToken(ParserMessage *pm, Inter *inter, PasersFunction callBack, int type, Token **tmp, char *message,
+bool callChildToken(PASERSSIGNATURE, PasersFunction callBack, int type, Token **tmp, char *message,
                     int error_type);
-bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_formal, bool is_list, bool is_dict,
+bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_list, bool is_dict,
                      int sep,int ass);
 
-void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBack, GetSymbolFunction getSymbol,
+void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol,
                   int call_type, int self_type, char *call_name, char *self_name, bool is_right);
 void tailOperation(PASERSSIGNATURE, PasersFunction callBack, TailFunction tailFunction, int call_type, int self_type,
                    char *call_name, char *self_name);

+ 3 - 5
parser/token.c

@@ -27,18 +27,16 @@ Token *makeStatementToken(int type, struct Statement *st){
     return tmp;
 }
 
-long freeToken(Token *tk, bool self, bool error) {
+long freeToken(Token *tk, bool self, bool free_st) {
     long int line = 0;
     freeBase(tk, return_);
     line = tk->line;
     memFree(tk->data.str);
     memFree(tk->data.second_str);
-    if (error){
+    if (free_st)
         freeStatement(tk->data.st);
-    }
-    if (self){
+    if (self)
         memFree(tk);
-    }
     return_:
     return line;
 }

+ 12 - 4
src/__run.c

@@ -12,12 +12,16 @@ Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     }
     if (operationSafeInterStatement(&times_tmp, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list)))
         return times_tmp;
-    *times = (int)times_tmp.value->value->data.num.num; // TODO-szh 类型检查
+    if (!isType(times_tmp.value->value, number)){
+        setResultError(&result, inter, "TypeException", "Don't get a number value", st, true);
+        goto return_;
+    }
+    *times = (int)times_tmp.value->value->data.num.num;
 
     not_times:
     setResultOperation(&result, inter);
     result.value->value = makeStringValue(st->u.base_var.name, inter);
-    return result;
+    return_: return result;
 }
 
 Result getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
@@ -34,11 +38,15 @@ Result getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     }
     if (operationSafeInterStatement(&times_tmp, CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list)))
         return times_tmp;
-    *times = (int)times_tmp.value->value->data.num.num; // TODO-szh 类型检查
+    if (!isType(times_tmp.value->value, number)){
+        setResultError(&result, inter, "TypeException", "Don't get a number value", st, true);
+        goto return_;
+    }
+    *times = (int)times_tmp.value->value->data.num.num;
 
     not_times:
     result.type = operation_return;
-    return result;
+    return_: return result;
 }
 
 Result getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){

+ 3 - 3
src/inter.c

@@ -18,7 +18,7 @@ Inter *newInter(char *code_file, char *debug_dir, Result *global_result, int *st
     if (access(debug_dir, R_OK) != 0)
         debug_dir = NULL;
 
-    global_inter = makeInter(debug_dir);
+    global_inter = makeInter(code_file, debug_dir);
     pm = makeParserMessage(code_file, debug_dir);
 
     parserCommandList(pm, global_inter, true, global_inter->statement);
@@ -41,12 +41,12 @@ Inter *newInter(char *code_file, char *debug_dir, Result *global_result, int *st
     return global_inter;
 }
 
-Inter *makeInter(char *debug){
+Inter *makeInter(char *code_file, char *debug) {
     Inter *tmp = memCalloc(1, sizeof(Inter));
     setBaseInterData(tmp);
     tmp->base = NULL;
     tmp->link_base = NULL;
-    tmp->statement = makeStatement(0, NULL);  // TODO-szh 设置文件
+    tmp->statement = makeStatement(0, code_file);
     tmp->var_list = makeVarList(tmp);
     tmp->data.log_dir = memStrcpy(debug, 0, false, false);
 

+ 5 - 5
src/operation.c

@@ -35,19 +35,19 @@ Result assOperation(INTER_FUNCTIONSIG);
 Result operationStatement(INTER_FUNCTIONSIG) {
     Result result;
     switch (st->u.operation.OperationType) {
-        case ADD:
+        case OPT_ADD:
             result = addOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
-        case SUB:
+        case OPT_SUB:
             result = subOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
-        case MUL:
+        case OPT_MUL:
             result = mulOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
-        case DIV:
+        case OPT_DIV:
             result = divOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
-        case ASS:
+        case OPT_ASS:
             result = assOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
         default:

+ 11 - 2
src/runbranch.c

@@ -1,5 +1,11 @@
 #include "__run.h"
 
+#define checkNumber(new_result) do{ \
+if (!isType(new_result.value->value, number)){ \
+setResultError(&result, inter, "TypeException", "Don't get a number value", st, true); \
+return result; \
+}}while(0) /*该Macro只适用于控制分支*/
+
 bool checkBool(Value *value){
     switch (value->type) {
         case number:
@@ -13,7 +19,6 @@ bool checkBool(Value *value){
     }
 }
 
-// TODO-szh 检查rego对else的支持
 Result ifBranch(INTER_FUNCTIONSIG) {
     Result result;
     Result else_tmp;
@@ -198,7 +203,7 @@ Result breakCycle(INTER_FUNCTIONSIG){
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.break_cycle.times, var_list)))
         return times;
-    // TODO-szh 类型检查处理
+    checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
     not_times:
     setResult(&result, inter);
@@ -217,6 +222,7 @@ Result continueCycle(INTER_FUNCTIONSIG){
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.continue_cycle.times, var_list)))
         return times;
+    checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
     not_times:
     setResult(&result, inter);
@@ -235,6 +241,7 @@ Result regoIf(INTER_FUNCTIONSIG){
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.rego_if.times, var_list)))
         return times;
+    checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
     not_times:
     setResult(&result, inter);
@@ -253,6 +260,7 @@ Result restartCode(INTER_FUNCTIONSIG){
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.restart.times, var_list)))
         return times;
+    checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
     not_times:
     setResult(&result, inter);
@@ -288,5 +296,6 @@ Result raiseCode(INTER_FUNCTIONSIG){
 
     set_result:
     result.type = error_return;
+    setResultError(&result, inter, "RaiseException", "Exception was raise by user", st, true);
     return result;
 }

+ 7 - 4
src/runfile.c

@@ -10,18 +10,21 @@ Result includeFile(INTER_FUNCTIONSIG) {
     if (operationSafeInterStatement(&file, CALL_INTER_FUNCTIONSIG(st->u.include_file.file, var_list)))
         return file;
 
-    // TODO-szh 类型检查
+    if (!isType(file.value->value, string)){
+        setResultError(&result, inter, "TypeException", "Don't get a string value", st, true);
+        goto return_;
+    }
+
     file_dir = file.value->value->data.str.str;
     if (access(file_dir, R_OK) != 0){
-        setResultError(&result, inter, "IncludeException", "File is not readable", st, true);
-        printf("tag 1\n");
+        setResultError(&result, inter, "IncludeFileException", "File is not readable", st, true);
         goto return_;
     }
     new_st = makeStatement(0, file_dir);
     pm = makeParserMessage(file_dir, NULL);
     parserCommandList(pm, inter, true, new_st);
     if (pm->status != success){
-        setResultError(&result, inter, "IncludeException", pm->status_message, st, true);
+        setResultError(&result, inter, "IncludeSyntaxException", pm->status_message, st, true);
         goto return_;
     }
 

+ 4 - 0
src/value.c

@@ -284,3 +284,7 @@ void printError(Error *error, Inter *inter, bool free) {
     if (free)
         freeError(base);
 }
+
+inline bool isType(Value *value, enum ValueType type){
+    return value->type == type;
+}