📝 improve note and code in codegen

This commit is contained in:
ValKmjolnir 2023-09-27 00:26:13 +08:00
parent 5e2bb411e5
commit 7a10392bea
1 changed files with 28 additions and 20 deletions

View File

@ -54,7 +54,8 @@ void codegen::check_id_exist(identifier* node) {
} }
die("undefined symbol \"" + name + die("undefined symbol \"" + name +
"\", and this symbol is useless here", "\", and this symbol is useless here",
node->get_location()); node->get_location()
);
} }
void codegen::regist_num(const f64 num) { void codegen::regist_num(const f64 num) {
@ -186,28 +187,31 @@ void codegen::func_gen(function* node) {
for(auto tmp : node->get_parameter_list()) { for(auto tmp : node->get_parameter_list()) {
if (tmp->get_parameter_type()== if (tmp->get_parameter_type()==
parameter::param_type::default_parameter) { parameter::param_type::default_parameter) {
checked_default=true; checked_default = true;
} else if (tmp->get_parameter_type()== } else if (tmp->get_parameter_type()==
parameter::param_type::dynamic_parameter) { parameter::param_type::dynamic_parameter) {
checked_dynamic=true; checked_dynamic = true;
} }
// check default parameter and dynamic parameter // check default parameter and dynamic parameter
if (checked_default && if (checked_default &&
tmp->get_parameter_type()!= tmp->get_parameter_type()!=
parameter::param_type::default_parameter) { parameter::param_type::default_parameter) {
die("must use default parameter here", die("must use default parameter here",
tmp->get_location()); tmp->get_location()
);
} }
if (checked_dynamic && if (checked_dynamic &&
tmp!=node->get_parameter_list().back()) { tmp!=node->get_parameter_list().back()) {
die("dynamic parameter must be the last one", die("dynamic parameter must be the last one",
tmp->get_location()); tmp->get_location()
);
} }
// check redefinition // check redefinition
const auto& name = tmp->get_parameter_name(); const auto& name = tmp->get_parameter_name();
if (argname.count(name)) { if (argname.count(name)) {
die("redefinition of parameter: " + name, die("redefinition of parameter: " + name,
tmp->get_location()); tmp->get_location()
);
} else { } else {
argname[name] = true; argname[name] = true;
} }
@ -230,7 +234,8 @@ void codegen::func_gen(function* node) {
const auto& name = tmp->get_parameter_name(); const auto& name = tmp->get_parameter_name();
if (name=="me") { if (name=="me") {
die("\"me\" should not be a parameter", die("\"me\" should not be a parameter",
tmp->get_location()); tmp->get_location()
);
} }
regist_str(name); regist_str(name);
switch(tmp->get_parameter_type()) { switch(tmp->get_parameter_type()) {
@ -279,7 +284,8 @@ void codegen::func_gen(function* node) {
code[lsize].num = local.back().size(); code[lsize].num = local.back().size();
if (local.back().size()>=STACK_DEPTH) { if (local.back().size()>=STACK_DEPTH) {
die("too many local variants: " + die("too many local variants: " +
std::to_string(local.back().size()), block->get_location()); std::to_string(local.back().size()), block->get_location()
);
} }
local.pop_back(); local.pop_back();
@ -394,14 +400,16 @@ void codegen::call_func_gen(call_function* node) {
void codegen::mcall(expr* node) { void codegen::mcall(expr* node) {
if (node->get_type()!=expr_type::ast_id && if (node->get_type()!=expr_type::ast_id &&
node->get_type()!=expr_type::ast_call) { node->get_type()!=expr_type::ast_call) {
die("bad left-value", node->get_location()); die("bad left-value: cannot get memory space", node->get_location());
return; return;
} }
// generate symbol call if node is just ast_id and return
if (node->get_type()==expr_type::ast_id) { if (node->get_type()==expr_type::ast_id) {
mcall_id((identifier*)node); mcall_id((identifier*)node);
return; return;
} }
auto call_node = (call_expr*)node; // generate call expression until the last sub-node
auto call_node = static_cast<call_expr*>(node);
calc_gen(call_node->get_first()); calc_gen(call_node->get_first());
for(usize i = 0; i<call_node->get_calls().size()-1; ++i) { for(usize i = 0; i<call_node->get_calls().size()-1; ++i) {
auto tmp = call_node->get_calls()[i]; auto tmp = call_node->get_calls()[i];
@ -412,15 +420,15 @@ void codegen::mcall(expr* node) {
default: break; default: break;
} }
} }
// the last sub-node will be used to generate memory call expression
auto tmp = call_node->get_calls().back(); auto tmp = call_node->get_calls().back();
if (tmp->get_type()==expr_type::ast_callh) { switch(tmp->get_type()) {
mcall_hash((call_hash*)tmp); case expr_type::ast_callh: mcall_hash((call_hash*)tmp); break;
} else if (tmp->get_type()==expr_type::ast_callv) { case expr_type::ast_callv: mcall_vec((call_vector*)tmp); break;
mcall_vec((call_vector*)tmp); case expr_type::ast_callf:
} else if (tmp->get_type()==expr_type::ast_callf) { die("bad left-value: function call", tmp->get_location()); break;
die("bad left-value: function call", tmp->get_location()); default:
} else { die("bad left-value: unknown call", tmp->get_location()); break;
die("bad left-value: unknown call", tmp->get_location());
} }
} }
@ -666,9 +674,9 @@ void codegen::assignment_statement(assignment_expr* node) {
case assignment_expr::assign_type::bitwise_xor_equal: case assignment_expr::assign_type::bitwise_xor_equal:
calc_gen(node); calc_gen(node);
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) { if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
code.back().num=1; code.back().num = 1;
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) { } else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
code.back().op=code.back().op-op_addeqc+op_addecp; code.back().op = code.back().op-op_addeqc+op_addecp;
} else { } else {
emit(op_pop, 0, node->get_location()); emit(op_pop, 0, node->get_location());
} }