move some more codegen into proper place
parent
295c905c32
commit
1bc94bf5af
|
@ -135,10 +135,10 @@ enum {
|
||||||
*/
|
*/
|
||||||
BC_INST_LOOKUP_U,
|
BC_INST_LOOKUP_U,
|
||||||
/* concatenate D values on top of the stack together, with topmost value
|
/* concatenate D values on top of the stack together, with topmost value
|
||||||
* being last; push the result according to M
|
* being last; delimit with spaces; push the result according to M
|
||||||
*/
|
*/
|
||||||
BC_INST_CONC,
|
BC_INST_CONC,
|
||||||
/* like above but delimit with spaces */
|
/* like above but without delimiter */
|
||||||
BC_INST_CONC_W,
|
BC_INST_CONC_W,
|
||||||
/* push the value of svar with index D on the stack according to M */
|
/* push the value of svar with index D on the stack according to M */
|
||||||
BC_INST_SVAR,
|
BC_INST_SVAR,
|
||||||
|
|
|
@ -9,6 +9,17 @@
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
||||||
|
static inline int ret_code(int type, int def = 0) {
|
||||||
|
if (type >= VAL_ANY) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
return type << BC_INST_RET;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t gen_state::count() const {
|
||||||
|
return code.size();
|
||||||
|
}
|
||||||
|
|
||||||
bcode_ref gen_state::steal_ref() {
|
bcode_ref gen_state::steal_ref() {
|
||||||
auto *cp = bcode_alloc(ts.istate, code.size());
|
auto *cp = bcode_alloc(ts.istate, code.size());
|
||||||
std::memcpy(cp, code.data(), code.size() * sizeof(std::uint32_t));
|
std::memcpy(cp, code.data(), code.size() * sizeof(std::uint32_t));
|
||||||
|
@ -19,10 +30,34 @@ void gen_state::gen_pop() {
|
||||||
code.push_back(BC_INST_POP);
|
code.push_back(BC_INST_POP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_dup(int ltype) {
|
||||||
|
code.push_back(BC_INST_DUP | ret_code(ltype));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_push_result(int ltype) {
|
||||||
|
code.push_back(BC_INST_RESULT_ARG | ret_code(ltype));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_force(int ltype) {
|
||||||
|
code.push_back(BC_INST_FORCE | ret_code(ltype, BC_RET_STRING));
|
||||||
|
}
|
||||||
|
|
||||||
void gen_state::gen_val_null() {
|
void gen_state::gen_val_null() {
|
||||||
code.push_back(BC_INST_VAL_INT | BC_RET_NULL);
|
code.push_back(BC_INST_VAL_INT | BC_RET_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_result_null(int ltype) {
|
||||||
|
code.push_back(BC_INST_NULL | ret_code(ltype));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_result_true(int ltype) {
|
||||||
|
code.push_back(BC_INST_TRUE | ret_code(ltype));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_result_false(int ltype) {
|
||||||
|
code.push_back(BC_INST_FALSE | ret_code(ltype));
|
||||||
|
}
|
||||||
|
|
||||||
void gen_state::gen_val_integer(integer_type v) {
|
void gen_state::gen_val_integer(integer_type v) {
|
||||||
if (v >= -0x800000 && v <= 0x7FFFFF) {
|
if (v >= -0x800000 && v <= 0x7FFFFF) {
|
||||||
code.push_back(BC_INST_VAL_INT | BC_RET_INT | (v << 8));
|
code.push_back(BC_INST_VAL_INT | BC_RET_INT | (v << 8));
|
||||||
|
@ -218,13 +253,6 @@ void gen_state::gen_val(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ret_code(int type, int def = 0) {
|
|
||||||
if (type >= VAL_ANY) {
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
return type << BC_INST_RET;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_state::gen_lookup_ivar(ident &id, int ltype) {
|
void gen_state::gen_lookup_ivar(ident &id, int ltype) {
|
||||||
code.push_back(
|
code.push_back(
|
||||||
BC_INST_IVAR | ret_code(ltype, BC_RET_INT) | (id.get_index() << 8)
|
BC_INST_IVAR | ret_code(ltype, BC_RET_INT) | (id.get_index() << 8)
|
||||||
|
@ -245,7 +273,7 @@ void gen_state::gen_lookup_svar(ident &id, int ltype) {
|
||||||
|
|
||||||
void gen_state::gen_lookup_alias(ident &id, int ltype, int dtype) {
|
void gen_state::gen_lookup_alias(ident &id, int ltype, int dtype) {
|
||||||
code.push_back(
|
code.push_back(
|
||||||
BC_INST_LOOKUP | ret_code(ltype, dtype) | (id.get_index() << 8)
|
BC_INST_LOOKUP | ret_code(ltype, ret_code(dtype)) | (id.get_index() << 8)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,6 +293,39 @@ void gen_state::gen_ident_lookup() {
|
||||||
code.push_back(BC_INST_IDENT_U);
|
code.push_back(BC_INST_IDENT_U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_concat(std::size_t concs, bool space, int ltype) {
|
||||||
|
if (!concs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (space) {
|
||||||
|
code.push_back(BC_INST_CONC | ret_code(ltype) | (concs << 8));
|
||||||
|
} else {
|
||||||
|
code.push_back(BC_INST_CONC_W | ret_code(ltype) | (concs << 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_command_call(
|
||||||
|
ident &id, int comt, int ltype, std::uint32_t nargs
|
||||||
|
) {
|
||||||
|
code.push_back(comt | ret_code(ltype) | (id.get_index() << 8));
|
||||||
|
if (comt != BC_INST_COM) {
|
||||||
|
code.push_back(nargs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_alias_call(ident &id, std::uint32_t nargs) {
|
||||||
|
code.push_back(BC_INST_CALL | (id.get_index() << 8));
|
||||||
|
code.push_back(nargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_call(std::uint32_t nargs) {
|
||||||
|
code.push_back(BC_INST_CALL_U | (nargs << 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_state::gen_local(std::uint32_t nargs) {
|
||||||
|
code.push_back(BC_INST_LOCAL | (nargs << 8));
|
||||||
|
}
|
||||||
|
|
||||||
void gen_state::gen_main_null() {
|
void gen_state::gen_main_null() {
|
||||||
code.reserve(code.size() + 4);
|
code.reserve(code.size() + 4);
|
||||||
code.push_back(BC_INST_START);
|
code.push_back(BC_INST_START);
|
||||||
|
|
|
@ -22,11 +22,19 @@ struct gen_state {
|
||||||
ts{tsr}, code{tsr.istate}
|
ts{tsr}, code{tsr.istate}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
std::size_t count() const;
|
||||||
|
|
||||||
bcode_ref steal_ref();
|
bcode_ref steal_ref();
|
||||||
|
|
||||||
void gen_pop();
|
void gen_pop();
|
||||||
|
void gen_dup(int ltype = 0);
|
||||||
|
void gen_push_result(int ltype = 0);
|
||||||
|
void gen_force(int ltype);
|
||||||
|
|
||||||
void gen_val_null();
|
void gen_val_null();
|
||||||
|
void gen_result_null(int ltype = 0);
|
||||||
|
void gen_result_true(int ltype = 0);
|
||||||
|
void gen_result_false(int ltype = 0);
|
||||||
|
|
||||||
void gen_val_integer(integer_type v = 0);
|
void gen_val_integer(integer_type v = 0);
|
||||||
void gen_val_integer(std::string_view v);
|
void gen_val_integer(std::string_view v);
|
||||||
|
@ -57,6 +65,16 @@ struct gen_state {
|
||||||
void gen_compile(bool cond = false);
|
void gen_compile(bool cond = false);
|
||||||
void gen_ident_lookup();
|
void gen_ident_lookup();
|
||||||
|
|
||||||
|
void gen_concat(std::size_t concs, bool space, int ltype = 0);
|
||||||
|
|
||||||
|
void gen_command_call(
|
||||||
|
ident &id, int comt, int ltype = 0, std::uint32_t nargs = 0
|
||||||
|
);
|
||||||
|
void gen_alias_call(ident &id, std::uint32_t nargs = 0);
|
||||||
|
void gen_call(std::uint32_t nargs = 0);
|
||||||
|
|
||||||
|
void gen_local(std::uint32_t nargs);
|
||||||
|
|
||||||
void gen_main_null();
|
void gen_main_null();
|
||||||
void gen_main_integer(integer_type v);
|
void gen_main_integer(integer_type v);
|
||||||
void gen_main_float(float_type v);
|
void gen_main_float(float_type v);
|
||||||
|
|
|
@ -479,7 +479,7 @@ lookupid:
|
||||||
gs.gs.gen_lookup_alias(id);
|
gs.gs.gen_lookup_alias(id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gs.gs.gen_lookup_alias(id, ltype, BC_RET_STRING);
|
gs.gs.gen_lookup_alias(id, ltype, VAL_STRING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -505,7 +505,7 @@ lookupid:
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
gs.gs.code.push_back(BC_INST_DUP | BC_RET_FLOAT);
|
gs.gs.gen_dup(VAL_FLOAT);
|
||||||
numargs++;
|
numargs++;
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
|
@ -531,10 +531,10 @@ lookupid:
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
comtype = BC_INST_COM_C;
|
comtype = BC_INST_COM_C;
|
||||||
goto compilecomv;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
comtype = BC_INST_COM_V;
|
comtype = BC_INST_COM_V;
|
||||||
goto compilecomv;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
case '3':
|
case '3':
|
||||||
|
@ -542,21 +542,8 @@ lookupid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.gs.code.push_back(
|
gs.gs.gen_command_call(id, comtype, ltype, numargs);
|
||||||
comtype | ret_code(ltype) | (id.get_index() << 8)
|
gs.gs.gen_push_result(ltype);
|
||||||
);
|
|
||||||
gs.gs.code.push_back(
|
|
||||||
BC_INST_RESULT_ARG | ret_code(ltype)
|
|
||||||
);
|
|
||||||
goto done;
|
|
||||||
compilecomv:
|
|
||||||
gs.gs.code.push_back(
|
|
||||||
comtype | ret_code(ltype) | (id.get_index() << 8)
|
|
||||||
);
|
|
||||||
gs.gs.code.push_back(numargs);
|
|
||||||
gs.gs.code.push_back(
|
|
||||||
BC_INST_RESULT_ARG | ret_code(ltype)
|
|
||||||
);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -741,9 +728,7 @@ static void compileblockmain(parser_state &gs, int wordtype) {
|
||||||
concs++;
|
concs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (concs) {
|
gs.gs.gen_concat(concs, false, wordtype);
|
||||||
gs.gs.code.push_back(BC_INST_CONC_W | ret_code(wordtype) | (concs << 8));
|
|
||||||
}
|
|
||||||
switch (wordtype) {
|
switch (wordtype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
if (concs || gs.source - 1 > start) {
|
if (concs || gs.source - 1 > start) {
|
||||||
|
@ -784,7 +769,7 @@ static void compileblockmain(parser_state &gs, int wordtype) {
|
||||||
if (gs.source - 1 <= start) {
|
if (gs.source - 1 <= start) {
|
||||||
gs.gs.gen_val(wordtype);
|
gs.gs.gen_val(wordtype);
|
||||||
} else {
|
} else {
|
||||||
gs.gs.code.push_back(BC_INST_FORCE | (wordtype << BC_INST_RET));
|
gs.gs.gen_force(wordtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -841,10 +826,10 @@ static bool compilearg(
|
||||||
return true;
|
return true;
|
||||||
case '(': {
|
case '(': {
|
||||||
gs.next_char();
|
gs.next_char();
|
||||||
std::size_t start = gs.gs.code.size();
|
auto start = gs.gs.count();
|
||||||
gs.parse_block(VAL_ANY, ')');
|
gs.parse_block(VAL_ANY, ')');
|
||||||
if (gs.gs.code.size() > start) {
|
if (gs.gs.count() > start) {
|
||||||
gs.gs.code.push_back(BC_INST_RESULT_ARG | ret_code(wordtype));
|
gs.gs.gen_push_result(wordtype);
|
||||||
} else {
|
} else {
|
||||||
gs.gs.gen_val(wordtype);
|
gs.gs.gen_val(wordtype);
|
||||||
return true;
|
return true;
|
||||||
|
@ -942,7 +927,7 @@ static void compile_cmd(
|
||||||
numconc++;
|
numconc++;
|
||||||
}
|
}
|
||||||
if (numconc > 1) {
|
if (numconc > 1) {
|
||||||
gs.gs.code.push_back(BC_INST_CONC | BC_RET_STRING | (numconc << 8));
|
gs.gs.gen_concat(numconc, true, VAL_STRING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
numargs++;
|
numargs++;
|
||||||
|
@ -998,7 +983,7 @@ static void compile_cmd(
|
||||||
if (rep) {
|
if (rep) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gs.gs.code.push_back(BC_INST_DUP | BC_RET_FLOAT);
|
gs.gs.gen_dup(VAL_FLOAT);
|
||||||
fakeargs++;
|
fakeargs++;
|
||||||
}
|
}
|
||||||
numargs++;
|
numargs++;
|
||||||
|
@ -1080,7 +1065,7 @@ static void compile_cmd(
|
||||||
numcargs++;
|
numcargs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto compilecomv;
|
break;
|
||||||
case 'V': /* varargs */
|
case 'V': /* varargs */
|
||||||
comtype = BC_INST_COM_V;
|
comtype = BC_INST_COM_V;
|
||||||
if (more && (!limit || (numcargs < limit))) {
|
if (more && (!limit || (numcargs < limit))) {
|
||||||
|
@ -1093,7 +1078,7 @@ static void compile_cmd(
|
||||||
numcargs++;
|
numcargs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto compilecomv;
|
break;
|
||||||
case '1': /* vararg repetition */
|
case '1': /* vararg repetition */
|
||||||
case '2':
|
case '2':
|
||||||
case '3':
|
case '3':
|
||||||
|
@ -1106,13 +1091,7 @@ static void compile_cmd(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.gs.code.push_back(comtype | ret_code(rettype) | (id->get_index() << 8));
|
gs.gs.gen_command_call(*id, comtype, rettype, numargs);
|
||||||
return;
|
|
||||||
compilecomv:
|
|
||||||
gs.gs.code.push_back(
|
|
||||||
comtype | ret_code(rettype) | (id->get_index() << 8)
|
|
||||||
);
|
|
||||||
gs.gs.code.push_back(numargs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_alias(parser_state &gs, alias *id, bool &more) {
|
static void compile_alias(parser_state &gs, alias *id, bool &more) {
|
||||||
|
@ -1124,10 +1103,7 @@ static void compile_alias(parser_state &gs, alias *id, bool &more) {
|
||||||
}
|
}
|
||||||
++numargs;
|
++numargs;
|
||||||
}
|
}
|
||||||
gs.gs.code.push_back(
|
gs.gs.gen_alias_call(*id, numargs);
|
||||||
BC_INST_CALL | (id->get_index() << 8)
|
|
||||||
);
|
|
||||||
gs.gs.code.push_back(numargs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_local(parser_state &gs, bool &more) {
|
static void compile_local(parser_state &gs, bool &more) {
|
||||||
|
@ -1141,7 +1117,7 @@ static void compile_local(parser_state &gs, bool &more) {
|
||||||
numargs++;
|
numargs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.gs.code.push_back(BC_INST_LOCAL | (numargs << 8));
|
gs.gs.gen_local(numargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_do(
|
static void compile_do(
|
||||||
|
@ -1150,7 +1126,11 @@ static void compile_do(
|
||||||
if (more) {
|
if (more) {
|
||||||
more = compilearg(gs, VAL_CODE);
|
more = compilearg(gs, VAL_CODE);
|
||||||
}
|
}
|
||||||
gs.gs.code.push_back((more ? opcode : BC_INST_NULL) | ret_code(rettype));
|
if (!more) {
|
||||||
|
gs.gs.gen_result_null(rettype);
|
||||||
|
} else {
|
||||||
|
gs.gs.code.push_back(opcode | ret_code(rettype));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_if(
|
static void compile_if(
|
||||||
|
@ -1160,13 +1140,13 @@ static void compile_if(
|
||||||
more = compilearg(gs, VAL_ANY);
|
more = compilearg(gs, VAL_ANY);
|
||||||
}
|
}
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gs.code.push_back(BC_INST_NULL | ret_code(rettype));
|
gs.gs.gen_result_null(rettype);
|
||||||
} else {
|
} else {
|
||||||
std::size_t start1 = gs.gs.code.size();
|
std::size_t start1 = gs.gs.code.size();
|
||||||
more = compilearg(gs, VAL_CODE);
|
more = compilearg(gs, VAL_CODE);
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gs.gen_pop();
|
gs.gs.gen_pop();
|
||||||
gs.gs.code.push_back(BC_INST_NULL | ret_code(rettype));
|
gs.gs.gen_result_null(rettype);
|
||||||
} else {
|
} else {
|
||||||
std::size_t start2 = gs.gs.code.size();
|
std::size_t start2 = gs.gs.code.size();
|
||||||
more = compilearg(gs, VAL_CODE);
|
more = compilearg(gs, VAL_CODE);
|
||||||
|
@ -1225,10 +1205,11 @@ static void compile_and_or(
|
||||||
more = compilearg(gs, VAL_COND);
|
more = compilearg(gs, VAL_COND);
|
||||||
}
|
}
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gs.code.push_back(
|
if (ident_p{*id}.impl().p_type == ID_AND) {
|
||||||
((ident_p{*id}.impl().p_type == ID_AND)
|
gs.gs.gen_result_true(rettype);
|
||||||
? BC_INST_TRUE : BC_INST_FALSE) | ret_code(rettype)
|
} else {
|
||||||
);
|
gs.gs.gen_result_false(rettype);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
numargs++;
|
numargs++;
|
||||||
std::size_t start = gs.gs.code.size(), end = start;
|
std::size_t start = gs.gs.code.size(), end = start;
|
||||||
|
@ -1363,7 +1344,7 @@ noid:
|
||||||
}
|
}
|
||||||
++numargs;
|
++numargs;
|
||||||
}
|
}
|
||||||
gs.code.push_back(BC_INST_CALL_U | (numargs << 8));
|
gs.gen_call(numargs);
|
||||||
} else {
|
} else {
|
||||||
idname.push_back('\0');
|
idname.push_back('\0');
|
||||||
ident *id = ts.pstate->get_ident(idname.str_term());
|
ident *id = ts.pstate->get_ident(idname.str_term());
|
||||||
|
@ -1423,18 +1404,21 @@ noid:
|
||||||
if (more) {
|
if (more) {
|
||||||
more = compilearg(*this, VAL_ANY);
|
more = compilearg(*this, VAL_ANY);
|
||||||
}
|
}
|
||||||
gs.code.push_back(
|
if (!more) {
|
||||||
(more ? BC_INST_RESULT : BC_INST_NULL) |
|
gs.gen_result_null(rettype);
|
||||||
ret_code(rettype)
|
} else {
|
||||||
);
|
gs.code.push_back(BC_INST_RESULT | ret_code(rettype));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ID_NOT:
|
case ID_NOT:
|
||||||
if (more) {
|
if (more) {
|
||||||
more = compilearg(*this, VAL_ANY);
|
more = compilearg(*this, VAL_ANY);
|
||||||
}
|
}
|
||||||
gs.code.push_back(
|
if (!more) {
|
||||||
(more ? BC_INST_NOT : BC_INST_TRUE) | ret_code(rettype)
|
gs.gen_result_true(rettype);
|
||||||
);
|
} else {
|
||||||
|
gs.code.push_back(BC_INST_NOT | ret_code(rettype));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ID_AND:
|
case ID_AND:
|
||||||
case ID_OR:
|
case ID_OR:
|
||||||
|
|
Loading…
Reference in New Issue