Selaa lähdekoodia

feat: 允许定义tuple

设置printValue和printLinkValue函数
可以可视化list
调整了参数匹配器的参数:
设定list不匹配name_value
形参只出现一个*表达式
设定dict不匹配only_value和*表达式
实参允许only_value, name_value等全部类型
SongZihuan 4 vuotta sitten
vanhempi
sitoutus
580f98ea49
17 muutettua tiedostoa jossa 496 lisäystä ja 281 poistoa
  1. 2 1
      include/__grammar.h
  2. 2 1
      include/__macro.h
  3. 0 19
      include/__run.h
  4. 6 3
      include/parameter.h
  5. 1 0
      include/run.h
  6. 9 0
      include/statement.h
  7. 4 3
      include/token.h
  8. 14 0
      include/value.h
  9. 0 1
      include/var.h
  10. 1 1
      main.c
  11. 210 0
      parser/__grammar.c
  12. 96 231
      parser/grammar.c
  13. 12 0
      src/operation.c
  14. 41 4
      src/parameter.c
  15. 11 8
      src/run.c
  16. 20 9
      src/statement.c
  17. 67 0
      src/value.c

+ 2 - 1
include/__grammar.h

@@ -20,7 +20,7 @@ writeLog(pm->paser_debug, pasers_level, "\n"message, __VA_ARGS__); \
 #define addStatementToken(type, st, pm) addBackToken(pm->tm->ts, makeStatementToken(type, st), pm->paser_debug)
 #define delToken(pm) freeToken(popAheadToken(pm), true, false)
 #define backToken_(pm, token) addBackToken(pm->tm->ts, (token), pm->paser_debug)
-#define addEnter(pm) backToken_(pm, makeLexToken(MATHER_ENTER, NULL, NULL))
+#define addLexToken(pm, type) backToken_(pm, makeLexToken(type, NULL, NULL))
 #define addToken_ backToken_
 #define call_success(pm) (pm->status == success)
 
@@ -37,6 +37,7 @@ void parserBaseValue(PASERSSIGNATURE);
 void parserCallBack(PASERSSIGNATURE);
 void parserFactor(PASERSSIGNATURE);
 void parserAssignment(PASERSSIGNATURE);
+void parserTuple(PASERSSIGNATURE);
 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 *);
 

+ 2 - 1
include/__macro.h

@@ -26,7 +26,8 @@ goto return_; \
 } \
 }while(0) \
 
-#define runContinue(result) (result.type == not_return || result.type == operation_return)
+#define run_continue(result) (result.type == not_return || result.type == operation_return)
+#define run_continue_(result) (result->type == not_return || result->type == operation_return)
 #define is_error(result) (result.type == error_return)
 
 #define checkResult(check_result) do{ \

+ 0 - 19
include/__run.h

@@ -4,25 +4,6 @@
 #include "__virtualmath.h"
 
 #if OUT_INTER_LOG && OUT_INTER_LOG
