Kaynağa Gözat

feat: if分支、while分支、break语句、continue语句

可以创建if...elif...do...else...finally分支
可以创建while...do...else...finally分支
可以使用break和break n语句
可以使用continue和continue n语句
SongZihuan 4 yıl önce
ebeveyn
işleme
c837a43d01
14 değiştirilmiş dosya ile 609 ekleme ve 160 silme
  1. 32 19
      include/__grammar.h
  2. 0 7
      include/__macro.h
  3. 8 1
      include/run.h
  4. 23 2
      include/statement.h
  5. 4 0
      include/token.h
  6. 3 0
      include/value.h
  7. 7 0
      main.c
  8. 255 106
      parser/grammar.c
  9. 12 10
      src/operation.c
  10. 54 0
      src/run.c
  11. 154 0
      src/runbranch.c
  12. 8 13
      src/runcall.c
  13. 48 1
      src/statement.c
  14. 1 1
      src/value.c

+ 32 - 19
include/__grammar.h

@@ -17,16 +17,7 @@ writeLog(pm->paser_debug, pasers_level, "\n"message, __VA_ARGS__); \
 #define writeLog_(...) PASS
 #endif
 
-#define readBackToken(status, pm) do{ \
-doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count); \
-pm->count ++; \
-status = safeGetToken(pm->tm, pm->paser_debug); \
-if (status == -2){ \
-syntaxError(pm, "lexical make some error", lexical_error); \
-} \
-backToken(pm->tm->ts, pm->paser_debug); \
-} while(0) /*预读token*/
-
+// TODO-szh 优化token操作, 减少内存操作
 #define popAheadToken(token_var, pm) do{ \
 doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count); \
 pm->count ++; \
@@ -52,27 +43,47 @@ backToken(pm->tm->ts, pm->paser_debug); \
 #define call_success(pm) (pm->status == success)
 
 #define delToken(pm) do{ \
-delTokenCore(pm, false); \
-}while(0)
-
-#define delTokenCore(pm, del_st) do{ \
 Token *tmp_token; \
 popAheadToken(tmp_token, pm); \
-freeToken(tmp_token, true, del_st); \
-tmp_token = NULL; \
+freeToken(tmp_token, true, false); \
 }while(0)
 
 #define checkToken(pm, type, error_) do{ \
-int token; \
-readBackToken(token, pm); \
+int token = readBackToken(pm); \
 if (token != type){ \
 goto error_; \
 } \
 delToken(pm); \
 }while(0)
 
+// pasersCommand专属macro
+#define commandCallBack(pm, st, call, type, return_) do{ \
+writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: call "#call"\n", NULL); \
+Token *tmp_token = NULL; \
+call(CALLPASERSSIGNATURE); \
+if (!call_success(pm) || readBackToken(pm) != type) \
+goto return_; \
+popAheadToken(tmp_token, pm); \
+st = tmp_token->data.st; \
+freeToken(tmp_token, true, false); \
+} while(0)
+
+#define commandCallControl(pm, st, call, type, return_) do{ \
+writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: call pasers"#call"\n", NULL); \
+Token *tmp_token = NULL; \
+parserControl(CALLPASERSSIGNATURE, call, type); \
+if (!call_success(pm) || readBackToken(pm) != type) \
+goto return_; \
+popAheadToken(tmp_token, pm); \
+st = tmp_token->data.st; \
+freeToken(tmp_token, true, false); \
+} while(0)
+
 void parserCommand(PASERSSIGNATURE);
+void parserControl(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type);
 void parserDef(PASERSSIGNATURE);
+void parserIf(PASERSSIGNATURE);
+void parserWhile(PASERSSIGNATURE);
 void parserCode(PASERSSIGNATURE);
 void parserOperation(PASERSSIGNATURE);
 void parserPolynomial(PASERSSIGNATURE);
@@ -80,8 +91,10 @@ void parserBaseValue(PASERSSIGNATURE);
 void parserCallBack(PASERSSIGNATURE);
 void parserFactor(PASERSSIGNATURE);
 void parserAssignment(PASERSSIGNATURE);
-void syntaxError(ParserMessage *pm, char *message, int status);
 void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int symbol, Statement **st), int, int, char *, char *);
 void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*tailFunction)(PASERSSIGNATURE, Token *left_token,  Statement **st), int , int , char *, char *);
 
+void syntaxError(ParserMessage *pm, char *message, int status);
+int readBackToken(ParserMessage *pm);
+
 #endif //VIRTUALMATH___GRAMMAR_H

+ 0 - 7
include/__macro.h

@@ -28,13 +28,6 @@ goto return_; \
 #define runContinue(result) (result.type == not_return || result.type == operation_return)
 #define is_error(result) (result.type == error_return)
 
