Procházet zdrojové kódy

feat: 添加rego和return功能, break语句会执行do部分的内容

允许使用rego和rego n跳转if语句
在while循环中使用break语句会执行后置do语句
while的do语句中支持使用break和continue语句
在函数中可以使用return语句

更新.gitignore, 去除冗余
SongZihuan před 4 roky
rodič
revize
6000a29b45
12 změnil soubory, kde provedl 120 přidání a 53 odebrání
  1. 0 22
      .gitignore
  2. 4 4
      include/__run.h
  3. 2 2
      include/grammar.h
  4. 2 0
      include/run.h
  5. 10 0
      include/statement.h
  6. 2 0
      include/token.h
  7. 1 0
      include/value.h
  8. 2 2
      main.c
  9. 12 7
      parser/grammar.c
  10. 13 2
      src/run.c
  11. 52 14
      src/runbranch.c
  12. 20 0
      src/statement.c

+ 0 - 22
.gitignore

@@ -216,24 +216,11 @@ Temporary Items
 *.iml
 out
 gen
-### C++ template
-# Prerequisites
-*.d
 
 # Compiled Object files
 *.slo
-*.lo
-*.o
-*.obj
-
-# Precompiled Headers
-*.gch
-*.pch
 
 # Compiled Dynamic libraries
-*.so
-*.dylib
-*.dll
 
 # Fortran module files
 *.mod
@@ -241,14 +228,5 @@ gen
 
 # Compiled Static libraries
 *.lai
-*.la
-*.a
-*.lib
-
-# Executables
-*.exe
-*.out
-*.app
-
 /Demo
 vgcore.* 

+ 4 - 4
include/__run.h

@@ -7,19 +7,19 @@
 #define printResult(result, first, last, debug) do{ \
 switch (result.value->value->type){ \
     case number: \
-        writeLog(debug, INFO, "%s%ld%s\n", first, result.value->value->data.num.num, last); \
+        writeLog(debug, INFO, first"%ld"last"\n", result.value->value->data.num.num); \
         break; \
     case string: \
-        writeLog(debug, INFO, "%s%s%s\n", first, result.value->value->data.str.str, last); \
+        writeLog(debug, INFO, first"%s"last"\n", result.value->value->data.str.str); \
         break; \
     case function: \
-        writeLog(debug, INFO, "%sfunction on %x%s\n", first, (int)result.value->value, last); \
+        writeLog(debug, INFO, "%sfunction on %lx%s\n", first, (unsigned long )result.value->value, last); \
         break; \
     case none: \
         writeLog(debug, INFO, "%sNone%s\n", first, last); \
         break; \
     default: \
-        writeLog(debug, INFO, "%sdefault on %x%s\n", first, (int)result.value->value, last); \
+        writeLog(debug, INFO, "%sdefault on %lx%s\n", first, (unsigned long )result.value->value, last); \
         break; \
 } \
 } while(0)

+ 2 - 2
include/grammar.h

@@ -20,7 +20,7 @@ typedef struct ParserMessage{
 } ParserMessage;
 
 ParserMessage *makeParserMessage(char *file_dir, char *debug);
-void freePasersMessage(ParserMessage *pm, bool self);
-void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st);
+void freeParserMessage(ParserMessage *pm, bool self);
+void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st);
 
 #endif //VIRTUALMATH_GRAMMAR_H

+ 2 - 0
include/run.h

@@ -20,4 +20,6 @@ Result whileBranch(INTER_FUNCTIONSIG);
 
 Result breakCycle(INTER_FUNCTIONSIG);
 Result continueCycle(INTER_FUNCTIONSIG);
+Result regoIf(INTER_FUNCTIONSIG);
+Result returnCode(INTER_FUNCTIONSIG);
 #endif //VIRTUALMATH_RUN_H

+ 10 - 0
include/statement.h

