Przeglądaj źródła

feat & refactor & style: 实参支持*args星号表达式

修改了value、var等结构体名, 使其typedef前后一致
添加Argument结构提, 取代Parameter的base_value设定
在函数赋值时, 提前计算所有的实参
list支持星号表达式
SongZihuan 4 lat temu
rodzic
commit
ed5efae303
12 zmienionych plików z 313 dodań i 160 usunięć
  1. 1 1
      include/__macro.h
  2. 5 5
      include/__virtualmath.h
  3. 5 5
      include/inter.h
  4. 28 4
      include/parameter.h
  5. 1 1
      include/statement.h
  6. 16 16
      include/value.h
  7. 10 10
      include/var.h
  8. 7 7
      parser/grammar.c
  9. 10 6
      src/operation.c
  10. 221 87
      src/parameter.c
  11. 2 3
      src/statement.c
  12. 7 15
      src/value.c

+ 1 - 1
include/__macro.h

@@ -15,7 +15,7 @@
 
 #define NUMBER_TYPE long int
 #define HASH_INDEX unsigned int
-#define INTER_FUNCTIONSIG_CORE struct globalInterpreter *inter, struct VirtualMathVarList *var_list
+#define INTER_FUNCTIONSIG_CORE struct Inter *inter, struct 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)

+ 5 - 5
include/__virtualmath.h

@@ -3,17 +3,17 @@
 
 #include "__macro.h"
 #include "mem.h"
+#include "inter.h"
+#include "value.h"
+#include "var.h"
+#include "parameter.h"
 #include "statement.h"
 #include "run.h"
 #include "syntax.h"
-#include "lexical.h"
 #include "token.h"
+#include "lexical.h"
 #include "grammar.h"
-#include "var.h"
-#include "value.h"
-#include "inter.h"
 #include "log.h"
-#include "parameter.h"
 
 struct Args{
     char *file;

+ 5 - 5
include/inter.h

@@ -1,12 +1,12 @@
 #ifndef VIRTUALMATH_INTER_H
 #define VIRTUALMATH_INTER_H
 
-typedef struct globalInterpreter{
-    struct VirtualMathValue *base;
-    struct VirtualMathLinkValue *link_base;
-    struct VirtualMathHashTable *hash_base;
+typedef struct Inter{
+    struct Value *base;
+    struct LinkValue *link_base;
+    struct HashTable *hash_base;
     struct Statement *statement;
-    struct VirtualMathVarList *var_list;
+    struct VarList *var_list;
     char *log_dir;  // 记录log文件夹的位置
     FILE *debug;
 } Inter;

+ 28 - 4
include/parameter.h

@@ -15,14 +15,38 @@ typedef struct Parameter{
     struct Parameter *next;
 } Parameter;
 
+typedef struct Argument{
+    enum {
+        value_arg,
+        name_arg,
+    } type;
+    struct {
+        struct LinkValue *value;
+        struct Statement *name;  // 仅在name-value模式生效
+    } data;
+    struct Argument *next;
+} Argument;
+
+Argument *makeArgument();
+Argument *makeOnlyValueArgument(LinkValue *value);
+Argument *makeNameValueArgument(LinkValue *value, struct Statement *name);
+Argument *connectArgument(Argument *new, Argument *base);
+Argument *connectOnlyValueArgument(LinkValue *value, Argument *base);
+Argument *connectNameValueArgument(LinkValue *value, struct Statement *name, Argument *base);
+void freeArgument(Argument *pt, bool free_st);
+
 Parameter *makeParameter();
+Parameter *copyParameter(Parameter *base);
 Parameter *makeOnlyValueParameter(struct Statement *st);
 Parameter *makeNameValueParameter(struct Statement *value, struct Statement *name);
-Parameter *makeOnlyArgsParameter(Statement *st);
+Parameter *makeOnlyArgsParameter(struct Statement *st);
 Parameter *connectParameter(Parameter *new, Parameter *base);
 Parameter *connectOnlyValueParameter(struct Statement *st, Parameter *base);
 Parameter *connectNameValueParameter(struct Statement *value, struct Statement *name, Parameter *base);
-Parameter *connectOnlyArgsParameter(Statement *st, Parameter *base);
-void freeParameter(Parameter *pt);
-struct VirtualMathResult setParameter(Parameter *call, Parameter *function, struct VirtualMathVarList *function_var, INTER_FUNCTIONSIG_CORE);
+Parameter *connectOnlyArgsParameter(struct Statement *st, Parameter *base);
+void freeParameter(Parameter *pt, bool free_st);
+
+Result setParameter(Parameter *call, Parameter *function, VarList *function_var, INTER_FUNCTIONSIG_CORE);
+Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE);
+Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE);
 #endif //VIRTUALMATH_PARAMETER_H