-#define printResult(result, first, last, debug) do{ \
-switch (result.value->value->type){ \
-    case number: \
-        writeLog(debug, INFO, first"%ld"last"\n", result.value->value->data.num.num); \
-        break; \
-    case string: \
-        writeLog(debug, INFO, first"%s"last"\n", result.value->value->data.str.str); \
-        break; \
-    case function: \
-        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 %lx%s\n", first, (unsigned long )result.value->value, last); \
-        break; \
-} \
-} while(0)
 #define writeLog_(...) writeLog(__VA_ARGS__)
 #else
 #define printResult(...)

+ 6 - 3
include/parameter.h

@@ -6,6 +6,7 @@ typedef struct Parameter{
     enum {
         only_value,
         name_value,
+        only_args,
     } type;
     struct {
         struct Statement *value;
@@ -16,10 +17,12 @@ typedef struct Parameter{
 
 Parameter *makeParameter();
 Parameter *makeOnlyValueParameter(struct Statement *st);
-Parameter *makeNameValueParameter(Statement *value, Statement *name);
+Parameter *makeNameValueParameter(struct Statement *value, struct Statement *name);
+Parameter *makeOnlyArgsParameter(Statement *st);
 Parameter *connectParameter(Parameter *new, Parameter *base);
 Parameter *connectOnlyValueParameter(struct Statement *st, Parameter *base);
-Parameter *connectNameValueParameter(Statement *value, Statement *name, Parameter *base);
+Parameter *connectNameValueParameter(struct Statement *value, struct Statement *name, Parameter *base);
+Parameter *connectOnlyArgsParameter(Statement *st, Parameter *base);
 void freeParameter(Parameter *pt);
-Result setParameter(Parameter *call, Parameter *function, VarList *function_var, INTER_FUNCTIONSIG_CORE);
+struct VirtualMathResult setParameter(Parameter *call, Parameter *function, struct VirtualMathVarList *function_var, INTER_FUNCTIONSIG_CORE);
 #endif //VIRTUALMATH_PARAMETER_H

+ 1 - 0
include/run.h

@@ -16,6 +16,7 @@ Result setFunction(INTER_FUNCTIONSIG);
 Result callFunction(INTER_FUNCTIONSIG);
 Result getBaseVar(INTER_FUNCTIONSIG);
 Result getBaseValue(INTER_FUNCTIONSIG);
+Result getList(INTER_FUNCTIONSIG);
 Result ifBranch(INTER_FUNCTIONSIG);
 Result whileBranch(INTER_FUNCTIONSIG);
 Result tryBranch(INTER_FUNCTIONSIG);

+ 9 - 0
include/statement.h

@@ -6,6 +6,7 @@ typedef struct Statement{
     enum StatementType{
         start = 1,
         base_value,
+        base_list,
         base_var,
         operation,
         set_function,
@@ -30,6 +31,13 @@ typedef struct Statement{
             char *name;
             struct Statement *times;
         } base_var;
+        struct {
+            enum{
+                list_,
+                tuple_,
+            } type;
+            struct Parameter *list;
+        } base_list;
         struct operation{
             enum OperationType{
                 ADD = 1,
@@ -123,6 +131,7 @@ Statement *makeStatement();
 Statement *makeOperationStatement(int type);
 struct Token *setOperationFromToken(Statement *st, struct Token *left, struct Token *right, int type);
 
+Statement *makeTupleStatement(struct Parameter *pt, int type);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);
 Statement *makeIfStatement();

+ 4 - 3
include/token.h

@@ -104,9 +104,10 @@
 #define CONTINUE -18
 #define REGO -19
 #define RETURN -20
-#define RESTART -20
-#define TRY_BRANCH -21
-#define RAISE -20
+#define RESTART -21
+#define TRY_BRANCH -22
+#define RAISE -23
+#define TUPLE -24
 
 typedef struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 14 - 0
include/value.h

@@ -8,6 +8,7 @@ typedef struct VirtualMathValue{
         number=1,
         string,
         function,
+        list,
     } type;
     union data{
         struct Number{
@@ -21,6 +22,14 @@ typedef struct VirtualMathValue{
             struct VirtualMathVarList *var;
             struct Parameter *pt;
         } function;
+        struct {
+            enum {
+                value_tuple,
+                value_list,
+            } type;
+            struct VirtualMathLinkValue **list;
+            long int size;
+        } list;
     }data;
     struct VirtualMathValue *next;
     struct VirtualMathValue *last;
@@ -56,9 +65,14 @@ void freeLinkValue(LinkValue *value, Inter *inter);
 Value *makeNumberValue(long num, Inter *inter);
 Value *makeStringValue(char *str, Inter *inter);
 Value *makeFunctionValue(Statement *st, struct Parameter *pt, struct VirtualMathVarList *var_list, Inter *inter);
+Value *makeListValue(struct Parameter **pt_ad, Result *result_tmp, struct globalInterpreter *inter, struct VirtualMathVarList *var_list,
+                     int type);
 
 void setResult(Result *ru, bool link, Inter *inter);
 void setResultError(Result *ru, Inter *inter);
 void setResultOperation(Result *ru, Inter *inter);
 
+void printValue(Value *value, FILE *debug);
+void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug);
+
 #endif //VIRTUALMATH_VALUE_H

+ 0 - 1
include/var.h

@@ -1,7 +1,6 @@
 #ifndef VIRTUALMATH_VAR_H
 #define VIRTUALMATH_VAR_H
 #include "inter.h"
-#include "value.h"
 
 #define MAX_SIZE (1024)
 

+ 1 - 1
main.c

@@ -118,6 +118,6 @@ void freeArgs(){
 }
 
 /*
- *  TODO-szh 函数参数
  *  TODO-szh 列表、字典
+ *  TODO-szh 赋值语句从右执行到左边
  */

+ 210 - 0
parser/__grammar.c

@@ -0,0 +1,210 @@
+#include "__grammar.h"
+
+inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int , Statement **), int type, int self_type, char *call_name, char *self_name){
+    while(true){
+        Token *left_token = NULL, *right_token = NULL;
+        struct Statement *st = NULL;
+
+        readBackToken(pm);
+        if (readBackToken(pm) != self_type){
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
+            if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
+                goto return_;
+            addStatementToken(self_type, st, pm);
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
+                      "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
+            continue;
+        }
+        left_token= popAheadToken(pm);
+
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
+        if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st)){
+            delToken(pm);
+        }
+        else{
+            backToken_(pm, left_token);
+            goto return_;
+        }
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
+                  "%s: get symbol success\n%s: call %s[right]\n", self_name, self_name, call_name);
+
+        callBack(CALLPASERSSIGNATURE);  // 获得右值
+        if (!call_success(pm)){
+            freeToken(left_token, true, false);
+            freeStatement(st);
+            goto return_;
+        }
+        if (readBackToken(pm) != type){  // 若非正确数值
+            syntaxError(pm, syntax_error, 3, "ERROR from ", self_name, "(get right)");
+            freeToken(left_token, true, true);
+            freeStatement(st);
+            goto return_;
+        }
+
+        right_token= popAheadToken(pm);
+        addToken_(pm, setOperationFromToken(st, left_token, right_token, self_type));
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: get base value(right) success[push polynomial]\n", NULL);
+    }
+    return_:
+    return;
+}
+
+inline void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*tailFunction)(PASERSSIGNATURE, Token *,  Statement **), int type, int self_type, char *call_name, char *self_name){
+    while(true){
+        Token *left_token = NULL;
+        struct Statement *st = NULL;
+
+        if (readBackToken(pm) != self_type){
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
+            if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
+                goto return_;
+            addStatementToken(self_type, st, pm);
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
+                      "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
+            continue;
+        }
+        left_token= popAheadToken(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
+ * @param message 错误信息
+ * @param status 错误类型
+ */
+void syntaxError(ParserMessage *pm, int status, int num, ...) {
+    if (pm->status != success)
+        return;
+
+    char *message = NULL;
+    va_list message_args;
+    if (status <= 0){
+        message = "Not message";
+        goto not_message;
+    }
+    va_start(message_args, num);
+    for (int i=0; i < num; i++) {
+        char *new_message;
+        new_message = memStrcat(message, va_arg(message_args, char *));
+        memFree(message);
+        message = new_message;
+    }
+    va_end(message_args);
+
+    not_message:
+    pm->status = status;
+    pm->status_message = message;
+}
+
+int readBackToken(ParserMessage *pm){
+    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 ++;
+    Token *tmp = popNewToken(pm->tm, pm->paser_debug);
+    if (tmp->token_type == -2){
+        freeToken(tmp, true, false);
+        syntaxError(pm, lexical_error, 1, "lexical make some error");
+    }
+    addBackToken(pm->tm->ts, tmp, pm->paser_debug);
+    return tmp->token_type;
+}
+
+Token *popAheadToken(ParserMessage *pm){
+    doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count ++);
+    return popNewToken(pm->tm, pm->paser_debug);
+}
+
+bool checkToken_(ParserMessage *pm, int type){
+    if (readBackToken(pm) != type){
+        return false;
+    }
+    delToken(pm);
+    return true;
+}
+
+bool commandCallControl_(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type, Statement **st, char *message){
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, message, NULL);
+    Token *tmp_token = NULL;
+    parserControl(CALLPASERSSIGNATURE, callBack, type);
+    if (!call_success(pm) || readBackToken(pm) != type)
+        return false;
+    tmp_token = popAheadToken(pm);
+    *st = tmp_token->data.st;
+    freeToken(tmp_token, true, false);
+    return true;
+}
+
+inline bool commandCallBack_(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int type, Statement **st, char *message){
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, message, NULL);
+    return callChildStatement(CALLPASERSSIGNATURE, callBack, type, st, NULL);
+}
+
+bool callParserCode(PASERSSIGNATURE, Statement **st,char *message){
+    Statement *new_st = NULL;
+    if(!callChildStatement(CALLPASERSSIGNATURE, parserCode, CODE, &new_st, message)){
+        return false;
+    }
+    if (*st != NULL)
+        freeStatement(*st);
+    *st = new_st;
+    return true;
+}
+
+bool callParserAs(PASERSSIGNATURE, Statement **st,char *message){
+    if (readBackToken(pm) == MATHER_AS) {
+        delToken(pm);
+        return callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, message);
+    }
+    else
+        *st = NULL;
+    return true;
+}
+
+bool callChildToken(ParserMessage *pm, Inter *inter, void (*call)(ParserMessage *, Inter *), int type, Token **tmp,
+                    char *message, int error_type) {
+    call(CALLPASERSSIGNATURE);
+    if (!call_success(pm)) {
+        *tmp = NULL;
+        return false;
+    }
+    if (readBackToken(pm) != type) {
+        *tmp = NULL;
+        if (message != NULL)
+            syntaxError(pm, error_type, 1, message);
+        return false;
+    }
+    *tmp = popAheadToken(pm);
+    return true;
+}
+
+bool callChildStatement(PASERSSIGNATURE, void (*call)(PASERSSIGNATURE), int type, Statement **st, char *message){
+    Token *tmp = NULL;
+    bool status = callChildToken(CALLPASERSSIGNATURE, call, type, &tmp, message, syntax_error);
+    if (!status){
+        *st = NULL;
+        return false;
+    }
+    *st = tmp->data.st;
+    freeToken(tmp, true, false);
+    return true;
+}

