implement break/continue in bytecode
parent
b05bc51b14
commit
38c17d1911
|
@ -1587,6 +1587,12 @@ compilecomv:
|
|||
}
|
||||
}
|
||||
break;
|
||||
case CsIdBreak:
|
||||
gs.code.push(CsCodeBreak | CsCodeFlagFalse);
|
||||
break;
|
||||
case CsIdContinue:
|
||||
gs.code.push(CsCodeBreak | CsCodeFlagTrue);
|
||||
break;
|
||||
case CsIdResult:
|
||||
if (more) {
|
||||
more = compilearg(gs, CsValAny, prevargs);
|
||||
|
|
14
src/cs_vm.cc
14
src/cs_vm.cc
|
@ -734,6 +734,20 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
case CsCodeBreak | CsCodeFlagFalse:
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsBreakException();
|
||||
} else {
|
||||
throw CsErrorException(cs, "no loop to break");
|
||||
}
|
||||
break;
|
||||
case CsCodeBreak | CsCodeFlagTrue:
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsContinueException();
|
||||
} else {
|
||||
throw CsErrorException(cs, "no loop to continue");
|
||||
}
|
||||
break;
|
||||
|
||||
case CsCodeMacro: {
|
||||
ostd::Uint32 len = op >> 8;
|
||||
|
|
|
@ -21,7 +21,8 @@ static constexpr int DbgaliasIdx = MaxArguments + 2;
|
|||
|
||||
enum {
|
||||
CsIdUnknown = -1, CsIdIvar, CsIdFvar, CsIdSvar, CsIdCommand, CsIdAlias,
|
||||
CsIdLocal, CsIdDo, CsIdDoArgs, CsIdIf, CsIdResult, CsIdNot, CsIdAnd, CsIdOr
|
||||
CsIdLocal, CsIdDo, CsIdDoArgs, CsIdIf, CsIdBreak, CsIdContinue, CsIdResult,
|
||||
CsIdNot, CsIdAnd, CsIdOr
|
||||
};
|
||||
|
||||
struct CsIdentLink {
|
||||
|
@ -76,6 +77,7 @@ enum {
|
|||
CsCodeLocal,
|
||||
CsCodeDo, CsCodeDoArgs,
|
||||
CsCodeJump, CsCodeJumpB, CsCodeJumpResult,
|
||||
CsCodeBreak,
|
||||
|
||||
CsCodeOpMask = 0x3F,
|
||||
CsCodeRet = 6,
|
||||
|
|
|
@ -332,6 +332,22 @@ CsState::CsState(CsAllocCb func, void *data):
|
|||
|
||||
new_command("local", nullptr, nullptr)->p_type = CsIdLocal;
|
||||
|
||||
new_command("break", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsBreakException();
|
||||
} else {
|
||||
throw CsErrorException(cs, "no loop to break");
|
||||
}
|
||||
})->p_type = CsIdBreak;
|
||||
|
||||
new_command("continue", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsContinueException();
|
||||
} else {
|
||||
throw CsErrorException(cs, "no loop to continue");
|
||||
}
|
||||
})->p_type = CsIdContinue;
|
||||
|
||||
cs_init_lib_base(*this);
|
||||
}
|
||||
|
||||
|
@ -1113,22 +1129,6 @@ void cs_init_lib_base(CsState &gcs) {
|
|||
}
|
||||
});
|
||||
|
||||
gcs.new_command("break", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsBreakException();
|
||||
} else {
|
||||
throw CsErrorException(cs, "no loop to break");
|
||||
}
|
||||
});
|
||||
|
||||
gcs.new_command("continue", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsContinueException();
|
||||
} else {
|
||||
throw CsErrorException(cs, "no loop to continue");
|
||||
}
|
||||
});
|
||||
|
||||
gcs.new_command("?", "tTT", [](auto &, auto args, auto &res) {
|
||||
if (args[0].get_bool()) {
|
||||
res = ostd::move(args[1]);
|
||||
|
|
Loading…
Reference in New Issue