@@ -17,6 +17,8 @@ typedef struct Statement{
         with_branch,
         break_cycle,
         continue_cycle,
+        rego_if,
+        return_code,
     } type;
     union StatementU{
         struct base_value{
@@ -84,6 +86,12 @@ typedef struct Statement{
         struct {
             struct Statement *times;
         } continue_cycle;
+        struct {
+            struct Statement *times;
+        } rego_if;
+        struct {
+            struct Statement *value;
+        } return_code;
     }u;
     struct Statement *next;
 } Statement;
@@ -109,6 +117,8 @@ Statement *makeIfStatement();
 Statement *makeWhileStatement();
 Statement *makeBreakStatement(Statement *times);
 Statement *makeContinueStatement(Statement *times);
+Statement *makeRegoStatement(Statement *times);
+Statement *makeReturnStatement(Statement *value);
 
 void connectStatement(Statement *base, Statement *new);
 void freeStatement(Statement *st);

+ 2 - 0
include/token.h

@@ -101,6 +101,8 @@
 #define WHILE_BRANCH -16
 #define BREAK -17
 #define CONTINUE -18
+#define REGO -19
+#define RETURN -20
 
 typedef struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 1 - 0
include/value.h

@@ -40,6 +40,7 @@ typedef struct VirtualMathResult{
         error_return,  // 错误
         break_return,
         continue_return,
+        rego_return,
     } type;
     struct VirtualMathLinkValue *value;
     int times;

+ 2 - 2
main.c

@@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
     ParserMessage *pm = makeParserMessage(args.file, args.log_file);
 
     printf("[start to lexical]\n");
-    pasersCommandList(pm, global_iter, true, global_iter->statement);
+    parserCommandList(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);
@@ -51,7 +51,7 @@ int main(int argc, char *argv[]) {
     }
 
     return_:
-    freePasersMessage(pm, true);
+    freeParserMessage(pm, true);
     freeInter(global_iter, true);
     freeArgs();
     printf("[exit Virtual [0]]\n");

+ 12 - 7
parser/grammar.c

@@ -25,7 +25,7 @@ ParserMessage *makeParserMessage(char *file_dir, char *debug){
     return tmp;
 }
 
-void freePasersMessage(ParserMessage *pm, bool self) {
+void freeParserMessage(ParserMessage *pm, bool self) {
     freeTokenMessage(pm->tm, true);
 #if OUT_LOG
     if (pm->paser_debug != NULL)
@@ -41,12 +41,12 @@ void freePasersMessage(ParserMessage *pm, bool self) {
 
 /**
  * 命令表匹配
- * pasersCommandList :
+ * parserCommandList :
  * | MATHER_EOF
  * | parserCommand MATHER_ENTER
  * | parserCommand MATHER_EOF
  */
-void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st) {
+void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st) {
     int token_type, stop;
     struct Statement *base_st = st;
     while (true){
@@ -133,6 +133,12 @@ void parserCommand(PASERSSIGNATURE){
         case MATHER_CONTINUE :
             commandCallControl(pm, st, makeContinueStatement, CONTINUE, return_);
             break;
+        case MATHER_REGO :
+            commandCallControl(pm, st, makeRegoStatement, REGO, return_);
+            break;
+        case MATHER_RETURN :
+            commandCallControl(pm, st, makeReturnStatement, RETURN, return_);
+            break;
         default :
             commandCallBack(pm, st, parserOperation, OPERATION, return_);
             break;
@@ -385,8 +391,8 @@ void parserCode(PASERSSIGNATURE){
         break;  // 若匹配到{则跳出循环
         again_: checkToken(pm, MATHER_ENTER, return_);  // 若不是\n则跳到return_
     }
-    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call pasersCommandList\n", NULL);
-    pasersCommandList(CALLPASERSSIGNATURE, false, st);
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList\n", NULL);
+    parserCommandList(CALLPASERSSIGNATURE, false, st);
     if (!call_success(pm)){
         goto return_;
     }
@@ -395,7 +401,7 @@ void parserCode(PASERSSIGNATURE){
         goto return_;
     }
     popAheadToken(code_token, pm);
-    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call pasersCommandList success\n", NULL);
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList success\n", NULL);
     checkToken(pm, MATHER_RC, error_);
 
     return_:
@@ -406,7 +412,6 @@ void parserCode(PASERSSIGNATURE){
     error_:
     syntaxError(pm, "Don't get the }", syntax_error);
     freeToken(code_token, true, true);
-    return;
 }
 
 /**

+ 13 - 2
src/run.c

@@ -38,6 +38,12 @@ Result runStatement(INTER_FUNCTIONSIG) {
         case continue_cycle:
             result = continueCycle(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
+        case rego_if:
+            result = regoIf(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
+        case return_code:
+            result = returnCode(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
         default:
             setResult(&result, true, inter);
             break;
@@ -81,7 +87,7 @@ Result globalIterStatement(Inter *inter) {
             break;
         base_st = base_st->next;
     }
-    if (result.type != error_return || result.type != function_return)
+    if (result.type != error_return && result.type != function_return)
         setResult(&result, true, inter);
     return result;
 }
@@ -99,6 +105,11 @@ bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     if (result->type == not_return || result->type == operation_return){
         return false;
     }
+    if (result->type == rego_return){
+        result->times--;
+        if (result->times < 0)
+            return false;
+    }
     return true;
 }
 
@@ -122,7 +133,7 @@ bool functionSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     }
     else if (result->type == function_return){
         result->type = operation_return;
-        return false;
+        return true;
     }
     result->type = not_return;
     return false;

+ 52 - 14
src/runbranch.c

@@ -16,25 +16,29 @@ bool checkBool(Value *value){
 Result ifBranch(INTER_FUNCTIONSIG) {
     Result result, else_tmp, finally_tmp;
     StatementList *if_list = st->u.if_branch.if_list;
-    bool set_result = true;
+    bool set_result = true, is_rego = false;
 
     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))){
+            if (!is_rego && operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(if_list->condition, var_list))){
                 result = tmp;
                 set_result = false;
                 goto not_else;
             }
-            if (checkBool(tmp.value->value)){
+            if (is_rego || checkBool(tmp.value->value)){
                 Result code_tmp;
+                is_rego = false;
                 if (ifBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(if_list->code, var_list))){
                     result = code_tmp;
                     set_result = false;
                     goto not_else;
                 }
-                goto not_else;
+                if (code_tmp.type == rego_return)
+                    is_rego = true;
+                else
+                    goto not_else;
             }
         }
         else{
@@ -44,6 +48,8 @@ Result ifBranch(INTER_FUNCTIONSIG) {
                 set_result = false;
                 goto not_else;
             }
+            if (code_tmp.type == rego_return)
+                is_rego = true;
         }
         if_list = if_list->next;
     }
@@ -67,10 +73,10 @@ Result ifBranch(INTER_FUNCTIONSIG) {
 Result whileBranch(INTER_FUNCTIONSIG) {
     Result result, else_tmp, finally_tmp;
     StatementList *while_list = st->u.while_branch.while_list;
-    bool set_result = true;
+    bool set_result = true, is_break = false;
 
     var_list = pushVarList(var_list, inter);
-    while (true){
+    while (!is_break){
         Result tmp, do_tmp;
         if (operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(while_list->condition, var_list))){
             result = tmp;
@@ -85,7 +91,7 @@ Result whileBranch(INTER_FUNCTIONSIG) {
                 goto not_else;
             }
             if (code_tmp.type == break_return)
-                goto not_else;  // 不会执行else语句
+                is_break = true;
             if (code_tmp.type == continue_return)
                 PASS;
         }
@@ -97,8 +103,12 @@ Result whileBranch(INTER_FUNCTIONSIG) {
             set_result = false;
             goto not_else;
         }
+        if (do_tmp.type == break_return)
+            goto not_else;  // 直接跳转到not_else
+        if (do_tmp.type == continue_return)
+            PASS;
     }
-    if (st->u.while_branch.else_list != NULL && cycleBranchSafeInterStatement(&else_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.else_list, var_list))){
+    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;
         result = else_tmp;
     }
@@ -120,14 +130,13 @@ Result breakCycle(INTER_FUNCTIONSIG){
     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))){
+    if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.break_cycle.times, var_list)))
         return times;
-    }
+    // TODO-szh 类型检查处理
     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;
     }
@@ -139,16 +148,45 @@ Result continueCycle(INTER_FUNCTIONSIG){
     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))){
+    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;
 }
+
+Result regoIf(INTER_FUNCTIONSIG){
+    Result result, times;
+    int times_int = 0;
+    if (st->u.rego_if.times == NULL)
+        goto not_times;
+    if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.rego_if.times, var_list)))
+        return times;
+    times_int = (int)times.value->value->data.num.num;
+    not_times:
+    setResult(&result, true, inter);
+    if (times_int >= 0) {
+        result.type = rego_return;
+        result.times = times_int;
+    }
+    return result;
+}
+
+Result returnCode(INTER_FUNCTIONSIG){
+    Result result;
+    if (st->u.return_code.value == NULL) {
+        setResult(&result, true, inter);
+        goto set_result;
+    }
+    if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st->u.return_code.value, var_list)))
+        return result;
+
+    set_result:
+    result.type = function_return;
+    return result;
+}

+ 20 - 0
src/statement.c

@@ -79,6 +79,20 @@ Statement *makeContinueStatement(Statement *times){
     return tmp;
 }
 
+Statement *makeRegoStatement(Statement *times){
+    Statement *tmp = makeStatement();
+    tmp->type = rego_if;
+    tmp->u.rego_if.times = times;
+    return tmp;
+}
+
+Statement *makeReturnStatement(Statement *value){
+    Statement *tmp = makeStatement();
+    tmp->type = return_code;
+    tmp->u.rego_if.times = value;
+    return tmp;
+}
+
 void connectStatement(Statement *base, Statement *new){
     while (base->next != NULL){
         base = base->next;
@@ -143,6 +157,12 @@ void freeStatement(Statement *st){
             case continue_cycle:
                 freeStatement(st->u.continue_cycle.times);
                 break;
+            case rego_if:
+                freeStatement(st->u.rego_if.times);
+                break;
+            case return_code:
+                freeStatement(st->u.return_code.value);
+                break;
             default:
                 break;
         }