+ 96 - 231
parser/grammar.c

@@ -238,7 +238,7 @@ void parserIf(PASERSSIGNATURE){
             break;
         default:{
             default_:
-            addEnter(pm);
+            addLexToken(pm, MATHER_ENTER);
             break;
         }
     }
@@ -317,7 +317,7 @@ void parserWhile(PASERSSIGNATURE){
             break;
         default: {
             default_:
-            addEnter(pm);
+            addLexToken(pm, MATHER_ENTER);
             break;
         }
     }
@@ -390,7 +390,7 @@ void parserTry(PASERSSIGNATURE){
             break;
         default: {
             default_:
-            addEnter(pm);
+            addLexToken(pm, MATHER_ENTER);
             break;
         }
     }
@@ -411,28 +411,51 @@ void parserTry(PASERSSIGNATURE){
     return;
 }
 
-bool parserParameter(PASERSSIGNATURE, Parameter **pt){
+/**
+ * @param pm
+ * @param inter
+ * @param pt
+ * @param is_formal 是否为形式参数, 若为true,则限定*args为only_value的结尾, **kwargs为name_value结尾
+ * @param is_list 若为true则关闭对name_value和**kwargs的支持
+ * @param is_dict 若为true则关闭对only_value和*args的支持
+ * @param sep 设定分割符号
+ * @param ass 设定赋值符号
+ * @return
+ */
+bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_formal, bool is_list, bool is_dict, int sep,
+                int ass) {
     Parameter *new_pt = NULL;
     Token *tmp;
     enum {
         s_1,  // only_value模式
         s_2,  // name_value模式
-    } status = s_1;
+        s_3,  // only_args模式
+    } status;
+    if (is_dict)
+        status = s_2;  // is_formal关闭对only_value的支持
+    else
+        status = s_1;
     bool last_pt = false;
     while (!last_pt){
         tmp = NULL;
+        if (!is_dict && status != s_2 && checkToken_(pm, MATHER_MUL))  // // is_formal关闭对*args的支持
+            status = s_3;
         parserPolynomial(CALLPASERSSIGNATURE);
         if (!call_success(pm))
             goto error_;
-        if (readBackToken(pm) != POLYNOMIAL)
+        if (readBackToken(pm) != POLYNOMIAL) {
+            if (status == s_3) {
+                syntaxError(pm, syntax_error, 1, "Don't get a parameter after *");
+                goto error_;
+            }
             break;
+        }
         tmp = popAheadToken(pm);
 
-        int pt_type;
+        int pt_type = only_value;
         if (status == s_1){
-            pt_type = only_value;
-            if (!checkToken_(pm, MATHER_COMMA)){
-                if (!checkToken_(pm, MATHER_ASSIGNMENT))
+            if (!checkToken_(pm, sep)){
+                if (is_list || !checkToken_(pm, is_formal))  // // is_list关闭对name_value的支持
                     last_pt = true;
                 else {
                     pt_type = name_value;
@@ -440,22 +463,34 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt){
                 }
             }
         }
-        else{
+        else if (status == s_2){
             pt_type = name_value;
-            if (!checkToken_(pm, MATHER_ASSIGNMENT))
+            if (!checkToken_(pm, is_formal))
                 goto error_;
         }
+        else if (status == s_3){
+            pt_type = only_args;
+            if (!checkToken_(pm, sep))
+                last_pt = true;
+        }
 
         if (pt_type == only_value)
             new_pt = connectOnlyValueParameter(tmp->data.st, new_pt);
         else if (pt_type == name_value){
             Statement *tmp_value;
-            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &tmp_value, "Don't get a parameter value"))
+            if (!callChildStatement(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp_value, "Don't get a parameter value"))
                 goto error_;
             new_pt = connectNameValueParameter(tmp_value, tmp->data.st, new_pt);
-            if (!checkToken_(pm, MATHER_COMMA))
+            if (!checkToken_(pm, sep))
                 last_pt = true;
         }
+        else if (pt_type == only_args){
+            new_pt = connectOnlyArgsParameter(tmp->data.st, new_pt);
+            if (is_formal)
+                status = s_2;  // 是否规定*args只出现一次
+            else
+                status = s_1;
+        }
         freeToken(tmp, true, false);
     }
     *pt = new_pt;
@@ -476,27 +511,34 @@ void parserDef(PASERSSIGNATURE){
     if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &name_tmp, "Don't get a function name"))
         goto error_;
 
-    if (!checkToken_(pm, MATHER_LP))
+    if (!checkToken_(pm, MATHER_LP)) {
+        syntaxError(pm, syntax_error, 1, "Don't get a function ( before parameter");
         goto error_;
-    if (!parserParameter(CALLPASERSSIGNATURE, &pt))
+    }
+    if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+        syntaxError(pm, syntax_error, 1, "Don't get a function parameter");
         goto error_;
-    if (!checkToken_(pm, MATHER_RP))
+    }
+    if (!checkToken_(pm, MATHER_RP)) {
+        syntaxError(pm, syntax_error, 1, "Don't get a function ) after parameter");
         goto 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);
 
-    if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code"))
+    if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code")) {
+        syntaxError(pm, syntax_error, 1, "Don't get a function code");
         goto error_;
+    }
 
     st = makeFunctionStatement(name_tmp, code_tmp, pt);
-    addEnter(pm);
+    addLexToken(pm, MATHER_ENTER);
     addStatementToken(FUNCTION, st, pm);
     return;
 
     error_:
     freeStatement(name_tmp);
     freeStatement(code_tmp);
-    syntaxError(pm, syntax_error, 1, "Don't get a function code");
     return;
 }
 
