implement break/continue in bytecode
parent
b05bc51b14
commit
38c17d1911
|
@ -1587,6 +1587,12 @@ compilecomv:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CsIdBreak:
|
||||||
|
gs.code.push(CsCodeBreak | CsCodeFlagFalse);
|
||||||
|
break;
|
||||||
|
case CsIdContinue:
|
||||||
|
gs.code.push(CsCodeBreak | CsCodeFlagTrue);
|
||||||
|
break;
|
||||||
case CsIdResult:
|
case CsIdResult:
|
||||||
if (more) {
|
if (more) {
|
||||||
more = compilearg(gs, CsValAny, prevargs);
|
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;
|
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: {
|
case CsCodeMacro: {
|
||||||
ostd::Uint32 len = op >> 8;
|
ostd::Uint32 len = op >> 8;
|
||||||
|
|
|
@ -21,7 +21,8 @@ static constexpr int DbgaliasIdx = MaxArguments + 2;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CsIdUnknown = -1, CsIdIvar, CsIdFvar, CsIdSvar, CsIdCommand, CsIdAlias,
|
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 {
|
struct CsIdentLink {
|
||||||
|
@ -76,6 +77,7 @@ enum {
|
||||||
CsCodeLocal,
|
CsCodeLocal,
|
||||||
CsCodeDo, CsCodeDoArgs,
|
CsCodeDo, CsCodeDoArgs,
|
||||||
CsCodeJump, CsCodeJumpB, CsCodeJumpResult,
|
CsCodeJump, CsCodeJumpB, CsCodeJumpResult,
|
||||||
|
CsCodeBreak,
|
||||||
|
|
||||||
CsCodeOpMask = 0x3F,
|
CsCodeOpMask = 0x3F,
|
||||||
CsCodeRet = 6,
|
CsCodeRet = 6,
|
||||||
|
|
|
@ -332,6 +332,22 @@ CsState::CsState(CsAllocCb func, void *data):
|
||||||
|
|
||||||
new_command("local", nullptr, nullptr)->p_type = CsIdLocal;
|
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);
|
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) {
|
gcs.new_command("?", "tTT", [](auto &, auto args, auto &res) {
|
||||||
if (args[0].get_bool()) {
|
if (args[0].get_bool()) {
|
||||||
res = ostd::move(args[1]);
|
res = ostd::move(args[1]);
|
||||||
|
|
Loading…
Reference in New Issue