1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123 |
- #include "__run.h"
- static bool checkNumber(FUNC){
- if (!isType(result->value->value, V_int)) {
- setResultErrorSt(E_TypeException, L"Don't get a int of layers", true, st, CNEXT_NT);
- return false;
- }
- return true;
- }
- static void newBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status, Inter *inter){
- if (new_var != NULL)
- new_var->next = NULL;
- branch_st->info.var_list = new_var;
- branch_st->info.node = node->type == yield_code ? node->next : node;
- branch_st->info.branch.sl_node = sl_node;
- branch_st->info.branch.status = status;
- branch_st->info.have_info = true;
- }
- static void newWithBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
- Inter *inter, LinkValue *value, LinkValue *_exit_, LinkValue *_enter_, LinkValue *with){
- newBranchYield(branch_st, node, sl_node, new_var, status, inter);
- branch_st->info.branch.with_.value = value;
- branch_st->info.branch.with_._exit_ = _exit_;
- branch_st->info.branch.with_._enter_ = _enter_;
- branch_st->info.branch.with_.with_belong = with;
- }
- static void newForBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
- Inter *inter, LinkValue *iter){
- newBranchYield(branch_st, node, sl_node, new_var, status, inter);
- branch_st->info.branch.for_.iter = iter;
- gc_addTmpLink(&iter->gc_status);
- }
- static void updateBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, enum StatementInfoStatus status){
- branch_st->info.node = node->type == yield_code ? node->next : node;
- branch_st->info.branch.sl_node = sl_node;
- branch_st->info.branch.status = status;
- branch_st->info.have_info = true;
- }
- static void setBranchResult(bool yield_run, StatementList *sl, Statement *st, Result *result, enum StatementInfoStatus status, FUNC_CORE) {
- if (yield_run) {
- if (result->type == R_yield)
- updateBranchYield(st, result->node, sl, status);
- else
- freeRunInfo(st);
- } else {
- if (result->type == R_yield)
- newBranchYield(st, result->node, sl, var_list, status, inter);
- else
- var_list = popVarList(var_list);
- }
- }
- static bool runBranchHeard(Statement *condition, Statement *var, LinkValue **condition_value, FUNC_NT) {
- setResultCore(result);
- if (operationSafeInterStatement(CFUNC(condition, var_list, result, belong)))
- return false;
- *condition_value = result->value;
- if (var != NULL) {
- result->value = NULL;
- freeResult(result);
- assCore(var, *condition_value, false, false, CNEXT_NT);
- gc_freeTmpLink(&(*condition_value)->gc_status);
- if (!CHECK_RESULT(result))
- return false;
- }
- return true;
- }
- static int checkCondition(bool is_rego, LinkValue *condition_value, fline line, char *file, FUNC_NT) {
- bool return_;
- if (is_rego)
- return 1;
- return_ = checkBool(condition_value, line, file, CNEXT_NT);
- if (!CHECK_RESULT(result))
- return -1;
- return return_;
- }
- static bool runFinally(bool set_result, bool (*run)(FUNC), FUNC) {
- Result finally_tmp;
- setResultCore(&finally_tmp);
- if (run(CFUNC(st, var_list, &finally_tmp, belong))) {
- if (!set_result)
- freeResult(result);
- *result = finally_tmp;
- return false;
- }
- freeResult(&finally_tmp);
- return true;
- }
- static int runIfList(StatementList *if_list, Statement *info_vl, fline line, char *file, FUNC_NT) {
- bool is_rego = false;
- setResultCore(result);
- for (PASS; if_list != NULL; if_list = if_list->next){
- bool condition;
- if (info_vl != NULL){
- if (ifBranchSafeInterStatement(CFUNC(info_vl, var_list, result, belong)))
- return -1;
- if (result->type == R_rego)
- is_rego = true;
- info_vl = NULL;
- } else if (if_list->type == if_b){
- LinkValue *condition_value = NULL;
- if (!runBranchHeard(if_list->condition, if_list->var, &condition_value, CNEXT_NT))
- return -1;
- freeResult(result);
- condition = checkCondition(is_rego, condition_value, line, file, CNEXT_NT);
- if (condition == -1)
- return -1;
- else if (condition == 1){
- is_rego = false;
- freeResult(result);
- if (ifBranchSafeInterStatement(CFUNC(if_list->code, var_list, result, belong)))
- return -1;
- if (result->type == R_rego)
- is_rego = true;
- else {
- freeResult(result);
- return 0;
- }
- }
- } else{
- if (ifBranchSafeInterStatement(CFUNC(if_list->code, var_list, result, belong)))
- return -1;
- if (result->type == R_rego)
- is_rego = true;
- }
- freeResult(result);
- }
- return 1;
- }
- ResultType ifBranch(FUNC) {
- StatementList *if_list = NULL;
- Statement *else_st = NULL;
- Statement *finally = NULL;
- Statement *info_vl = NULL;
- bool set_result = true;
- bool yield_run = false;
- enum StatementInfoStatus result_from = info_vl_branch;
- setResultCore(result);
- yield_run = popYieldVarList(st, &var_list, var_list, inter);
- if (yield_run) {
- if (st->info.branch.status == info_vl_branch){
- if_list = st->info.branch.sl_node;
- info_vl = st->info.node;
- else_st = st->u.if_branch.else_list;
- finally = st->u.if_branch.finally;
- if (info_vl == NULL)
- if_list = NULL; // 证明if分支的yield已经到头了
- } else if (st->info.branch.status == info_else_branch) {
- else_st = st->info.node;
- finally = st->u.if_branch.finally;
- } else if (st->info.branch.status == info_finally_branch)
- finally = st->info.node;
- else {
- var_list = popVarList(var_list);
- setResultError(E_SystemException, L"yield info error", st->line, st->code_file, true, CNEXT_NT);
- return R_error;
- }
- } else {
- if_list = st->u.if_branch.if_list;
- else_st = st->u.if_branch.else_list;
- finally = st->u.if_branch.finally;
- }
- if (if_list != NULL) {
- int status = runIfList(if_list, info_vl, st->line, st->code_file, CNEXT_NT);
- if (status == -1 || status == 0)
- else_st = NULL;
- if (status == -1)
- set_result = false;
- }
- if (else_st != NULL) {
- if (ifBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
- set_result = false;
- result_from = info_else_branch;
- } else
- freeResult(result);
- }
- if (finally != NULL && !runFinally(set_result, ifBranchSafeInterStatement, finally, CNEXT_NT)) {
- set_result = false;
- result_from = info_finally_branch;
- }
- setBranchResult(yield_run, if_list, st, result, result_from, CFUNC_CORE(var_list));
- if (set_result)
- setResult(result, inter);
- return result->type;
- }
- static int runWhileList(StatementList *while_list, Statement *after, Statement *info_vl, Statement *after_vl, bool do_while, fline line, char *file, enum StatementInfoStatus *from, FUNC_NT) {
- bool is_break = false;
- setResultCore(result);
- while (!is_break){
- LinkValue *condition_value = NULL;
- Statement *after_st = after;
- Statement *while_st = while_list->code;
- bool condition;
- *from = info_vl_branch;
- if (info_vl != NULL) {
- condition = 1;
- while_st = info_vl;
- info_vl = NULL;
- } else if (after_vl != NULL) {
- condition = -2;
- after_st = after_vl;
- after_vl = NULL;
- } else{
- if (!runBranchHeard(while_list->condition, while_list->var, &condition_value, CNEXT_NT))
- return -1;
- freeResult(result);
- condition = checkCondition(do_while, condition_value, line, file, CNEXT_NT);
- }
- do_while = false;
- if (condition == -1)
- return -1;
- else if (condition == 1){
- freeResult(result);
- if (cycleBranchSafeInterStatement(CFUNC(while_st, var_list, result, belong)))
- return -1;
- else if (result->type == R_break)
- is_break = true;
- } else if (condition != -2){
- freeResult(result);
- break;
- }
- if (after_st != NULL) {
- *from = info_after_do;
- freeResult(result);
- if (cycleBranchSafeInterStatement(CFUNC(after_st, var_list, result, belong)))
- return -1;
- else if (result->type == R_break) {
- freeResult(result);
- return 0;
- }
- }
- freeResult(result);
- }
- return is_break ? 0 : 1;
- }
- ResultType whileBranch(FUNC) {
- StatementList *while_list = st->u.while_branch.while_list;
- Statement *first = st->u.while_branch.first;
- Statement *after = st->u.while_branch.after;
- Statement *else_st = st->u.while_branch.else_list;
- Statement *finally = st->u.while_branch.finally;
- Statement *info_vl = NULL;
- Statement *after_vl = NULL;
- bool set_result = true;
- bool yield_run = false;
- bool do_while = st->u.while_branch.type == do_while_;
- enum StatementInfoStatus result_from = info_first_do;
- setResultCore(result);
- yield_run = popYieldVarList(st, &var_list, var_list, inter);
- if (yield_run) {
- if (st->info.branch.status == info_first_do)
- first = st->info.node;
- else if (st->info.branch.status == info_vl_branch){
- first = NULL;
- info_vl = st->info.node;
- }
- else if (st->info.branch.status == info_after_do){
- first = NULL;
- after_vl = st->info.node;
- }
- else if (st->info.branch.status == info_else_branch){
- first = NULL;
- while_list = NULL;
- else_st = st->info.node;
- }
- else if (st->info.branch.status == info_finally_branch){
- first = NULL;
- while_list = NULL;
- else_st = NULL;
- finally = st->info.node;
- } else {
- var_list = popVarList(var_list);
- setResultError(E_SystemException, L"yield info error", st->line, st->code_file, true, CNEXT_NT);
- return R_error;
- }
- }
- if (first != NULL) {
- if (cycleBranchSafeInterStatement(CFUNC(first, var_list, result, belong))) {
- set_result = false;
- while_list = NULL;
- else_st = NULL;
- } else
- freeResult(result);
- }
- if (while_list != NULL){
- int status = runWhileList(while_list, after, info_vl, after_vl, do_while, st->line, st->code_file, &result_from, CNEXT_NT);
- if (status == -1 || status == 0)
- else_st = NULL;
- if (status == -1)
- set_result = false;
- }
- if (else_st != NULL) {
- if (cycleBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
- result_from = info_else_branch;
- set_result = false;
- } else
- freeResult(result);
- }
- if (finally != NULL && !runFinally(set_result, cycleBranchSafeInterStatement, finally, CNEXT_NT)) {
- set_result = false;
- result_from = info_finally_branch;
- }
- setBranchResult(yield_run, while_list, st, result, result_from, CFUNC_CORE(var_list));
- if (set_result)
- setResult(result, inter);
- return result->type;
- }
- static int getForHeard(LinkValue **iter, LinkValue **first_yield, StatementList *for_list, fline line, char *file, FUNC_NT) {
- LinkValue *tmp = NULL;
- setResultCore(result);
- if (operationSafeInterStatement(CFUNC(for_list->condition, var_list, result, belong)))
- return -1;
- if (result->is_yield){
- iter = NULL;
- GET_RESULTONLY(*first_yield, result);
- return 1;
- }
- GET_RESULT(tmp, result);
- getIter(tmp, 1, line, file, CNEXT_NT);
- gc_freeTmpLink(&tmp->gc_status);
- if (!CHECK_RESULT(result))
- return -1;
- GET_RESULTONLY(*iter, result);
- return 0;
- }
- static int runForHeard(LinkValue *iter, LinkValue *first_yield, StatementList *for_list, fline line, char *file, FUNC_NT) {
- LinkValue *element = NULL;
- if (iter != NULL) {
- getIter(iter, 0, line, file, CNEXT_NT);
- if (!CHECK_RESULT(result)) {
- if (is_iterStop(result->value, inter)) {
- freeResult(result);
- return 1;
- } else
- return -1;
- }
- GET_RESULT(element, result);
- } else if (first_yield != NULL)
- element = first_yield;
- else {
- if (operationSafeInterStatement(CFUNC(for_list->condition, var_list, result, belong)))
- return -1;
- GET_RESULT(element, result);
- if (!result->is_yield)
- return 1;
- }
- assCore(for_list->var, element, false, false, CNEXT_NT);
- gc_freeTmpLink(&element->gc_status);
- if (!CHECK_RESULT(result))
- return -1;
- freeResult(result);
- return 0;
- }
- static int runForList(StatementList *for_list, Statement *after, Statement *info_vl, Statement *after_vl, LinkValue *iter, LinkValue *first_yield, fline line, char *file, enum StatementInfoStatus *from, FUNC_NT) {
- bool is_break = false;
- while (!is_break){ // 循环执行的本体
- Statement *for_st = for_list->code;
- Statement *after_st = after;
- *from = info_vl_branch;
- if (info_vl != NULL){
- for_st = info_vl;
- info_vl = NULL;
- }
- else if (after_vl != NULL){
- after_st = after_vl;
- after_vl = NULL;
- for_st = NULL;
- } else {
- int status = runForHeard(iter, first_yield, for_list, line, file, CNEXT_NT);
- first_yield = NULL;
- if (status == -1)
- return -1;
- else if (status == 1)
- break;
- }
- if (for_st != NULL) {
- if (cycleBranchSafeInterStatement(CFUNC(for_st, var_list, result, belong)))
- return -1;
- else if (result->type == R_break)
- is_break = true;
- }
- *from = info_after_do;
- if (after_st != NULL) {
- freeResult(result);
- if (cycleBranchSafeInterStatement(CFUNC(after_st, var_list, result, belong)))
- return -1;
- else if (result->type == R_break)
- is_break = true;
- }
- freeResult(result);
- }
- return is_break ? 0 : 1;
- }
- static void setForResult(bool yield_run, StatementList *sl, Statement *st, Result *result, LinkValue *iter, enum StatementInfoStatus status, FUNC_CORE) {
- if (yield_run) {
- if (result->type == R_yield)
- updateBranchYield(st, result->node, sl, status);
- else
- freeRunInfo(st);
- } else {
- if (result->type == R_yield)
- newForBranchYield(st, result->node, sl, var_list, status, inter, iter);
- else
- popVarList(var_list);
- }
- }
- ResultType forBranch(FUNC) {
- StatementList *for_list = st->u.for_branch.for_list;
- Statement *first = st->u.for_branch.first_do;
- Statement *after = st->u.for_branch.after_do;
- Statement *else_st = st->u.for_branch.else_list;
- Statement *finally = st->u.for_branch.finally;
- Statement *info_vl = NULL;
- Statement *after_vl = NULL;
- bool set_result = true;
- bool yield_run = false;
- bool heard = true;
- LinkValue *first_yield = NULL;
- LinkValue *iter = NULL;
- enum StatementInfoStatus result_from = info_first_do;
- setResultCore(result);
- yield_run = popYieldVarList(st, &var_list, var_list, inter);
- if (yield_run) {
- if (st->info.branch.status == info_first_do)
- first = st->info.node;
- else if (st->info.branch.status == info_vl_branch) {
- first = NULL;
- info_vl = st->info.node;
- iter = st->info.branch.for_.iter;
- heard = false;
- } else if (st->info.branch.status == info_after_do) {
- first = NULL;
- after_vl = st->info.node;
- iter = st->info.branch.for_.iter;
- heard = false;
- } else if (st->info.branch.status == info_else_branch) {
- first = NULL;
- heard = false;
- for_list = false;
- else_st = st->info.node;
- } else if (st->info.branch.status == info_finally_branch) {
- first = NULL;
- heard = false;
- for_list = false;
- else_st = NULL;
- finally = st->info.node;
- } else {
- var_list = popVarList(var_list);
- setResultError(E_SystemException, L"yield info error", st->line, st->code_file, true, CNEXT_NT);
- return R_error;
- }
- }
- if (first != NULL) {
- if (cycleBranchSafeInterStatement(CFUNC(first, var_list, result, belong))) {
- set_result = false;
- heard = false;
- for_list = NULL;
- else_st = NULL;
- } else
- freeResult(result);
- }
- if (heard){
- int status = getForHeard(&iter, &first_yield, for_list, st->line, st->code_file, CNEXT_NT);
- if (status == -1) {
- set_result = false;
- for_list = NULL;
- else_st = NULL;
- } else
- freeResult(result);
- }
- if (for_list != NULL){
- int status = runForList(for_list, after, info_vl, after_vl, iter, first_yield, st->line, st->code_file, &result_from, CNEXT_NT);
- if (status == -1 || status == 0)
- else_st = NULL;
- if (status == -1)
- set_result = false;
- }
- if (else_st != NULL) {
- if (cycleBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
- result_from = info_else_branch;
- set_result = false;
- }
- else
- freeResult(result);
- }
- if (finally != NULL && !runFinally(set_result, cycleBranchSafeInterStatement, finally, CNEXT_NT)) {
- set_result = false;
- result_from = info_finally_branch;
- }
- setForResult(yield_run, for_list, st, result, iter, result_from, CFUNC_CORE(var_list));
- if (!yield_run && iter != NULL)
- gc_freeTmpLink(&iter->gc_status);
- if (set_result)
- setResult(result, inter);
- return result->type;
- }
- static bool getEnterExit(LinkValue *value, LinkValue **_enter_, LinkValue **_exit_, fline line, char *file, FUNC_NT) {
- setResultCore(result);
- *_enter_ = findAttributes(inter->data.mag_func[M_ENTER], false, LINEFILE, true, CFUNC_NT(var_list, result, value));
- if (!CHECK_RESULT(result))
- return false;
- freeResult(result);
- *_exit_ = findAttributes(inter->data.mag_func[M_EXIT], false, LINEFILE, true, CFUNC_NT(var_list, result, value));
- if (!CHECK_RESULT(result))
- return false;
- freeResult(result);
- if (*_enter_ == NULL || *_exit_ == NULL) {
- *_enter_ = NULL;
- *_exit_ = NULL;
- setResultError(E_TypeException, OBJ_NOTSUPPORT(__enter__/__exit__), line, file, true, CNEXT_NT);
- return false;
- }
- gc_addTmpLink(&(*_enter_)->gc_status);
- gc_addTmpLink(&(*_exit_)->gc_status);
- return true;
- }
- static int runWithList(StatementList *with_list, LinkValue **with_belong, LinkValue **value, VarList **new, LinkValue **_enter_, LinkValue **_exit_, fline line, char *file, FUNC_NT) {
- if (operationSafeInterStatement(CFUNC(with_list->condition, var_list, result, belong)))
- return -1;
- GET_RESULT(*value, result);
- if (with_list->var == NULL) {
- *with_belong = *value;
- gc_addTmpLink(&(*with_belong)->gc_status);
- *new = copyVarListCore((*value)->value->object.var, inter);
- (*new)->next = var_list;
- *_enter_ = NULL;
- *_exit_ = NULL;
- } else {
- LinkValue *enter_value = NULL;
- *with_belong = belong;
- gc_addTmpLink(&(*with_belong)->gc_status);
- *_enter_ = findAttributes(inter->data.mag_func[M_ENTER], false, LINEFILE, true, CFUNC_NT(var_list, result, *value));
- if (!CHECK_RESULT(result))
- goto error_;
- freeResult(result);
- *_exit_ = findAttributes(inter->data.mag_func[M_EXIT], false, LINEFILE, true, CFUNC_NT(var_list, result, *value));
- if (!CHECK_RESULT(result))
- goto error_;
- freeResult(result);
- if (!getEnterExit(*value, _enter_, _exit_, line, file, CNEXT_NT)) {
- error_:
- gc_freeTmpLink(&(*value)->gc_status);
- gc_freeTmpLink(&(*with_belong)->gc_status);
- *value = NULL;
- return -1;
- }
- callBackCore(*_enter_, NULL, line, file, 0, CNEXT_NT);
- if (!CHECK_RESULT(result))
- return 0;
- *new = pushVarList(var_list, inter);
- enter_value = result->value;
- freeResult(result);
- assCore(with_list->var, enter_value, false, false, CFUNC_NT(*new, result, belong));
- if (!CHECK_RESULT(result)) {
- *new = popVarList(*new);
- return 0;
- }
- freeResult(result);
- }
- return 1;
- }
- static void setWithResult(bool yield_run, StatementList *sl, Statement *st, Result *result, LinkValue *value, LinkValue *_enter_, LinkValue *_exit_, LinkValue *with, enum StatementInfoStatus status, FUNC_CORE) {
- if (yield_run) {
- if (result->type == R_yield)
- if (status == info_finally_branch) {
- freeRunInfo(st);
- newBranchYield(st, result->node, sl, NULL, status, inter);
- } else
- updateBranchYield(st, result->node, sl, status);
- else
- freeRunInfo(st);
- } else {
- if (result->type == R_yield)
- if (status == info_finally_branch) {
- newBranchYield(st, result->node, sl, NULL, status, inter);
- popVarList(var_list);
- }
- else
- newWithBranchYield(st, result->node, sl, var_list, status, inter, value, _exit_, _enter_, with);
- else {
- if (var_list != NULL)
- popVarList(var_list);
- }
- }
- }
- ResultType withBranch(FUNC) {
- StatementList *with_list = st->u.with_branch.with_list;
- Statement *else_st = st->u.with_branch.else_list;
- Statement *finally = st->u.with_branch.finally;
- Statement *vl_info = NULL;
- VarList *new = NULL;
- LinkValue *_enter_ = NULL;
- LinkValue *_exit_ = NULL;
- LinkValue *value = NULL;
- LinkValue *with_belong = NULL; // with在运行的时候调整belong, 就类似于定义class的时候调整belong
- bool set_result = true;
- bool run_block = true;
- bool run_exit = true;
- bool yield_run;
- enum StatementInfoStatus result_from = info_vl_branch;
- setResultCore(result);
- if ((yield_run = st->info.have_info)){
- value = st->info.branch.with_.value;
- _enter_ = st->info.branch.with_._enter_;
- _exit_ = st->info.branch.with_._exit_;
- with_belong = st->info.branch.with_.with_belong;
- if (st->info.var_list != NULL) {
- new = st->info.var_list;
- new->next = var_list;
- }
- if (st->info.branch.status == info_vl_branch) {
- vl_info = st->info.node;
- if (vl_info == NULL)
- run_block = false;
- }
- else if (st->info.branch.status == info_else_branch) {
- run_block = false;
- else_st = st->info.node;
- }
- else if (st->info.branch.status == info_finally_branch){
- run_block = false;
- else_st = NULL;
- finally = st->info.node;
- }
- } else {
- int status = runWithList(with_list, &with_belong, &value, &new, &_enter_, &_exit_, st->line, st->code_file, CNEXT_NT);
- if (status == -1) {
- set_result = false;
- run_block = false;
- else_st = NULL;
- } else if (status == 0) {
- set_result = false;
- gc_freeTmpLink(&value->gc_status);
- gc_freeTmpLink(&_enter_->gc_status);
- gc_freeTmpLink(&_exit_->gc_status);
- gc_freeTmpLink(&with_belong->gc_status);
- run_block = false;
- else_st = NULL;
- }
- }
- if (run_block) {
- if (vl_info == NULL)
- vl_info = with_list->code;
- if (withBranchSafeInterStatement(CFUNC(vl_info, new, result, with_belong))) {
- set_result = false;
- if (result->type == R_yield) {
- run_exit = false;
- else_st = NULL;
- }
- } else
- freeResult(result);
- }
- if (else_st != NULL){
- Result else_tmp;
- setResultCore(&else_tmp);
- if (withBranchSafeInterStatement(CFUNC(else_st, new, &else_tmp, with_belong))) {
- if (!set_result)
- freeResult(result);
- set_result = false;
- *result = else_tmp;
- result_from = info_else_branch;
- if (result->type == R_yield)
- run_exit = false;
- } else
- freeResult(&else_tmp);
- }
- if (run_exit){ // 若运行中的某处返回了R_yield则不执行exit
- if (_exit_ != NULL){
- Result exit_tmp;
- setResultCore(&exit_tmp);
- callBackCore(_exit_, NULL, st->line, st->code_file, 0, CFUNC_NT(var_list, &exit_tmp, belong));
- if (!RUN_TYPE(exit_tmp.type)) {
- if (!set_result)
- freeResult(result);
- set_result = false;
- *result = exit_tmp;
- } else
- freeResult(&exit_tmp);
- if (!yield_run) {
- gc_freeTmpLink(&_enter_->gc_status);
- gc_freeTmpLink(&_exit_->gc_status);
- _enter_ = NULL;
- _exit_ = NULL;
- }
- }
- if (!yield_run) {
- if (with_belong != NULL){
- gc_freeTmpLink(&with_belong->gc_status);
- with_belong = NULL;
- }
- if (value != NULL){
- gc_freeTmpLink(&value->gc_status);
- value = NULL;
- }
- }
- }
- if (finally != NULL && !runFinally(set_result, withBranchSafeInterStatement, finally, CNEXT_NT)) {
- set_result = false;
- result_from = info_finally_branch;
- }
- setWithResult(yield_run, with_list, st, result, value, _enter_, _exit_, with_belong, result_from, CFUNC_CORE(new));
- if (set_result)
- setResult(result, inter);
- return result->type;
- }
- static int checkError(StatementList **except_list, LinkValue *error_value, FUNC_NT) {
- setResultCore(result);
- if (*except_list == NULL)
- return -1;
- for (PASS; *except_list != NULL; except_list = &(*except_list)->next) {
- freeResult(result);
- if ((*except_list)->condition == NULL)
- break;
- if (operationSafeInterStatement(CFUNC((*except_list)->condition, var_list, result, belong)))
- return 0;
- if (result->value->value == error_value->value || checkAttribution(error_value->value, result->value->value))
- break;
- }
- return *except_list == NULL ? -1 : 1;
- }
- ResultType tryBranch(FUNC) {
- StatementList *except_list = NULL;
- Statement *try = st->u.try_branch.try;
- Statement *else_st = st->u.try_branch.else_list;
- Statement *finally = st->u.try_branch.finally;
- Statement *info_vl = NULL;
- LinkValue *error_value = NULL;
- bool set_result = true;
- bool yield_run;
- enum StatementInfoStatus result_from = info_first_do;
- setResultCore(result);
- yield_run = popYieldVarList(st, &var_list, var_list, inter);
- if (yield_run && st->info.branch.status == info_first_do)
- try = st->info.node;
- else if (yield_run && st->info.branch.status == info_vl_branch){
- try = NULL;
- info_vl = st->info.node;
- }
- else if (yield_run && st->info.branch.status == info_else_branch){
- try = NULL;
- else_st = st->info.node;
- }
- else if (yield_run && st->info.branch.status == info_finally_branch){
- try = NULL;
- else_st = NULL;
- finally = st->info.node;
- }
- if (try != NULL){
- if (tryBranchSafeInterStatement(CFUNC(try, var_list, result, belong))) {
- if (result->type == R_yield) {
- result_from = info_first_do;
- set_result = false;
- else_st = NULL;
- } else {
- int status;
- GET_RESULT(error_value, result);
- except_list = st->u.try_branch.except_list;
- status = checkError(&except_list, error_value, CNEXT_NT);
- if (status == -1 || status == 0) {
- set_result = false;
- result_from = info_vl_branch;
- except_list = NULL;
- else_st = NULL;
- } else
- freeResult(result);
- gc_freeTmpLink(&error_value->gc_status);
- }
- } else
- freeResult(result);
- }
- if (except_list != NULL) {
- if (except_list->var != NULL) {
- gc_addTmpLink(&error_value->gc_status);
- assCore(except_list->var, error_value, false, false, CNEXT_NT);
- gc_freeTmpLink(&error_value->gc_status);
- if (!CHECK_RESULT(result)) {
- set_result = false;
- else_st = NULL;
- } else
- freeResult(result);
- }
- info_vl = except_list->code;
- }
- if (info_vl != NULL) {
- freeResult(result);
- if (tryBranchSafeInterStatement(CFUNC(info_vl, var_list, result, belong))) {
- result_from = info_vl_branch;
- set_result = false;
- } else
- freeResult(result);
- }
- if (else_st != NULL) {
- if (tryBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
- set_result = false;
- result_from = info_else_branch;
- }
- else
- freeResult(result);
- }
- if (finally != NULL && !runFinally(set_result, ifBranchSafeInterStatement, finally, CNEXT_NT)) {
- set_result = false;
- result_from = info_finally_branch;
- }
- setBranchResult(yield_run, except_list, st, result, result_from, CFUNC_CORE(var_list));
- if (set_result)
- setResult(result, inter);
- return result->type;
- }
- ResultType breakCycle(FUNC){
- int times_int = 0;
- setResultCore(result);
- if (st->u.break_cycle.times == NULL)
- goto not_times;
- if (operationSafeInterStatement(CFUNC(st->u.break_cycle.times, var_list, result, belong)))
- return result->type;
- if (!checkNumber(CNEXT))
- return result->type;
- times_int = (int)result->value->value->data.int_.num;
- freeResult(result);
- not_times:
- setResult(result, inter);
- if (times_int >= 0) {
- result->type = R_break;
- result->times = times_int;
- }
- return result->type;
- }
- ResultType continueCycle(FUNC){
- int times_int = 0;
- setResultCore(result);
- if (st->u.continue_cycle.times == NULL)
- goto not_times;
- if (operationSafeInterStatement(CFUNC(st->u.continue_cycle.times, var_list, result, belong)))
- return result->type;
- if (!checkNumber(CNEXT))
- return result->type;
- times_int = (int)result->value->value->data.int_.num;
- freeResult(result);
- not_times:
- setResult(result, inter);
- if (times_int >= 0) {
- result->type = R_continue;
- result->times = times_int;
- }
- return result->type;
- }
- ResultType regoIf(FUNC){
- int times_int = 0;
- setResultCore(result);
- if (st->u.rego_if.times == NULL)
- goto not_times;
- if (operationSafeInterStatement(CFUNC(st->u.rego_if.times, var_list, result, belong)))
- return result->type;
- if (!checkNumber(CNEXT))
- return result->type;
- times_int = (int)result->value->value->data.int_.num;
- freeResult(result);
- not_times:
- setResult(result, inter);
- if (times_int >= 0) {
- result->type = R_rego;
- result->times = times_int;
- }
- return result->type;
- }
- ResultType restartCode(FUNC){
- int times_int = 0;
- setResultCore(result);
- if (st->u.restart.times == NULL)
- goto not_times;
- if (operationSafeInterStatement(CFUNC(st->u.restart.times, var_list, result, belong)))
- return result->type;
- if (!checkNumber(CNEXT))
- return result->type;
- times_int = (int)result->value->value->data.int_.num;
- freeResult(result);
- not_times:
- setResult(result, inter);
- if (times_int >= 0) {
- result->type = R_restart;
- result->times = times_int;
- }
- return result->type;
- }
- ResultType returnCode(FUNC){
- setResultCore(result);
- if (st->u.return_code.value == NULL) {
- setResult(result, inter);
- goto set_result;
- }
- if (operationSafeInterStatement(CFUNC(st->u.return_code.value, var_list, result, belong)))
- return result->type;
- set_result:
- result->type = R_func;
- return result->type;
- }
- ResultType yieldCode(FUNC){
- setResultCore(result);
- if (st->u.yield_code.value == NULL) {
- setResult(result, inter);
- goto set_result;
- }
- if (operationSafeInterStatement(CFUNC(st->u.yield_code.value, var_list, result, belong)))
- return result->type;
- set_result:
- result->type = R_yield;
- return result->type;
- }
- ResultType raiseCode(FUNC){
- setResultCore(result);
- if (st->u.raise_code.value == NULL) {
- setResult(result, inter);
- goto set_result;
- }
- if (operationSafeInterStatement(CFUNC(st->u.raise_code.value, var_list, result, belong)))
- return result->type;
- set_result:
- result->type = R_error;
- result->error = connectError(makeError(L"RaiseException", L"Exception was raise by user", st->line, st->code_file), result->error);
- return result->type;
- }
- ResultType assertCode(FUNC){
- bool result_;
- LinkValue *opt;
- setResultCore(result);
- if (inter->data.assert_run == assert_ignore) { // 不执行断言
- setResult(result, inter);
- return result->type;
- }
- if (operationSafeInterStatement(CFUNC(st->u.raise_code.value, var_list, result, belong)) || inter->data.assert_run == assert_run)
- return result->type;
- GET_RESULT(opt, result);
- result_ = checkBool(opt, st->line, st->code_file, CNEXT_NT);
- gc_freeTmpLink(&opt->gc_status);
- if (!CHECK_RESULT(result))
- return result->type;
- else if (result_)
- setResult(result, inter);
- else
- setResultErrorSt(E_AssertException, L"Assertion check error", true, st, CNEXT_NT);
- return result->type;
- }
- ResultType gotoLabel(FUNC){
- int times_int = 0;
- wchar_t *label = NULL;
- setResultCore(result);
- if (operationSafeInterStatement(CFUNC(st->u.goto_.label, var_list, result, belong)))
- return result->type;
- if (!isType(result->value->value, V_str)) {
- setResultErrorSt(E_TypeException, ONLY_ACC(label name, V_str), true, st, CNEXT_NT);
- return result->type;
- }
- label = memWidecpy(result->value->value->data.str.str);
- freeResult(result);
- if (st->u.goto_.times == NULL)
- goto not_times;
- if (operationSafeInterStatement(CFUNC(st->u.goto_.times, var_list, result, belong))) {
- memFree(label);
- return result->type;
- }
- if (!checkNumber(CNEXT)) {
- memFree(label);
- return result->type;
- }
- times_int = (int)result->value->value->data.int_.num;
- freeResult(result);
- not_times:
- if (st->u.goto_.return_ == NULL)
- setResult(result, inter);
- else if (operationSafeInterStatement(CFUNC(st->u.goto_.return_, var_list, result, belong))) {
- memFree(label);
- return result->type;
- }
- result->times = times_int;
- result->type = R_goto;
- result->label = label;
- return result->type;
- }
- ResultType runLabel(FUNC) {
- LinkValue *goto_value;
- GET_RESULT(goto_value, result); // goto的值通过result传入, 因此不能进行setResultCore
- if (st->u.label_.as != NULL)
- assCore(st->u.label_.as, goto_value, false, false, CNEXT_NT);
- gc_freeTmpLink(&goto_value->gc_status);
- if (st->u.label_.as != NULL && !CHECK_RESULT(result))
- return result->type;
- freeResult(result);
- if (st->u.label_.command != NULL)
- operationSafeInterStatement(CFUNC(st->u.label_.command, var_list, result, belong));
- else
- setResult(result, inter);
- return result->type;
- }
|