123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- #include "__run.h"
- /**
- * 运行单个statement
- * @param st
- * @param inter
- * @param var_list
- * @return
- */
- ResultType runStatement(FUNC) {
- ResultType type = R_not;
- setResultCore(result);
- gc_addTmpLink(&belong->gc_status);
- switch (st->type) { // TODO-list 优化: 只有指定的st需要执行gc
- case base_value:
- type = getBaseValue(CNEXT);
- break;
- case base_var:
- type = getVar(CNEXT, getBaseVarInfo);
- break;
- case base_svar:
- type = getVar(CNEXT, getBaseSVarInfo);
- break;
- case base_list:
- type = getList(CNEXT);
- break;
- case base_dict:
- type = getDict(CNEXT);
- break;
- case base_lambda:
- type = setLambda(CNEXT);
- break;
- case operation:
- type = operationStatement(CNEXT);
- break;
- case set_class:
- type = setClass(CNEXT);
- break;
- case set_function:
- type = setFunction(CNEXT);
- break;
- case slice_:
- type = elementSlice(CNEXT);
- break;
- case call_function:
- type = callBack(CNEXT);
- break;
- case if_branch:
- type = ifBranch(CNEXT);
- break;
- case while_branch:
- type = whileBranch(CNEXT);
- break;
- case for_branch:
- type = forBranch(CNEXT);
- break;
- case with_branch:
- type = withBranch(CNEXT);
- break;
- case try_branch:
- type = tryBranch(CNEXT);
- break;
- case break_cycle:
- type = breakCycle(CNEXT);
- break;
- case continue_cycle:
- type = continueCycle(CNEXT);
- break;
- case rego_if:
- type = regoIf(CNEXT);
- break;
- case restart:
- type = restartCode(CNEXT);
- break;
- case return_code:
- type = returnCode(CNEXT);
- break;
- case yield_code:
- type = yieldCode(CNEXT);
- break;
- case raise_code:
- type = raiseCode(CNEXT);
- break;
- case include_file:
- type = includeFile(CNEXT);
- break;
- case import_file:
- type = importFile(CNEXT);
- break;
- case from_import_file:
- type = fromImportFile(CNEXT);
- break;
- case default_var:
- type = setDefault(CNEXT);
- break;
- case assert_:
- type = assertCode(CNEXT);
- break;
- case goto_:
- type = gotoLabel(CNEXT);
- break;
- case del_:
- type = delOperation(CNEXT);
- break;
- default:
- setResult(result, inter);
- break;
- }
- if (RUN_TYPE(type) && st->aut != auto_aut)
- result->value->aut = st->aut; // 权限覆盖
- result->node = st;
- gc_freeTmpLink(&belong->gc_status);
- #if START_GC
- gc_run(inter, var_list, 1, 2, 0, var_list, belong, result->value);
- #endif
- return type;
- }
- ResultType runStatementOpt(FUNC) { // 不运行gc机制
- ResultType type = R_not;
- setResultCore(result);
- gc_addTmpLink(&belong->gc_status);
- switch (st->type) {
- case base_value:
- type = getBaseValue(CNEXT);
- break;
- case base_var:
- type = getVar(CNEXT, getBaseVarInfo);
- break;
- case base_svar:
- type = getVar(CNEXT, getBaseSVarInfo);
- break;
- case base_list:
- type = getList(CNEXT);
- break;
- case base_dict:
- type = getDict(CNEXT);
- break;
- case base_lambda:
- type = setLambda(CNEXT);
- break;
- case operation:
- type = operationStatement(CNEXT);
- break;
- case slice_:
- type = elementSlice(CNEXT);
- break;
- case call_function:
- type = callBack(CNEXT);
- break;
- default:
- setResult(result, inter);
- errasert(runStatementOpt default);
- break;
- }
- if (RUN_TYPE(type) && st->aut != auto_aut)
- result->value->aut = st->aut; // 权限覆盖
- result->node = st;
- gc_freeTmpLink(&belong->gc_status);
- return type;
- }
- static bool checkSignal(fline line, char *file, FUNC_NT) {
- if (is_KeyInterrupt == signal_appear){
- is_KeyInterrupt = signal_reset;
- setResultError(E_KeyInterrupt, KEY_INTERRUPT, line, file, true, CNEXT_NT);
- return true;
- }
- return false;
- }
- static bool gotoStatement(Statement **next, FUNC) {
- Statement *label_st = checkLabel(st, result->label);
- if (label_st == NULL){
- setResultErrorSt(E_GotoException, L"Don't find label", true, st, CNEXT_NT);
- return false;
- }
- runLabel(CFUNC(label_st, var_list, result, belong));
- if (!CHECK_RESULT(result))
- return false;
- *next = label_st->next;
- return true;
- }
- /**
- * 局部程序运行statement
- * @param st
- * @param inter
- * @param var_list
- * @return
- */
- ResultType iterStatement(FUNC) {
- Statement *base;
- ResultType type;
- void *bak = NULL;
- setResultCore(result);
- if (st == NULL){
- setResult(result, inter);
- return result->type;
- }
- is_KeyInterrupt = signal_reset;
- bak = signal(SIGINT, signalStopInter);
- gc_addTmpLink(&belong->gc_status);
- do {
- base = st;
- if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
- type = result->type;
- break;
- }
- while (base != NULL) {
- freeResult(result);
- type = runStatement(CFUNC(base, var_list, result, belong));
- if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
- type = result->type;
- break;
- }
- if (type == R_goto && result->times == 0){
- if (!gotoStatement(&base, CNEXT)) {
- type = result->type;
- break;
- }
- }
- else if (!RUN_TYPE(type))
- break;
- else
- base = base->next;
- }
- } while (type == R_restart && result->times == 0);
- if (type == R_not || type == R_restart)
- setResultOperationNone(result, inter, belong);
- result->node = base;
- gc_freeTmpLink(&belong->gc_status);
- signal(SIGINT, bak);
- return result->type;
- }
- /**
- * 全局程序运行statement
- * @param inter
- * @return
- */
- ResultType globalIterStatement(Result *result, Inter *inter, Statement *st, bool p_clock) {
- ResultType type;
- VarList *var_list = NULL;
- Statement *base;
- LinkValue *belong = inter->base_belong;
- void *bak = NULL;
- clock_t start, stop;
- if (st == NULL){
- setResult(result, inter);
- return result->type;
- }
- is_KeyInterrupt = signal_reset;
- bak = signal(SIGINT, signalStopInter);
- gc_addTmpLink(&belong->gc_status);
- start = clock();
- do {
- base = st;
- var_list = inter->var_list;
- if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
- type = result->type;
- break;
- }
- while (base != NULL) {
- freeResult(result);
- type = runStatement(CFUNC(base, var_list, result, belong));
- if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
- type = result->type;
- break;
- }
- if (type == R_goto){
- if (!gotoStatement(&base, CNEXT)) {
- type = result->type;
- break;
- }
- }
- else if (!RUN_TYPE(type))
- break;
- else
- base = base->next;
- }
- } while (type == R_restart && result->times == 0);
- stop = clock();
- if (type != R_error && type != R_func)
- setResultOperationNone(result, inter, belong);
- result->node = base;
- if (p_clock)
- printf("run times = %Lf sec\n", (double long)(stop - start) / CLOCKS_PER_SEC);
- gc_freeTmpLink(&belong->gc_status);
- signal(SIGINT, bak);
- return result->type;
- }
- // 若需要中断执行, 则返回true
- bool operationSafeInterStatement(FUNC){
- ResultType type;
- assert(st->next == NULL); // opt 以单句形式存在
- type = runStatementOpt(CNEXT);
- if (RUN_TYPE(type))
- return false;
- assert(type == return_code || type == R_error);
- return true;
- }
- bool ifBranchSafeInterStatement(FUNC){
- ResultType type;
- type = iterStatement(CNEXT);
- if (RUN_TYPE(type))
- return false;
- if (type == R_rego){
- result->times--;
- if (result->times < 0)
- return false;
- }
- if (type == R_restart || type == R_goto)
- result->times--;
- return true;
- }
- bool cycleBranchSafeInterStatement(FUNC){
- ResultType type;
- type = iterStatement(CNEXT);
- if (RUN_TYPE(type))
- return false;
- if (type == R_break || type == R_continue){
- result->times--;
- if (result->times < 0)
- return false;
- }
- if (type == R_restart || type == R_goto)
- result->times--;
- return true;
- }
- bool withBranchSafeInterStatement(FUNC){
- ResultType type;
- type = iterStatement(CNEXT);
- if (RUN_TYPE(type))
- return false;
- if (type == R_restart || type == R_goto)
- result->times--;
- return true;
- }
- bool tryBranchSafeInterStatement(FUNC){
- ResultType type;
- type = iterStatement(CNEXT);
- if (RUN_TYPE(type))
- return false;
- if (type == R_restart || type == R_goto)
- result->times--;
- return true;
- }
- bool functionSafeInterStatement(FUNC){
- ResultType type;
- type = iterStatement(CNEXT);
- if (type == R_error || result->type == R_yield)
- return true;
- else if (type == R_func)
- result->type = R_opt;
- else
- result->type = R_not;
- return false;
- }
- bool includeSafeInterStatement(FUNC){
- iterStatement(CNEXT);
- return !CHECK_RESULT(result);
- }
- bool blockSafeInterStatement(FUNC){
- ResultType type;
- type = iterStatement(CNEXT);
- if (type == R_error || type == R_yield)
- return true;
- result->type = R_opt;
- return false;
- }
- Statement *checkLabel(Statement *base, wchar_t *label){
- for (PASS; base != NULL; base = base->next)
- if (base->type == label_ && eqWide(base->u.label_.label, label))
- return base;
- return NULL;
- }
- bool is_quitExc(LinkValue *value, Inter *inter) {
- return value->value == inter->data.base_exc[E_QuitException]->value || checkAttribution(value->value, inter->data.base_exc[E_QuitException]->value);
- }
|