@@ -572,10 +614,42 @@ bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
     return true;
 }
 void parserAssignment(PASERSSIGNATURE){
-    return twoOperation(CALLPASERSSIGNATURE, parserPolynomial, switchAssignment, POLYNOMIAL, ASSIGNMENT,
+    return twoOperation(CALLPASERSSIGNATURE, parserTuple, switchAssignment, TUPLE, ASSIGNMENT,
                         "polynomial", "assignment");
 }
 
+/**
+ * 元组匹配
+ * parserTuple
+ * | switchPolynomial
+ * | parserTuple COMMA switchPolynomial
+ * @param pm
+ * @param inter
+ */
+void parserTuple(PASERSSIGNATURE){
+    struct Parameter *pt = NULL;
+    struct Statement *st = NULL;
+    Token *tmp = NULL;
+    if (!callChildToken(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp, NULL, syntax_error))
+        goto return_;
+    if (!checkToken_(pm, MATHER_COMMA)){  // TODO-szh 需要弹出token才可以检查
+        tmp->token_type = TUPLE;
+        addToken_(pm ,tmp);
+        goto return_;
+    }
+    addLexToken(pm, MATHER_COMMA);
+    addToken_(pm ,tmp);
+    if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, true, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+        syntaxError(pm, syntax_error, 1, "Don't get tuple element");
+        goto return_;
+    }
+    st = makeTupleStatement(pt, tuple_);
+    addStatementToken(TUPLE, st, pm);
+
+    return_:
+    return;
+}
+
 /**
  * 多项式匹配
  * parserPolynomial:
@@ -631,7 +705,7 @@ int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
     if (readBackToken(pm) != MATHER_LP)
         return -1;
     delToken(pm);
-    if (!parserParameter(CALLPASERSSIGNATURE, &pt)) {
+    if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
         syntaxError(pm, syntax_error, 1, "Don't get call parameter");
         return 0;
     }
@@ -746,212 +820,3 @@ void parserBaseValue(PASERSSIGNATURE){
     return_:
     return;
 }
-
-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){
-        Token *left_token = NULL, *right_token = NULL;
-        struct Statement *st = NULL;
-
-        readBackToken(pm);
-        if (readBackToken(pm) != self_type){
-            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
-            if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
-                goto return_;
-            addStatementToken(self_type, st, pm);
-            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
-                      "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
-            continue;
-        }
-        left_token= popAheadToken(pm);
-
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
-        if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st)){
-            delToken(pm);
-        }
-        else{
-            backToken_(pm, left_token);
-            goto return_;
-        }
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
-                  "%s: get symbol success\n%s: call %s[right]\n", self_name, self_name, call_name);
-
-        callBack(CALLPASERSSIGNATURE);  // 获得右值
-        if (!call_success(pm)){
-            freeToken(left_token, true, false);
-            freeStatement(st);
-            goto return_;
-        }
-        if (readBackToken(pm) != type){  // 若非正确数值
-            syntaxError(pm, syntax_error, 3, "ERROR from ", self_name, "(get right)");
-            freeToken(left_token, true, true);
-            freeStatement(st);
-            goto return_;
-        }
-
-        right_token= popAheadToken(pm);
-        addToken_(pm, setOperationFromToken(st, left_token, right_token, self_type));
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: get base value(right) success[push polynomial]\n", NULL);
-    }
-    return_:
-    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){
-        Token *left_token = NULL;
-        struct Statement *st = NULL;
-
-        if (readBackToken(pm) != self_type){
-            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
-            if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
-                goto return_;
-            addStatementToken(self_type, st, pm);
-            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
-                      "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
-            continue;
-        }
-        left_token= popAheadToken(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
- * @param message 错误信息
- * @param status 错误类型
- */
-void syntaxError(ParserMessage *pm, int status, int num, ...) {
-    if (pm->status != success)
-        return;
-
-    char *message = NULL;
-    va_list message_args;
-    if (status <= 0){
-        message = "Not message";
-        goto not_message;
-    }
-    va_start(message_args, num);
-    for (int i=0; i < num; i++) {
-        char *new_message;
-        new_message = memStrcat(message, va_arg(message_args, char *));
-        memFree(message);
-        message = new_message;
-    }
-    va_end(message_args);
-
-    not_message:
-    pm->status = status;
-    pm->status_message = message;
-}
-
-int readBackToken(ParserMessage *pm){
-    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 ++;
-    Token *tmp = popNewToken(pm->tm, pm->paser_debug);
-    if (tmp->token_type == -2){
-        freeToken(tmp, true, false);
-        syntaxError(pm, lexical_error, 1, "lexical make some error");
-    }
-    addBackToken(pm->tm->ts, tmp, pm->paser_debug);
-    return tmp->token_type;
-}
-
-Token *popAheadToken(ParserMessage *pm){
-    doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count ++);
-    return popNewToken(pm->tm, pm->paser_debug);
-}
-
-bool checkToken_(ParserMessage *pm, int type){
-    if (readBackToken(pm) != type){
-        return false;
-    }
-    delToken(pm);
-    return true;
-}
-
-bool commandCallControl_(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type, Statement **st, char *message){
-    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "message", NULL);
-    Token *tmp_token = NULL;
-    parserControl(CALLPASERSSIGNATURE, callBack, type);
-    if (!call_success(pm) || readBackToken(pm) != type)
-        return false;
-    tmp_token = popAheadToken(pm);
-    *st = tmp_token->data.st;
-    freeToken(tmp_token, true, false);
-    return true;
-}
-
-inline bool commandCallBack_(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int type, Statement **st, char *message){
-    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, message, NULL);
-    return callChildStatement(CALLPASERSSIGNATURE, callBack, type, st, NULL);
-}
-
-bool callParserCode(PASERSSIGNATURE, Statement **st,char *message){
-    Statement *new_st = NULL;
-    if(!callChildStatement(CALLPASERSSIGNATURE, parserCode, CODE, &new_st, message)){
-        return false;
-    }
-    if (*st != NULL)
-        freeStatement(*st);
-    *st = new_st;
-    return true;
-}
-
-bool callParserAs(PASERSSIGNATURE, Statement **st,char *message){
-    if (readBackToken(pm) == MATHER_AS) {
-        delToken(pm);
-        return callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, message);
-    }
-    else
-        *st = NULL;
-    return true;
-}
-
-bool callChildToken(ParserMessage *pm, Inter *inter, void (*call)(ParserMessage *, Inter *), int type, Token **tmp,
-                    char *message, int error_type) {
-    call(CALLPASERSSIGNATURE);
-    if (!call_success(pm)) {
-        *tmp = NULL;
-        return false;
-    }
-    if (readBackToken(pm) != type) {
-        *tmp = NULL;
-        if (message != NULL)
-            syntaxError(pm, error_type, 1, message);
-        return false;
-    }
-    *tmp = popAheadToken(pm);
-    return true;
-}
-
-bool callChildStatement(PASERSSIGNATURE, void (*call)(PASERSSIGNATURE), int type, Statement **st, char *message){
-    Token *tmp = NULL;
-    bool status = callChildToken(CALLPASERSSIGNATURE, call, type, &tmp, message, syntax_error);
-    if (!status){
-        *st = NULL;
-        return false;
-    }
-    *st = tmp->data.st;
-    freeToken(tmp, true, false);
-    return true;
-}

