diff --git a/src/cs_gen.cc b/src/cs_gen.cc index f681492..c7e9542 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -34,6 +34,10 @@ void gen_state::gen_dup(int ltype) { code.push_back(BC_INST_DUP | ret_code(ltype)); } +void gen_state::gen_result(int ltype) { + code.push_back(BC_INST_RESULT | ret_code(ltype)); +} + void gen_state::gen_push_result(int ltype) { code.push_back(BC_INST_RESULT_ARG | ret_code(ltype)); } @@ -42,6 +46,10 @@ void gen_state::gen_force(int ltype) { code.push_back(BC_INST_FORCE | ret_code(ltype, BC_RET_STRING)); } +void gen_state::gen_not(int ltype) { + code.push_back(BC_INST_NOT | ret_code(ltype)); +} + void gen_state::gen_val_null() { code.push_back(BC_INST_VAL_INT | BC_RET_NULL); } @@ -281,6 +289,14 @@ void gen_state::gen_lookup_ident(int ltype) { code.push_back(BC_INST_LOOKUP_U | ret_code(ltype)); } +void gen_state::gen_assign_alias(ident &id) { + code.push_back(BC_INST_ALIAS | (id.get_index() << 8)); +} + +void gen_state::gen_assign() { + code.push_back(BC_INST_ALIAS_U); +} + void gen_state::gen_compile(bool cond) { if (cond) { code.push_back(BC_INST_COND); @@ -326,6 +342,22 @@ void gen_state::gen_local(std::uint32_t nargs) { code.push_back(BC_INST_LOCAL | (nargs << 8)); } +void gen_state::gen_do(bool args, int ltype) { + if (args) { + code.push_back(BC_INST_DO_ARGS | ret_code(ltype)); + } else { + code.push_back(BC_INST_DO | ret_code(ltype)); + } +} + +void gen_state::gen_break() { + code.push_back(BC_INST_BREAK | BC_INST_FLAG_FALSE); +} + +void gen_state::gen_continue() { + code.push_back(BC_INST_BREAK | BC_INST_FLAG_TRUE); +} + void gen_state::gen_main(std::string_view v, std::string_view src) { parser_state ps{ts, *this}; ps.source = v.data(); @@ -340,7 +372,7 @@ void gen_state::gen_main_null() { code.reserve(code.size() + 4); code.push_back(BC_INST_START); gen_val_null(); - code.push_back(BC_INST_RESULT); + gen_result(); code.push_back(BC_INST_EXIT); } @@ -348,7 +380,7 @@ void gen_state::gen_main_integer(integer_type v) { code.reserve(code.size() + bc_store_size + 3); code.push_back(BC_INST_START); gen_val_integer(v); - code.push_back(BC_INST_RESULT); + gen_result(); code.push_back(BC_INST_EXIT); } @@ -356,7 +388,7 @@ void gen_state::gen_main_float(float_type v) { code.reserve(code.size() + bc_store_size + 3); code.push_back(BC_INST_START); gen_val_float(v); - code.push_back(BC_INST_RESULT); + gen_result(); code.push_back(BC_INST_EXIT); } diff --git a/src/cs_gen.hh b/src/cs_gen.hh index ccd6565..326a29d 100644 --- a/src/cs_gen.hh +++ b/src/cs_gen.hh @@ -28,9 +28,12 @@ struct gen_state { void gen_pop(); void gen_dup(int ltype = 0); + void gen_result(int ltype = 0); void gen_push_result(int ltype = 0); void gen_force(int ltype); + void gen_not(int ltype = 0); + void gen_val_null(); void gen_result_null(int ltype = 0); void gen_result_true(int ltype = 0); @@ -62,6 +65,9 @@ struct gen_state { void gen_lookup_alias(ident &id, int ltype = 0, int dtype = 0); void gen_lookup_ident(int ltype = 0); + void gen_assign_alias(ident &id); + void gen_assign(); + void gen_compile(bool cond = false); void gen_ident_lookup(); @@ -74,6 +80,10 @@ struct gen_state { void gen_call(std::uint32_t nargs = 0); void gen_local(std::uint32_t nargs); + void gen_do(bool args, int ltype = 0); + + void gen_break(); + void gen_continue(); void gen_main( std::string_view s, std::string_view src = std::string_view{} diff --git a/src/cs_parser.cc b/src/cs_parser.cc index 35f9230..cfc97fe 100644 --- a/src/cs_parser.cc +++ b/src/cs_parser.cc @@ -1121,7 +1121,7 @@ static void compile_local(parser_state &gs, bool &more) { } static void compile_do( - parser_state &gs, bool &more, int rettype, int opcode + parser_state &gs, bool args, int rettype, bool &more ) { if (more) { more = compilearg(gs, VAL_CODE); @@ -1129,7 +1129,7 @@ static void compile_do( if (!more) { gs.gs.gen_result_null(rettype); } else { - gs.gs.code.push_back(opcode | ret_code(rettype)); + gs.gs.gen_do(args, rettype); } } @@ -1293,9 +1293,7 @@ void parser_state::parse_block(int rettype, int brak) { if (!more) { gs.gen_val_string(); } - gs.code.push_back( - BC_INST_ALIAS | (id.get_index() << 8) - ); + gs.gen_assign_alias(id); goto endstatement; case ident_type::IVAR: { auto *hid = ts.istate->cmd_ivar; @@ -1330,7 +1328,7 @@ void parser_state::parse_block(int rettype, int brak) { if (!more) { gs.gen_val_string(); } - gs.code.push_back(BC_INST_ALIAS_U); + gs.gen_assign(); goto endstatement; } } @@ -1368,7 +1366,7 @@ noid: gs.gen_val(rettype, idname.str_term(), int(curline)); break; } - gs.code.push_back(BC_INST_RESULT); + gs.gen_result(); } else { switch (ident_p{*id}.impl().p_type) { case ID_ALIAS: @@ -1386,19 +1384,19 @@ noid: compile_local(*this, more); break; case ID_DO: - compile_do(*this, more, rettype, BC_INST_DO); + compile_do(*this, false, rettype, more); break; case ID_DOARGS: - compile_do(*this, more, rettype, BC_INST_DO_ARGS); + compile_do(*this, true, rettype, more); break; case ID_IF: compile_if(*this, id, more, rettype); break; case ID_BREAK: - gs.code.push_back(BC_INST_BREAK | BC_INST_FLAG_FALSE); + gs.gen_break(); break; case ID_CONTINUE: - gs.code.push_back(BC_INST_BREAK | BC_INST_FLAG_TRUE); + gs.gen_continue(); break; case ID_RESULT: if (more) { @@ -1407,7 +1405,7 @@ noid: if (!more) { gs.gen_result_null(rettype); } else { - gs.code.push_back(BC_INST_RESULT | ret_code(rettype)); + gs.gen_result(rettype); } break; case ID_NOT: @@ -1417,7 +1415,7 @@ noid: if (!more) { gs.gen_result_true(rettype); } else { - gs.code.push_back(BC_INST_NOT | ret_code(rettype)); + gs.gen_not(rettype); } break; case ID_AND: