Prechádzať zdrojové kódy

feat: if和while分支的as功能

可以使用if as和while as来获取逻辑判断的结果
SongZihuan 4 rokov pred
rodič
commit
744bef563a
2 zmenil súbory, kde vykonal 48 pridanie a 7 odobranie
  1. 39 5
      parser/grammar.c
  2. 9 2
      src/runbranch.c

+ 39 - 5
parser/grammar.c

@@ -169,10 +169,10 @@ void parserControl(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int typ
 
 void parserIf(PASERSSIGNATURE){
     Token *if_token = NULL, *code_token = NULL;
-    struct Statement *st = NULL, *else_st = NULL, *finally_st = NULL;
+    struct Statement *st = NULL, *var_st = NULL, *else_st = NULL, *finally_st = NULL;
     StatementList *sl = NULL;
     bool have_if = false;
-
+    // TODO-szh 设置重复警告 (添加PASS语句)
     again:
     switch (readBackToken(pm)) {
         case MATHER_IF:
@@ -190,6 +190,22 @@ void parserIf(PASERSSIGNATURE){
                 goto return_;
             }
             popAheadToken(if_token, pm);
+
+            if (readBackToken(pm) == MATHER_AS){
+                delToken(pm);
+                Token *var_token = NULL;
+                parserOperation(CALLPASERSSIGNATURE);
+                if (!call_success(pm))
+                    goto return_;
+                if (readBackToken(pm) != OPERATION){
+                    syntaxError(pm, "Don't get a if var", syntax_error);
+                    goto return_;
+                }
+                popAheadToken(var_token, pm);
+                var_st = var_token->data.st;
+                freeToken(var_token, true, false);
+            }
+
             parserCode(CALLPASERSSIGNATURE);
             if (!call_success(pm) && readBackToken(pm) != CODE){
                 error_:
@@ -198,9 +214,10 @@ void parserIf(PASERSSIGNATURE){
                 goto return_;
             }
             popAheadToken(code_token, pm);
-            sl = makeConnectStatementList(sl, if_token->data.st, NULL, code_token->data.st, if_b);
+            sl = makeConnectStatementList(sl, if_token->data.st, var_st, code_token->data.st, if_b);
             freeToken(if_token, true, false);
             freeToken(code_token, true, false);
+            var_st = NULL;
             goto again;
         case MATHER_DO:
             delToken(pm);
@@ -255,7 +272,7 @@ void parserIf(PASERSSIGNATURE){
 
 void parserWhile(PASERSSIGNATURE){
     Token *while_token = NULL, *code_token = NULL;
-    struct Statement *st = NULL, *else_st = NULL, *finally_st = NULL,*do_st = NULL;
+    struct Statement *st = NULL, *var_st = NULL, *else_st = NULL, *finally_st = NULL,*do_st = NULL;
     StatementList *sl = NULL;
     bool have_while = false;
 
@@ -276,6 +293,22 @@ void parserWhile(PASERSSIGNATURE){
                 goto return_;
             }
             popAheadToken(while_token, pm);
+
+            if (readBackToken(pm) == MATHER_AS){
+                delToken(pm);
+                Token *var_token = NULL;
+                parserOperation(CALLPASERSSIGNATURE);
+                if (!call_success(pm))
+                    goto return_;
+                if (readBackToken(pm) != OPERATION){
+                    syntaxError(pm, "Don't get a while var", syntax_error);
+                    goto return_;
+                }
+                popAheadToken(var_token, pm);
+                var_st = var_token->data.st;
+                freeToken(var_token, true, false);
+            }
+
             parserCode(CALLPASERSSIGNATURE);
             if (!call_success(pm) && readBackToken(pm) != CODE){
                 error_:
@@ -286,9 +319,10 @@ void parserWhile(PASERSSIGNATURE){
             popAheadToken(code_token, pm);
             if (sl != NULL)
                 freeStatementList(sl);
-            sl = makeStatementList(while_token->data.st, NULL, code_token->data.st, if_b);
+            sl = makeStatementList(while_token->data.st, var_st, code_token->data.st, if_b);
             freeToken(while_token, true, false);
             freeToken(code_token, true, false);
+            var_st = NULL;
             goto again;
         case MATHER_DO:
             delToken(pm);

+ 9 - 2
src/runbranch.c

@@ -22,11 +22,13 @@ Result ifBranch(INTER_FUNCTIONSIG) {
     while (if_list != NULL){
         if (if_list->type == if_b){
             Result tmp;
-            if (!is_rego && operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(if_list->condition, var_list))){
+            if (operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(if_list->condition, var_list))){
                 result = tmp;
                 set_result = false;
                 goto not_else;
             }
+            if (if_list->var != NULL)
+                assCore(if_list->var, tmp.value, inter, var_list);
             if (is_rego || checkBool(tmp.value->value)){
                 Result code_tmp;
                 is_rego = false;
@@ -83,6 +85,8 @@ Result whileBranch(INTER_FUNCTIONSIG) {
             set_result = false;
             goto not_else;
         }
+        if (while_list->var != NULL)
+            assCore(while_list->var, tmp.value, inter, var_list);
         if (checkBool(tmp.value->value)){
             Result code_tmp;
             if (cycleBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(while_list->code, var_list))){
@@ -98,7 +102,9 @@ Result whileBranch(INTER_FUNCTIONSIG) {
         else{
             break;
         }
-        if (st->u.while_branch.after != NULL && cycleBranchSafeInterStatement(&do_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.after, var_list))){
+        if (st->u.while_branch.after == NULL)
+            goto not_after_do;
+        if (cycleBranchSafeInterStatement(&do_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.after, var_list))){
             result = do_tmp;
             set_result = false;
             goto not_else;
@@ -107,6 +113,7 @@ Result whileBranch(INTER_FUNCTIONSIG) {
             goto not_else;  // 直接跳转到not_else
         if (do_tmp.type == continue_return)
             PASS;
+        not_after_do: PASS;
     }
     if (!is_break && st->u.while_branch.else_list != NULL && cycleBranchSafeInterStatement(&else_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.else_list, var_list))){
         set_result = false;