+ 1 - 1
include/statement.h

@@ -25,7 +25,7 @@ typedef struct Statement{
     } type;
     union StatementU{
         struct base_value{
-            struct VirtualMathValue *value;
+            struct LinkValue *value;
         } base_value;
         struct base_var{
             char *name;

+ 16 - 16
include/value.h

@@ -1,8 +1,7 @@
 #ifndef VIRTUALMATH_VALUE_H
 #define VIRTUALMATH_VALUE_H
-#include "inter.h"
 
-typedef struct VirtualMathValue{
+typedef struct Value{
     enum ValueType{
         none=0,
         number=1,
@@ -19,7 +18,7 @@ typedef struct VirtualMathValue{
         } str;
         struct {
             struct Statement *function;
-            struct VirtualMathVarList *var;
+            struct VarList *var;
             struct Parameter *pt;
         } function;
         struct {
@@ -27,22 +26,22 @@ typedef struct VirtualMathValue{
                 value_tuple,
                 value_list,
             } type;
-            struct VirtualMathLinkValue **list;
+            struct LinkValue **list;
             long int size;
         } list;
     }data;
-    struct VirtualMathValue *next;
-    struct VirtualMathValue *last;
+    struct Value *next;
+    struct Value *last;
 } Value;
 
-typedef struct VirtualMathLinkValue{
-    struct VirtualMathValue *value;
-    struct VirtualMathLinkValue *father;
-    struct VirtualMathLinkValue *next;
-    struct VirtualMathLinkValue *last;
+typedef struct LinkValue{
+    struct Value *value;
+    struct LinkValue *father;
+    struct LinkValue *next;
+    struct LinkValue *last;
 } LinkValue;
 
-typedef struct VirtualMathResult{
+typedef struct Result{
     enum ResultType{
         not_return = 1,  // 无返回值
         function_return,  // 函数返回值
@@ -53,10 +52,12 @@ typedef struct VirtualMathResult{
         rego_return,
         restart_return,
     } type;
-    struct VirtualMathLinkValue *value;
+    struct LinkValue *value;
     int times;
 } Result;
 
+struct VarList;
+struct Argument;
 
 Value *makeValue(Inter *inter);
 void freeValue(Value *value, Inter *inter);
@@ -64,9 +65,8 @@ 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 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);
+Value *makeFunctionValue(struct Statement *st, struct Parameter *pt, struct VarList *var_list, Inter *inter);
+Value *makeListValue(struct Argument **ad_ad, Inter *inter, int type);
 
 void setResult(Result *ru, bool link, Inter *inter);
 void setResultError(Result *ru, Inter *inter);

+ 10 - 10
include/var.h

@@ -4,22 +4,22 @@
 
 #define MAX_SIZE (1024)
 
-typedef struct VirtualMathVar{
+typedef struct Var{
     char *name;
-    struct VirtualMathLinkValue *value;
-    struct VirtualMathVar *next;
+    struct LinkValue *value;
+    struct Var *next;
 } Var;
 
-typedef struct VirtualMathHashTable{
-    struct VirtualMathVar **hashtable;
+typedef struct HashTable{
+    struct Var **hashtable;
     int count;
-    struct VirtualMathHashTable *next;
-    struct VirtualMathHashTable *last;
+    struct HashTable *next;
+    struct HashTable *last;
 } HashTable;
 
-typedef struct VirtualMathVarList{
-    struct VirtualMathHashTable *hashtable;
-    struct VirtualMathVarList *next;
+typedef struct VarList{
+    struct HashTable *hashtable;
+    struct VarList *next;
 } VarList;
 
 VarList *makeVarList(Inter *inter);

+ 7 - 7
parser/grammar.c

@@ -438,7 +438,7 @@ bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_fo
     bool last_pt = false;
     while (!last_pt){
         tmp = NULL;
-        if (!is_dict && status != s_2 && checkToken_(pm, MATHER_MUL))  // // is_formal关闭对*args的支持
+        if (!is_dict && status != s_2 && checkToken_(pm, MATHER_MUL))  // is_formal关闭对*args的支持
             status = s_3;
         parserPolynomial(CALLPASERSSIGNATURE);
         if (!call_success(pm))
@@ -455,7 +455,7 @@ bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_fo
         int pt_type = only_value;
         if (status == s_1){
             if (!checkToken_(pm, sep)){
-                if (is_list || !checkToken_(pm, is_formal))  // // is_list关闭对name_value的支持
+                if (is_list || !checkToken_(pm, ass))  // // is_list关闭对name_value的支持
                     last_pt = true;
                 else {
                     pt_type = name_value;
@@ -465,7 +465,7 @@ bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_fo
         }
         else if (status == s_2){
             pt_type = name_value;
-            if (!checkToken_(pm, is_formal))
+            if (!checkToken_(pm, ass))
                 goto error_;
         }
         else if (status == s_3){
@@ -498,7 +498,7 @@ bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_fo
 
     error_:
     freeToken(tmp, true, true);
-    freeParameter(new_pt);
+    freeParameter(new_pt, true);
     *pt = NULL;
     return false;
 }
@@ -632,7 +632,7 @@ void parserTuple(PASERSSIGNATURE){
     Token *tmp = NULL;
     if (!callChildToken(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp, NULL, syntax_error))
         goto return_;
-    if (!checkToken_(pm, MATHER_COMMA)){  // TODO-szh 需要弹出token才可以检查
+    if (!checkToken_(pm, MATHER_COMMA)){
         tmp->token_type = TUPLE;
         addToken_(pm ,tmp);
         goto return_;
@@ -750,14 +750,14 @@ void parserBaseValue(PASERSSIGNATURE){
         char *stop;
         st = makeStatement();
         st->type = base_value;
-        st->u.base_value.value = makeNumberValue(strtol(value_token->data.str, &stop, 10), inter);
+        st->u.base_value.value = makeLinkValue(makeNumberValue(strtol(value_token->data.str, &stop, 10), inter), NULL, inter);
     }
     else if(MATHER_STRING == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get string\n", NULL);
         value_token= popAheadToken(pm);
         st = makeStatement();
         st->type = base_value;
-        st->u.base_value.value = makeStringValue(value_token->data.str, inter);
+        st->u.base_value.value = makeLinkValue(makeStringValue(value_token->data.str, inter), NULL, inter);
     }
     else if(MATHER_VAR == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get var\n", NULL);

+ 10 - 6
src/operation.c

@@ -179,19 +179,23 @@ Result getBaseVar(INTER_FUNCTIONSIG) {
 Result getBaseValue(INTER_FUNCTIONSIG) {
     Result result;
     setResult(&result, true, inter);
-    result.value->value = st->u.base_value.value;
+    result.value = st->u.base_value.value;
     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的指针导致其值发生改变
+    Result result;
+    Argument *at = getArgument(st->u.base_list.list, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list)), *at_tmp = at;
+    if (!run_continue(result)){
+        freeArgument(at_tmp, true);
+        return result;
+    }
+
     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;
+    Value *value = makeListValue(&at, inter, type);
     setResultOperation(&result ,inter);
     result.value->value = value;
+    freeArgument(at_tmp, true);
     return result;
 }

+ 221 - 87
src/parameter.c

@@ -1,4 +1,62 @@
 #include "__virtualmath.h"
+#define returnResult(result) do{ \
+if (!run_continue(result)) { \
+return result; \
+} \
+}while(0)
+
+Argument *makeArgument(){
+    Argument *tmp = memCalloc(1, sizeof(Argument));
+    tmp->type = value_arg;
+    tmp->data.value = NULL;
+    tmp->data.name = NULL;
+    tmp->next = NULL;
+    return tmp;
+}
+
+Argument *makeOnlyValueArgument(LinkValue *value){
+    Argument *tmp = makeArgument();
+    tmp->data.value = value;
+    return tmp;
+}
+
+Argument *makeNameValueArgument(LinkValue *value, Statement *name){
+    Argument *tmp = makeArgument();
+    tmp->type = name_arg;
+    tmp->data.value = value;
+    tmp->data.name = name;
+    return tmp;
+}
+
+Argument *connectArgument(Argument *new, Argument *base){
+    if (base == NULL)
+        return new;
+    Argument *tmp = base;
+    while (base->next != NULL)
+        base = base->next;
+    base->next = new;
+    return tmp;
+}
+
+Argument *connectOnlyValueArgument(LinkValue *value, Argument *base){
+    Argument *new = makeOnlyValueArgument(value);
+    return connectArgument(new, base);
+}
+
+Argument *connectNameValueArgument(LinkValue *value, Statement *name, Argument *base){
+    Argument *new = makeNameValueArgument(value, name);
+    return connectArgument(new, base);
+}
+
+void freeArgument(Argument *pt, bool free_st) {
+    while (pt != NULL){
+        if (free_st)
+            freeStatement(pt->data.name);
+        Argument *tmp = pt->next;
+        memFree(pt);
+        pt = tmp;
+    }
+}
 
 Parameter *makeParameter(){
     Parameter *tmp = memCalloc(1, sizeof(Parameter));
@@ -9,6 +67,22 @@ Parameter *makeParameter(){
     return tmp;
 }
 
+Parameter *copyParameter(Parameter *base){
+    if (base == NULL)
+        return NULL;
+    Parameter *tmp = makeParameter(), *base_tmp = tmp;
+    tmp->data = base->data;
+    tmp->type = base->type;
+    while (base->next != NULL){
+        tmp->next = makeParameter();
+        tmp = tmp->next;
+        base = base->next;
+        tmp->data = base->data;
+        tmp->type = base->type;
+    }
+    return base_tmp;
+}
+
 Parameter *makeOnlyValueParameter(Statement *st){
     Parameter *tmp = makeParameter();
     tmp->data.value = st;
@@ -55,24 +129,36 @@ Parameter *connectOnlyArgsParameter(Statement *st, Parameter *base){
     return connectParameter(new, base);
 }
 
-void freeParameter(Parameter *pt){
+void freeParameter(Parameter *pt, bool free_st) {
     while (pt != NULL){
-        freeStatement(pt->data.value);
-        freeStatement(pt->data.name);
+        if (free_st) {
+            freeStatement(pt->data.value);
+            freeStatement(pt->data.name);
+        }
         Parameter *tmp = pt->next;
         memFree(pt);
         pt = tmp;
     }
 }
 
+Argument *listToArgument(LinkValue *list_value, INTER_FUNCTIONSIG_CORE){
+    Argument *at = NULL;
+    for (int i=0;i<list_value->value->data.list.size;i++){
+        at = connectOnlyValueArgument(list_value->value->data.list.list[i], at);
+    }
+    return at;
+}
+
 /**
- * 使用形式参数的默认值
+ * 设置形式参数的默认值
+ * 仅支持name_value
  * @param function_ad
  * @param inter
  * @param var_list
+ * @param num
  * @return
  */
-Result varParameter(Parameter **function_ad, INTER_FUNCTIONSIG_CORE, int *num){
+Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list, int *num) {
     Parameter *function = *function_ad;
     Result result;
     while (function != NULL && function->type == name_value){
@@ -81,6 +167,7 @@ Result varParameter(Parameter **function_ad, INTER_FUNCTIONSIG_CORE, int *num){
             *function_ad = function;
             return tmp;
         }
+
         tmp_ass = assCore(function->data.name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (tmp_ass.type == error_return) {
             *function_ad = function;
@@ -96,46 +183,74 @@ Result varParameter(Parameter **function_ad, INTER_FUNCTIONSIG_CORE, int *num){
 }
 
 /**
- * 使用形式参数的默认值
+ * 设置实际参数的默认值, 仅支持name_base_value
  * @param call_ad
  * @param inter
  * @param var_list
+ * @param num
  * @return
  */
-Result nameParameter(Parameter **call_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE, int *num){
-    Parameter *call = *call_ad;
+Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, int *num) {
+    Argument *call = *call_ad;
+    Result result;
+    while (call != NULL && call->type == name_arg){
+        Result tmp_ass;
+        tmp_ass = assCore(call->data.name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        if (tmp_ass.type == error_return) {
+            *call_ad = call;
+            return tmp_ass;
+        }
+        (*num)++;
+        call = call->next;
+    }
+    setResult(&result, true, inter);
+
+    *call_ad = call;
+    return result;
+}
+
+/**
+ * 形式参数从变量空间中获取值
+ * @param function_ad
+ * @param function_var
+ * @param inter
+ * @param var_list
+ * @param num
+ * @return
+ */
+Result parameterFromVar(Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE, int *num){
+    Parameter *function = *function_ad;
     Result result;
     bool get;
-    while (call != NULL){
+    while (function != NULL){
         Result tmp, tmp_ass;
         get = true;
-        Statement *name = call->type == only_value ? call->data.value : call->data.name;
+        Statement *name = function->type == only_value ? function->data.value : function->data.name;
         if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(name, var_list))) {
             get = false;
-            if (call->type == name_value && !operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(call->data.value, var_list))){
+            if (function->type == name_value && !operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list)))
                 goto not_return;
-            }
-            *call_ad = call;
+            *function_ad = function;
             return tmp;
         }
         not_return:
         tmp_ass = assCore(name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
         if (tmp_ass.type == error_return) {
-            *call_ad = call;
+            *function_ad = function;
             return tmp_ass;
         }
         if (get)
             (*num)++;
-        call = call->next;
+        function = function->next;
     }
     setResult(&result, true, inter);
 
-    *call_ad = call;
+    *function_ad = function;
     return result;
 }
 
 /**
- * 根据形参和实参对位赋值
+ * 对位赋值
  * @param call_ad
  * @param function_ad
  * @param function_var
@@ -143,20 +258,14 @@ Result nameParameter(Parameter **call_ad, VarList *function_var, INTER_FUNCTIONS
  * @param var_list
  * @return
  */
-Result valueParameter(Parameter **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE){
-    Parameter *call = *call_ad, *function = *function_ad;
+Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE){
+    Argument *call = *call_ad;
+    Parameter *function = *function_ad;
     Result result;
-    while (call != NULL && function != NULL && call->type != name_value && function->type != only_args){
-        Result tmp, tmp_ass;
+    while (call != NULL && function != NULL && (call->type == value_arg) && function->type != only_args){
+        Result tmp_ass;
         Statement *name = function->type == only_value ? function->data.value : function->data.name;
-
-        if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(call->data.value, var_list))) {
-            *call_ad = call;
-            *function_ad = function;
-            return tmp;
-        }
-
-        tmp_ass = assCore(name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
+        tmp_ass = assCore(name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
         if (tmp_ass.type == error_return) {
             *call_ad = call;
             *function_ad = function;
@@ -172,23 +281,51 @@ Result valueParameter(Parameter **call_ad, Parameter **function_ad, VarList *fun
     return result;
 }
 
-#define returnResult(result) do{ \
-if (!run_continue(result)) { \
-return result; \
-} \
-}while(0)
+/**
+ * 把所有实际参数的值计算出来
+ * @param call_ad
+ * @param inter
+ * @param var_list
+ * @return
+ */
+Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE){
+    Result result;
+    Argument *base = *base_ad;
+    while (call != NULL){
+        Result tmp;
+        if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(call->data.value, var_list)))
+            return tmp;
+
+        if (call->type == only_value)
+            base = connectOnlyValueArgument(tmp.value, base);
+        else if (call->type == name_value)
+            base = connectNameValueArgument(tmp.value, call->data.name, base);
+        else if (call->type == only_args){
+            Argument *tmp_at = listToArgument(tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            base = connectArgument(tmp_at, base);
+        }
+        call = call->next;
+    }
+    setResult(&result, true, inter);
+    *base_ad = base;
+    return result;
+}
+
+Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE){
+    Argument *new_arg = NULL;
+    *result = iterParameter(call, &new_arg, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    return new_arg;
+}
 
 /**
- * 参数设定
- * [1] 形式参数和实际参数对位赋值
- * [2] 形式参数默认值
- * [1] -实参完成, 形参空缺-> [2]
- * [3] 实际参数直接赋值, 形式默认值补充
- * [1] -实参出现name_value类型-> [3]
- * [4] 把剩余的only_name实参转化为list
- * [1] -形参遇到only_args->[4]
- * [4] -实参完成-> [2]
- * [4] -实参未完成-> [3]
+ * 参数表:
+ |实参 \ 形参| name | value | arg | null |
+ ----------------------------------------
+ |name     | p_3  |  p_3  | p_4 | error |
+ |value    | p_1  |  p_1  | p_4 | error |
+ |null     | p_2  | error | p_4 | okay  |
+ ----------------------------------------
+ * 注解: @p_1 match_status; @p_2 default_status; @p_3 self_ass; @p_4 mul_par
  * @param call
  * @param function
  * @param function_var
@@ -196,82 +333,79 @@ return result; \
  * @param var_list
  * @return
  */
-Result setParameter(Parameter *call, Parameter *function, VarList *function_var, INTER_FUNCTIONSIG_CORE){
+Result setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_CORE){
+    Result result;
+    Argument *call, *tmp_call;
+    Parameter *function = copyParameter(function_base), *tmp_function = function;  // 释放使用
+    tmp_call = call = getArgument(call_base, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    returnResult(result);
+
     enum {
-        p_1 = 1,
-        p_2 = 2,
-        p_3 = 3,
-        p_4 = 4,
+        match_status = 1,
+        default_status = 2,
+        self_ass = 3,
+        mul_par = 4,
         error = -1,
         finished = 0
-    } status = p_1;
-    Result result;
+    } status = match_status;
     while (true){
+        if (call == NULL && function == NULL)
+            status = finished;
+        else if ((call != NULL && function == NULL) || (call == NULL && function != NULL && function->type == only_value))
+            status = error;
+        else if (call == NULL && function->type == name_value)  // 根据前面的条件, 已经决定function不会为NULL
+            status = default_status;
+        else if (function->type == only_args)
+            status = mul_par;
+        else if (call->type == value_arg)
+            status = match_status;
+        else if (call->type == name_arg)
+            status = self_ass;
+
         switch (status) {
-            case p_1: {
-                result = valueParameter(&call, &function, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            case match_status: {
+                result = argumentToParameter(&call, &function, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
                 returnResult(result);
-                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 && function->type == only_args && call->type == only_value)
-                    status = p_4;
-                else if (call != NULL || function != NULL)
-                    status = error;
-                else
-                    status = finished;
                 break;
             }
-            case p_2: {
+            case default_status: {
                 int num = 0;
-                result = varParameter(&function, CALL_INTER_FUNCTIONSIG_CORE(function_var), &num);
+                result = defaultParameter(&function, CALL_INTER_FUNCTIONSIG_CORE(function_var), &num);
                 returnResult(result);
-                status = finished;
                 break;
             }
-            case p_3: {
+            case self_ass: {
                 VarList *tmp = makeVarList(inter);
                 int set_num = 0, get_num = 0;
-                result = varParameter(&call, CALL_INTER_FUNCTIONSIG_CORE(tmp), &set_num);
+                result = argumentToVar(&call, CALL_INTER_FUNCTIONSIG_CORE(tmp), &set_num);
                 returnResult(result);
-                result = nameParameter(&function, function_var, CALL_INTER_FUNCTIONSIG_CORE(tmp), &get_num);
+                result = parameterFromVar(&function, function_var, CALL_INTER_FUNCTIONSIG_CORE(tmp), &get_num);
                 returnResult(result);
                 freeVarList(tmp, true);
-                if (set_num > get_num) {
+
+                if (set_num > get_num)
                     status = error;
-                    break;
-                }
-                status = finished;
                 break;
             }
-            case p_4: {
+            case mul_par: {
                 Result tmp_result;
-                Value *value = makeListValue(&call, &tmp_result, CALL_INTER_FUNCTIONSIG_CORE(var_list), value_tuple);
-                returnResult(tmp_result);
+                Value *value = makeListValue(&call, inter, value_tuple);
                 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:
+                writeLog(inter->debug, ERROR, "setParameter error", NULL);
                 setResultError(&result, inter);
-                return result;
+                goto return_;
             default:
                 goto return_;
         }
     }
     return_:
+    freeArgument(tmp_call, false);
+    freeParameter(tmp_function, false);
     return result;
 }
-
-#undef returnResult

+ 2 - 3
src/statement.c

@@ -14,7 +14,6 @@ struct Token *setOperationFromToken(Statement **st_ad, struct Token *left, struc
         st->u.operation.left = left_st->u.operation.right;
         left_st->u.operation.right = st;
         st->u.operation.right = right->data.st;
-
         st = left_st;  // left_st是主中心
     }
     else{
@@ -166,10 +165,10 @@ void freeStatement(Statement *st){
                 break;
             case call_function:
                 freeStatement(st->u.call_function.function);
-                freeParameter(st->u.call_function.parameter);
+                freeParameter(st->u.call_function.parameter, true);
                 break;
             case base_list:
-                freeParameter(st->u.base_list.list);
+                freeParameter(st->u.base_list.list, true);
                 break;
             case if_branch:
                 freeStatementList(st->u.if_branch.if_list);

+ 7 - 15
src/value.c

@@ -47,29 +47,21 @@ 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 *makeListValue(Argument **ad_ad, Inter *inter, int type) {
     Value *tmp;
-    Parameter *pt = *pt_ad;
+    Argument *at = *ad_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_;
-        }
+    while (at != NULL && at->type == value_arg){
         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;
+        tmp->data.list.list[tmp->data.list.size - 1] = at->data.value;
+        at = at->next;
     }
-    setResult(result_tmp, true, inter);
-    return_:
-    *pt_ad = pt;
+    *ad_ad = at;
     return tmp;
 }
 
@@ -90,7 +82,7 @@ void freeValue(Value *value, Inter *inter){
             break;
         case function: {
             VarList *tmp = value->data.function.var;
-            freeParameter(value->data.function.pt);
+            freeParameter(value->data.function.pt, true);
             while (tmp != NULL)
                 tmp = freeVarList(tmp, true);
             break;