123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- #include "__virtualmath.h"
- #define returnResult(result) do{ \
- if (!run_continue(result)) { \
- goto return_; \
- } \
- }while(0)
- Argument *makeArgument(void){
- Argument *tmp = memCalloc(1, sizeof(Argument));
- tmp->type = value_arg;
- tmp->data.value = NULL;
- tmp->data.name = NULL;
- tmp->data.name_ = NULL;
- tmp->name_type = name_st;
- tmp->next = NULL;
- return tmp;
- }
- Argument *makeValueArgument(LinkValue *value){
- Argument *tmp = makeArgument();
- tmp->data.value = value;
- gc_addTmpLink(&value->gc_status);
- return tmp;
- }
- Argument *makeStatementNameArgument(LinkValue *value, Statement *name){
- Argument *tmp = makeArgument();
- tmp->type = name_arg;
- tmp->data.value = value;
- tmp->data.name = name;
- gc_addTmpLink(&value->gc_status);
- return tmp;
- }
- Argument *makeCharNameArgument(LinkValue *value, LinkValue *name_value, char *name) {
- Argument *tmp = makeArgument();
- tmp->type = name_arg;
- tmp->name_type = name_char;
- tmp->data.value = value;
- tmp->data.name_ = memStrcpy(name);
- tmp->data.name_value = name_value;
- gc_addTmpLink(&value->gc_status);
- gc_addTmpLink(&name_value->gc_status);
- return tmp;
- }
- Argument *connectArgument(Argument *new, Argument *base){
- Argument *tmp = base;
- if (base == NULL)
- return new;
- for (PASS; base->next != NULL; base = base->next)
- PASS;
- base->next = new;
- return tmp;
- }
- Argument *connectValueArgument(LinkValue *value, Argument *base){
- Argument *new = makeValueArgument(value);
- return connectArgument(new, base);
- }
- Argument *connectStatementNameArgument(LinkValue *value, Statement *name, Argument *base){
- Argument *new = makeStatementNameArgument(value, name);
- return connectArgument(new, base);
- }
- Argument *connectCharNameArgument(LinkValue *value, LinkValue *name_value, char *name, Argument *base) {
- Argument *new = makeCharNameArgument(value, name_value, name);
- return connectArgument(new, base);
- }
- void freeArgument(Argument *at, bool free_st) {
- for (Argument *tmp=NULL; at != NULL;at = tmp){
- tmp = at->next;
- if (free_st)
- freeStatement(at->data.name);
- memFree(at->data.name_);
- if (at->data.name_value != NULL)
- gc_freeTmpLink(&at->data.name_value->gc_status);
- if (at->data.value != NULL)
- gc_freeTmpLink(&at->data.value->gc_status);
- memFree(at);
- }
- }
- Parameter *makeParameter(void){
- Parameter *tmp = memCalloc(1, sizeof(Parameter));
- tmp->type = value_par;
- tmp->data.value = NULL;
- tmp->data.name = NULL;
- tmp->next = NULL;
- return tmp;
- }
- Parameter *copyenOneParameter(Parameter *base){
- Parameter *tmp = makeParameter();
- tmp->data.value = copyStatement(base->data.value);
- tmp->data.name = copyStatement(base->data.name);
- tmp->type = base->type;
- return tmp;
- }
- Parameter *copyParameter(Parameter *base){
- Parameter *base_tmp = NULL;
- Parameter **tmp = &base_tmp;
- for (PASS; base != NULL; tmp = &(*tmp)->next,base = base->next)
- *tmp = copyenOneParameter(base);
- return base_tmp;
- }
- Parameter *makeValueParameter(Statement *st){
- Parameter *tmp = makeParameter();
- tmp->data.value = st;
- return tmp;
- }
- Parameter *makeNameParameter(Statement *value, Statement *name){
- Parameter *tmp = makeParameter();
- tmp->type = name_par;
- tmp->data.value = value;
- tmp->data.name = name;
- return tmp;
- }
- Parameter *makeArgsParameter(Statement *st){
- Parameter *tmp = makeParameter();
- tmp->type = args_par;
- tmp->data.value = st;
- return tmp;
- }
- Parameter *makeKwrgsParameter(Statement *st){
- Parameter *tmp = makeParameter();
- tmp->type = kwargs_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 *connectValueParameter(Statement *st, Parameter *base){
- Parameter *new = makeValueParameter(st);
- return connectParameter(new, base);
- }
- Parameter *connectNameParameter(Statement *value, Statement *name, Parameter *base){
- Parameter *new = makeNameParameter(value, name);
- return connectParameter(new, base);
- }
- Parameter *connectArgsParameter(Statement *st, Parameter *base){
- Parameter *new = makeArgsParameter(st);
- return connectParameter(new, base);
- }
- Parameter *connectKwargsParameter(Statement *st, Parameter *base){
- Parameter *new = makeKwrgsParameter(st);
- return connectParameter(new, base);
- }
- void freeParameter(Parameter *pt, bool free_st) {
- for (Parameter *tmp=NULL;pt != NULL;pt = tmp){
- tmp = pt->next;
- if (free_st) {
- freeStatement(pt->data.value);
- freeStatement(pt->data.name);
- }
- memFree(pt);
- }
- }
- Argument *listToArgument(LinkValue *list_value, INTER_FUNCTIONSIG_CORE){
- Argument *at = NULL;
- for (int i=0;i<list_value->value->data.list.size;i++)
- at = connectValueArgument(list_value->value->data.list.list[i], at);
- return at;
- }
- Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE){
- Argument *at = NULL;
- Var *tmp = NULL;
- for (int i = 0; i < MAX_SIZE; i++)
- for (tmp = dict_value->value->data.dict.dict->hashtable[i]; tmp != NULL; tmp = tmp->next)
- at = connectCharNameArgument(tmp->value, tmp->name_, tmp->name, at);
- return at;
- }
- /**
- * 设置形式参数的默认值
- * 仅支持name_value
- * @param function_ad
- * @param inter
- * @param var_list
- * @param num
- * @return
- */
- ResultType defaultParameter(Parameter **function_ad, NUMBER_TYPE *num, INTER_FUNCTIONSIG_NOT_ST) {
- Parameter *function = *function_ad;
- setResultCore(result);
- for (*num = 0; function != NULL && function->type == name_par; (*num)++, function = function->next){
- LinkValue *value = NULL;
- if(operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(function->data.value, var_list, result, father)))
- goto return_;
- value = result->value;
- freeResult(result);
- assCore(function->data.name, value, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
- if (!run_continue(result))
- goto return_;
- }
- setResult(result, inter, father);
- return_:
- *function_ad = function;
- return result->type;
- }
- /**
- * 设置实际参数的默认值, 仅支持name_base_value
- * @param call_ad
- * @param inter
- * @param var_list
- * @param num
- * @return
- */
- ResultType argumentToVar(Argument **call_ad, NUMBER_TYPE *num, INTER_FUNCTIONSIG_NOT_ST) {
- Argument *call = *call_ad;
- setResultCore(result);
- for (*num = 0; call != NULL && call->type == name_arg; (*num)++, call = call->next){
- if (call->name_type == name_char){
- addFromVarList(call->data.name_, call->data.name_value, 0, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- continue;
- }
- freeResult(result);
- assCore(call->data.name, call->data.value, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
- if (!run_continue(result))
- goto return_;
- }
- setResult(result, inter, father);
- return_:
- *call_ad = call;
- return result->type;
- }
- /**
- * 形式参数从变量空间中获取值
- * @param function_ad
- * @param function_var
- * @param inter
- * @param var_list
- * @param num
- * @return
- */
- ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, NUMBER_TYPE *num, NUMBER_TYPE max, bool *status,
- INTER_FUNCTIONSIG_NOT_ST) {
- Parameter *function = *function_ad;
- bool get = true;
- setResultCore(result);
- for (*num = 0, *status = false; function != NULL; function = function->next){
- int int_times;
- char *str_name = NULL;
- Statement *name = function->type == name_par ? function->data.name : function->data.value;
- LinkValue *value = NULL;
- get = true;
- if (function->type == kwargs_par){
- value = makeLinkValue(makeDictValue(NULL, false, father, NULL, inter, var_list), father, inter);
- value->value->data.dict.dict = var_list->hashtable;
- value->value->data.dict.size = max - *num;
- *status = true;
- goto not_return;
- }
- freeResult(result);
- getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, father));
- if (!run_continue(result)) {
- memFree(str_name);
- *function_ad = function;
- return result->type;
- }
- freeResult(result);
- value = findFromVarList(str_name, var_list, int_times, true);
- memFree(str_name);
- if(value == NULL) {
- get = false;
- if (function->type == name_par && !operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(function->data.value, var_list, result, father))) {
- value = result->value;
- goto not_return;
- }
- setResultError(result, inter, "ArgumentException", "Too less Argument", name, father, true);
- goto reutnr_;
- }
- else if ((name->aut == public_aut || name->aut == auto_aut) && (value->aut != public_aut && value->aut != auto_aut)) {
- setResultError(result, inter, "PermissionsException", "Wrong Permissions: access Argument as public", name,
- father, true);
- goto reutnr_;
- }
- else if ((name->aut == protect_aut) && (value->aut == private_aut)) {
- setResultError(result, inter, "PermissionsException", "Wrong Permissions: access variables as protect",
- name, father, true);
- goto reutnr_;
- }
- value = copyLinkValue(value, inter);
- not_return:
- freeResult(result);
- assCore(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST (function_var, result, father));
- if (!run_continue(result)) {
- *function_ad = function;
- return result->type;
- }
- else
- freeResult(result);
- if (get)
- (*num)++;
- }
- setResult(result, inter, father);
- reutnr_:
- *function_ad = function;
- return result->type;
- }
- /**
- * 对位赋值
- * @param call_ad
- * @param function_ad
- * @param function_var
- * @param inter
- * @param var_list
- * @return
- */
- ResultType argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST){
- Argument *call = *call_ad;
- Parameter *function = *function_ad;
- setResultCore(result);
- for (PASS; call != NULL && function != NULL && (call->type == value_arg) && function->type != args_par; call = call->next, function = function->next){
- Statement *name = function->type == value_par ? function->data.value : function->data.name;
- assCore(name, call->data.value, CALL_INTER_FUNCTIONSIG_NOT_ST (function_var, result, father));
- if (!run_continue(result))
- goto return_;
- freeResult(result);
- }
- setResult(result, inter, father);
- return_:
- *call_ad = call;
- *function_ad = function;
- return result->type;
- }
- /**
- * 把所有实际参数的值计算出来
- * @param call_ad
- * @param inter
- * @param var_list
- * @return
- */
- ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTER_FUNCTIONSIG_NOT_ST){
- Argument *base = *base_ad;
- setResultCore(result);
- for (PASS; call != NULL; call = call->next){
- if(operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(call->data.value, var_list, result, father)))
- goto return_;
- if (call->type == value_par)
- base = connectValueArgument(result->value, base);
- else if (call->type == name_par){
- if (is_dict){
- LinkValue *value = result->value;
- setResultCore(result);
- if(operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(call->data.name, var_list, result, father))) {
- gc_freeTmpLink(&value->gc_status);
- goto return_;
- }
- char *name_str = getNameFromValue(result->value->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- base = connectCharNameArgument(value, result->value, name_str, base);
- memFree(name_str);
- gc_freeTmpLink(&value->gc_status);
- }
- else
- base = connectStatementNameArgument(result->value, call->data.name, base);
- }
- else if (call->type == args_par){
- Argument *tmp_at = listToArgument(result->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- base = connectArgument(tmp_at, base);
- }
- else if (call->type == kwargs_par){
- Argument *tmp_at = dictToArgument(result->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- base = connectArgument(tmp_at, base);
- }
- freeResult(result);
- }
- setResult(result, inter, father);
- return_:
- *base_ad = base;
- return result->type;
- }
- Argument * getArgument(Parameter *call, bool is_dict, INTER_FUNCTIONSIG_NOT_ST) {
- Argument *new_arg = NULL;
- freeResult(result);
- iterParameter(call, &new_arg, is_dict, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
- return new_arg;
- }
- /**
- * 参数表:
- |实参 \ 形参| name | value | arg | kwarg | null |
- ----------------------------------------
- |name | p_3 | p_3 | p_4 | p_3! | 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; @p_3! 通过p_3处理**kwargs
- * @param call
- * @param function
- * @param function_var
- * @param inter
- * @param var_list
- * @return
- */
- ResultType setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, LinkValue *function_father, INTER_FUNCTIONSIG_NOT_ST) {
- Argument *call = NULL;
- setResultCore(result);
- call = getArgument(call_base, false, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
- if (!run_continue(result)) {
- freeArgument(call, false);
- return result->type;
- }
- freeResult(result);
- setParameterCore(call, function_base, function_var, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, function_father));
- freeArgument(call, false);
- return result->type;
- }
- ResultType setParameterCore(Argument *call, Parameter *function_base, VarList *function_var,
- INTER_FUNCTIONSIG_NOT_ST) {
- Parameter *function = NULL;
- Parameter *tmp_function = NULL; // 释放使用
- enum {
- match_status = 1,
- default_status = 2,
- self_ass = 3,
- mul_par = 4,
- space_kwargs = 5,
- error = -1,
- finished = 0,
- } status = match_status;
- function = copyParameter(function_base);
- tmp_function = function;
- setResultCore(result);
- while (true){
- if (call == NULL && function == NULL)
- status = finished;
- else if ((call != NULL && (function == NULL || call->type == value_par && function->type == kwargs_par)) ||
- (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 (call == NULL && function->type == kwargs_par)
- status = space_kwargs;
- else if (function->type == args_par) // 根据前面的条件, 已经决定call不会为NULL
- status = mul_par;
- else if (call->type == value_arg)
- status = match_status;
- else if (call->type == name_arg)
- status = self_ass;
- freeResult(result);
- switch (status) {
- case match_status: {
- argumentToParameter(&call, &function, function_var, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
- returnResult(result);
- break;
- }
- case default_status: {
- NUMBER_TYPE num = 0;
- defaultParameter(&function, &num, CALL_INTER_FUNCTIONSIG_NOT_ST (function_var, result, father));
- returnResult(result);
- break;
- }
- case self_ass: {
- NUMBER_TYPE set_num = 0;
- NUMBER_TYPE get_num = 0;
- bool dict_status = false;
- VarList *tmp = pushVarList(var_list, inter);
- argumentToVar(&call, &set_num, CALL_INTER_FUNCTIONSIG_NOT_ST (tmp, result, father));
- returnResult(result);
- if (!run_continue(result)) {
- popVarList(tmp);
- goto return_;
- }
- freeResult(result);
- parameterFromVar(&function, function_var, &get_num, set_num, &dict_status, CALL_INTER_FUNCTIONSIG_NOT_ST (tmp, result, father));
- if (!run_continue(result)) {
- popVarList(tmp);
- goto return_;
- }
- popVarList(tmp);
- if (!dict_status && set_num > get_num) {
- freeResult(result);
- goto error_;
- }
- break;
- }
- case mul_par: {
- LinkValue *tmp = makeLinkValue(makeListValue(&call, inter, value_tuple), father, inter);
- if (!run_continue(result))
- goto return_;
- else
- freeResult(result);
- assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST (function_var, result, father));
- returnResult(result);
- function = function->next;
- break;
- }
- case space_kwargs:{
- LinkValue *tmp = makeLinkValue(makeDictValue(NULL, true, father, result, inter, var_list), father, inter);
- assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST (function_var, result, father));
- returnResult(result);
- function = function->next;
- break;
- }
- case error:
- error_: // Statement 处理
- writeLog(inter->data.debug, ERROR, "setParameter error\n", NULL);
- setResultError(result, inter, "ArgumentException", "Set Argument error", 0, father, true);
- goto return_;
- default:
- goto break_;
- }
- }
- break_:
- setResult(result, inter, father);
- return_:
- freeParameter(tmp_function, true);
- return result->type;
- }
- FatherValue *setFather(Argument *call, INTER_FUNCTIONSIG_NOT_ST) {
- setResultCore(result);
- FatherValue *father_tmp = NULL;
- for (Argument *tmp = call; tmp != NULL && tmp->type == value_arg; tmp = tmp->next)
- if (tmp->data.value->value->type == class) {
- father_tmp = connectFatherValue(father_tmp, makeFatherValue(tmp->data.value));
- father_tmp = connectFatherValue(father_tmp, copyFatherValue(tmp->data.value->value->object.father));
- }
- return setFatherCore(father_tmp);
- }
- FatherValue *setFatherCore(FatherValue *father_tmp) {
- FatherValue *base_father = NULL;
- while (father_tmp != NULL){
- FatherValue *next = father_tmp->next;
- father_tmp->next = NULL;
- base_father = connectSafeFatherValue(base_father, father_tmp);
- father_tmp = next;
- }
- return base_father;
- }
|