123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- #include "__virtualmath.h"
- #define returnResult(result) do{ \
- if (!run_continue(result)) { \
- goto return_; \
- } \
- }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));
- tmp->type = value_par;
- tmp->data.value = NULL;
- tmp->data.name = NULL;
- tmp->next = NULL;
- 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;
- return tmp;
- }
- Parameter *makeNameValueParameter(Statement *value, Statement *name){
- Parameter *tmp = makeParameter();
- tmp->type = name_par;
- tmp->data.value = value;
- tmp->data.name = name;
- return tmp;
- }
- Parameter *makeOnlyArgsParameter(Statement *st){
- Parameter *tmp = makeParameter();
- tmp->type = args_par;
- 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 tmp;
- }
- Parameter *connectOnlyValueParameter(Statement *st, Parameter *base){
- Parameter *new = makeOnlyValueParameter(st);
- return connectParameter(new, base);
- }
- Parameter *connectNameValueParameter(Statement *value, Statement *name, Parameter *base){
- Parameter *new = makeNameValueParameter(value, name);
- return connectParameter(new, base);
- }
- Parameter *connectOnlyArgsParameter(Statement *st, Parameter *base){
- Parameter *new = makeOnlyArgsParameter(st);
- return connectParameter(new, base);
- }
- void freeParameter(Parameter *pt, bool free_st) {
- while (pt != NULL){
- 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 defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list, int *num) {
- Parameter *function = *function_ad;
- Result result;
- while (function != NULL && function->type == name_par){
- Result tmp, tmp_ass;
- if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list))) {
- *function_ad = function;
- return tmp;
- }
- tmp_ass = assCore(function->data.name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- if (!run_continue(tmp_ass)) {
- *function_ad = function;
- return tmp_ass;
- }
- (*num)++;
- function = function->next;
- }
- setResult(&result, true, inter);
- *function_ad = function;
- return result;
- }
- /**
- * 设置实际参数的默认值, 仅支持name_base_value
- * @param call_ad
- * @param inter
- * @param var_list
- * @param num
- * @return
- */
- Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, NUMBER_TYPE *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 (!run_continue(tmp_ass)) {
- *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, NUMBER_TYPE *num){
- Parameter *function = *function_ad;
- Result result;
- setResultOperation(&result, inter);
- bool get;
- while (function != NULL){
- Result tmp;
- Statement *name = function->type == value_par ? function->data.value : function->data.name;
- char *str_name = NULL;
- int int_times;
- LinkValue *value = NULL;
- get = true;
- tmp = getBaseVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
- if (!run_continue(tmp)) {
- memFree(str_name);
- return tmp;
- }
- value = findFromVarList(str_name, var_list, int_times, true);
- memFree(str_name);
- if(value == NULL) {
- get = false;
- if (function->type == name_par && !operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list))) {
- value = tmp.value;
- goto not_return;
- }
- setResultError(&tmp, inter);
- *function_ad = function;
- return tmp;
- }
- not_return:
- tmp = assCore(name, value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
- if (!run_continue(tmp)) {
- *function_ad = function;
- return tmp;
- }
- if (get)
- (*num)++;
- function = function->next;
- }
- setResult(&result, true, inter);
- *function_ad = function;
- return result;
- }
- /**
- * 对位赋值
- * @param call_ad
- * @param function_ad
- * @param function_var
- * @param inter
- * @param var_list
- * @return
- */
- 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 == value_arg) && function->type != args_par){
- Result tmp_ass;
- Statement *name = function->type == value_par ? function->data.value : function->data.name;
- tmp_ass = assCore(name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
- if (!run_continue(tmp_ass)) {
- *call_ad = call;
- *function_ad = function;
- return tmp_ass;
- }
- call = call->next;
- function = function->next;
- }
- setResult(&result, true, inter);
- *call_ad = call;
- *function_ad = function;
- return result;
- }
- /**
- * 把所有实际参数的值计算出来
- * @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))) {
- *base_ad = base;
- return tmp;
- }
- if (call->type == value_par)
- base = connectOnlyValueArgument(tmp.value, base);
- else if (call->type == name_par)
- base = connectNameValueArgument(tmp.value, call->data.name, base);
- else if (call->type == args_par){
- 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;
- }
- /**
- * 参数表:
- |实参 \ 形参| name | value | arg | kwarg | null |
- ----------------------------------------
- |name | p_3 | p_3 | p_4 | p_5! | error |
- |value | p_1 | p_1 | p_4 | error | error |
- |null | p_2 | error | p_4 | p_5 | okay |
- ----------------------------------------
- * 注解: @p_1 match_status; @p_2 default_status; @p_3 self_ass; @p_4 mul_par; @p_5 pow_par
- * @param call
- * @param function
- * @param function_var
- * @param inter
- * @param var_list
- * @return
- */
- Result setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_CORE) {
- Result result;
- Argument *call;
- call = getArgument(call_base, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- if (!run_continue(result)) {
- freeArgument(call, false);
- return result;
- }
- result = setParameterCore(call, function_base, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- freeArgument(call, false);
- return result;
- }
- Result setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_CORE){
- Result result;
- Parameter *function = copyParameter(function_base), *tmp_function = function; // 释放使用
- enum {
- match_status = 1,
- default_status = 2,
- self_ass = 3,
- mul_par = 4,
- error = -1,
- finished = 0
- } status = match_status;
- while (true){
- if (call == NULL && function == NULL)
- status = finished;
- else if ((call != NULL && function == NULL) || (call == NULL && function != NULL && function->type == value_par))
- status = error;
- else if (call == NULL && function->type == name_par) // 根据前面的条件, 已经决定function不会为NULL
- status = default_status;
- else if (function->type == args_par)
- status = mul_par;
- else if (call->type == value_arg)
- status = match_status;
- else if (call->type == name_arg)
- status = self_ass;
- switch (status) {
- case match_status: {
- result = argumentToParameter(&call, &function, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- returnResult(result);
- break;
- }
- case default_status: {
- int num = 0;
- result = defaultParameter(&function, CALL_INTER_FUNCTIONSIG_CORE(function_var), &num);
- returnResult(result);
- break;
- }
- case self_ass: {
- VarList *tmp = makeVarList(inter);
- NUMBER_TYPE set_num = 0, get_num = 0;
- result = argumentToVar(&call, CALL_INTER_FUNCTIONSIG_CORE(tmp), &set_num);
- returnResult(result);
- result = parameterFromVar(&function, function_var, CALL_INTER_FUNCTIONSIG_CORE(tmp), &get_num);
- returnResult(result);
- freeVarList(tmp, true);
- if (set_num > get_num)
- status = error;
- break;
- }
- case mul_par: {
- Value *value = makeListValue(&call, inter, value_tuple);
- LinkValue *tmp = makeLinkValue(value, NULL, inter);
- result = assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_CORE(function_var));
- returnResult(result);
- function = function->next;
- break;
- }
- case error:
- writeLog(inter->debug, ERROR, "setParameter error", NULL);
- setResultError(&result, inter);
- goto return_;
- default:
- goto break_;
- }
- }
- break_:
- setResult(&result, true ,inter);
- return_:
- freeParameter(tmp_function, false);
- return result;
- }
|