-#define safeIterStatement(new_result, sig) do{ \
-new_result = iterStatement(sig); \
-if (is_error(new_result)){ \
-return new_result; \
-} \
-} while(0)
-
 #define checkResult(check_result) do{ \
 if (is_error(check_result)){ \
 return check_result; \

+ 8 - 1
include/run.h

@@ -4,13 +4,20 @@
 #include "value.h"
 #include "var.h"
 
-Result iterStatement(INTER_FUNCTIONSIG);
 Result operationStatement(INTER_FUNCTIONSIG);
 Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE);
 Result globalIterStatement(Inter *inter);
+bool operationSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
+bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
+bool functionSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
+bool cycleBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
 Result setFunction(INTER_FUNCTIONSIG);
 Result callFunction(INTER_FUNCTIONSIG);
 Result getBaseVar(INTER_FUNCTIONSIG);
 Result getBaseValue(INTER_FUNCTIONSIG);
+Result ifBranch(INTER_FUNCTIONSIG);
+Result whileBranch(INTER_FUNCTIONSIG);
 
+Result breakCycle(INTER_FUNCTIONSIG);
+Result continueCycle(INTER_FUNCTIONSIG);
 #endif //VIRTUALMATH_RUN_H

+ 23 - 2
include/statement.h

@@ -15,6 +15,8 @@ typedef struct Statement{
         for_branch,
         try_branch,
         with_branch,
+        break_cycle,
+        continue_cycle,
     } type;
     union StatementU{
         struct base_value{
@@ -71,11 +73,26 @@ typedef struct Statement{
             struct Statement *else_list;  // else分支(无condition)
             struct Statement *finally;
         } try_branch;
+        struct {
+            struct StatementList *with_list;  // for循环体
+            struct Statement *else_list;  // else分支(无condition)
+            struct Statement *finally;
+        } with_branch;
+        struct {
+            struct Statement *times;
+        } break_cycle;
+        struct {
+            struct Statement *times;
+        } continue_cycle;
     }u;
     struct Statement *next;
 } Statement;
 
 typedef struct StatementList{
+    enum {
+        if_b,
+        do_b,
+    } type;
     struct Statement *condition;
     struct Statement *var;  // TODO-szh if等分支计算结果允许赋值
     struct Statement *code;
@@ -88,13 +105,17 @@ struct Token *setOperationFromToken(Statement *st, struct Token *left, struct To
 
 Statement *makeFunctionStatement(Statement *name, Statement *function);
 Statement *makeCallStatement(Statement *function);
+Statement *makeIfStatement();
+Statement *makeWhileStatement();
+Statement *makeBreakStatement(Statement *times);
+Statement *makeContinueStatement(Statement *times);
 
 void connectStatement(Statement *base, Statement *new);
 void freeStatement(Statement *st);
 
 StatementList *connectStatementList(StatementList *base, StatementList *new);
-StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code);
+StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code, int type);
 void freeStatementList(StatementList *base);
-#define makeConnectStatementList(base, condition, var, code) connectStatementList(base, makeStatementList(condition, var, code))
+#define makeConnectStatementList(base, condition, var, code, type) connectStatementList(base, makeStatementList(condition, var, code, type))
 
 #endif //VIRTUALMATH_STATEMENT_H

+ 4 - 0
include/token.h

@@ -97,6 +97,10 @@
 #define CODE -12
 #define FUNCTION -13
 #define CALLBACK -14
+#define IF_BRANCH -15
+#define WHILE_BRANCH -16
+#define BREAK -17
+#define CONTINUE -18
 
 typedef struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 3 - 0
include/value.h

@@ -38,8 +38,11 @@ typedef struct VirtualMathResult{
         function_return,  // 函数返回值
         operation_return,  // 表达式返回值
         error_return,  // 错误
+        break_return,
+        continue_return,
     } type;
     struct VirtualMathLinkValue *value;
+    int times;
 } Result;
 
 Value *makeValue(Inter *inter);

+ 7 - 0
main.c

