123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134 |
- #include "__run.h"
- #define SET_FOLDING_BRANCH(folding_bak, set_folding, inter)bool folding_bak[] = {(inter)->data.value_folding /*[0]*/, \
- (inter)->data.var_folding /*[1]*/, (inter)->data.opt_folding /*[2]*/}; \
- bool set_folding = (inter)->data.func_folding; \
- if (set_folding) { (inter)->data.value_folding = (inter)->data.var_folding = (inter)->data.opt_folding = true;}
- #define SET_FOLDING_END(folding_bak, set_folding, inter) if (set_folding) {(inter)->data.value_folding = (folding_bak)[0];(inter)->data.var_folding = (folding_bak)[1];(inter)->data.opt_folding = (folding_bak)[2];}
- 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;
- SET_FOLDING_BRANCH(folding_bak, set_folding, inter) // 不需要分号
- 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);
- SET_FOLDING_END(folding_bak, set_folding, 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;
- SET_FOLDING_BRANCH(folding_bak, set_folding, inter) // 不需要分号
- 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);
- SET_FOLDING_END(folding_bak, set_folding, 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;
- }
|