+ 12 - 0
src/operation.c

@@ -183,3 +183,15 @@ Result getBaseValue(INTER_FUNCTIONSIG) {
     result.type = operation_return;
     return result;
 }
+
+Result getList(INTER_FUNCTIONSIG) {
+    Result tmp, result;
+    Parameter *tmp_pt = st->u.base_list.list;  // 避免直接传入st->u.base_list.list的指针导致其值发生改变
+    int type = st->u.base_list.type == tuple_ ? value_tuple : value_list;
+    Value *value = makeListValue(&tmp_pt, &tmp, CALL_INTER_FUNCTIONSIG_CORE(var_list), type);
+    if (!run_continue(tmp))
+        return tmp;
+    setResultOperation(&result ,inter);
+    result.value->value = value;
+    return result;
+}

+ 41 - 4
src/parameter.c

@@ -23,13 +23,21 @@ Parameter *makeNameValueParameter(Statement *value, Statement *name){
     return tmp;
 }
 
+Parameter *makeOnlyArgsParameter(Statement *st){
+    Parameter *tmp = makeParameter();
+    tmp->type = only_args;
+    tmp->data.value = st;
+    return tmp;
+}
+
 Parameter *connectParameter(Parameter *new, Parameter *base){
     if (base == NULL)
         return new;
+    Parameter *tmp = base;
     while (base->next != NULL)
         base = base->next;
     base->next = new;
-    return base;
+    return tmp;
 }
 
 Parameter *connectOnlyValueParameter(Statement *st, Parameter *base){
@@ -42,6 +50,11 @@ Parameter *connectNameValueParameter(Statement *value, Statement *name, Paramete
     return connectParameter(new, base);
 }
 
+Parameter *connectOnlyArgsParameter(Statement *st, Parameter *base){
+    Parameter *new = makeOnlyArgsParameter(st);
+    return connectParameter(new, base);
+}
+
 void freeParameter(Parameter *pt){
     while (pt != NULL){
         freeStatement(pt->data.value);
@@ -133,7 +146,7 @@ Result nameParameter(Parameter **call_ad, VarList *function_var, INTER_FUNCTIONS
 Result valueParameter(Parameter **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE){
     Parameter *call = *call_ad, *function = *function_ad;
     Result result;
-    while (call != NULL && function != NULL && call->type != name_value){
+    while (call != NULL && function != NULL && call->type != name_value && function->type != only_args){
         Result tmp, tmp_ass;
         Statement *name = function->type == only_value ? function->data.value : function->data.name;
 
@@ -160,7 +173,7 @@ Result valueParameter(Parameter **call_ad, Parameter **function_ad, VarList *fun
 }
 
 #define returnResult(result) do{ \
-if (result.type == error_return) { \
+if (!run_continue(result)) { \
 return result; \
 } \
 }while(0)
@@ -172,6 +185,10 @@ return result; \
  * [1] -实参完成, 形参空缺-> [2]
  * [3] 实际参数直接赋值, 形式默认值补充
  * [1] -实参出现name_value类型-> [3]
+ * [4] 把剩余的only_name实参转化为list
+ * [1] -形参遇到only_args->[4]
+ * [4] -实参完成-> [2]
+ * [4] -实参未完成-> [3]
  * @param call
  * @param function
  * @param function_var
@@ -184,11 +201,11 @@ Result setParameter(Parameter *call, Parameter *function, VarList *function_var,
         p_1 = 1,
         p_2 = 2,
         p_3 = 3,
+        p_4 = 4,
         error = -1,
         finished = 0
     } status = p_1;
     Result result;
-
     while (true){
         switch (status) {
             case p_1: {
@@ -198,6 +215,8 @@ Result setParameter(Parameter *call, Parameter *function, VarList *function_var,
                     status = p_3;
                 else if (call == NULL && function != NULL && function->type == name_value)
                     status = p_2;
+                else if (call != NULL && function != NULL && function->type == only_args && call->type == only_value)
+                    status = p_4;
                 else if (call != NULL || function != NULL)
                     status = error;
                 else
@@ -226,6 +245,24 @@ Result setParameter(Parameter *call, Parameter *function, VarList *function_var,
                 status = finished;
                 break;
             }
+            case p_4: {
+                Result tmp_result;
+                Value *value = makeListValue(&call, &tmp_result, CALL_INTER_FUNCTIONSIG_CORE(var_list), value_tuple);
+                returnResult(tmp_result);
+                LinkValue *tmp = makeLinkValue(value, NULL, inter);
+                tmp_result = assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_CORE(function_var));
+                returnResult(tmp_result);
+                function = function->next;
+                if (call != NULL && function != NULL && call->type == name_value)
+                    status = p_3;
+                else if (call == NULL && function != NULL && function->type == name_value)
+                    status = p_2;
+                else if (call != NULL || function != NULL)
+                    status = error;
+                else
+                    status = finished;
+                break;
+            }
             case error:
                 setResultError(&result, inter);
                 return result;

+ 11 - 8
src/run.c

@@ -16,9 +16,12 @@ Result runStatement(INTER_FUNCTIONSIG) {
         case base_var:
             result = getBaseVar(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
+        case base_list:
+            result = getList(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
         case operation:
             result = operationStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
-            printResult(result, "operation result = ", "", inter->debug);
+            printLinkValue(result.value, "operation result = ", "\n", inter->debug);
             break;
         case set_function:
             result = setFunction(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -75,7 +78,7 @@ Result iterStatement(INTER_FUNCTIONSIG) {
         base_st = st;
         while (base_st != NULL) {
             result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
-            if (!runContinue(result))
+            if (!run_continue(result))
                 break;
             base_st = base_st->next;
         }
@@ -104,7 +107,7 @@ Result globalIterStatement(Inter *inter) {
         var_list = inter->var_list;
         while (base_st != NULL) {
             result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
-            if (!runContinue(result))
+            if (!run_continue(result))
                 break;
             base_st = base_st->next;
         }
@@ -120,14 +123,14 @@ Result globalIterStatement(Inter *inter) {
 // 若需要中断执行, 则返回true
 bool operationSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
-    if (result->type == not_return || result->type == operation_return)
+    if (run_continue_(result))
         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){
+    if (run_continue_(result)){
         return false;
     }
     if (result->type == rego_return){
@@ -142,7 +145,7 @@ bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 
 bool cycleBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
-    if (result->type == not_return || result->type == operation_return){
+    if (run_continue_(result)){
         return false;
     }
     if (result->type == break_return || result->type == continue_return){
@@ -157,7 +160,7 @@ bool cycleBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 
 bool tryBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
-    if (result->type == not_return || result->type == operation_return){
+    if (run_continue_(result)){
         return false;
     }
     if (result->type == restart_return)
@@ -176,4 +179,4 @@ bool functionSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
     }
     result->type = not_return;
     return false;
-}
+}

+ 20 - 9
src/statement.c

@@ -7,15 +7,6 @@ Statement *makeStatement(){
     return tmp;
 }
 
-Statement *makeOperationStatement(int type){
-    Statement *tmp = makeStatement();
-    tmp->type = operation;
-    tmp->u.operation.OperationType = type;
-    tmp->u.operation.left = NULL;
-    tmp->u.operation.right = NULL;
-    return tmp;
-}
-
 Token *setOperationFromToken(Statement *st, Token *left, Token *right, int type) {
     Token *new_token = NULL;
     st->u.operation.left = left->data.st;
@@ -29,6 +20,23 @@ Token *setOperationFromToken(Statement *st, Token *left, Token *right, int type)
     return new_token;
 }
 
+Statement *makeOperationStatement(int type){
+    Statement *tmp = makeStatement();
+    tmp->type = operation;
+    tmp->u.operation.OperationType = type;
+    tmp->u.operation.left = NULL;
+    tmp->u.operation.right = NULL;
+    return tmp;
+}
+
+Statement *makeTupleStatement(Parameter *pt, int type) {
+    Statement *tmp = makeStatement();
+    tmp->type = base_list;
+    tmp->u.base_list.type = type;
+    tmp->u.base_list.list = pt;
+    return tmp;
+}
+
 Statement *makeFunctionStatement(Statement *name, Statement *function, Parameter *pt) {
     Statement *tmp = makeStatement();
     tmp->type = set_function;
@@ -149,6 +157,9 @@ void freeStatement(Statement *st){
                 freeStatement(st->u.call_function.function);
                 freeParameter(st->u.call_function.parameter);
                 break;
+            case base_list:
+                freeParameter(st->u.base_list.list);
+                break;
             case if_branch:
                 freeStatementList(st->u.if_branch.if_list);
                 freeStatement(st->u.if_branch.finally);

+ 67 - 0
src/value.c

@@ -47,6 +47,32 @@ Value *makeFunctionValue(Statement *st, Parameter *pt, VarList *var_list, Inter
     return tmp;
 }
 
+Value *makeListValue(Parameter **pt_ad, Result *result_tmp, struct globalInterpreter *inter, struct VirtualMathVarList *var_list,
+                     int type) {
+    Value *tmp;
+    Parameter *pt = *pt_ad;
+    tmp = makeValue(inter);
+    tmp->type = list;
+    tmp->data.list.type = type;
+    tmp->data.list.list = NULL;
+    tmp->data.list.size = 0;
+    while (pt != NULL && pt->type == only_value){  // TODO-szh 支持only_args
+        Result element;
+        if(operationSafeInterStatement(&element, CALL_INTER_FUNCTIONSIG(pt->data.value, var_list))) {
+            *result_tmp = element;
+            goto return_;
+        }
+        tmp->data.list.size++;
+        tmp->data.list.list = memRealloc(tmp->data.list.list, tmp->data.list.size * sizeof(LinkValue *));
+        tmp->data.list.list[tmp->data.list.size - 1] = element.value;
+        pt = pt->next;
+    }
+    setResult(result_tmp, true, inter);
+    return_:
+    *pt_ad = pt;
+    return tmp;
+}
+
 void freeValue(Value *value, Inter *inter){
     freeBase(value, return_);
     if (value->last == NULL){
@@ -69,6 +95,9 @@ void freeValue(Value *value, Inter *inter){
                 tmp = freeVarList(tmp, true);
             break;
         }
+        case list:
+            memFree(value->data.list.list);
+            break;
         default:
             break;
     }
@@ -131,3 +160,41 @@ void setResultOperation(Result *ru, Inter *inter) {
     ru->type = operation_return;
     ru->value = makeLinkValue(inter->base, NULL, inter);
 }
+
+void printValue(Value *value, FILE *debug){
+    switch (value->type){
+        case number:
+            writeLog(debug, INFO, "<%ld>", value->data.num.num);
+            break;
+        case string:
+            writeLog(debug, INFO, "<'%s'>", value->data.str.str);
+            break;
+        case function:
+            writeLog(debug, INFO, "function on <%lx>", (unsigned long )value);
+            break;
+        case list:
+            writeLog(debug, INFO, "list on %lx, size = %d, [", (unsigned long )value, (int)value->data.list.size);
+            for (int i=0;i < value->data.list.size;i++){
+                printLinkValue(value->data.list.list[i], "", "", debug);
+            }
+            writeLog(debug, INFO, "]", NULL);
+            break;
+        case none:
+            writeLog(debug, INFO, "<None>", NULL);
+            break;
+        default:
+            writeLog(debug, INFO, "default on <%lx>", (unsigned long )value);
+            break;
+    }
+}
+
+void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug){
+    writeLog(debug, INFO, "%s", first);
+    if (value->father != NULL) {
+        printLinkValue(value->father, "", "", debug);
+        writeLog(debug, INFO, " . ", NULL);
+    }
+    printValue(value->value, debug);
+    writeLog(debug, INFO, "%s", last);
+}
+