123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- #include "__run.h"
- static bool getLeftRightValue(Result *left, Result *right, INTER_FUNCTIONSIG);
- static ResultType operationCore(INTER_FUNCTIONSIG, char *name);
- ResultType assOperation(INTER_FUNCTIONSIG);
- ResultType pointOperation(INTER_FUNCTIONSIG);
- ResultType blockOperation(INTER_FUNCTIONSIG);
- /**
- * operation的整体操作
- * @param st
- * @param inter
- * @param var_list
- * @return
- */
- ResultType operationStatement(INTER_FUNCTIONSIG) {
- setResultCore(result);
- switch (st->u.operation.OperationType) {
- case OPT_ADD:
- operationCore(CALL_INTER_FUNCTIONSIG(st, var_list, result, father), inter->data.object_add);
- break;
- case OPT_SUB:
- operationCore(CALL_INTER_FUNCTIONSIG(st, var_list, result, father), inter->data.object_sub);
- break;
- case OPT_MUL:
- operationCore(CALL_INTER_FUNCTIONSIG(st, var_list, result, father), inter->data.object_mul);
- break;
- case OPT_DIV:
- operationCore(CALL_INTER_FUNCTIONSIG(st, var_list, result, father), inter->data.object_div);
- break;
- case OPT_ASS:
- assOperation(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
- break;
- case OPT_POINT:
- pointOperation(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
- break;
- case OPT_BLOCK:
- blockOperation(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
- break;
- default:
- setResult(result, inter, father);
- break;
- }
- return result->type;
- }
- ResultType blockOperation(INTER_FUNCTIONSIG) {
- Statement *info_st = st->u.operation.left;
- bool yield_run;
- if ((yield_run = popStatementVarList(st, &var_list, var_list, inter)))
- info_st = st->info.node;
- blockSafeInterStatement(CALL_INTER_FUNCTIONSIG(info_st, var_list, result, father));
- if (result->type == error_return)
- return result->type;
- else if (yield_run) {
- if (result->type == yield_return){
- updateFunctionYield(st, result->node);
- result->type = operation_return;
- }
- else
- freeFunctionYield(st, inter);
- }
- else {
- if (result->type == yield_return){
- newFunctionYield(st, result->node, var_list, inter);
- result->type = operation_return;
- }
- else
- popVarList(var_list);
- }
- if (run_continue(result) && st->aut != auto_aut)
- result->value->aut = st->aut;
- return result->type;
- }
- ResultType pointOperation(INTER_FUNCTIONSIG) {
- LinkValue *left;
- VarList *object = NULL;
- VarList *out_var = NULL;
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.left, var_list, result, father)) || result->value->value->type == none)
- return result->type;
- left = result->value;
- setResultCore(result);
- object = left->value->object.var;
- for (out_var = object; out_var->next != NULL; out_var = out_var->next)
- PASS;
- out_var->next = left->value->object.out_var;
- gc_freeze(inter, var_list, object, true);
- operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, object, result, left));
- if (!run_continue(result))
- goto return_;
- else if ((left->aut == public_aut || left->aut == auto_aut) && (result->value->aut != public_aut && result->value->aut != auto_aut))
- setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access variables as public", st,
- father, true);
- else if ((left->aut == protect_aut) && (result->value->aut == private_aut))
- setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access variables as protect", st,
- father, true);
- if (result->value->father->value != left->value && checkAttribution(left->value, result->value->father->value))
- result->value->father = left;
- return_:
- gc_freeze(inter, var_list, object, false);
- if (out_var != NULL)
- out_var->next = NULL;
- gc_freeTmpLink(&left->gc_status);
- return result->type;
- }
- ResultType assOperation(INTER_FUNCTIONSIG) {
- LinkValue *value = NULL;
- if (st->u.operation.left->type == call_function){
- VarList *function_var = NULL;
- Value *function_value = NULL;
- LinkValue *tmp = NULL;
- function_var = copyVarList(var_list, false, inter);
- function_value = makeVMFunctionValue(st->u.operation.right, st->u.operation.left->u.call_function.parameter,
- function_var, inter);
- tmp = makeLinkValue(function_value, father, inter);
- assCore(st->u.operation.left->u.call_function.function, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- }
- else{
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, var_list, result, father)))
- return result->type;
- value = result->value;
- freeResult(result);
- assCore(st->u.operation.left, value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- }
- return result->type;
- }
- ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
- setResultCore(result);
- gc_addTmpLink(&value->gc_status);
- if (name->type == base_list && name->u.base_list.type == value_tuple){
- Parameter *pt = NULL;
- Argument *call = NULL;
- Statement *tmp_st = makeBaseLinkValueStatement(value, name->line, name->code_file);
- pt = makeArgsParameter(tmp_st);
- call = getArgument(pt, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- if (!run_continue(result)) {
- freeArgument(call, false);
- freeParameter(pt, true);
- goto return_;
- }
- freeResult(result);
- setParameterCore(name->line, name->code_file, call, name->u.base_list.list, var_list, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- if (run_continue(result)){
- Argument *tmp = call;
- LinkValue *new_value = makeLinkValue(makeListValue(&tmp, inter, value_tuple), father, inter);
- freeResult(result);
- setResultOperation(result, new_value);
- }
- freeArgument(call, false);
- freeParameter(pt, true);
- }
- else if (name->type == operation && name->u.operation.OperationType == OPT_POINT)
- pointAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- else{
- char *str_name = NULL;
- int int_times = 0;
- LinkValue *var_value = NULL;
- getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, father));
- if (!run_continue(result)) {
- memFree(str_name);
- return result->type;
- }
- var_value = copyLinkValue(value, inter);
- if (var_value->aut == auto_aut)
- var_value->aut = name->aut;
- addFromVarList(str_name, result->value, int_times, var_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- memFree(str_name);
- freeResult(result);
- result->type = operation_return;
- result->value = value;
- gc_addTmpLink(&result->value->gc_status);
- }
- return_:
- gc_freeTmpLink(&value->gc_status);
- return result->type;
- }
- ResultType pointAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST) {
- Result left;
- VarList *object = NULL;
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.operation.left, var_list, result, father)))
- return result->type;
- left = *result;
- setResultCore(result);
- object = left.value->value->object.var;
- gc_freeze(inter, var_list, object, true);
- if (name->u.operation.right->type == OPERATION && name->u.operation.right->u.operation.OperationType == OPT_POINT)
- pointAss(name->u.operation.right, value, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, father));
- else
- assCore(name->u.operation.right, value, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, father));
- gc_freeze(inter, var_list, object, false);
- freeResult(&left);
- return result->type;
- }
- ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
- int int_times = 0;
- char *name = NULL;
- freeResult(result);
- var_info(&name, &int_times, CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
- if (!run_continue(result)) {
- memFree(name);
- return result->type;
- }
- freeResult(result);
- result->type = operation_return;
- result->value = findFromVarList(name, int_times, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
- if (result->value == NULL) {
- char *info = memStrcat("Name Not Found: ", name, false, false);
- setResultErrorSt(result, inter, "NameException", info, st, father, true);
- memFree(info);
- }
- else if ((st->aut == public_aut) && (result->value->aut != public_aut && result->value->aut != auto_aut)){
- setResultCore(result);
- char *info = memStrcat("Wrong Permissions: access variables as public ", name, false, false);
- setResultErrorSt(result, inter, "PermissionsException", info, st, father, true);
- memFree(info);
- }
- else if ((st->aut == protect_aut) && (result->value->aut == private_aut)){
- setResultCore(result);
- char *info = memStrcat("Wrong Permissions: access variables as protect ", name, false, false);
- setResultErrorSt(result, inter, "PermissionsException", info, st, father, true);
- memFree(info);
- }
- else
- setResultOperationBase(result, result->value);
- memFree(name);
- return result->type;
- }
- ResultType getBaseValue(INTER_FUNCTIONSIG) {
- setResultCore(result);
- if (st->u.base_value.type == link_value)
- result->value = st->u.base_value.value;
- else {
- Value *value = NULL;
- if (st->u.base_value.type == number_str) {
- char *stop = NULL;
- value = makeNumberValue(strtol(st->u.base_value.str, &stop, 10), inter);
- }
- else if (st->u.base_value.type == bool_true)
- value = makeBoolValue(true, inter);
- else if (st->u.base_value.type == bool_false)
- value = makeBoolValue(false, inter);
- else if (st->u.base_value.type == pass_value)
- value = makePassValue(inter);
- else if (st->u.base_value.type == null_value)
- value = makeNoneValue(inter);
- else
- value = makeStringValue(st->u.base_value.str, inter);
- result->value = makeLinkValue(value, father, inter);
- }
- result->type = operation_return;
- gc_addTmpLink(&result->value->gc_status);
- return result->type;
- }
- ResultType getList(INTER_FUNCTIONSIG) {
- Argument *at = NULL;
- Argument *at_tmp = NULL;
- setResultCore(result);
- at = getArgument(st->u.base_list.list, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- at_tmp = at;
- if (!run_continue(result)){
- freeArgument(at_tmp, false);
- return result->type;
- }
- LinkValue *value = makeLinkValue(makeListValue(&at, inter, st->u.base_list.type), father, inter);
- setResultOperation(result, value);
- freeArgument(at_tmp, false);
- return result->type;
- }
- ResultType getDict(INTER_FUNCTIONSIG) {
- Argument *at = NULL;
- Argument *at_tmp = NULL;
- setResultCore(result);
- at = getArgument(st->u.base_dict.dict, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- at_tmp = at;
- if (!run_continue(result)){
- freeArgument(at_tmp, false);
- return result->type;
- }
- freeResult(result);
- Value *tmp_value = makeDictValue(&at, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- if (!run_continue(result)) {
- freeArgument(at_tmp, false);
- return result->type;
- }
- freeResult(result);
- LinkValue *value = makeLinkValue(tmp_value, father, inter);
- setResultOperation(result, value);
- freeArgument(at_tmp, false);
- return result->type;
- }
- ResultType setDefault(INTER_FUNCTIONSIG){
- enum DefaultType type = st->u.default_var.default_type;
- int base = 0; // 用于nonlocal和global
- setResultCore(result);
- if (type == global_)
- for (VarList *tmp = var_list; tmp->next != NULL; tmp = tmp->next)
- base++;
- else if (type == nonlocal_)
- base = 1;
- for (Parameter *pt = st->u.default_var.var; pt != NULL; pt = pt->next){
- char *name = NULL;
- int times = 0;
- freeResult(result);
- getVarInfo(&name, ×, CALL_INTER_FUNCTIONSIG(pt->data.value, var_list, result, father));
- if (!run_continue(result))
- break;
- if (type != default_)
- times = base;
- var_list->default_var = connectDefaultVar(var_list->default_var, name, times);
- memFree(name);
- }
- return result->type;
- }
- bool getLeftRightValue(Result *left, Result *right, INTER_FUNCTIONSIG){
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.left, var_list, result, father)) || result->value->value->type == none)
- return true;
- *left = *result;
- setResultCore(result);
- if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, var_list, result, father)) || result->value->value->type == none)
- return true;
- *right = *result;
- setResultCore(result);
- return false;
- }
- ResultType operationCore(INTER_FUNCTIONSIG, char *name) {
- Result left;
- Result right;
- LinkValue *_func_ = NULL;
- setResultCore(&left);
- setResultCore(&right);
- if (getLeftRightValue(&left, &right, CALL_INTER_FUNCTIONSIG(st, var_list, result, father)))
- return result->type;
- _func_ = findAttributes(name, false, left.value, inter);
- if (_func_ != NULL){
- Argument *arg = makeValueArgument(right.value);
- gc_addTmpLink(&_func_->gc_status);
- callBackCore(_func_, arg, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
- gc_freeTmpLink(&_func_->gc_status);
- freeArgument(arg, true);
- }
- else {
- char *message = memStrcat("Don't find ", name, false, false);
- setResultErrorSt(result, inter, "TypeException", message, st, father, true);
- memFree(message);
- }
- freeResult(&left);
- freeResult(&right);
- return result->type;
- }
|