📝 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) {
@ -196,18 +197,21 @@ void codegen::func_gen(function* node) {
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());
} }
} }