1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174 |
- #include "__run.h"
- #define returnResult(result) do{ \
- if (!CHECK_RESULT(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, wchar_t *name) {
- Argument *tmp = makeArgument();
- tmp->type = name_arg;
- tmp->name_type = name_char;
- tmp->data.value = value;
- tmp->data.name_ = memWidecpy(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, wchar_t *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->data.is_sep = false;
- 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->data.is_sep = base->data.is_sep;
- 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, bool is_sep) {
- Parameter *new = makeValueParameter(st);
- new->data.is_sep = is_sep;
- 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, bool is_sep) {
- Parameter *new = makeArgsParameter(st);
- new->data.is_sep = is_sep;
- 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, long line, char *file, FUNC_NT){
- Argument *at = NULL;
- LinkValue *iter = NULL;
- setResultCore(result);
- getIter(list_value, 1, line, file, CNEXT_NT);
- if (!CHECK_RESULT(result))
- return NULL;
- GET_RESULT(iter, result);
- while (true) {
- getIter(iter, 0, line, file, CNEXT_NT);
- if (is_iterStop(result->value, inter)){
- freeResult(result);
- break;
- }
- else if (!CHECK_RESULT(result)) {
- freeArgument(at, true);
- at = NULL;
- goto return_;
- }
- at = connectValueArgument(result->value, at);
- freeResult(result);
- }
- setResult(result, inter);
- return_:
- gc_freeTmpLink(&iter->gc_status);
- return at;
- }
- Argument *dictToArgument(LinkValue *dict_value, long line, char *file, FUNC_NT) {
- Argument *at = NULL;
- LinkValue *iter = NULL;
- setResultCore(result);
- getIter(dict_value, 1, line, file, CNEXT_NT);
- if (!CHECK_RESULT(result))
- return NULL;
- GET_RESULT(iter, result);
- while (true) {
- LinkValue *name_ = NULL;
- wchar_t *name = NULL;
- getIter(iter, 0, line, file, CNEXT_NT);
- if (is_iterStop(result->value, inter)){
- freeResult(result);
- break;
- }
- else if (!CHECK_RESULT(result)) {
- freeArgument(at, true);
- at = NULL;
- goto return_;
- }
- GET_RESULT(name_, result);
- getElement(iter, name_, line, file, CNEXT_NT);
- if (!CHECK_RESULT(result)) {
- gc_freeTmpLink(&name_->gc_status);
- freeArgument(at, true);
- at = NULL;
- goto return_;
- }
- name = getNameFromValue(name_->value, inter->data.var_deep, inter);
- at = connectCharNameArgument(result->value, name_, name, at);
- gc_freeTmpLink(&name_->gc_status);
- memFree(name);
- freeResult(result);
- }
- setResult(result, inter);
- return_:
- gc_freeTmpLink(&iter->gc_status);
- return at;
- }
- /**
- * 设置形式参数的默认值
- * 仅支持name_value
- * @param function_ad
- * @param inter
- * @param var_list
- * @param num
- * @return
- */
- ResultType defaultParameter(Parameter **function_ad, vint *num, FUNC_NT) {
- Parameter *function = *function_ad;
- setResultCore(result);
- for (*num = 0; function != NULL && function->type == name_par; (*num)++, function = function->next){
- LinkValue *value = NULL;
- if(operationSafeInterStatement(CFUNC(function->data.value, var_list, result, belong)))
- goto return_;
- GET_RESULT(value, result);
- assCore(function->data.name, value, false, false, CNEXT_NT);
- gc_freeTmpLink(&value->gc_status);
- if (!CHECK_RESULT(result))
- goto return_;
- freeResult(result);
- }
- setResult(result, inter);
- 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, vint *num, FUNC_NT) {
- 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, CFUNC_CORE(var_list)); // 参数赋值不需要处理变量式参数
- continue;
- }
- freeResult(result);
- assCore(call->data.name, call->data.value, false, false, CNEXT_NT);
- if (!CHECK_RESULT(result))
- goto return_;
- }
- setResult(result, inter);
- 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, vint *num, vint max, bool *status,
- FUNC_NT) {
- Parameter *function = *function_ad;
- bool get = true;
- setResultCore(result);
- for (*num = 0, *status = false; function != NULL; function = function->next){
- int int_times;
- wchar_t *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){
- makeDictValue(NULL, false, LINEFILE, CNEXT_NT);
- if (!CHECK_RESULT(result))
- return result->type;
- GET_RESULT(value, result);
- value->value->data.dict.dict = var_list->hashtable;
- value->value->data.dict.size = max - *num;
- *status = true;
- gc_freeTmpLink(&value->gc_status);
- goto not_return;
- }
- getVarInfo(&str_name, &int_times, CFUNC(name, var_list, result, belong));
- if (!CHECK_RESULT(result)) {
- memFree(str_name);
- *function_ad = function;
- return result->type;
- }
- freeResult(result);
- value = findFromVarList(str_name, int_times, NULL, del_var, CFUNC_CORE(var_list)); // 形式参数取值不需要执行变量式函数
- memFree(str_name);
- if(value == NULL) {
- get = false;
- if (function->type == name_par && !operationSafeInterStatement(CFUNC(function->data.value, var_list, result, belong))) {
- value = result->value;
- goto not_return;
- }
- setResultErrorSt(E_ArgumentException, FEW_ARG, true, name, CNEXT_NT);
- goto return_;
- } else if (!checkAut(name->aut, value->aut, name->line, name->code_file, NULL, false, CNEXT_NT)) // 与varAss作用相同
- goto return_;
- not_return:
- freeResult(result);
- assCore(name, value, false, false, CFUNC_NT(function_var, result, belong));
- if (!CHECK_RESULT(result)) {
- *function_ad = function;
- return result->type;
- }
- freeResult(result);
- if (get)
- (*num)++;
- }
- setResult(result, inter);
- return_:
- *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, FUNC_NT){
- 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, false, false, CFUNC_NT(function_var, result, belong));
- if (!CHECK_RESULT(result))
- goto return_;
- freeResult(result);
- }
- setResult(result, inter);
- 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, FUNC_NT){
- Argument *base = *base_ad;
- setResultCore(result);
- for (PASS; call != NULL; call = call->next){
- if(operationSafeInterStatement(CFUNC(call->data.value, var_list, result, belong)))
- 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(CFUNC(call->data.name, var_list, result, belong))) {
- gc_freeTmpLink(&value->gc_status);
- goto return_;
- }
- wchar_t *name_str = getNameFromValue(result->value->value, inter->data.var_deep, inter);
- 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){
- LinkValue *start = NULL;
- Argument *tmp_at = NULL;
- GET_RESULT(start, result);
- tmp_at = listToArgument(start, LINEFILE, CNEXT_NT);
- gc_freeTmpLink(&start->gc_status);
- if (!CHECK_RESULT(result))
- goto return_;
- base = connectArgument(tmp_at, base);
- }
- else if (call->type == kwargs_par){
- LinkValue *start = NULL;
- Argument *tmp_at = NULL;
- GET_RESULT(start, result);
- tmp_at = dictToArgument(start, LINEFILE, CNEXT_NT);
- gc_freeTmpLink(&start->gc_status);
- if (!CHECK_RESULT(result))
- goto return_;
- base = connectArgument(tmp_at, base);
- }
- freeResult(result);
- }
- setResult(result, inter);
- return_:
- *base_ad = base;
- return result->type;
- }
- Argument * getArgument(Parameter *call, bool is_dict, FUNC_NT) {
- Argument *new_arg = NULL;
- setResultCore(result);
- iterParameter(call, &new_arg, is_dict, CNEXT_NT);
- return new_arg;
- }
- bool checkIsSep(Parameter *pt) {
- for (PASS; pt != NULL; pt = pt->next) {
- if (pt->data.is_sep == true)
- return true;
- }
- return false;
- }
- /**
- * 参数表:
- |实参 \ 形参| 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 func_var
- * @param inter
- * @param var_list
- * @return
- */
- ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *function_base, VarList *function_var,
- FUNC_NT) {
- Parameter *function = NULL;
- Parameter *tmp_function = NULL; // 释放使用
- enum {
- match_status = 1,
- default_status = 2,
- self_ass = 3,
- mul_par = 4,
- space_kwargs = 5,
- error_to_less = -1,
- error_to_more = -2,
- error_kw = -3,
- error_unknown = -4,
- finished = 0,
- } 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)
- status = error_to_more;
- else if ((call == NULL && function->type == value_par))
- status = error_to_less;
- else if (call != NULL && call->type == value_par && function->type == kwargs_par)
- status = error_kw;
- 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)
- status = mul_par;
- else if (call->type == value_arg) // 根据前面的条件, 已经决定call不会为NULL
- status = match_status;
- else if (call->type == name_arg) {
- if (checkIsSep(function))
- status = error_to_less;
- else
- status = self_ass;
- } else
- status = error_unknown;
- freeResult(result);
- switch (status) {
- case match_status: {
- argumentToParameter(&call, &function, function_var, CNEXT_NT);
- returnResult(result);
- break;
- }
- case default_status: {
- vint num = 0;
- defaultParameter(&function, &num, CFUNC_NT(function_var, result, belong));
- returnResult(result);
- break;
- }
- case self_ass: {
- vint set_num = 0;
- vint get_num = 0;
- bool dict_status = false;
- VarList *tmp = makeVarList(inter, true, NULL);
- argumentToVar(&call, &set_num, CFUNC_NT(tmp, result, belong));
- if (!CHECK_RESULT(result)) {
- freeVarList(tmp);
- goto return_;
- }
- freeResult(result);
- parameterFromVar(&function, function_var, &get_num, set_num, &dict_status, CFUNC_NT(tmp, result, belong));
- freeVarList(tmp);
- if (!CHECK_RESULT(result))
- goto return_;
- if (!dict_status && set_num > get_num)
- goto to_more;
- break;
- }
- case mul_par: {
- LinkValue *tmp;
- if (call != NULL) {
- Argument *backup;
- Argument *base = call;
- for (PASS; call->next != NULL && call->next->type == value_arg; call = call->next)
- PASS;
- backup = call->next;
- call->next = NULL;
- makeListValue(base, LINEFILE, L_tuple, CNEXT_NT);
- call->next = backup;
- call = backup;
- } else
- makeListValue(NULL, LINEFILE, L_tuple, CNEXT_NT);
- returnResult(result);
- GET_RESULT(tmp, result);
- assCore(function->data.value, tmp, false, false, CFUNC_NT(function_var, result, belong));
- gc_freeTmpLink(&tmp->gc_status);
- returnResult(result);
- function = function->next;
- break;
- }
- case space_kwargs:{
- LinkValue *tmp;
- makeDictValue(NULL, true, LINEFILE, CNEXT_NT);
- returnResult(result);
- GET_RESULT(tmp, result);
- assCore(function->data.value, tmp, false, false, CFUNC_NT(function_var, result, belong));
- gc_freeTmpLink(&tmp->gc_status);
- returnResult(result);
- function = function->next;
- break;
- }
- case error_to_less:
- setResultError(E_ArgumentException, FEW_ARG, line, file, true, CNEXT_NT);
- goto return_;
- case error_to_more:
- to_more:
- setResultError(E_ArgumentException, MANY_ARG, line, file, true, CNEXT_NT);
- goto return_;
- case error_kw:
- setResultError(E_ArgumentException, OBJ_NOTSUPPORT(**), line, file, true, CNEXT_NT);
- goto return_;
- case error_unknown:
- setResultError(E_ArgumentException, L"argument Unknown Exception", line, file, true, CNEXT_NT);
- goto return_;
- default:
- goto break_;
- }
- }
- break_:
- setResult(result, inter);
- return_:
- freeParameter(tmp_function, true);
- return result->type;
- }
- Inherit *setFather(Argument *call) {
- Inherit *father_tmp = NULL;
- for (Argument *tmp = call; tmp != NULL && tmp->type == value_arg; tmp = tmp->next)
- if (tmp->data.value->value->type == V_class) {
- father_tmp = connectInherit(father_tmp, makeInherit(tmp->data.value));
- father_tmp = connectInherit(father_tmp, copyInherit(tmp->data.value->value->object.inherit));
- }
- return setFatherCore(father_tmp);
- }
- Inherit *setFatherCore(Inherit *father_tmp) {
- Inherit *base_father = NULL;
- while (father_tmp != NULL){
- Inherit *next = father_tmp->next;
- father_tmp->next = NULL;
- base_father = connectSafeInherit(base_father, father_tmp);
- father_tmp = next;
- }
- return base_father;
- }
- bool checkFormal(Parameter *pt) {
- enum {
- Formal_1,
- Formal_2,
- } status = Formal_1;
- for (PASS; pt != NULL; pt = pt->next){
- if (status == Formal_1 && (pt->type == name_par || pt->type == args_par))
- status = Formal_2;
- else if (status == Formal_2 && (pt->type == value_par || pt->type == args_par) || pt->type == kwargs_par && pt->next != NULL)
- return false;
- }
- return true;
- }
- int parserArgumentUnion(ArgumentParser ap[], Argument *arg, FUNC_NT){
- setResultCore(result);
- if (ap->type != only_name){
- ArgumentParser *bak = NULL;
- int status = 1;
- arg = parserValueArgument(ap, arg, &status, &bak);
- if (status != 1){
- setResultError(E_ArgumentException, FEW_ARG, LINEFILE, true, CNEXT_NT);
- return 0;
- }
- ap = bak;
- }
- if (ap->must != -1){
- ArgumentParser *bak = NULL;
- int status;
- if (arg != NULL && arg->type != name_arg) {
- setResultError(E_ArgumentException, MANY_ARG, LINEFILE, true, CNEXT_NT);
- return -6;
- }
- status = parserNameArgument(ap, arg, &bak, CNEXT_NT);
- if (!CHECK_RESULT(result))
- return -1;
- if (status == -3){
- if (parserArgumentNameDefault(ap)->must != -1){
- setResultError(E_ArgumentException, FEW_ARG, LINEFILE, true, CNEXT_NT);
- return -7;
- }
- }
- else if (status == 0){
- setResultError(E_ArgumentException, MANY_ARG, LINEFILE, true, CNEXT_NT);
- return -2;
- } else if (status == -4){
- setResultError(E_ArgumentException, FEW_ARG, LINEFILE, true, CNEXT_NT);
- return -3;
- }
- } else{
- if (arg != NULL) {
- setResultError(E_ArgumentException, MANY_ARG, LINEFILE, true, CNEXT_NT);
- return -4;
- }
- }
- return 1;
- }
- Argument *parserValueArgument(ArgumentParser *ap, Argument *arg, int *status, ArgumentParser **bak){
- *status = 1;
- for (PASS; ap->must != -1 && (ap->type == only_value || ap->type == name_value); ap++){
- if (arg == NULL || arg->name_type != value_arg) { // 形参进入key=value模式
- if ((ap = parserArgumentValueDefault(ap))->must != -1 && ap->type == only_value) // 检查剩余的是否.must=1
- *status = 0; // 存在.must=1则返回 0
- break; // 正常情况返回 1
- }
- arg = parserArgumentValueCore(arg, ap);
- }
- if (bak != NULL)
- *bak = ap;
- return arg;
- }
- int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak, FUNC_NT){
- VarList *tmp = NULL;
- vint set_num = 0;
- vint get_num = 0;
- int return_;
- setResultCore(result);
- for (PASS; arg != NULL && arg->type != name_arg; arg = arg->next)
- PASS;
- if (arg == NULL) {
- return_ = -3; // 参数缺失
- goto return_;
- }
- tmp = makeVarList(inter, true, NULL);
- argumentToVar(&arg, &set_num, CFUNC_NT(tmp, result, belong));
- if (!CHECK_RESULT(result)) {
- return_ = -1;
- goto return_;
- }
- setResult(result, inter);
- for (PASS; ap->must != -1 && (ap->type == only_name || ap->type == name_value); ap++) {
- int status = parserArgumentVar(ap, inter, tmp);
- if (status == 1)
- get_num ++;
- else{
- return_ = -2; // 参数缺失
- goto return_;
- }
- }
- return_ = (get_num < set_num) ? 0 : ((get_num > set_num) ? -4 : 1);
- return_:
- freeVarList(tmp);
- if (bak != NULL)
- *bak = ap;
- return return_;
- }
- Argument *parserArgumentValueCore(Argument *arg, ArgumentParser *ap){
- int count = 1;
- ap->arg = arg;
- ap->value = arg->data.value;
- arg = arg->next;
- if (ap->long_arg)
- for (PASS; arg != NULL && arg->type == value_arg; arg = arg->next, count++)
- PASS;
- ap->c_count = count;
- return arg;
- }
- int parserArgumentVar(ArgumentParser *ap, Inter *inter, VarList *var_list){
- LinkValue *value = NULL;
- findStrVarOnly(ap->name, false, CFUNC_CORE(var_list)); // 参数取值不执行变量式函数
- ap->value = value;
- if (value != NULL)
- return 1;
- else if (ap->must)
- return -1;
- return 0;
- }
- ArgumentParser *parserArgumentValueDefault(ArgumentParser *ap){
- for (PASS; ap->type == only_value && ap->must == 0; ap++) {
- ap->arg = NULL;
- ap->value = NULL;
- ap->c_count = 0;
- }
- return ap;
- }
- ArgumentParser *parserArgumentNameDefault(ArgumentParser *ap){
- for (PASS; ap->must == 0; ap++) {
- ap->arg = NULL;
- ap->value = NULL;
- ap->c_count = 0;
- }
- return ap;
- }
- void setArgumentFFICore(ArgumentFFI *af) { // 初始化设定
- af->type = NULL;
- af->arg = NULL;
- af->arg_v = NULL;
- af->size = 0;
- af->b_va = 0;
- }
- void setArgumentFFI(ArgumentFFI *af, unsigned int size) {
- af->type = memCalloc((size_t)size, sizeof(enum ArgumentFFIType));
- af->arg = memCalloc((size_t)size, sizeof(ffi_type *));
- af->arg_v = memCalloc((size_t)size, sizeof(void *));
- af->size = size;
- af->b_va = size;
- memset(af->type, 0, (size_t)size);
- memset(af->arg, 0, (size_t)size);
- memset(af->arg_v, 0, (size_t)size);
- }
- void freeArgumentFFI(ArgumentFFI *af) {
- for (unsigned int i=0; i < af->size; i++) {
- switch (af->type[i]) {
- case af_wstr:
- case af_str:
- if (af->arg_v[i] != NULL)
- memFree(*(void **)af->arg_v[i]);
- memFree(af->arg_v[i]);
- break;
- case af_void:
- break;
- default:
- memFree(af->arg_v[i]);
- break;
- }
- }
- memFree(af->type);
- memFree(af->arg);
- memFree(af->arg_v);
- }
- unsigned int checkArgument(Argument *arg, enum ArgumentType type) {
- unsigned int count;
- for (count = 0; arg != NULL; arg = arg->next, count ++) {
- if (arg->type != type)
- return -1;
- }
- return count;
- }
- enum ResultType listToArgumentFFI(ArgumentFFI *af, LinkValue *list_b, LinkValue *valiste_b, FUNC_NT) { // TODO-szh 内存检查
- int i = 0;
- LinkValue *iter[3] = {}; // 待遍历列表 (默认三个都为NULL)
- setResultCore(result);
- gc_addTmpLink(&list_b->gc_status);
- if (valiste_b != NULL)
- gc_addTmpLink(&valiste_b->gc_status);
- getIter(list_b, 1, LINEFILE, CNEXT_NT); // 获取__iter__对象
- if (!CHECK_RESULT(result))
- goto return_;
- iter[0] = result->value;
- result->value = NULL;
- freeResult(result);
- if (valiste_b != NULL) {
- getIter(valiste_b, 1, LINEFILE, CNEXT_NT); // 获取__iter__对象
- if (!CHECK_RESULT(result))
- goto return_;
- iter[1] = result->value;
- result->value = NULL;
- freeResult(result);
- } else
- iter[1] = NULL;
- for (int a=0; iter[a] != NULL; a++) { // 开始遍历
- while (1) {
- LinkValue *str;
- getIter(iter[a], 0, LINEFILE, CNEXT_NT);
- if (is_iterStop(result->value, inter)) { // 执行__next__
- freeResult(result);
- break;
- } else if (!CHECK_RESULT(result))
- return result->type;
- else
- str = result->value;
- if (str->value->type != V_str) { // 检查是否为str
- freeResult(result);
- setResultError(E_ArgumentException, L"no-support argument type for C function", LINEFILE, true,
- CNEXT_NT);
- goto return_;
- }
- af->arg[i] = getFFIType(str->value->data.str.str, af->type + i);
- i++;
- freeResult(result);
- if (af->arg[i] == NULL || af->type[i] == af_void) { // 不支持的类型
- setResultError(E_ArgumentException, L"no-support argument type for C function", LINEFILE, true,
- CNEXT_NT);
- goto return_;
- }
- }
- }
- setResult(result, inter);
- return_:
- gc_freeTmpLink(&list_b->gc_status);
- gc_freeTmpLink(&iter[0]->gc_status);
- if (valiste_b != NULL) {
- gc_freeTmpLink(&valiste_b->gc_status);
- gc_freeTmpLink(&iter[1]->gc_status);
- }
- return result->type;
- }
- #define setFFIValue(v_t, ffi_t, af_t, type_, data_) case v_t: \
- af->arg[i] = &(ffi_t); /* af->arg是ffi_type **arg, 即*arg[] */ \
- af->type[i] = af_t; \
- af->arg_v[i] = (type_ *)memCalloc(1, sizeof(type_)); /* af->arg_v是ffi_type **arg_v, 即 *arg_v[] */ \
- *(type_ *)(af->arg_v[i]) = (type_)(data_); \
- break
- static bool setFFIArgFromValue(ArgumentFFI *af, Argument *arg, unsigned int i) {
- switch (arg->data.value->value->type) {
- setFFIValue(V_int, ffi_type_sint32, af_int, int, arg->data.value->value->data.int_.num);
- setFFIValue(V_dou, ffi_type_double, af_double, double, arg->data.value->value->data.dou.num);
- setFFIValue(V_bool, ffi_type_sint32, af_int, double, arg->data.value->value->data.bool_.bool_);
- setFFIValue(V_str, ffi_type_pointer, af_str, char *, memWcsToStr(arg->data.value->value->data.str.str, false));
- setFFIValue(V_pointer, ffi_type_void, af_pointer, void *, arg->data.value->value->data.pointer.pointer);
- setFFIValue(V_struct, ffi_type_void, af_pointer, void *, arg->data.value->value->data.struct_.data);
- case V_ell:
- setFFIValue(V_none, ffi_type_sint32, af_int, int, 0);
- default:
- return false;
- }
- return true;
- }
- #undef setFFIValue
- #define setFFIArgFromTypeNumber(aft_type, type_) \
- case aft_type: \
- do { \
- af->arg_v[i] = memCalloc(1, sizeof(type_)); \
- switch (arg->data.value->value->type) { \
- case V_int: \
- *(type_ *)(af->arg_v[i]) = (type_)arg->data.value->value->data.int_.num; \
- break; \
- case V_dou: \
- *(type_ *)(af->arg_v[i]) = (type_)arg->data.value->value->data.dou.num; \
- break; \
- case V_ell: \
- case V_none: \
- *(type_ *)(af->arg_v[i]) = (type_)0; \
- break; \
- case V_bool: \
- *(type_ *)(af->arg_v[i]) = (type_)arg->data.value->value->data.bool_.bool_; \
- break; \
- case V_pointer: \
- *(type_ *)(af->arg_v[i]) = (type_)(vint)arg->data.value->value->data.pointer.pointer; \
- break; \
- default: \
- return false; \
- } } while(0); \
- break
- #define setFFIArgFromTypeChar(aft_type, type_) case aft_type: \
- af->arg_v[i] = memCalloc(1, sizeof(type_)); \
- if (arg->data.value->value->type == V_str && memWidelen(arg->data.value->value->data.str.str) == 1) \
- *(type_ *)(af->arg_v[i]) = (type_)(arg->data.value->value->data.str.str[0]); \
- else \
- return false; \
- break
- static bool setFFIArgFromType(ArgumentFFI *af, Argument *arg, unsigned int i) {
- switch (af->type[i]) {
- setFFIArgFromTypeNumber(af_sint, int16_t);
- setFFIArgFromTypeNumber(af_usint, uint16_t);
- setFFIArgFromTypeNumber(af_int, int32_t);
- setFFIArgFromTypeNumber(af_uint, uint32_t);
- setFFIArgFromTypeNumber(af_lint, int64_t);
- setFFIArgFromTypeNumber(af_ulint, uint64_t);
- setFFIArgFromTypeNumber(af_float, float);
- setFFIArgFromTypeNumber(af_ldouble, long double);
- setFFIArgFromTypeNumber(af_double, double);
- case af_pointer:
- af->arg_v[i] = memCalloc(1, sizeof(void *));
- switch (arg->data.value->value->type) {
- case V_int:
- *(void **) (af->arg_v[i]) = (void *) arg->data.value->value->data.int_.num;
- break;
- case V_ell:
- case V_none:
- *(void **) (af->arg_v[i]) = NULL;
- break;
- case V_pointer:
- *(void **) (af->arg_v[i]) = (void *)arg->data.value->value->data.pointer.pointer;
- break;
- case V_struct:
- *(void **) (af->arg_v[i]) = (void *)arg->data.value->value->data.struct_.data;
- break;
- default:
- return 0;
- }
- break;
- setFFIArgFromTypeChar(af_char, int8_t);
- setFFIArgFromTypeChar(af_uchar, uint8_t);
- case af_str:
- af->arg_v[i] = memCalloc(1, sizeof(char *)); // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
- if (arg->data.value->value->type == V_str) {
- *(char **)(af->arg_v[i]) = memWcsToStr(arg->data.value->value->data.str.str, false);
- } else
- return false;
- break;
- case af_wstr:
- af->arg_v[i] = memCalloc(1, sizeof(wchar_t *)); // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
- if (arg->data.value->value->type == V_str) {
- *(wchar_t **)(af->arg_v[i]) = memWidecpy(arg->data.value->value->data.str.str);
- } else
- return false;
- break;
- default:
- return false;
- }
- return true;
- }
- #undef setFFIArgFromTypeNumber
- #undef setFFIArgFromTypeChar
- bool setArgumentToFFI(ArgumentFFI *af, Argument *arg) {
- for (unsigned int i=0; arg != NULL && i < af->size; arg = arg->next, i++) {
- if (af->arg[i] == NULL) { // af->arg即ffi_type, 为NULL则表示该参数类型没有指定
- if (!setFFIArgFromValue(af, arg, i))
- return false;
- } else{
- if (!setFFIArgFromType(af, arg, i))
- return false;
- }
- }
- return arg == NULL; // 若arg还没迭代完, 则证明有问题
- }
- ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft) { // 从str中翻译ffi类型
- ffi_type *return_ = NULL;
- if (eqWide(str, L"int")) {
- return_ = &ffi_type_sint32;
- *aft = af_int;
- } else if (eqWide(str, L"uint")) {
- return_ = &ffi_type_uint32;
- *aft = af_uint;
- } else if (eqWide(str, L"sint")) {
- return_ = &ffi_type_sint16;
- *aft = af_sint;
- } else if (eqWide(str, L"usint")) {
- return_ = &ffi_type_uint16;
- *aft = af_usint;
- } else if (eqWide(str, L"lint")) {
- return_ = &ffi_type_sint64;
- *aft = af_lint;
- } else if (eqWide(str, L"ulint")) {
- return_ = &ffi_type_uint64;
- *aft = af_ulint;
- } else if (eqWide(str, L"float")) {
- return_ = &ffi_type_float;
- *aft = af_float;
- } else if (eqWide(str, L"double")) {
- return_ = &ffi_type_double;
- *aft = af_double;
- } else if (eqWide(str, L"ldouble")) {
- return_ = &ffi_type_longdouble;
- *aft = af_ldouble;
- } else if (eqWide(str, L"str")) {
- return_ = &ffi_type_pointer;
- *aft = af_str;
- } else if (eqWide(str, L"wstr")) {
- return_ = &ffi_type_pointer;
- *aft = af_wstr;
- } else if (eqWide(str, L"char")) {
- return_ = &ffi_type_sint8;
- *aft = af_char;
- } else if (eqWide(str, L"uchar")) {
- return_ = &ffi_type_uint8;
- *aft = af_char;
- } else if (eqWide(str, L"void")) {
- return_ = &ffi_type_void;
- *aft = af_void;
- } else if (eqWide(str, L"pointer")) {
- return_ = &ffi_type_pointer;
- *aft = af_pointer;
- }
- return return_;
- }
- ffi_type *getFFITypeUp(wchar_t *str, enum ArgumentFFIType *aft) { // 自带参数类型提升
- ffi_type *return_ = NULL;
- if (eqWide(str, L"int") || eqWide(str, L"sint") || eqWide(str, L"char")) {
- return_ = &ffi_type_sint32;
- *aft = af_int;
- } else if (eqWide(str, L"uint") || eqWide(str, L"usint") || eqWide(str, L"uchar")) {
- return_ = &ffi_type_uint32;
- *aft = af_uint;
- } else if (eqWide(str, L"lint")) {
- return_ = &ffi_type_sint64;
- *aft = af_lint;
- } else if (eqWide(str, L"ulint")) {
- return_ = &ffi_type_uint64;
- *aft = af_ulint;
- } else if (eqWide(str, L"float") || eqWide(str, L"double")) {
- return_ = &ffi_type_double;
- *aft = af_double;
- } else if (eqWide(str, L"ldouble")) {
- return_ = &ffi_type_longdouble;
- *aft = af_ldouble;
- } else if (eqWide(str, L"str")) {
- return_ = &ffi_type_pointer;
- *aft = af_str;
- } else if (eqWide(str, L"wstr")) {
- return_ = &ffi_type_pointer;
- *aft = af_wstr;
- } else if (eqWide(str, L"void")) {
- return_ = &ffi_type_void;
- *aft = af_void;
- } else if (eqWide(str, L"pointer")) {
- return_ = &ffi_type_pointer;
- *aft = af_pointer;
- }
- return return_;
- }
|