123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- #include "__run.h"
- ResultType getBaseVarInfo(wchar_t **name, int *times, INTER_FUNCTIONSIG){
- *name = setStrVarName(st->u.base_var.name, false, inter);
- *times = 0;
- if (st->u.base_var.times == NULL){
- *times = 0;
- goto not_times;
- }
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list, result, belong)))
- return result->type;
- if (!isType(result->value->value, V_num)){
- setResultErrorSt(E_TypeException, L"Variable operation got unsupported V_num of layers", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return result->type;
- }
- *times = (int)result->value->value->data.num.num;
- freeResult(result);
- not_times:
- makeStringValue(st->u.base_var.name, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return result->type;
- }
- ResultType getBaseSVarInfo(wchar_t **name, int *times, INTER_FUNCTIONSIG){
- freeResult(result);
- if (st->u.base_svar.times == NULL){
- *times = 0;
- goto not_times;
- }
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list, result, belong)))
- return result->type;
- if (!isType(result->value->value, V_num)){
- setResultErrorSt(E_TypeException, L"Variable operation got unsupported V_num of layers", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return result->type;
- }
- *times = (int)result->value->value->data.num.num;
- freeResult(result);
- not_times:
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.name, var_list, result, belong)))
- return result->type;
- *name = getNameFromValue(result->value->value, inter);
- result->type = R_opt; // 执行 operationSafeInterStatement 的时候已经初始化 result
- return result->type;
- }
- ResultType getVarInfo(wchar_t **name, int *times, INTER_FUNCTIONSIG){
- if (st->type == base_var)
- getBaseVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
- else if (st->type == base_svar)
- getBaseSVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
- else{
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
- return result->type;
- *name = getNameFromValue(result->value->value, inter);
- *times = 0;
- }
- return result->type;
- }
- wchar_t *setStrVarName(wchar_t *old, bool free_old, Inter *inter) {
- return memWidecat(inter->data.var_str_prefix, old, false, free_old);
- }
- wchar_t *setNumVarName(vnum num, struct Inter *inter) {
- wchar_t name[50];
- swprintf(name, 50, L"%lld", num);
- return memWidecat(inter->data.var_num_prefix, name, false, false);
- }
- wchar_t *getNameFromValue(Value *value, struct Inter *inter) {
- switch (value->type){
- case V_str:
- return setStrVarName(value->data.str.str, true, inter);
- case V_num:
- return setNumVarName(value->data.num.num, inter);
- case V_bool:
- if (value->data.bool_.bool_)
- return memWidecat(inter->data.var_bool_prefix, L"true", false, false);
- else
- return memWidecat(inter->data.var_bool_prefix, L"false", false, false);
- case V_none:
- return memWidecpy(inter->data.var_none);
- case V_ell:
- return memWidecpy(inter->data.var_pass);
- case V_class:{
- size_t len = memWidelen(inter->data.var_class_prefix) + 20; // 预留20个字节给指针
- wchar_t *name = memWide(len);
- wchar_t *return_ = NULL;
- swprintf(name, len, L"%ls%p", inter->data.var_class_prefix, value);
- return_ = memWidecpy(name); // 再次复制去除多余的空字节
- memFree(name);
- return return_;
- }
- default:{
- size_t len = memWidelen(inter->data.var_object_prefix) + 20;
- wchar_t *name = memWide(len);
- wchar_t *return_ = NULL;
- swprintf(name, len, L"%ls%p", inter->data.var_object_prefix, value);
- return_ = memWidecpy(name); // 再次复制去除多余的空字节
- memFree(name);
- return return_;
- }
- }
- }
- bool popStatementVarList(Statement *funtion_st, VarList **function_var, VarList *out_var, Inter *inter){
- bool yield_run;
- if ((yield_run = funtion_st->info.have_info)) {
- *function_var = funtion_st->info.var_list;
- (*function_var)->next = out_var;
- }
- else
- *function_var = pushVarList(out_var, inter);
- return yield_run;
- }
- void newFunctionYield(Statement *funtion_st, Statement *node, VarList *new_var, Inter *inter){
- new_var->next = NULL;
- gc_freeze(inter, new_var, NULL, true);
- funtion_st->info.var_list = new_var;
- funtion_st->info.node = node->type == yield_code ? node->next : node;
- funtion_st->info.have_info = true;
- }
- void updateFunctionYield(Statement *function_st, Statement *node){
- function_st->info.node = node->type == yield_code ? node->next : node;
- function_st->info.have_info = true;
- }
- ResultType setFunctionArgument(Argument **arg, Argument **base, LinkValue *_func, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST){
- Argument *tmp = NULL;
- LinkValue *self;
- LinkValue *func;
- enum FunctionPtType pt_type = _func->value->data.function.function_data.pt_type;
- setResultCore(result);
- switch (pt_sep) {
- case 0:
- func = _func;
- self = pt_type == cls_free_ || pt_type == cls_static_ ? _func->value->data.function.function_data.cls : _func->belong;
- *base = *arg;
- break;
- case 1: {
- if (*arg != NULL) {
- if (pt_type == static_) {
- func = (*arg)->data.value;
- self = NULL; // static_模式不需要self
- }
- else {
- func = _func;
- self = (*arg)->data.value;
- }
- *arg = (*arg)->next; // 忽略第一个arg, 但是不释放(在该函数外部统一释放)
- *base = *arg;
- } else {
- error_:
- setResultError(E_ArgumentException, FEW_ARG, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return R_error;
- }
- break;
- }
- case 2: {
- if (*arg != NULL && (*arg)->next != NULL) {
- func = (*arg)->data.value;
- self = (*arg)->next->data.value; // 第一个参数是func, 第二个是self; 这样做保证了和形参调用的一致
- *arg = (*arg)->next->next;
- *base = *arg;
- } else
- goto error_;
- break;
- }
- default:
- setResultError(E_ArgumentException, MANY_ARG, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return R_error;
- }
- if (pt_type != free_ && self == NULL) {
- setResultError(E_ArgumentException, L"Function does not belong to anything(not self)", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return R_error;
- }
- switch (pt_type) {
- case static_:
- tmp = makeValueArgument(func);
- tmp->next = *arg;
- *arg = tmp;
- break;
- case class_static_:
- tmp = makeValueArgument(func);
- if (self->value->type != V_class) {
- Inherit *ih = self->value->object.inherit;
- self = NULL;
- for (PASS; ih != NULL; ih = ih->next) // 使用循环的方式检查
- if (ih->value->value->type == V_class) {
- self = ih->value;
- break;
- }
- }
- if (self != NULL) {
- tmp->next = makeValueArgument(self);
- tmp->next->next = *arg;
- } else // 若未检查到class, 则放弃该形参(由原arg补上)
- tmp->next = *arg;
- *arg = tmp;
- break;
- case cls_static_:
- case all_static_:
- tmp = makeValueArgument(func);
- tmp->next = makeValueArgument(self);
- tmp->next->next = *arg;
- *arg = tmp;
- break;
- case object_static_:
- tmp = makeValueArgument(func);
- if (self->value->type != V_class){
- tmp->next = makeValueArgument(self);
- tmp->next->next = *arg;
- }
- else
- tmp->next = *arg;
- *arg = tmp;
- break;
- case class_free_:
- if (self->value->type != V_class){
- Inherit *ih = self->value->object.inherit;
- self = NULL;
- for (PASS; ih != NULL; ih = ih->next) // 循环检查
- if (ih->value->value->type == V_class) {
- self = ih->value;
- break;
- }
- }
- if (self != NULL) { // 若检查到class
- tmp = makeValueArgument(self);
- tmp->next = *arg;
- *arg = tmp;
- } // 若无class则不对arg做任何调整
- break;
- case object_free_:
- if (self->value->type != V_class) {
- tmp = makeValueArgument(self);
- tmp->next = *arg;
- *arg = tmp;
- }
- break;
- case cls_free_:
- case all_free_:
- tmp = makeValueArgument(self);
- tmp->next = *arg;
- *arg = tmp;
- break;
- default:
- break;
- }
- setResultBase(result, inter);
- return result->type;
- }
- void freeFunctionArgument(Argument *arg, Argument *base) {
- for (Argument *tmp = arg; tmp != NULL; tmp = tmp->next) {
- if (tmp->next == base) {
- tmp->next = NULL;
- freeArgument(arg, true);
- break;
- }
- }
- }
- LinkValue *findStrVar(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE){
- LinkValue *tmp = NULL;
- wchar_t *name_ = setStrVarName(name, free_old, inter);
- tmp = findFromVarList(name_, 0, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- memFree(name_);
- return tmp;
- }
- LinkValue *checkStrVar(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE){
- LinkValue *tmp = NULL;
- wchar_t *name_ = setStrVarName(name, free_old, inter);
- tmp = findFromVarList(name_, 0, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- memFree(name_);
- return tmp;
- }
- void addStrVarCore(int setting, wchar_t *var_name, LinkValue *name_, LinkValue *value, fline line, char *file, VarList *out_var, INTER_FUNCTIONSIG_NOT_ST) {
- addFromVarList(var_name, name_, 0, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- out_var = out_var == NULL ? var_list : out_var;
- if (setting)
- newObjectSetting(name_, line, file, value, result, inter, out_var);
- else
- setResult(result, inter);
- }
- void addStrVar(wchar_t *name, bool free_old, bool setting, LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- LinkValue *name_;
- wchar_t *var_name = setStrVarName(name, free_old, inter);
- setResultCore(result);
- makeStringValue(var_name, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- if (!CHECK_RESULT(result))
- goto return_;
- name_ = result->value;
- result->value = NULL;
- freeResult(result);
- addStrVarCore(setting, var_name, name_, value, line, file, NULL, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- gc_freeTmpLink(&name_->gc_status);
- return_:
- memFree(var_name);
- }
- LinkValue *findAttributes(wchar_t *name, bool free_old, LinkValue *value, Inter *inter) {
- LinkValue *attr = findStrVar(name, free_old, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
- if (attr != NULL && (attr->belong == NULL || attr->belong->value != value->value && checkAttribution(value->value, attr->belong->value)))
- attr->belong = value;
- return attr;
- }
- bool addAttributes(wchar_t *name, bool free_old, LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- wchar_t *var_name = setStrVarName(name, free_old, inter);
- LinkValue *name_;
- setResultCore(result);
- makeStringValue(var_name, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- if (!CHECK_RESULT(result))
- goto return_;
- name_ = result->value;
- result->value = NULL;
- freeResult(result);
- gc_freeze(inter, var_list, belong->value->object.var, true);
- addStrVarCore(false, var_name, name_, value, line, file, var_list, CALL_INTER_FUNCTIONSIG_NOT_ST(belong->value->object.var, result, belong));
- gc_freeze(inter, var_list, belong->value->object.var, false);
- gc_freeTmpLink(&name_->gc_status);
- return_:
- memFree(var_name);
- return CHECK_RESULT(result);
- }
- void newObjectSetting(LinkValue *name, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- setResultCore(result);
- addAttributes(inter->data.object_name, false, name, line, file, belong, result, inter, var_list);
- if (CHECK_RESULT(result))
- return;
- freeResult(result);
- addAttributes(inter->data.object_self, false, belong, line, file, belong, result, inter, var_list);
- if (CHECK_RESULT(result) && belong->value->object.inherit != NULL) {
- freeResult(result);
- addAttributes(inter->data.object_father, false, belong->value->object.inherit->value, line, file, belong,
- result, inter, var_list);
- }
- }
- ResultType getElement(LinkValue *from, LinkValue *index, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- LinkValue *_func_ = NULL;
- setResultCore(result);
- gc_addTmpLink(&from->gc_status);
- gc_addTmpLink(&index->gc_status);
- _func_ = findAttributes(inter->data.object_down, false, from, inter);
- if (_func_ != NULL){
- Argument *arg = NULL;
- gc_addTmpLink(&_func_->gc_status);
- arg = makeValueArgument(index);
- callBackCore(_func_, arg, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- gc_freeTmpLink(&_func_->gc_status);
- freeArgument(arg, true);
- }
- else
- setResultError(E_TypeException, OBJ_NOTSUPPORT(subscript(__down__)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- gc_freeTmpLink(&from->gc_status);
- gc_freeTmpLink(&index->gc_status);
- return result->type;
- }
- ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- LinkValue *_func_ = NULL;
- setResultCore(result);
- if (status == 1)
- _func_ = findAttributes(inter->data.object_iter, false, value, inter);
- else
- _func_ = findAttributes(inter->data.object_next, false, value, inter);
- if (_func_ != NULL){
- gc_addTmpLink(&_func_->gc_status);
- callBackCore(_func_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- gc_freeTmpLink(&_func_->gc_status);
- }
- else
- setResultError(E_TypeException, OBJ_NOTSUPPORT(iter), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return result->type;
- }
- bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
- LinkValue *_bool_ = findAttributes(inter->data.object_bool, false, value, inter);
- if (_bool_ != NULL){
- gc_addTmpLink(&_bool_->gc_status);
- callBackCore(_bool_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- gc_freeTmpLink(&_bool_->gc_status);
- if (result->value->value->type != V_bool)
- setResultError(E_TypeException, RETURN_ERROR(__bool__, bool), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- else
- return result->value->value->data.bool_.bool_;
- } else {
- makeBoolValue(true, 0, "sys.bool", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return true;
- }
- return false;
- }
- wchar_t *getRepoStr(LinkValue *value, bool is_repo, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
- LinkValue *_repo_ = findAttributes(is_repo ? inter->data.object_repo : inter->data.object_str, false, value, inter);
- setResultCore(result);
- if (_repo_ != NULL){
- gc_addTmpLink(&value->gc_status);
- gc_addTmpLink(&_repo_->gc_status);
- callBackCore(_repo_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- gc_freeTmpLink(&_repo_->gc_status);
- gc_freeTmpLink(&value->gc_status);
- if (!CHECK_RESULT(result))
- return NULL;
- else if (result->value->value->type != V_str){
- setResultError(E_TypeException, OBJ_NOTSUPPORT(repo(str)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return NULL;
- }
- return result->value->value->data.str.str;
- }
- else
- setResultError(E_TypeException, OBJ_NOTSUPPORT(repo(str)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return NULL;
- }
- bool is_iterStop(LinkValue *value, Inter *inter) {
- return value->value == inter->data.iterstop_exc->value || checkAttribution(value->value, inter->data.iterstop_exc->value);
- }
- bool is_indexException(LinkValue *value, Inter *inter) {
- return value->value == inter->data.index_exc->value || checkAttribution(value->value, inter->data.index_exc->value);
- }
- bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, char *file, char *name, bool pri_auto, INTER_FUNCTIONSIG_NOT_ST) {
- if ((value == public_aut || (!pri_auto && value == auto_aut)) && (base != public_aut && base != auto_aut)) {
- if (name == NULL)
- setResultError(E_PermissionsException, L"Wrong Permissions: access variables as public", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- else {
- wchar_t *message = memWidecat(L"Wrong Permissions: access variables as public: ", memStrToWcs(name, false), false, true);
- setResultError(E_PermissionsException, message, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- memFree(message);
- }
- return false;
- }
- else if ((value == protect_aut) && (base == private_aut)) {
- if (name == NULL)
- setResultError(E_PermissionsException, L"Wrong Permissions: access variables as protect", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- else {
- wchar_t *message = memWidecat(L"Wrong Permissions: access variables as protect: ", memStrToWcs(name, false), false, true);
- setResultError(E_PermissionsException, message, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- memFree(message);
- }
- return false;
- }
- return true;
- }
- LinkValue *make_new(Inter *inter, LinkValue *belong, LinkValue *class){
- Inherit *object_father = getInheritFromValueCore(class);
- VarList *new_var = copyVarList(class->value->object.out_var, false, inter);
- Value *new_object = makeObject(inter, NULL, new_var, object_father);
- return makeLinkValue(new_object, belong, inter);
- }
- static int init_new(LinkValue *obj, Argument *arg, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- LinkValue *_init_ = NULL;
- _init_ = findAttributes(inter->data.object_init, false, obj, inter);
- if (_init_ == NULL) {
- if (arg != NULL) {
- setResultError(E_ArgumentException, MANY_ARG, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- return 0;
- } else
- return 1;
- }
- _init_->belong = obj;
- gc_addTmpLink(&_init_->gc_status);
- callBackCore(_init_, arg, 0, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, obj));
- gc_freeTmpLink(&_init_->gc_status);
- return CHECK_RESULT(result) ? 1 : -1;
- }
- int run_init(LinkValue *obj, Argument *arg, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
- int return_;
- setResultCore(result);
- return_ = init_new(obj, arg, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- if (return_ == 1) {
- freeResult(result);
- setResultOperation(result, obj);
- }
- return return_;
- }
- bool setBoolAttrible(bool value, wchar_t *var, fline line, char *file, LinkValue *obj, INTER_FUNCTIONSIG_NOT_ST) {
- LinkValue *bool_value = NULL;
- setResultCore(result);
- makeBoolValue(value, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
- if (!CHECK_RESULT(result))
- return false;
- bool_value = result->value;
- freeResult(result);
- if (!addAttributes(var, false, bool_value, line, file, obj, result, inter, var_list))
- return false;
- freeResult(result);
- return true;
- }
|