@@ -26,18 +26,23 @@ int getArgs(int argc, char *argv[]);
 void freeArgs();
 
 int main(int argc, char *argv[]) {
+    printf("[start VirtualMath]\n");
     if (getArgs(argc, argv)){
         goto args_error_;
     }
 
     Inter *global_iter = makeInter(args.log_file);
     ParserMessage *pm = makeParserMessage(args.file, args.log_file);
+
+    printf("[start to lexical]\n");
     pasersCommandList(pm, global_iter, true, global_iter->statement);
     if (pm->status != success){
         writeLog(pm->paser_debug, ERROR, "Syntax Error: %s\n", pm->status_message);
         writeLog(stderr, ERROR, "Syntax Error: %s\n", pm->status_message);
         goto return_;
     }
+
+    printf("[start to run]\n");
     Result tmp;
     tmp = globalIterStatement(global_iter);
     if (tmp.type == error_return){
@@ -49,10 +54,12 @@ int main(int argc, char *argv[]) {
     freePasersMessage(pm, true);
     freeInter(global_iter, true);
     freeArgs();
+    printf("[exit Virtual [0]]\n");
     return 0;
 
     args_error_:
     freeArgs();
+    printf("[exit Virtual [1]]\n");
     return 1;
 }
 

+ 255 - 106
parser/grammar.c

@@ -47,10 +47,10 @@ void freePasersMessage(ParserMessage *pm, bool self) {
  * | parserCommand MATHER_EOF
  */
 void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st) {
-    int token_type, command_int, stop;
+    int token_type, stop;
     struct Statement *base_st = st;
     while (true){
-        readBackToken(token_type, pm);
+        token_type = readBackToken(pm);
         if (token_type == MATHER_EOF){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command List: <EOF>\n", NULL);
             delToken(pm);
@@ -68,8 +68,7 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
             if (!call_success(pm)){
                 goto return_;
             }
-            readBackToken(command_int, pm);
-            if (COMMAND != command_int){
+            if (COMMAND != readBackToken(pm)){
                 if (global){
                     syntaxError(pm, "ERROR from command list(get parserCommand)", command_list_error);
                 }
@@ -77,7 +76,7 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
             }
             popAheadToken(command_token, pm);
 
-            readBackToken(stop, pm);
+            stop = readBackToken(pm);
             if (stop == MATHER_ENTER || stop == MATHER_SEMICOLON){
                 delToken(pm);
             }
@@ -117,34 +116,26 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
 void parserCommand(PASERSSIGNATURE){
     int token_type;
     Statement *st = NULL;
-    readBackToken(token_type, pm);
-    if (MATHER_DEF == token_type){
-        int def;
-        Token *def_token = NULL;
-        parserDef(CALLPASERSSIGNATURE);
-        if (!call_success(pm))
-            goto return_;
-        readBackToken(def, pm);
-        if (def != FUNCTION)
-            goto return_;
-        popAheadToken(def_token, pm);
-        st = def_token->data.st;
-        freeToken(def_token, true, false);
-    }
-    else{
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: call operation\n", NULL);
-        int command_type;
-        Token *command_token = NULL;
-        parserOperation(CALLPASERSSIGNATURE);
-        if (!call_success(pm))
-            goto return_;
-        readBackToken(command_type, pm);
-        if (command_type != OPERATION)
-            goto return_;
-        popAheadToken(command_token, pm);
-        /*...do something for command...*/
-        st = command_token->data.st;
-        freeToken(command_token, true, false);
+    token_type = readBackToken(pm);
+    switch (token_type) {
+        case MATHER_DEF :
+            commandCallBack(pm, st, parserDef, FUNCTION, return_);
+            break;
+        case MATHER_IF :
+            commandCallBack(pm, st, parserIf, IF_BRANCH, return_);
+            break;
+        case MATHER_WHILE :
+            commandCallBack(pm, st, parserWhile, WHILE_BRANCH, return_);
+            break;
+        case MATHER_BREAK :
+            commandCallControl(pm, st, makeBreakStatement, BREAK, return_);
+            break;
+        case MATHER_CONTINUE :
+            commandCallControl(pm, st, makeContinueStatement, CONTINUE, return_);
+            break;
+        default :
+            commandCallBack(pm, st, parserOperation, OPERATION, return_);
+            break;
     }
     addStatementToken(COMMAND, st, pm);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get  command success\n", NULL);
@@ -152,45 +143,210 @@ void parserCommand(PASERSSIGNATURE){
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get return\n", NULL);
 }
 
+void parserControl(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type){
+    Statement *times = NULL, *st = NULL;
+    delToken(pm);
+    parserOperation(CALLPASERSSIGNATURE);
+    if (!call_success(pm))
+        goto return_;
+    if (readBackToken(pm) == OPERATION){
+        Token *tmp;
+        popAheadToken(tmp, pm);
+        times = tmp->data.st;
+        freeToken(tmp, true, false);
+    }
+    st = callBack(times);
+    addStatementToken(type, st, pm);
+    return_:
+    return;
+}
+
 void parserIf(PASERSSIGNATURE){
-//    int if_type, code;
-//    Token *if_token = NULL, *code_token = NULL;
-//    struct Statement *st = NULL, *tmp = NULL;
-//    StatementList *sl = NULL;
-//
-//    checkToken(pm, MATHER_IF, return_);
-//    callChild(pm, if_type, if_token, parserOperation, OPERATION, return_, error_);
-//    if (if_type != OPERATION){
-//        goto return_;
-//    }
-//    callChild(pm, code, code_token, parserCode, CODE, error_, error_);
-//
-//    sl = makeConnectStatementList(sl, if_token->data.st, NULL, code_token->data.st);
-//
-//    st = makeFunctionStatement(name_token->data.st, code_token->data.st);
-//    addStatementToken(FUNCTION, st, pm);
-//    freeToken(code_token, true, false);
-//    freeToken(name_token, true, false);
-//    return_: return;
-//
-//    error_:
-//    freeToken(if_token, true, true);
-//    freeToken(code_token, true, true);
-//    syntaxError(pm, "Don't get a if titile", syntax_error);
-//    return;
+    Token *if_token = NULL, *code_token = NULL;
+    struct Statement *st = NULL, *else_st = NULL, *finally_st = NULL;
+    StatementList *sl = NULL;
+    bool have_if = false;
+
+    again:
+    switch (readBackToken(pm)) {
+        case MATHER_IF:
+            if (have_if)
+                goto default_;
+            else
+                have_if = true;
+        case MATHER_ELIF:
+            delToken(pm);
+            parserOperation(CALLPASERSSIGNATURE);
+            if (!call_success(pm))
+                goto return_;
+            if (readBackToken(pm) != OPERATION){
+                syntaxError(pm, "Don't get a if condition", syntax_error);
+                goto return_;
+            }
+            popAheadToken(if_token, pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                error_:
+                freeToken(if_token, true, true);
+                syntaxError(pm, "Don't get a if code", syntax_error);
+                goto return_;
+            }
+            popAheadToken(code_token, pm);
+            sl = makeConnectStatementList(sl, if_token->data.st, NULL, code_token->data.st, if_b);
+            freeToken(if_token, true, false);
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_DO:
+            delToken(pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                goto error_;
+            }
+            popAheadToken(code_token, pm);
+            sl = makeConnectStatementList(sl, NULL, NULL, code_token->data.st, do_b);
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_ELSE:
+            delToken(pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                goto error_;
+            }
+            popAheadToken(code_token, pm);
+            if (else_st != NULL)
+                freeStatement(else_st);
+            else_st = code_token->data.st;
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_FINALLY:
+            delToken(pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                goto error_;
+            }
+            popAheadToken(code_token, pm);
+            if (finally_st != NULL)
+                freeStatement(finally_st);
+            finally_st = code_token->data.st;
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_ENTER:
+            delToken(pm);
+            goto again;
+        default:
+            default_: break;
+    }
+
+    st = makeIfStatement();
+    st->u.if_branch.if_list = sl;
+    st->u.if_branch.else_list = else_st;
+    st->u.if_branch.finally = finally_st;
+    addStatementToken(IF_BRANCH, st, pm);
+
+    return_:
+    return;
+}
+
+void parserWhile(PASERSSIGNATURE){
+    Token *while_token = NULL, *code_token = NULL;
+    struct Statement *st = NULL, *else_st = NULL, *finally_st = NULL,*do_st = NULL;
+    StatementList *sl = NULL;
+    bool have_while = false;
+
+    again:
+    switch (readBackToken(pm)) {
+        case MATHER_WHILE:
+            if (have_while)
+                goto default_;
+            else
+                have_while = true;
+
+            delToken(pm);
+            parserOperation(CALLPASERSSIGNATURE);
+            if (!call_success(pm))
+                goto return_;
+            if (readBackToken(pm) != OPERATION){
+                syntaxError(pm, "Don't get a else while condition", syntax_error);
+                goto return_;
+            }
+            popAheadToken(while_token, pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                error_:
+                freeToken(while_token, true, true);
+                syntaxError(pm, "Don't get a while code", syntax_error);
+                goto return_;
+            }
+            popAheadToken(code_token, pm);
+            if (sl != NULL)
+                freeStatementList(sl);
+            sl = makeStatementList(while_token->data.st, NULL, code_token->data.st, if_b);
+            freeToken(while_token, true, false);
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_DO:
+            delToken(pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                goto error_;
+            }
+            popAheadToken(code_token, pm);
+            if (do_st != NULL)
+                freeStatement(do_st);
+            do_st = code_token->data.st;
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_ELSE:
+            delToken(pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                goto error_;
+            }
+            popAheadToken(code_token, pm);
+            if (else_st != NULL)
+                freeStatement(else_st);
+            else_st = code_token->data.st;
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_FINALLY:
+            delToken(pm);
+            parserCode(CALLPASERSSIGNATURE);
+            if (!call_success(pm) && readBackToken(pm) != CODE){
+                goto error_;
+            }
+            popAheadToken(code_token, pm);
+            if (finally_st != NULL)
+                freeStatement(finally_st);
+            finally_st = code_token->data.st;
+            freeToken(code_token, true, false);
+            goto again;
+        case MATHER_ENTER:
+            delToken(pm);
+            goto again;
+        default:
+            default_: break;
+    }
+
+    st = makeWhileStatement();
+    st->u.while_branch.while_list = sl;
+    st->u.while_branch.else_list = else_st;
+    st->u.while_branch.finally = finally_st;
+    st->u.while_branch.after = do_st;
+    addStatementToken(WHILE_BRANCH, st, pm);
+
+    return_:
+    return;
 }
 
 void parserDef(PASERSSIGNATURE){
-    int name_type, code;
     Token *name_token = NULL, *code_token = NULL;
     struct Statement *st = NULL;
+    delToken(pm);
 
-    checkToken(pm, MATHER_DEF, return_);
     parserBaseValue(CALLPASERSSIGNATURE);
     if (!call_success(pm))
         goto return_;
-    readBackToken(name_type, pm);
-    if (name_type != BASEVALUE){
+    if (readBackToken(pm) != BASEVALUE){
         syntaxError(pm, "Don't get a function name", syntax_error);
         goto return_;
     }
@@ -198,14 +354,15 @@ void parserDef(PASERSSIGNATURE){
 
     checkToken(pm, MATHER_LP, error_);
     checkToken(pm, MATHER_RP, 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);
     parserCode(CALLPASERSSIGNATURE);
     if (!call_success(pm)){
         goto error_;
     }
-    readBackToken(code, pm);
-    if (code != CODE){
-        freeToken(name_token, true, true);
+    if (readBackToken(pm) != CODE){
         error_:
+        freeToken(name_token, true, true);
         syntaxError(pm, "Don't get a function code", syntax_error);
         goto return_;
     }
@@ -221,24 +378,24 @@ void parserDef(PASERSSIGNATURE){
 }
 
 void parserCode(PASERSSIGNATURE){
-    int code_type;
-    Token *code_token = NULL;
+    Token *code_token = NULL, *tk = NULL;
     struct Statement *st = makeStatement();
     while (true){
         checkToken(pm, MATHER_LC, again_);  // 若匹配的不是{则检查是否匹配到\n
         break;  // 若匹配到{则跳出循环
         again_: checkToken(pm, MATHER_ENTER, return_);  // 若不是\n则跳到return_
     }
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call pasersCommandList\n", NULL);
     pasersCommandList(CALLPASERSSIGNATURE, false, st);
     if (!call_success(pm)){
         goto return_;
     }
-    readBackToken(code_type, pm);
-    if (code_type != COMMANDLIST){
+    if (readBackToken(pm) != COMMANDLIST){
         syntaxError(pm, "Not CommandList\n", syntax_error);
         goto return_;
     }
     popAheadToken(code_token, pm);
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call pasersCommandList success\n", NULL);
     checkToken(pm, MATHER_RC, error_);
 
     return_:
@@ -258,14 +415,12 @@ void parserCode(PASERSSIGNATURE){
  * | parserAssignment
  */
 void parserOperation(PASERSSIGNATURE){
-    int operation_type;
     Token *operation_token = NULL;
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: call assignment\n", NULL);
     parserAssignment(CALLPASERSSIGNATURE);
     if (!call_success(pm))
         goto return_;
-    readBackToken(operation_type, pm);
-    if (operation_type != ASSIGNMENT){
+    if (readBackToken(pm) != ASSIGNMENT){
         goto return_;
     }
     popAheadToken(operation_token, pm);
@@ -351,9 +506,7 @@ void parserFactor(PASERSSIGNATURE){
 }
 
 int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
-    int symbol;
-    readBackToken(symbol, pm);
-    if (symbol != MATHER_LP){
+    if (readBackToken(pm) != MATHER_LP){
         return -1;
     }
     delToken(pm);
@@ -371,21 +524,18 @@ void parserCallBack(PASERSSIGNATURE){
 }
 
 int getOperation(PASERSSIGNATURE, int right_type, Statement **st, char *name){
-    int operation_type, rp;
     Token *operation_token;
 
     parserOperation(CALLPASERSSIGNATURE);
     if (!call_success(pm)){
         return 0;
     }
-    readBackToken(operation_type, pm);
-    if (operation_type != OPERATION){
+    if (readBackToken(pm) != OPERATION){
         return 0;
     }
     popAheadToken(operation_token, pm);
 
-    readBackToken(rp, pm);
-    if (right_type != rp){
+    if (readBackToken(pm) != right_type){
         return -1;
     }
     delToken(pm);
@@ -405,7 +555,7 @@ void parserBaseValue(PASERSSIGNATURE){
     int token_type;
     Token *value_token = NULL;
     struct Statement *st = NULL;
-    readBackToken(token_type, pm);
+    token_type = readBackToken(pm);
     if(MATHER_NUMBER == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get number\n", NULL);
         popAheadToken(value_token, pm);
@@ -430,7 +580,7 @@ void parserBaseValue(PASERSSIGNATURE){
         st->u.base_var.times = NULL;
     }
     else if(MATHER_LB == token_type){
-        int var, tmp;
+        int tmp;
         Statement *tmp_st = NULL;
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
         popAheadToken(value_token, pm);
@@ -446,8 +596,7 @@ void parserBaseValue(PASERSSIGNATURE){
             syntaxError(pm, "Don't get ] from list/var", syntax_error);
             goto return_;
         }
-        readBackToken(var, pm);
-        if (MATHER_VAR == var){
+        if (MATHER_VAR == readBackToken(pm)){
             Token *var_token;
             popAheadToken(var_token, pm);
             st = makeStatement();
@@ -486,20 +635,15 @@ void parserBaseValue(PASERSSIGNATURE){
 
 inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int symbol, Statement **st), int type, int self_type, char *call_name, char *self_name){
     while(true){
-        int left, symbol, right;
-        Token *left_token = NULL, *symbol_token = NULL, *right_token = NULL;
+        Token *left_token = NULL, *right_token = NULL;
         struct Statement *st = NULL;
 
-        readBackToken(left, pm);
-        if (left != self_type){
+        readBackToken(pm);
+        if (readBackToken(pm) != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
             callBack(CALLPASERSSIGNATURE);
-            if (!call_success(pm))
-                goto return_;
-            readBackToken(left, pm);
-            if (left != type){
+            if (!call_success(pm) || (readBackToken(pm) != type))
                 goto return_;
-            }
             popAheadToken(left_token, pm);
             addStatementToken(self_type, left_token->data.st, pm);
             freeToken(left_token, true, false);
@@ -510,8 +654,7 @@ inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int
         popAheadToken(left_token, pm);
 
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
-        readBackToken(symbol, pm);
-        if (getSymbol(CALLPASERSSIGNATURE, symbol, &st)){
+        if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st)){
             delToken(pm);
         }
         else{
@@ -527,8 +670,7 @@ inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int
             freeStatement(st);
             goto return_;
         }
-        readBackToken(right, pm);
-        if (right != type){  // 若非正确数值
+        if (readBackToken(pm) != type){  // 若非正确数值
             char *tmp1, *tmp2;
             tmp1 = memStrcat("ERROR from ", self_name);
             tmp2 = memStrcat(tmp1, "(get right)");
@@ -550,20 +692,14 @@ inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int
 
 inline void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*tailFunction)(PASERSSIGNATURE, Token *left_token,  Statement **st), int type, int self_type, char *call_name, char *self_name){
     while(true){
-        int left, symbol;
-        Token *left_token = NULL, *symbol_token = NULL, *right_token = NULL;
+        Token *left_token = NULL;
         struct Statement *st = NULL;
 
-        readBackToken(left, pm);
-        if (left != self_type){
+        if (readBackToken(pm) != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
             callBack(CALLPASERSSIGNATURE);
-            if (!call_success(pm))
+            if ((!call_success(pm)) || readBackToken(pm) != type)
                 goto return_;
-            readBackToken(left, pm);
-            if (left != type){
-                goto return_;
-            }
             popAheadToken(left_token, pm);
             addStatementToken(self_type, left_token->data.st, pm);
             freeToken(left_token, true, false);
@@ -606,3 +742,16 @@ void syntaxError(ParserMessage *pm, char *message, int status){
     pm->status = status;
     pm->status_message = memStrcpy(message, 0, false, false);
 }
+
+int readBackToken(ParserMessage *pm){
+    // TODO-szh 优化执行效果
+    writeLog(pm->grammar_debug, GRAMMAR_DEBUG, "token operation number : %d\n", pm->count);
+    writeLog(pm->paser_debug, DEBUG, "\ntoken operation number : %d\n", pm->count);
+    pm->count ++;
+    int status = safeGetToken(pm->tm, pm->paser_debug);
+    if (status == -2){
+        syntaxError(pm, "lexical make some error", lexical_error);
+    }
+    backToken(pm->tm->ts, pm->paser_debug);
+    return status;
+}

+ 12 - 10
src/operation.c

@@ -3,7 +3,9 @@
  * operation.c中是用于数学计算的函数
  */
 
-#define getresult(base, var, inter) safeIterStatement(var, CALL_INTER_FUNCTIONSIG(st->u.operation. base, var_list))
+#define getresult(base, var, inter) do{ \
+if (operationSafeInterStatement(&var, CALL_INTER_FUNCTIONSIG(st->u.operation. base, var_list))){ return var; } \
+}while(0)
 #define viewtype_core(a, b, valuetype_a, valuetype_a_b) a .value->value->type == valuetype_a && b.value->value->type == valuetype_a_b
 #define viewtype(a, b, valuetype) viewtype_core(a, b, valuetype, valuetype)
 #define operationValue(a, b, type, symbol) a.value->value->data.type symbol b.value->value->data.type
@@ -131,26 +133,24 @@ Result assOperation(INTER_FUNCTIONSIG) {
 }
 
 Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
-    Result times;
+    Result result, times;
+    setResult(&result, true, inter);
     int int_times;
     if (name->type == base_var){
         if (name->u.base_var.times == NULL){
             int_times = 0;
-            setResult(&times, true, inter);
             goto not_times;
         }
 
-        safeIterStatement(times, CALL_INTER_FUNCTIONSIG(name->u.base_var.times, var_list));
+        if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(name->u.base_var.times, var_list))){
+            return times;
+        }
 
-        times = iterStatement(CALL_INTER_FUNCTIONSIG(name->u.base_var.times, var_list));
         int_times = (int)times.value->value->data.num.num;
         not_times:
         addFromVarList(name->u.base_var.name, var_list, int_times, value);
     }
-    else{
-        setResult(&times, true, inter);
-    }
-    return times;
+    return result;
 }
 
 Result getBaseVar(INTER_FUNCTIONSIG) {
@@ -162,7 +162,9 @@ Result getBaseVar(INTER_FUNCTIONSIG) {
         int_times = 0;
         goto not_times;
     }
-    safeIterStatement(times, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list));
+    if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list))){
+        return times;
+    }
     int_times = (int)times.value->value->data.num.num;
 
     not_times:

+ 54 - 0
src/run.c

@@ -26,6 +26,18 @@ Result runStatement(INTER_FUNCTIONSIG) {
         case call_function:
             result = callFunction(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
+        case if_branch:
+            result = ifBranch(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
+        case while_branch:
+            result = whileBranch(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
+        case break_cycle:
+            result = breakCycle(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
+        case continue_cycle:
+            result = continueCycle(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
         default:
             setResult(&result, true, inter);
             break;
@@ -73,3 +85,45 @@ Result globalIterStatement(Inter *inter) {
         setResult(&result, true, inter);
     return result;
 }
+
+// 若需要中断执行, 则返回true
+bool operationSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
+    if (result->type == not_return || result->type == operation_return)
+        return false;
+    return true;
+}
+
+bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
+    if (result->type == not_return || result->type == operation_return){
+        return false;
+    }
+    return true;
+}
+
+bool cycleBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
+    if (result->type == not_return || result->type == operation_return){
+        return false;
+    }
+    if (result->type == break_return || result->type == continue_return){
+        result->times--;
+        if (result->times < 0)
+            return false;
+    }
+    return true;
+}
+
+bool functionSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
+    if (result->type == error_return){
+        return true;
+    }
+    else if (result->type == function_return){
+        result->type = operation_return;
+        return false;
+    }
+    result->type = not_return;
+    return false;
+}

+ 154 - 0
src/runbranch.c

@@ -0,0 +1,154 @@
+#include "__run.h"
+
+bool checkBool(Value *value){
+    switch (value->type) {
+        case number:
+            return value->data.num.num != 0;
+        case string:
+            return memStrlen(value->data.str.str) > 0;
+        case none:
+            return false;
+        default:
+            return true;
+    }
+}
+
+Result ifBranch(INTER_FUNCTIONSIG) {
+    Result result, else_tmp, finally_tmp;
+    StatementList *if_list = st->u.if_branch.if_list;
+    bool set_result = true;
+
+    var_list = pushVarList(var_list, inter);
+    while (if_list != NULL){
+        if (if_list->type == if_b){
+            Result tmp;
+            if (operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(if_list->condition, var_list))){
+                result = tmp;
+                set_result = false;
+                goto not_else;
+            }
+            if (checkBool(tmp.value->value)){
+                Result code_tmp;
+                if (ifBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(if_list->code, var_list))){
+                    result = code_tmp;
+                    set_result = false;
+                    goto not_else;
+                }
+                goto not_else;
+            }
+        }
+        else{
+            Result code_tmp;
+            if (ifBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(if_list->code, var_list))){
+                result = code_tmp;
+                set_result = false;
+                goto not_else;
+            }
+        }
+        if_list = if_list->next;
+    }
+    if (st->u.if_branch.else_list != NULL && ifBranchSafeInterStatement(&else_tmp, CALL_INTER_FUNCTIONSIG(st->u.if_branch.else_list, var_list))){
+        set_result = false;
+        result = else_tmp;
+    }
+    not_else:
+
+    if (st->u.if_branch.finally != NULL && ifBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.if_branch.finally, var_list))){
+        set_result = false;
+        result = finally_tmp;
+    }
+
+    var_list = popVarList(var_list, inter);
+    if (set_result)
+        setResult(&result, true, inter);
+    return result;
+}
+
+Result whileBranch(INTER_FUNCTIONSIG) {
+    Result result, else_tmp, finally_tmp;
+    StatementList *while_list = st->u.while_branch.while_list;
+    bool set_result = true;
+
+    var_list = pushVarList(var_list, inter);
+    while (true){
+        Result tmp, do_tmp;
+        if (operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(while_list->condition, var_list))){
+            result = tmp;
+            set_result = false;
+            goto not_else;
+        }
+        if (checkBool(tmp.value->value)){
+            Result code_tmp;
+            if (cycleBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(while_list->code, var_list))){
+                result = code_tmp;
+                set_result = false;
+                goto not_else;
+            }
+            if (code_tmp.type == break_return)
+                goto not_else;  // 不会执行else语句
+            if (code_tmp.type == continue_return)
+                PASS;
+        }
+        else{
+            break;
+        }
+        if (st->u.while_branch.after != NULL && cycleBranchSafeInterStatement(&do_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.after, var_list))){
+            result = do_tmp;
+            set_result = false;
+            goto not_else;
+        }
+    }
+    if (st->u.while_branch.else_list != NULL && cycleBranchSafeInterStatement(&else_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.else_list, var_list))){
+        set_result = false;
+        result = else_tmp;
+    }
+    not_else:
+
+    if (st->u.while_branch.finally != NULL && cycleBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.finally, var_list))){
+        set_result = false;
+        result = finally_tmp;
+    }
+
+    var_list = popVarList(var_list, inter);
+    if (set_result)
+        setResult(&result, true, inter);
+    return result;
+}
+
+Result breakCycle(INTER_FUNCTIONSIG){
+    Result result, times;
+    int times_int = 0;
+    if (st->u.break_cycle.times == NULL)
+        goto not_times;
+    if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.break_cycle.times, var_list))){
+        return times;
+    }
+    times_int = (int)times.value->value->data.num.num;
+    not_times:
+    setResult(&result, true, inter);
+    if (times_int >= 0) {
+        // TODO-szh 类型检查处理
+        result.type = break_return;
+        result.times = times_int;
+    }
+    return result;
+}
+
+Result continueCycle(INTER_FUNCTIONSIG){
+    Result result, times;
+    int times_int = 0;
+    if (st->u.continue_cycle.times == NULL)
+        goto not_times;
+    if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.continue_cycle.times, var_list))){
+        return times;
+    }
+    times_int = (int)times.value->value->data.num.num;
+    not_times:
+    setResult(&result, true, inter);
+    if (times_int >= 0) {
+        // TODO-szh 类型检查处理
+        result.type = continue_return;
+        result.times = times_int;
+    }
+    return result;
+}

+ 8 - 13
src/runcall.c

@@ -12,25 +12,20 @@ Result setFunction(INTER_FUNCTIONSIG) {
 Result callFunction(INTER_FUNCTIONSIG) {
     Result call_function, result;
 
-    safeIterStatement(call_function, CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list));
+    if (operationSafeInterStatement(&call_function, CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list)))
+        return call_function;
+
     if (call_function.value->value->type != function){
         writeLog_(inter->debug, WARNING, "call not function[%d]\n", call_function.type);
         setResultError(&result, inter);
         result.type = error_return;
         goto return_;
     }
-
-    var_list = pushVarList(var_list, inter);
-    result = iterStatement(CALL_INTER_FUNCTIONSIG(call_function.value->value->data.function.function, var_list));
-    var_list = popVarList(var_list, inter);
-
-    // 降级操作
-    if (result.type == function_return)
-        result.type = operation_return;
-    else if(result.type == error_return)
-        PASS;
-    else
-        result.type = not_return;
+    VarList *function_var = call_function.value->value->data.function.var;
+    function_var = pushVarList(function_var, inter);
+    functionSafeInterStatement(&result,
+                               CALL_INTER_FUNCTIONSIG(call_function.value->value->data.function.function, function_var));
+    popVarList(function_var, inter);
 
     return_:
     return result;

+ 48 - 1
src/statement.c

@@ -44,6 +44,41 @@ Statement *makeCallStatement(Statement *function){
     return tmp;
 }
 
+Statement *makeIfStatement(){
+    Statement *tmp = makeStatement();
+    tmp->type = if_branch;
+    tmp->u.if_branch.if_list = NULL;
+    tmp->u.if_branch.else_list = NULL;
+    tmp->u.if_branch.finally = NULL;
+    return tmp;
+}
+
+Statement *makeWhileStatement(){
+    Statement *tmp = makeStatement();
+    tmp->type = while_branch;
+    tmp->u.while_branch.type = while_;
+    tmp->u.while_branch.while_list = NULL;
+    tmp->u.while_branch.else_list = NULL;
+    tmp->u.while_branch.finally = NULL;
+    tmp->u.while_branch.first = NULL;
+    tmp->u.while_branch.after = NULL;
+    return tmp;
+}
+
+Statement *makeBreakStatement(Statement *times){
+    Statement *tmp = makeStatement();
+    tmp->type = break_cycle;
+    tmp->u.break_cycle.times = times;
+    return tmp;
+}
+
+Statement *makeContinueStatement(Statement *times){
+    Statement *tmp = makeStatement();
+    tmp->type = continue_cycle;
+    tmp->u.continue_cycle.times = times;
+    return tmp;
+}
+
 void connectStatement(Statement *base, Statement *new){
     while (base->next != NULL){
         base = base->next;
@@ -97,6 +132,17 @@ void freeStatement(Statement *st){
                 freeStatement(st->u.try_branch.else_list);
                 freeStatement(st->u.try_branch.finally);
                 break;
+            case with_branch:
+                freeStatementList(st->u.with_branch.with_list);
+                freeStatement(st->u.with_branch.else_list);
+                freeStatement(st->u.with_branch.finally);
+                break;
+            case break_cycle:
+                freeStatement(st->u.break_cycle.times);
+                break;
+            case continue_cycle:
+                freeStatement(st->u.continue_cycle.times);
+                break;
             default:
                 break;
         }
@@ -108,11 +154,12 @@ void freeStatement(Statement *st){
     return;
 }
 
-StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code){
+StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code, int type) {
     StatementList *tmp = memCalloc(1, sizeof(StatementList));
     tmp->condition = condition;
     tmp->var = var;
     tmp->code = code;
+    tmp->type = type;
     tmp->next = NULL;
     return tmp;
 }

+ 1 - 1
src/value.c

@@ -42,7 +42,7 @@ Value *makeFunctionValue(Statement *st, VarList *var_list, Inter *inter) {
     tmp = makeValue(inter);
     tmp->type = function;
     tmp->data.function.function = st;
-    tmp->data.function.var = copyVarList(var_list, true, inter);
+    tmp->data.function.var = copyVarList(var_list, false, inter);
     return tmp;
 }