Quellcode durchsuchen

feat: 无参数函数、括号匹配、变量层次操作

使用def定义函数, 目前不支持参数
处理表达式返回值
错误处理
支持表达式使用括号
括号匹配是在grammar层面的
允许使用[n]a的形式操作变量
SongZihuan vor 4 Jahren
Ursprung
Commit
f75a30ffa7
18 geänderte Dateien mit 693 neuen und 99 gelöschten Zeilen
  1. 14 9
      include/__grammar.h
  2. 20 2
      include/__macro.h
  3. 7 1
      include/__run.h
  4. 0 2
      include/__virtualmath.h
  5. 5 0
      include/run.h
  6. 58 0
      include/statement.h
  7. 3 0
      include/token.h
  8. 13 2
      include/value.h
  9. 4 0
      include/var.h
  10. 7 2
      main.c
  11. 282 33
      parser/grammar.c
  12. 1 0
      src/inter.c
  13. 69 14
      src/operation.c
  14. 19 24
      src/run.c
  15. 37 0
      src/runcall.c
  16. 82 5
      src/statement.c
  17. 29 4
      src/value.c
  18. 43 1
      src/var.c

+ 14 - 9
include/__grammar.h

@@ -52,31 +52,36 @@ 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, false); \
+freeToken(tmp_token, true, del_st); \
 tmp_token = NULL; \
 }while(0)
 
-#define callChild(pm, status, token, call, type, error_) do{ \
-call(CALLPASERSSIGNATURE); \
-if (!call_success(pm)){ \
-goto error_; \
-} \
-readBackToken(status, pm); \
-if (status != type){ \
+#define checkToken(pm, type, error_) do{ \
+int token; \
+readBackToken(token, pm); \
+if (token != type){ \
 goto error_; \
 } \
-popAheadToken(token, pm); \
+delToken(pm); \
 }while(0)
 
 void parserCommand(PASERSSIGNATURE);
+void parserDef(PASERSSIGNATURE);
+void parserCode(PASERSSIGNATURE);
 void parserOperation(PASERSSIGNATURE);
 void parserPolynomial(PASERSSIGNATURE);
 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 *);
 
 #endif //VIRTUALMATH___GRAMMAR_H

+ 20 - 2
include/__macro.h

@@ -14,8 +14,10 @@
 
 #define NUMBER_TYPE long int
 #define HASH_INDEX unsigned int
-#define INTER_FUNCTIONSIG Statement *st, Inter *inter, VarList *var_list
-#define CALL_INTER_FUNCTIONSIG(st, var_list) st, inter, var_list
+#define INTER_FUNCTIONSIG_CORE Inter *inter, VarList *var_list
+#define INTER_FUNCTIONSIG Statement *st, INTER_FUNCTIONSIG_CORE
+#define CALL_INTER_FUNCTIONSIG_CORE(var_list) inter, var_list
+#define CALL_INTER_FUNCTIONSIG(st, var_list) st, CALL_INTER_FUNCTIONSIG_CORE(var_list)
 
 #define freeBase(element, return_) do{ \
 if (element == NULL){ \
@@ -23,4 +25,20 @@ goto return_; \
 } \
 }while(0) \
 
+#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; \
+} \
+}while(0) \
+
 #endif //VIRTUALMATH___MACRO_H

+ 7 - 1
include/__run.h

@@ -12,8 +12,14 @@ switch (result.value->value->type){ \
     case string: \
         writeLog(debug, INFO, "%s%s%s\n", first, result.value->value->data.str.str, last); \
         break; \
+    case function: \
+        writeLog(debug, INFO, "%sfunction on %x%s\n", first, (int)result.value->value, last); \
+        break; \
+    case none: \
+        writeLog(debug, INFO, "%sNone%s\n", first, last); \
+        break; \
     default: \
-        writeLog(debug, INFO, "%sdefault%s\n", first, last); \
+        writeLog(debug, INFO, "%sdefault on %x%s\n", first, (int)result.value->value, last); \
         break; \
 } \
 } while(0)

+ 0 - 2
include/__virtualmath.h

@@ -1,7 +1,6 @@
 #ifndef VIRTUALMATH___VIRTUALMATH_H
 #define VIRTUALMATH___VIRTUALMATH_H
 
-#define PRIVATE_INCLUDE false
 #include "__macro.h"
 #include "mem.h"
 #include "statement.h"
@@ -14,7 +13,6 @@
 #include "value.h"
 #include "inter.h"
 #include "log.h"
-#undef PRIVATE_INCLUDE
 
 struct Args{
     char *file;

+ 5 - 0
include/run.h

@@ -6,6 +6,11 @@
 
 Result iterStatement(INTER_FUNCTIONSIG);
 Result operationStatement(INTER_FUNCTIONSIG);
+Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE);
 Result globalIterStatement(Inter *inter);
