t6: refactor calls & fix devblock bug
This commit is contained in:
parent
aca2c7b3aa
commit
37b4c96d86
@ -31,7 +31,7 @@ auto compiler::output_raw() -> std::vector<std::uint8_t>
|
|||||||
std::vector<std::uint8_t> output;
|
std::vector<std::uint8_t> output;
|
||||||
|
|
||||||
output.resize(output_->pos());
|
output.resize(output_->pos());
|
||||||
memcpy(output.data(), output_->buffer().data(), output.size());
|
std::memcpy(output.data(), output_->buffer().data(), output.size());
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@ -332,13 +332,11 @@ void compiler::emit_stmt_expr(const ast::stmt_expr::ptr& stmt)
|
|||||||
void compiler::emit_stmt_call(const ast::stmt_call::ptr& stmt)
|
void compiler::emit_stmt_call(const ast::stmt_call::ptr& stmt)
|
||||||
{
|
{
|
||||||
if (stmt->expr == ast::kind::expr_call)
|
if (stmt->expr == ast::kind::expr_call)
|
||||||
emit_expr_call(stmt->expr.as_call);
|
emit_expr_call(stmt->expr.as_call, true);
|
||||||
else if (stmt->expr == ast::kind::expr_method)
|
else if (stmt->expr == ast::kind::expr_method)
|
||||||
emit_expr_method(stmt->expr.as_method);
|
emit_expr_method(stmt->expr.as_method, true);
|
||||||
else
|
else
|
||||||
throw comp_error(stmt->loc(), "unknown call statement expression");
|
throw comp_error(stmt->loc(), "unknown call statement expression");
|
||||||
|
|
||||||
emit_opcode(opcode::OP_DecTop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_stmt_assign(const ast::stmt_assign::ptr& stmt)
|
void compiler::emit_stmt_assign(const ast::stmt_assign::ptr& stmt)
|
||||||
@ -816,10 +814,10 @@ void compiler::emit_expr(const ast::expr& expr)
|
|||||||
emit_expr_not(expr.as_not);
|
emit_expr_not(expr.as_not);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_call:
|
case ast::kind::expr_call:
|
||||||
emit_expr_call(expr.as_call);
|
emit_expr_call(expr.as_call, false);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_method:
|
case ast::kind::expr_method:
|
||||||
emit_expr_method(expr.as_method);
|
emit_expr_method(expr.as_method, false);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_isdefined:
|
case ast::kind::expr_isdefined:
|
||||||
emit_expr_isdefined(expr.as_isdefined);
|
emit_expr_isdefined(expr.as_isdefined);
|
||||||
@ -1024,9 +1022,9 @@ void compiler::emit_expr_clear(const ast::expr& expr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_increment(const ast::expr_increment::ptr& expr, bool fromstmt)
|
void compiler::emit_expr_increment(const ast::expr_increment::ptr& expr, bool is_stmt)
|
||||||
{
|
{
|
||||||
if (fromstmt)
|
if (is_stmt)
|
||||||
{
|
{
|
||||||
emit_expr_variable_ref(expr->lvalue, false);
|
emit_expr_variable_ref(expr->lvalue, false);
|
||||||
emit_opcode(opcode::OP_Inc);
|
emit_opcode(opcode::OP_Inc);
|
||||||
@ -1037,9 +1035,9 @@ void compiler::emit_expr_increment(const ast::expr_increment::ptr& expr, bool fr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_decrement(const ast::expr_decrement::ptr& expr, bool fromstmt)
|
void compiler::emit_expr_decrement(const ast::expr_decrement::ptr& expr, bool is_stmt)
|
||||||
{
|
{
|
||||||
if (fromstmt)
|
if (is_stmt)
|
||||||
{
|
{
|
||||||
emit_expr_variable_ref(expr->lvalue, false);
|
emit_expr_variable_ref(expr->lvalue, false);
|
||||||
emit_opcode(opcode::OP_Dec);
|
emit_opcode(opcode::OP_Dec);
|
||||||
@ -1168,17 +1166,17 @@ void compiler::emit_expr_not(const ast::expr_not::ptr& expr)
|
|||||||
emit_opcode(opcode::OP_BoolNot);
|
emit_opcode(opcode::OP_BoolNot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_call(const ast::expr_call::ptr& expr)
|
void compiler::emit_expr_call(const ast::expr_call::ptr& expr, bool is_stmt)
|
||||||
{
|
{
|
||||||
if (expr->call == ast::kind::expr_pointer)
|
if (expr->call == ast::kind::expr_pointer)
|
||||||
emit_expr_call_pointer(expr->call.as_pointer);
|
emit_expr_call_pointer(expr->call.as_pointer, is_stmt);
|
||||||
else if (expr->call == ast::kind::expr_function)
|
else if (expr->call == ast::kind::expr_function)
|
||||||
emit_expr_call_function(expr->call.as_function);
|
emit_expr_call_function(expr->call.as_function, is_stmt);
|
||||||
else
|
else
|
||||||
throw comp_error(expr->loc(), "unknown function call expression");
|
throw comp_error(expr->loc(), "unknown function call expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_call_pointer(const ast::expr_pointer::ptr& expr)
|
void compiler::emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, bool is_stmt)
|
||||||
{
|
{
|
||||||
emit_opcode(opcode::OP_PreScriptCall);
|
emit_opcode(opcode::OP_PreScriptCall);
|
||||||
emit_expr_arguments(expr->args);
|
emit_expr_arguments(expr->args);
|
||||||
@ -1197,9 +1195,11 @@ void compiler::emit_expr_call_pointer(const ast::expr_pointer::ptr& expr)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_stmt) emit_opcode(opcode::OP_DecTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr)
|
void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr, bool is_stmt)
|
||||||
{
|
{
|
||||||
if (expr->path->value != "")
|
if (expr->path->value != "")
|
||||||
{
|
{
|
||||||
@ -1221,6 +1221,16 @@ void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: resolve import calls path
|
// TODO: resolve import calls path
|
||||||
|
bool as_dev = false;
|
||||||
|
std::string end;
|
||||||
|
|
||||||
|
if (!developer_thread_ && is_stmt && expr->name->value == "assert")
|
||||||
|
{
|
||||||
|
as_dev = true;
|
||||||
|
developer_thread_ = true;
|
||||||
|
end = create_label();
|
||||||
|
emit_opcode(opcode::OP_DevblockBegin, end);
|
||||||
|
}
|
||||||
|
|
||||||
emit_opcode(opcode::OP_PreScriptCall);
|
emit_opcode(opcode::OP_PreScriptCall);
|
||||||
emit_expr_arguments(expr->args);
|
emit_expr_arguments(expr->args);
|
||||||
@ -1241,19 +1251,27 @@ void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_stmt) emit_opcode(opcode::OP_DecTop);
|
||||||
|
|
||||||
|
if (as_dev)
|
||||||
|
{
|
||||||
|
insert_label(end);
|
||||||
|
developer_thread_ = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_method(const ast::expr_method::ptr& expr)
|
void compiler::emit_expr_method(const ast::expr_method::ptr& expr, bool is_stmt)
|
||||||
{
|
{
|
||||||
if (expr->call == ast::kind::expr_pointer)
|
if (expr->call == ast::kind::expr_pointer)
|
||||||
emit_expr_method_pointer(expr->call.as_pointer, expr->obj);
|
emit_expr_method_pointer(expr->call.as_pointer, expr->obj, is_stmt);
|
||||||
else if (expr->call == ast::kind::expr_function)
|
else if (expr->call == ast::kind::expr_function)
|
||||||
emit_expr_method_function(expr->call.as_function, expr->obj);
|
emit_expr_method_function(expr->call.as_function, expr->obj, is_stmt);
|
||||||
else
|
else
|
||||||
throw comp_error(expr->loc(), "unknown method call expression");
|
throw comp_error(expr->loc(), "unknown method call expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, const ast::expr& obj)
|
void compiler::emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, const ast::expr& obj, bool is_stmt)
|
||||||
{
|
{
|
||||||
emit_opcode(opcode::OP_PreScriptCall);
|
emit_opcode(opcode::OP_PreScriptCall);
|
||||||
emit_expr_arguments(expr->args);
|
emit_expr_arguments(expr->args);
|
||||||
@ -1273,9 +1291,11 @@ void compiler::emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, cons
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_stmt) emit_opcode(opcode::OP_DecTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_method_function(const ast::expr_function::ptr& expr, const ast::expr& obj)
|
void compiler::emit_expr_method_function(const ast::expr_function::ptr& expr, const ast::expr& obj, bool is_stmt)
|
||||||
{
|
{
|
||||||
if (expr->path->value != "")
|
if (expr->path->value != "")
|
||||||
{
|
{
|
||||||
@ -1318,6 +1338,8 @@ void compiler::emit_expr_method_function(const ast::expr_function::ptr& expr, co
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_stmt) emit_opcode(opcode::OP_DecTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler::emit_expr_parameters(const ast::expr_parameters::ptr&)
|
void compiler::emit_expr_parameters(const ast::expr_parameters::ptr&)
|
||||||
@ -1576,13 +1598,13 @@ void compiler::emit_expr_field_ref(const ast::expr_field::ptr& expr, bool set)
|
|||||||
if (set) emit_opcode(opcode::OP_SetVariableField);
|
if (set) emit_opcode(opcode::OP_SetVariableField);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_call:
|
case ast::kind::expr_call:
|
||||||
emit_expr_call(expr->obj.as_call);
|
emit_expr_call(expr->obj.as_call, false);
|
||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
emit_opcode(opcode::OP_EvalFieldVariableRef, field);
|
emit_opcode(opcode::OP_EvalFieldVariableRef, field);
|
||||||
if (set) emit_opcode(opcode::OP_SetVariableField);
|
if (set) emit_opcode(opcode::OP_SetVariableField);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_method:
|
case ast::kind::expr_method:
|
||||||
emit_expr_method(expr->obj.as_method);
|
emit_expr_method(expr->obj.as_method, false);
|
||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
emit_opcode(opcode::OP_EvalFieldVariableRef, field);
|
emit_opcode(opcode::OP_EvalFieldVariableRef, field);
|
||||||
if (set) emit_opcode(opcode::OP_SetVariableField);
|
if (set) emit_opcode(opcode::OP_SetVariableField);
|
||||||
@ -1663,12 +1685,12 @@ void compiler::emit_expr_field(const ast::expr_field::ptr& expr)
|
|||||||
emit_opcode(opcode::OP_EvalFieldVariable, field);
|
emit_opcode(opcode::OP_EvalFieldVariable, field);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_call:
|
case ast::kind::expr_call:
|
||||||
emit_expr_call(expr->obj.as_call);
|
emit_expr_call(expr->obj.as_call, false);
|
||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
emit_opcode(opcode::OP_EvalFieldVariable, field);
|
emit_opcode(opcode::OP_EvalFieldVariable, field);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_method:
|
case ast::kind::expr_method:
|
||||||
emit_expr_method(expr->obj.as_method);
|
emit_expr_method(expr->obj.as_method, false);
|
||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
emit_opcode(opcode::OP_EvalFieldVariable, field);
|
emit_opcode(opcode::OP_EvalFieldVariable, field);
|
||||||
break;
|
break;
|
||||||
@ -1720,11 +1742,11 @@ void compiler::emit_expr_object(const ast::expr& expr)
|
|||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_call:
|
case ast::kind::expr_call:
|
||||||
emit_expr_call(expr.as_call);
|
emit_expr_call(expr.as_call, false);
|
||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_method:
|
case ast::kind::expr_method:
|
||||||
emit_expr_method(expr.as_method);
|
emit_expr_method(expr.as_method, false);
|
||||||
emit_opcode(opcode::OP_CastFieldObject);
|
emit_opcode(opcode::OP_CastFieldObject);
|
||||||
break;
|
break;
|
||||||
case ast::kind::expr_identifier:
|
case ast::kind::expr_identifier:
|
||||||
|
@ -73,20 +73,20 @@ private:
|
|||||||
void emit_expr(const ast::expr& expr);
|
void emit_expr(const ast::expr& expr);
|
||||||
void emit_expr_assign(const ast::expr_assign::ptr& expr);
|
void emit_expr_assign(const ast::expr_assign::ptr& expr);
|
||||||
void emit_expr_clear(const ast::expr& expr);
|
void emit_expr_clear(const ast::expr& expr);
|
||||||
void emit_expr_increment(const ast::expr_increment::ptr& expr, bool stmt);
|
void emit_expr_increment(const ast::expr_increment::ptr& expr, bool is_stmt);
|
||||||
void emit_expr_decrement(const ast::expr_decrement::ptr& expr, bool stmt);
|
void emit_expr_decrement(const ast::expr_decrement::ptr& expr, bool is_stmt);
|
||||||
void emit_expr_ternary(const ast::expr_ternary::ptr& expr);
|
void emit_expr_ternary(const ast::expr_ternary::ptr& expr);
|
||||||
void emit_expr_binary(const ast::expr_binary::ptr& expr);
|
void emit_expr_binary(const ast::expr_binary::ptr& expr);
|
||||||
void emit_expr_and(const ast::expr_and::ptr& expr);
|
void emit_expr_and(const ast::expr_and::ptr& expr);
|
||||||
void emit_expr_or(const ast::expr_or::ptr& expr);
|
void emit_expr_or(const ast::expr_or::ptr& expr);
|
||||||
void emit_expr_complement(const ast::expr_complement::ptr& expr);
|
void emit_expr_complement(const ast::expr_complement::ptr& expr);
|
||||||
void emit_expr_not(const ast::expr_not::ptr& expr);
|
void emit_expr_not(const ast::expr_not::ptr& expr);
|
||||||
void emit_expr_call(const ast::expr_call::ptr& expr);
|
void emit_expr_call(const ast::expr_call::ptr& expr, bool is_stmt);
|
||||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr);
|
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, bool is_stmt);
|
||||||
void emit_expr_call_function(const ast::expr_function::ptr& expr);
|
void emit_expr_call_function(const ast::expr_function::ptr& expr, bool is_stmt);
|
||||||
void emit_expr_method(const ast::expr_method::ptr& expr);
|
void emit_expr_method(const ast::expr_method::ptr& expr, bool is_stmt);
|
||||||
void emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, const ast::expr& obj);
|
void emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, const ast::expr& obj, bool is_stmt);
|
||||||
void emit_expr_method_function(const ast::expr_function::ptr& expr, const ast::expr& obj);
|
void emit_expr_method_function(const ast::expr_function::ptr& expr, const ast::expr& obj, bool is_stmt);
|
||||||
void emit_expr_parameters(const ast::expr_parameters::ptr& expr);
|
void emit_expr_parameters(const ast::expr_parameters::ptr& expr);
|
||||||
void emit_expr_arguments(const ast::expr_arguments::ptr& expr);
|
void emit_expr_arguments(const ast::expr_arguments::ptr& expr);
|
||||||
void emit_expr_isdefined(const ast::expr_isdefined::ptr& expr);
|
void emit_expr_isdefined(const ast::expr_isdefined::ptr& expr);
|
||||||
|
@ -1285,6 +1285,8 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
|||||||
|
|
||||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||||
{
|
{
|
||||||
|
if (stmt->list.size() == 0) return;
|
||||||
|
|
||||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||||
{
|
{
|
||||||
if (stmt->list.at(i) == ast::kind::asm_jump)
|
if (stmt->list.at(i) == ast::kind::asm_jump)
|
||||||
@ -1516,6 +1518,22 @@ void decompiler::decompile_devblocks(const ast::stmt_list::ptr& stmt)
|
|||||||
decompile_statements(list_stmt);
|
decompile_statements(list_stmt);
|
||||||
blocks_.pop_back();
|
blocks_.pop_back();
|
||||||
|
|
||||||
|
if (list_stmt->list.size() == 1 && list_stmt->list.at(0) == ast::kind::stmt_call)
|
||||||
|
{
|
||||||
|
const auto& st = list_stmt->list.at(0);
|
||||||
|
|
||||||
|
if (st.as_call->expr == ast::kind::expr_call && st.as_call->expr.as_call->call == ast::kind::expr_function)
|
||||||
|
{
|
||||||
|
if (st.as_call->expr.as_call->call.as_function->name->value == "assert")
|
||||||
|
{
|
||||||
|
auto new_stmt = ast::stmt(std::make_unique<ast::stmt_call>(loc, std::move(st.as_call->expr)));
|
||||||
|
stmt->list.insert(stmt->list.begin() + i, std::move(new_stmt));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto new_stmt = ast::stmt(std::make_unique<ast::stmt_dev>(loc, std::move(list_stmt)));
|
auto new_stmt = ast::stmt(std::make_unique<ast::stmt_dev>(loc, std::move(list_stmt)));
|
||||||
stmt->list.insert(stmt->list.begin() + i, std::move(new_stmt));
|
stmt->list.insert(stmt->list.begin() + i, std::move(new_stmt));
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ auto disassembler::output_raw() -> std::vector<std::uint8_t>
|
|||||||
std::vector<std::uint8_t> output;
|
std::vector<std::uint8_t> output;
|
||||||
|
|
||||||
output.resize(output_->pos());
|
output.resize(output_->pos());
|
||||||
memcpy(output.data(), output_->buffer().data(), output.size());
|
std::memcpy(output.data(), output_->buffer().data(), output.size());
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user