+Result setFunction(INTER_FUNCTIONSIG);
+Result callFunction(INTER_FUNCTIONSIG);
+Result getBaseVar(INTER_FUNCTIONSIG);
+Result getBaseValue(INTER_FUNCTIONSIG);
 
 #endif //VIRTUALMATH_RUN_H

+ 58 - 0
include/statement.h

@@ -8,6 +8,13 @@ typedef struct Statement{
         base_value,
         base_var,
         operation,
+        set_function,
+        call_function,
+        if_branch,
+        while_branch,
+        for_branch,
+        try_branch,
+        with_branch,
     } type;
     union StatementU{
         struct base_value{
@@ -28,15 +35,66 @@ typedef struct Statement{
             struct Statement *left;
             struct Statement *right;
         } operation;
+        struct {
+            struct Statement *name;
+            struct Statement *function;
+        } set_function;
+        struct {
+            struct Statement *function;
+        } call_function;
+        struct {
+            struct StatementList *if_list;  // if elif
+            struct Statement *else_list;  // else分支(无condition)
+            struct Statement *finally;
+        } if_branch;
+        struct {
+            enum {
+                while_,
+                do_while_,
+            } type;
+            struct Statement *first;  // first do
+            struct StatementList *while_list;  // while循环体
+            struct Statement *after;  // after do
+            struct Statement *else_list;  // else分支(无condition)
+            struct Statement *finally;
+        } while_branch;
+        struct {
+            struct Statement *var;  // first do
+            struct Statement *iter;  // after do
+            struct StatementList *for_list;  // for循环体
+            struct Statement *else_list;  // else分支(无condition)
+            struct Statement *finally;
+        } for_branch;
+        struct {
+            struct Statement *try;  // first do
+            struct StatementList *except_list;  // for循环体
+            struct Statement *else_list;  // else分支(无condition)
+            struct Statement *finally;
+        } try_branch;
     }u;
     struct Statement *next;
 } Statement;
 
+typedef struct StatementList{
+    struct Statement *condition;
+    struct Statement *var;  // TODO-szh if等分支计算结果允许赋值
+    struct Statement *code;
+    struct StatementList *next;
+} StatementList;
+
 Statement *makeStatement();
 Statement *makeOperationStatement(int type);
 struct Token *setOperationFromToken(Statement *st, struct Token *left, struct Token *right, int type);
 
+Statement *makeFunctionStatement(Statement *name, Statement *function);
+Statement *makeCallStatement(Statement *function);
+
 void connectStatement(Statement *base, Statement *new);
 void freeStatement(Statement *st);
 
+StatementList *connectStatementList(StatementList *base, StatementList *new);
+StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code);
+void freeStatementList(StatementList *base);
+#define makeConnectStatementList(base, condition, var, code) connectStatementList(base, makeStatementList(condition, var, code))
+
 #endif //VIRTUALMATH_STATEMENT_H

+ 3 - 0
include/token.h

@@ -94,6 +94,9 @@
 #define FACTOR -9
 #define BASEVALUE -10
 #define ASSIGNMENT -11
+#define CODE -12
+#define FUNCTION -13
+#define CALLBACK -14
 
 typedef struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 13 - 2
include/value.h

@@ -4,8 +4,10 @@
 
 typedef struct VirtualMathValue{
     enum ValueType{
+        none=0,
         number=1,
         string,
+        function,
     } type;
     union data{
         struct Number{
@@ -14,6 +16,10 @@ typedef struct VirtualMathValue{
         struct String{
             char *str;
         } str;
+        struct {
+            struct Statement *function;
+            struct VirtualMathVarList *var;
+        } function;
     }data;
     struct VirtualMathValue *next;
     struct VirtualMathValue *last;
@@ -28,7 +34,10 @@ typedef struct VirtualMathLinkValue{
 
 typedef struct VirtualMathResult{
     enum ResultType{
-        statement_end = 1,
+        not_return = 1,  // 无返回值
+        function_return,  // 函数返回值
+        operation_return,  // 表达式返回值
+        error_return,  // 错误
     } type;
     struct VirtualMathLinkValue *value;
 } Result;
@@ -39,8 +48,10 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue,Inter *inter);
 void freeLinkValue(LinkValue *value, Inter *inter);
 Value *makeNumberValue(long num, Inter *inter);
 Value *makeStringValue(char *str, Inter *inter);
+Value *makeFunctionValue(Statement *st, struct VirtualMathVarList *var_list, Inter *inter);
 
 void setResult(Result *ru, bool link, Inter *inter);
-
+void setResultError(Result *ru, Inter *inter);
+void setResultOperation(Result *ru, Inter *inter);
 
 #endif //VIRTUALMATH_VALUE_H

+ 4 - 0
include/var.h

@@ -29,4 +29,8 @@ LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times);
 void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue *value);
 void freeHashTable(HashTable *ht, Inter *inter);
 
+VarList *pushVarList(VarList *base, Inter *inter);
+VarList *popVarList(VarList *base, Inter *inter);
+VarList *copyVarList(VarList *base, bool n_new, Inter *inter);
+
 #endif //VIRTUALMATH_VAR_H

+ 7 - 2
main.c

@@ -35,10 +35,15 @@ int main(int argc, char *argv[]) {
     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(stdout, ERROR, "Syntax Error: %s\n", pm->status_message);
+        writeLog(stderr, ERROR, "Syntax Error: %s\n", pm->status_message);
         goto return_;
     }
-    globalIterStatement(global_iter);
+    Result tmp;
+    tmp = globalIterStatement(global_iter);
+    if (tmp.type == error_return){
+        writeLog(global_iter->debug, ERROR, "Run Error\n", NULL);
+        writeLog(stderr, ERROR, "Run Error\n", NULL);
+    }
 
     return_:
     freePasersMessage(pm, true);

+ 282 - 33
parser/grammar.c

@@ -53,21 +53,17 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
         readBackToken(token_type, pm);
         if (token_type == MATHER_EOF){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command List: <EOF>\n", NULL);
-            Token *tmp;
-            popAheadToken(tmp, pm);
-            freeToken(tmp, true, false);
+            delToken(pm);
             goto return_;
         }
         else if (token_type == MATHER_ENTER){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command List: <ENTER>\n", NULL);
-            Token *tmp;
-            popAheadToken(tmp, pm);
-            freeToken(tmp, true, false);
+            delToken(pm);
             continue;
         }
         else{
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command List: call command\n", NULL);
-            Token *command_token,*stop_token;
+            Token *command_token;
             parserCommand(CALLPASERSSIGNATURE);
             if (!call_success(pm)){
                 goto return_;
@@ -82,13 +78,11 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
             popAheadToken(command_token, pm);
 
             readBackToken(stop, pm);
-            if (stop == MATHER_ENTER){
-                popAheadToken(stop_token, pm);
-                freeToken(stop_token, true, false);
+            if (stop == MATHER_ENTER || stop == MATHER_SEMICOLON){
+                delToken(pm);
             }
             else if(stop == MATHER_EOF){
-                popAheadToken(stop_token, pm);
-                backToken_(pm, stop_token);
+                PASS;
             }
             else{
                 if (global) {
@@ -96,9 +90,7 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
                     freeToken(command_token, true, true);
                 }
                 else{
-                    // 若非global模式, 即可以匹配大括号
-                    popAheadToken(stop_token, pm);
-                    backToken_(pm, stop_token);
+                    // 若非global模式, 即可以匹配大括号, token保留在ahead中
                     connectStatement(base_st, command_token->data.st);
                     freeToken(command_token, true, false);
                     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
@@ -126,21 +118,29 @@ void parserCommand(PASERSSIGNATURE){
     int token_type;
     Statement *st = NULL;
     readBackToken(token_type, pm);
-    if (false){
-        PASS;
+    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_int;
-        Token *command_token;
+        int command_type;
+        Token *command_token = NULL;
         parserOperation(CALLPASERSSIGNATURE);
-        if (!call_success(pm)){
+        if (!call_success(pm))
             goto return_;
-        }
-        readBackToken(command_int, pm);
-        if (command_int != OPERATION){
+        readBackToken(command_type, pm);
+        if (command_type != OPERATION)
             goto return_;
-        }
         popAheadToken(command_token, pm);
         /*...do something for command...*/
         st = command_token->data.st;
@@ -152,16 +152,123 @@ void parserCommand(PASERSSIGNATURE){
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get return\n", NULL);
 }
 
+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;
+}
+
+void parserDef(PASERSSIGNATURE){
+    int name_type, code;
+    Token *name_token = NULL, *code_token = NULL;
+    struct Statement *st = NULL;
+
+    checkToken(pm, MATHER_DEF, return_);
+    parserBaseValue(CALLPASERSSIGNATURE);
+    if (!call_success(pm))
+        goto return_;
+    readBackToken(name_type, pm);
+    if (name_type != BASEVALUE){
+        syntaxError(pm, "Don't get a function name", syntax_error);
+        goto return_;
+    }
+    popAheadToken(name_token, pm);
+
+    checkToken(pm, MATHER_LP, error_);
+    checkToken(pm, MATHER_RP, error_);
+    parserCode(CALLPASERSSIGNATURE);
+    if (!call_success(pm)){
+        goto error_;
+    }
+    readBackToken(code, pm);
+    if (code != CODE){
+        freeToken(name_token, true, true);
+        error_:
+        syntaxError(pm, "Don't get a function code", syntax_error);
+        goto return_;
+    }
+    popAheadToken(code_token, pm);
+
+    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;
+}
+
+void parserCode(PASERSSIGNATURE){
+    int code_type;
+    Token *code_token = NULL;
+    struct Statement *st = makeStatement();
+    while (true){
+        checkToken(pm, MATHER_LC, again_);  // 若匹配的不是{则检查是否匹配到\n
+        break;  // 若匹配到{则跳出循环
+        again_: checkToken(pm, MATHER_ENTER, return_);  // 若不是\n则跳到return_
+    }
+    pasersCommandList(CALLPASERSSIGNATURE, false, st);
+    if (!call_success(pm)){
+        goto return_;
+    }
+    readBackToken(code_type, pm);
+    if (code_type != COMMANDLIST){
+        syntaxError(pm, "Not CommandList\n", syntax_error);
+        goto return_;
+    }
+    popAheadToken(code_token, pm);
+    checkToken(pm, MATHER_RC, error_);
+
+    return_:
+    addStatementToken(CODE, st, pm);
+    freeToken(code_token, true, false);
+    return;
+
+    error_:
+    syntaxError(pm, "Don't get the }", syntax_error);
+    freeToken(code_token, true, true);
+    return;
+}
+
 /**
  * 表达式匹配
  * parserOperation:
  * | parserAssignment
  */
 void parserOperation(PASERSSIGNATURE){
-    int operation_int;
-    Token *operation_token;
+    int operation_type;
+    Token *operation_token = NULL;
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: call assignment\n", NULL);
-    callChild(pm, operation_int, operation_token, parserAssignment, ASSIGNMENT, return_);
+    parserAssignment(CALLPASERSSIGNATURE);
+    if (!call_success(pm))
+        goto return_;
+    readBackToken(operation_type, pm);
+    if (operation_type != ASSIGNMENT){
+        goto return_;
+    }
+    popAheadToken(operation_token, pm);
     /*...do something for operation...*/
 
     addStatementToken(OPERATION, operation_token->data.st, pm);
@@ -239,8 +346,53 @@ bool switchFactor(PASERSSIGNATURE, int symbol, Statement **st){
     return true;
 }
 void parserFactor(PASERSSIGNATURE){
-    return twoOperation(CALLPASERSSIGNATURE, parserBaseValue, switchFactor, BASEVALUE, FACTOR,
-                        "base value", "factor");
+    return twoOperation(CALLPASERSSIGNATURE, parserCallBack, switchFactor, CALLBACK, FACTOR,
+                        "call back", "factor");
+}
+
+int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
+    int symbol;
+    readBackToken(symbol, pm);
+    if (symbol != MATHER_LP){
+        return -1;
+    }
+    delToken(pm);
+    checkToken(pm, MATHER_RP, error_);
+    *st = makeCallStatement(left_token->data.st);
+    return 1;
+
+    error_:
+    syntaxError(pm, "Don't get ) from call back", syntax_error);
+    return 0;
+}
+void parserCallBack(PASERSSIGNATURE){
+    return tailOperation(CALLPASERSSIGNATURE, parserBaseValue, tailCall, BASEVALUE, CALLBACK,
+            "Base Value", "Call Back");
+}
+
+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){
+        return 0;
+    }
+    popAheadToken(operation_token, pm);
+
+    readBackToken(rp, pm);
+    if (right_type != rp){
+        return -1;
+    }
+    delToken(pm);
+
+    *st = operation_token->data.st;
+    freeToken(operation_token, true, false);
+    return 1;
 }
 
 /**
@@ -251,7 +403,7 @@ void parserFactor(PASERSSIGNATURE){
  */
 void parserBaseValue(PASERSSIGNATURE){
     int token_type;
-    Token *value_token;
+    Token *value_token = NULL;
     struct Statement *st = NULL;
     readBackToken(token_type, pm);
     if(MATHER_NUMBER == token_type){
@@ -277,6 +429,50 @@ void parserBaseValue(PASERSSIGNATURE){
         st->u.base_var.name = memStrcpy(value_token->data.str, 0, false, false);
         st->u.base_var.times = NULL;
     }
+    else if(MATHER_LB == token_type){
+        int var, tmp;
+        Statement *tmp_st = NULL;
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
+        popAheadToken(value_token, pm);
+
+        tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RB, &tmp_st, "base value");
+        if (tmp == 0){
+            freeToken(value_token, true, true);
+            syntaxError(pm, "Don't get operation from list/var", syntax_error);
+            goto return_;
+        }
+        else if(tmp == -1){
+            freeToken(value_token, true, true);
+            syntaxError(pm, "Don't get ] from list/var", syntax_error);
+            goto return_;
+        }
+        readBackToken(var, pm);
+        if (MATHER_VAR == var){
+            Token *var_token;
+            popAheadToken(var_token, pm);
+            st = makeStatement();
+            st->type = base_var;
+            st->u.base_var.name = memStrcpy(var_token->data.str, 0, false, false);
+            st->u.base_var.times = tmp_st;
+            freeToken(var_token, true, false);
+        }
+        // TODO-szh list处理
+    }
+    else if(MATHER_LP == token_type){
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
+        popAheadToken(value_token, pm);
+        int tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RP, &st, "base value");
+        if (tmp == 0){
+            freeToken(value_token, true, true);
+            syntaxError(pm, "Don't get operation from Base Value", syntax_error);
+            goto return_;
+        }
+        else if(tmp == -1){
+            freeToken(value_token, true, true);
+            syntaxError(pm, "Don't get ) from Base Value", syntax_error);
+            goto return_;
+        }
+    }
     else{
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: else\n", NULL);
         goto return_;
@@ -291,22 +487,29 @@ 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, *symbol_token, *right_token;
+        Token *left_token = NULL, *symbol_token = NULL, *right_token = NULL;
         struct Statement *st = NULL;
 
         readBackToken(left, pm);
         if (left != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
-            callChild(pm, left, left_token, callBack, type, return_);
+            callBack(CALLPASERSSIGNATURE);
+            if (!call_success(pm))
+                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);
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
                       "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
             continue;
         }
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
         popAheadToken(left_token, pm);
 
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
         readBackToken(symbol, pm);
         if (getSymbol(CALLPASERSSIGNATURE, symbol, &st)){
             delToken(pm);
@@ -345,6 +548,52 @@ inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int
     return;
 }
 
+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;
+        struct Statement *st = NULL;
+
+        readBackToken(left, pm);
+        if (left != 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){
+                goto return_;
+            }
+            popAheadToken(left_token, pm);
+            addStatementToken(self_type, left_token->data.st, pm);
+            freeToken(left_token, true, false);
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
+                      "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
+            continue;
+        }
+        popAheadToken(left_token, pm);
+
+        int tail_status = tailFunction(CALLPASERSSIGNATURE, left_token, &st);
+        if (tail_status == -1){
+            backToken_(pm, left_token);
+            goto return_;
+        }
+        else if(!tail_status){
+            goto error_;
+        }
+        addStatementToken(self_type, st, pm);
+        freeToken(left_token, true, false);
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call tail success\n", self_name);
+        continue;
+
+        error_:
+        freeToken(left_token, true, true);
+        goto return_;
+    }
+    return_:
+    return;
+}
+
 /**
  * syntax错误处理器
  * @param pm

+ 1 - 0
src/inter.c

@@ -7,6 +7,7 @@ Inter *makeInter(char *debug){
     tmp->statement = makeStatement();
     tmp->var_list = makeVarList(tmp);
     tmp->log_dir = memStrcpy(debug, 0, false, false);
+    makeValue(tmp);  // 注册None值
     if (debug != NULL && !args.stdout_inter){
         char *debug_dir = memStrcat(debug, INTER_LOG);
         tmp->debug = fopen(debug_dir, "w");

+ 69 - 14
src/operation.c

@@ -1,13 +1,21 @@
-#include "__virtualmath.h"
+#include "__run.h"
 /**
  * operation.c中是用于数学计算的函数
  */
 
-#define getresult(base, var, inter) var = iterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation. base, var_list))
+#define getresult(base, var, inter) safeIterStatement(var, CALL_INTER_FUNCTIONSIG(st->u.operation. base, var_list))
 #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
 #define valueToResult(result, result_value, type, inter) result.value->value = make##type##Value(result_value, inter)
+#define noneOperation(left, right, result) do{ \
+if (left.value->value->type == none){ \
+result = right; \
+} \
+else if (right.value->value->type == none){ \
+result = left; \
+} \
+} while(0)
 
 Result addOperation(INTER_FUNCTIONSIG);
 Result subOperation(INTER_FUNCTIONSIG);
@@ -24,7 +32,6 @@ Result assOperation(INTER_FUNCTIONSIG);
  */
 Result operationStatement(INTER_FUNCTIONSIG) {
     Result result;
-    setResult(&result, true, inter);
     switch (st->u.operation.OperationType) {
         case ADD:
             result = addOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -42,6 +49,7 @@ Result operationStatement(INTER_FUNCTIONSIG) {
             result = assOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
         default:
+            setResult(&result, true, inter);
             break;
     }
     return result;
@@ -49,7 +57,7 @@ Result operationStatement(INTER_FUNCTIONSIG) {
 
 Result addOperation(INTER_FUNCTIONSIG) {
     Result left, right, result;
-    setResult(&result, true, inter);
+    setResultOperation(&result, inter);
     getresult(left, left, inter);
     getresult(right, right, inter);
     if (viewtype(left, right, number)){
@@ -60,23 +68,25 @@ Result addOperation(INTER_FUNCTIONSIG) {
         valueToResult(result, new_string, String, inter);
         memFree(new_string);
     }
+    noneOperation(left, right, result);
     return result;
 }
 
 Result subOperation(INTER_FUNCTIONSIG) {
     Result left, right, result;
-    setResult(&result, true, inter);
+    setResultOperation(&result, inter);
     getresult(left, left, inter);
     getresult(right, right, inter);
     if (viewtype(left, right, number)){
         valueToResult(result, (operationValue(left, right, num.num, -)), Number, inter);
     }
+    noneOperation(left, right, result);
     return result;
 }
 
 Result mulOperation(INTER_FUNCTIONSIG) {
     Result left, right, result;
-    setResult(&result, true, inter);
+    setResultOperation(&result, inter);
     getresult(left, left, inter);
     getresult(right, right, inter);
     if (viewtype(left, right, number)){
@@ -96,33 +106,78 @@ Result mulOperation(INTER_FUNCTIONSIG) {
             memFree(new_string);
         }
     }
+    noneOperation(left, right, result);
     return result;
 }
 
 Result divOperation(INTER_FUNCTIONSIG) {
     Result left, right, result;
-    setResult(&result, true, inter);
+    setResultOperation(&result, inter);
     getresult(left, left, inter);
     getresult(right, right, inter);
     if (viewtype(left, right, number)){
         valueToResult(result, (operationValue(left, right, num.num, /)), Number, inter);
     }
+    noneOperation(left, right, result);
     return result;
 }
 
 Result assOperation(INTER_FUNCTIONSIG) {
-    Result times, right;
+    Result result, times;
+    getresult(right, result, inter);
+    times = assCore(st->u.operation.left, result.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    checkResult(times);
+    return result;
+}
+
+Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
+    Result times;
     int int_times;
-    getresult(right, right, inter);
-    if (st->u.operation.left->type == base_var){
-        if (st->u.operation.left->u.base_var.times == NULL){
+    if (name->type == base_var){
+        if (name->u.base_var.times == NULL){
             int_times = 0;
+            setResult(&times, true, inter);
             goto not_times;
         }
-        times = iterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.left->u.base_var.times, var_list));
+
+        safeIterStatement(times, CALL_INTER_FUNCTIONSIG(name->u.base_var.times, var_list));
+
+        times = iterStatement(CALL_INTER_FUNCTIONSIG(name->u.base_var.times, var_list));
         int_times = (int)times.value->value->data.num.num;
         not_times:
-        addFromVarList(st->u.operation.left->u.base_var.name, var_list, int_times, right.value);
+        addFromVarList(name->u.base_var.name, var_list, int_times, value);
+    }
+    else{
+        setResult(&times, true, inter);
     }
-    return right;
+    return times;
+}
+
+Result getBaseVar(INTER_FUNCTIONSIG) {
+    Result times, result;
+    int int_times;
+    setResultOperation(&result, inter);
+
+    if (st->u.base_var.times == NULL){
+        int_times = 0;
+        goto not_times;
+    }
+    safeIterStatement(times, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list));
+    int_times = (int)times.value->value->data.num.num;
+
+    not_times:
+    result.value = findFromVarList(st->u.base_var.name, var_list, int_times);
+    if (result.value == NULL){
+        writeLog_(inter->debug, WARNING, "var not found[%s]\n", st->u.base_var.name);
+        setResultError(&result, inter);
+    }
+    return result;
+}
+
+Result getBaseValue(INTER_FUNCTIONSIG) {
+    Result result;
+    setResult(&result, true, inter);
+    result.value->value = st->u.base_value.value;
+    result.type = operation_return;
+    return result;
 }

+ 19 - 24
src/run.c

@@ -1,23 +1,5 @@
 #include "__run.h"
 
-Result getBaseVar(INTER_FUNCTIONSIG) {
-    Result times, result;
-    int int_times;
-    if (st->u.base_var.times == NULL){
-        int_times = 0;
-        goto not_times;
-    }
-    times = iterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list));
-    int_times = (int)times.value->value->data.num.num;
-
-    not_times:
-    result.value = findFromVarList(st->u.base_var.name, var_list, int_times);
-    if (result.value == NULL){
-        writeLog_(inter->debug, WARNING, "not found[%s]\n", st->u.base_var.name);
-    }
-    return result;
-}
-
 /**
  * 运行单个statement
  * @param st
@@ -27,10 +9,9 @@ Result getBaseVar(INTER_FUNCTIONSIG) {
  */
 Result runStatement(INTER_FUNCTIONSIG) {
     Result result;
-    setResult(&result, true, inter);
     switch (st->type) {
         case base_value:
-            result.value->value = st->u.base_value.value;
+            result = getBaseValue(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
         case base_var:
             result = getBaseVar(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -39,7 +20,14 @@ Result runStatement(INTER_FUNCTIONSIG) {
             result = operationStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
             printResult(result, "operation result = ", "", inter->debug);
             break;
+        case set_function:
+            result = setFunction(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
+        case call_function:
+            result = callFunction(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
         default:
+            setResult(&result, true, inter);
             break;
     }
     return result;
@@ -55,11 +43,14 @@ Result runStatement(INTER_FUNCTIONSIG) {
 Result iterStatement(INTER_FUNCTIONSIG) {
     Result result;
     Statement *base_st = st;
-    VarList *new_var_list = var_list;
     while(base_st != NULL){
-        result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, new_var_list));
+        result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
+        if (!runContinue(result))
+            break;
         base_st = base_st->next;
     }
+    if (result.type == not_return)
+        setResult(&result, true, inter);
     return result;
 }
 
@@ -71,10 +62,14 @@ Result iterStatement(INTER_FUNCTIONSIG) {
 Result globalIterStatement(Inter *inter) {
     Result result;
     Statement *base_st = inter->statement;
-    VarList *new_var_list = inter->var_list;
+    VarList *var_list = inter->var_list;
     while(base_st != NULL){
-        result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, new_var_list));
+        result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
+        if (!runContinue(result))
+            break;
         base_st = base_st->next;
     }
+    if (result.type != error_return || result.type != function_return)
+        setResult(&result, true, inter);
     return result;
 }

+ 37 - 0
src/runcall.c

@@ -0,0 +1,37 @@
+#include "__run.h"
+
+Result setFunction(INTER_FUNCTIONSIG) {
+    Result result, tmp;
+    setResultOperation(&tmp, inter);
+
+    tmp.value->value = makeFunctionValue(st->u.set_function.function, var_list, inter);
+    result = assCore(st->u.set_function.name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    return result;
+}
+
+Result callFunction(INTER_FUNCTIONSIG) {
+    Result call_function, result;
+
+    safeIterStatement(call_function, CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list));
+    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;
+
+    return_:
+    return result;
+}

+ 82 - 5
src/statement.c

@@ -1,16 +1,14 @@
 #include "__virtualmath.h"
 
 Statement *makeStatement(){
-    Statement *tmp;
-    tmp = memCalloc(1, sizeof(Statement));
+    Statement *tmp = memCalloc(1, sizeof(Statement));
     tmp->type = start;
     tmp->next = NULL;
     return tmp;
 }
 
 Statement *makeOperationStatement(int type){
-    Statement *tmp;
-    tmp = memCalloc(1, sizeof(Statement));
+    Statement *tmp = makeStatement();
     tmp->type = operation;
     tmp->u.operation.OperationType = type;
     tmp->u.operation.left = NULL;
@@ -19,7 +17,7 @@ Statement *makeOperationStatement(int type){
 }
 
 Token *setOperationFromToken(Statement *st, Token *left, Token *right, int type) {
-    Token *new_token;
+    Token *new_token = NULL;
     st->u.operation.left = left->data.st;
     st->u.operation.right = right->data.st;
     new_token = makeToken();
@@ -31,6 +29,21 @@ Token *setOperationFromToken(Statement *st, Token *left, Token *right, int type)
     return new_token;
 }
 
+Statement *makeFunctionStatement(Statement *name, Statement *function){
+    Statement *tmp = makeStatement();
+    tmp->type = set_function;
+    tmp->u.set_function.name = name;
+    tmp->u.set_function.function = function;
+    return tmp;
+}
+
+Statement *makeCallStatement(Statement *function){
+    Statement *tmp = makeStatement();
+    tmp->type = call_function;
+    tmp->u.call_function.function = function;
+    return tmp;
+}
+
 void connectStatement(Statement *base, Statement *new){
     while (base->next != NULL){
         base = base->next;
@@ -43,6 +56,7 @@ void freeStatement(Statement *st){
     Statement *next_tmp;
     while (st != NULL){
         switch (st->type) {
+            // base-value 不需要释放
             case operation:
                 freeStatement(st->u.operation.right);
                 freeStatement(st->u.operation.left);
@@ -51,6 +65,38 @@ void freeStatement(Statement *st){
                 memFree(st->u.base_var.name);
                 freeStatement(st->u.base_var.times);
                 break;
+            case set_function:
+                freeStatement(st->u.set_function.name);
+                freeStatement(st->u.set_function.function);
+                break;
+            case call_function:
+                freeStatement(st->u.call_function.function);
+                break;
+            case if_branch:
+                freeStatementList(st->u.if_branch.if_list);
+                freeStatement(st->u.if_branch.finally);
+                freeStatement(st->u.if_branch.else_list);
+                break;
+            case while_branch:
+                freeStatementList(st->u.while_branch.while_list);
+                freeStatement(st->u.while_branch.first);
+                freeStatement(st->u.while_branch.after);
+                freeStatement(st->u.while_branch.else_list);
+                freeStatement(st->u.while_branch.finally);
+                break;
+            case for_branch:
+                freeStatementList(st->u.for_branch.for_list);
+                freeStatement(st->u.for_branch.var);
+                freeStatement(st->u.for_branch.iter);
+                freeStatement(st->u.for_branch.else_list);
+                freeStatement(st->u.for_branch.finally);
+                break;
+            case try_branch:
+                freeStatementList(st->u.try_branch.except_list);
+                freeStatement(st->u.try_branch.try);
+                freeStatement(st->u.try_branch.else_list);
+                freeStatement(st->u.try_branch.finally);
+                break;
             default:
                 break;
         }
@@ -61,3 +107,34 @@ void freeStatement(Statement *st){
     return_:
     return;
 }
+
+StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code){
+    StatementList *tmp = memCalloc(1, sizeof(StatementList));
+    tmp->condition = condition;
+    tmp->var = var;
+    tmp->code = code;
+    tmp->next = NULL;
+    return tmp;
+}
+
+StatementList *connectStatementList(StatementList *base, StatementList *new){
+    StatementList *tmp = base;
+    if (base == NULL)
+        return new;
+    while (tmp->next != NULL){
+        tmp = tmp->next;
+    }
+    tmp->next = new;
+    return base;
+}
+
+void freeStatementList(StatementList *base){
+    while (base != NULL){
+        freeStatement(base->condition);
+        freeStatement(base->code);
+        freeStatement(base->var);
+        StatementList *tmp = base;
+        base = base->next;
+        memFree(tmp);
+    }
+}

+ 29 - 4
src/value.c

@@ -3,8 +3,7 @@
 Value *makeValue(Inter *inter) {
     Value *tmp, *list_tmp = inter->base;
     tmp = memCalloc(1, sizeof(Value));
-    tmp->type = number;
-    tmp->data.num.num = 0;
+    tmp->type = none;
     tmp->next = NULL;
     if (list_tmp == NULL){
         inter->base = tmp;
@@ -38,6 +37,15 @@ Value *makeStringValue(char *str, Inter *inter) {
     return tmp;
 }
 
+Value *makeFunctionValue(Statement *st, VarList *var_list, Inter *inter) {
+    Value *tmp;
+    tmp = makeValue(inter);
+    tmp->type = function;
+    tmp->data.function.function = st;
+    tmp->data.function.var = copyVarList(var_list, true, inter);
+    return tmp;
+}
+
 void freeValue(Value *value, Inter *inter){
     freeBase(value, return_);
     if (value->last == NULL){
@@ -53,6 +61,12 @@ void freeValue(Value *value, Inter *inter){
         case string:
             memFree(value->data.str.str);
             break;
+        case function: {
+            VarList *tmp = value->data.function.var;
+            while (tmp != NULL)
+                tmp = freeVarList(tmp, true);
+            break;
+        }
         default:
             break;
     }
@@ -99,8 +113,19 @@ void freeLinkValue(LinkValue *value, Inter *inter){
 }
 
 void setResult(Result *ru, bool link, Inter *inter) {
-    ru->type = statement_end;
+    ru->type = not_return;
     if (link){
-        ru->value = makeLinkValue(NULL, NULL, inter);
+        // inter->base即None值
+        ru->value = makeLinkValue(inter->base, NULL, inter);
     }
 }
+
+void setResultError(Result *ru, Inter *inter) {
+    ru->type = error_return;
+    ru->value = makeLinkValue(inter->base, NULL, inter);
+}
+
+void setResultOperation(Result *ru, Inter *inter) {
+    ru->type = operation_return;
+    ru->value = makeLinkValue(inter->base, NULL, inter);
+}

+ 43 - 1
src/var.c

@@ -105,10 +105,21 @@ void addVar(char *name, LinkValue *value, VarList *var_list){
         var_list->hashtable->hashtable[index] = makeVar(name, value);
         goto return_;
     }
-    while (base->next != NULL){
+    while (true){
+        if (base->next != NULL)
+            goto new_one;
+        if (eqString(base->name, name))
+            goto change;
         base = base->next;
     }
+    new_one:
     base->next = makeVar(name, value);
+    goto return_;
+
+    change:
+    base->value = value;
+    goto return_;
+
     return_:
     return;
 }
@@ -153,3 +164,34 @@ void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue
     }
     addVar(name, value, var_list);
 }
+
+VarList *pushVarList(VarList *base, Inter *inter){
+    VarList *new = makeVarList(inter);
+    new->next = base;
+    return new;
+}
+
+VarList *popVarList(VarList *base, Inter *inter){
+    if (base->next == NULL)
+        return base;
+    return freeVarList(base, true);
+}
+
+VarList *copyVarListCore(VarList *base, Inter *inter){
+    VarList *tmp = makeVarList(inter);
+    tmp->hashtable = base->hashtable;
+    return tmp;
+}
+
+VarList *copyVarList(VarList *base, bool n_new, Inter *inter){
+    VarList *new, *tmp;
+    new = tmp = copyVarListCore(base, inter);
+    while (base->next != NULL){
+        tmp->next = copyVarListCore(base->next, inter);
+        tmp = tmp->next;
+        base = base->next;
+    }
+    if (n_new)
+        new = pushVarList(new, inter);
+    return new;
+}