update

This commit is contained in:
ValKmjolnir 2023-06-30 00:25:58 +08:00
parent 5d9267d3b9
commit 8e4e4bfe89
9 changed files with 206 additions and 203 deletions

View File

@ -379,7 +379,7 @@ bool ast_dumper::visit_iter_expr(iter_expr* node) {
bool ast_dumper::visit_forei_expr(forei_expr* node) {
dump_indent();
if (node->get_type()==forei_expr::forei_loop_type::foreach) {
if (node->get_loop_type()==forei_expr::forei_loop_type::foreach) {
std::cout << "foreach";
} else {
std::cout << "forindex";

View File

@ -583,11 +583,11 @@ public:
type(forei_loop_type::foreach), iterator(nullptr),
vector_node(nullptr), block(nullptr) {}
~forei_expr();
void set_type(forei_loop_type ft) {type = ft;}
void set_loop_type(forei_loop_type ft) {type = ft;}
void set_iterator(iter_expr* node) {iterator = node;}
void set_value(expr* node) {vector_node = node;}
void set_code_block(code_block* node) {block = node;}
forei_loop_type get_type() const {return type;}
forei_loop_type get_loop_type() const {return type;}
iter_expr* get_iterator() {return iterator;}
expr* get_value() {return vector_node;}
code_block* get_code_block() {return block;}

View File

@ -1,17 +1,19 @@
#include "nasal_new_codegen.h"
bool codegen::check_memory_reachable(call_expr* node) {
if (node->get_type()==expr_type::ast_call) {
const ast& tmp=node.child().back();
if (node->get_first()->get_type()==expr_type::ast_call) {
const auto tmp=node->get_calls().back();
if (tmp->get_type()==expr_type::ast_callf) {
die("bad left-value with function call", node->get_location());
return false;
}
if (tmp->get_type()==expr_type::ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0]->get_type()==expr_type::ast_subvec)) {
if (tmp->get_type()==expr_type::ast_callv &&
(((call_vector*)tmp)->get_slices().size()!=1 ||
((call_vector*)tmp)->get_slices()[0]->get_end())) {
die("bad left-value with subvec", node->get_location());
return false;
}
} else if (node->get_type()!=ast_id) {
} else if (node->get_first()->get_type()!=expr_type::ast_id) {
die("bad left-value", node->get_location());
return false;
}
@ -186,20 +188,20 @@ void codegen::func_gen(function* node) {
// generate parameter list
for(auto& tmp : node->get_parameter_list()) {
const std::string& str=tmp.str();
const auto& str = tmp->get_parameter_name();
if (str=="me") {
die("\"me\" should not be a parameter", tmp->get_location());
}
regist_str(str);
switch(tmp->get_type()) {
case expr_type::ast_id:
switch(tmp->get_parameter_type()) {
case parameter::param_type::normal_parameter:
gen(op_para, str_table[str], tmp->get_location().begin_line);
break;
case expr_type::ast_default:
calc_gen(tmp[0]);
case parameter::param_type::default_parameter:
calc_gen(tmp->get_default_value());
gen(op_deft, str_table[str], tmp->get_location().begin_line);
break;
case expr_type::ast_dynamic:
case parameter::param_type::dynamic_parameter:
gen(op_dyn, str_table[str], tmp->get_location().begin_line);
break;
}
@ -223,7 +225,8 @@ void codegen::func_gen(function* node) {
}
local.pop_back();
if (!block.size() || block.child().back()->get_type()!=ast_ret) {
if (!block->get_expressions().size() ||
block->get_expressions().back()->get_type()!=expr_type::ast_ret) {
gen(op_pnil, 0, block->get_location().begin_line);
gen(op_ret, 0, block->get_location().begin_line);
}
@ -245,9 +248,9 @@ void codegen::call_gen(call_expr* node) {
}
void codegen::call_id(identifier* node) {
const auto& name = node->get_location();
for(u32 i=0;builtin[i].name;++i) {
if (builtin[i].name==str) {
const auto& name = node->get_name();
for(u32 i=0; builtin[i].name; ++i) {
if (builtin[i].name==name) {
gen(op_callb, i, node->get_location().begin_line);
if (local.empty()) {
die("should warp native function in local scope", node->get_location());
@ -256,41 +259,42 @@ void codegen::call_id(identifier* node) {
}
}
i32 index;
if ((index=local_find(str))>=0) {
if ((index=local_find(name))>=0) {
gen(op_calll, index, node->get_location().begin_line);
return;
}
if ((index=upvalue_find(str))>=0) {
if ((index=upvalue_find(name))>=0) {
gen(op_upval, index, node->get_location().begin_line);
return;
}
if ((index=global_find(str))>=0) {
if ((index=global_find(name))>=0) {
gen(op_callg, index, node->get_location().begin_line);
return;
}
die("undefined symbol \""+str+"\"", node->get_location());
die("undefined symbol \"" + name + "\"", node->get_location());
}
void codegen::call_hash_gen(call_hash* node) {
regist_str(node.str());
gen(op_callh, str_table[node.str()], node->get_location().begin_line);
regist_str(node->get_field());
gen(op_callh, str_table[node->get_field()], node->get_location().begin_line);
}
void codegen::call_vec(call_vector* node) {
// maybe this place can use callv-const if ast's first child is ast_num
if (node.size()==1 && node[0]->get_type()!=ast_subvec) {
calc_gen(node[0]);
gen(op_callv, 0, node[0]->get_location().begin_line);
if (node->get_slices().size()==1 &&
!node->get_slices()[0]->get_end()) {
calc_gen(node->get_slices()[0]->get_begin());
gen(op_callv, 0, node->get_slices()[0]->get_location().begin_line);
return;
}
gen(op_slcbeg,0,node->get_location().begin_line);
for(auto& tmp:node.child()) {
if (tmp->get_type()!=ast_subvec) {
calc_gen(tmp);
for(auto tmp : node->get_slices()) {
if (!tmp->get_end()) {
calc_gen(tmp->get_begin());
gen(op_slc, 0, tmp->get_location().begin_line);
} else {
calc_gen(tmp[0]);
calc_gen(tmp[1]);
calc_gen(tmp->get_begin());
calc_gen(tmp->get_end());
gen(op_slc2, 0, tmp->get_location().begin_line);
}
}
@ -298,16 +302,21 @@ void codegen::call_vec(call_vector* node) {
}
void codegen::call_func(call_function* node) {
if (!node.size()) {
gen(op_callfv, 0, node->get_location().begin_line);
} else if (node[0]->get_type()==expr_type::ast_pair) {
hash_gen(node);
if (node->get_argument().size() &&
node->get_argument()[0]->get_type()==expr_type::ast_pair) {
gen(op_newh, 0, node->get_location().begin_line);
for(auto child : node->get_argument()) {
calc_gen(((hash_pair*)child)->get_value());
const auto& str = ((hash_pair*)child)->get_name();
regist_str(str);
gen(op_happ, str_table[str], child->get_location().begin_line);
}
gen(op_callfh, 0, node->get_location().begin_line);
} else {
for(auto& child:node.child()) {
for(auto child : node->get_argument()) {
calc_gen(child);
}
gen(op_callfv, node.size(), node->get_location().begin_line);
gen(op_callfv, node->get_argument().size(), node->get_location().begin_line);
}
}
@ -323,28 +332,24 @@ void codegen::mcall(call_expr* node) {
if (!check_memory_reachable(node)) {
return;
}
if (node->get_type()==expr_type::ast_id) {
mcall_id(node);
return;
if (node->get_first()->get_type()==expr_type::ast_id &&
!node->get_calls().size()) {
mcall_id((identifier*)node->get_first());
}
if (node.size()==1) { // foreach and forindex use call-id ast to get mcall
mcall_id(node[0]);
return;
}
calc_gen(node[0]);
for(usize i=1;i<node.size()-1;++i) {
const ast& tmp=node[i];
calc_gen(node->get_first());
for(usize i = 0; i<node->get_calls().size()-1; ++i) {
auto tmp = node->get_calls()[i];
switch(tmp->get_type()) {
case expr_type::ast_callh:call_hash(tmp);break;
case expr_type::ast_callv:call_vec(tmp); break;
case expr_type::ast_callf:call_func(tmp);break;
case expr_type::ast_callh: call_hash_gen((call_hash*)tmp); break;
case expr_type::ast_callv: call_vec((call_vector*)tmp); break;
case expr_type::ast_callf: call_func((call_function*)tmp); break;
}
}
const ast& tmp=node.child().back();
auto tmp = node->get_calls().back();
if (tmp->get_type()==expr_type::ast_callh) {
mcall_hash(tmp);
mcall_hash((call_hash*)tmp);
} else if (tmp->get_type()==expr_type::ast_callv) {
mcall_vec(tmp);
mcall_vec((call_vector*)tmp);
}
}
@ -373,13 +378,13 @@ void codegen::mcall_id(identifier* node) {
}
void codegen::mcall_vec(call_vector* node) {
calc_gen(node[0]);
calc_gen(node->get_slices()[0]);
gen(op_mcallv, 0, node->get_location().begin_line);
}
void codegen::mcall_hash(call_hash* node) {
regist_str(node.str());
gen(op_mcallh, str_table[node.str()], node->get_location().begin_line);
regist_str(node->get_field());
gen(op_mcallh, str_table[node->get_field()], node->get_location().begin_line);
}
void codegen::single_def(definition_expr* node) {
@ -391,32 +396,27 @@ void codegen::single_def(definition_expr* node) {
}
void codegen::multi_def(definition_expr* node) {
auto& ids=node[0].child();
usize size=ids.size();
if (node[1]->get_type()==expr_type::ast_tuple) { // (var a,b,c)=(c,b,a);
auto& vals=node[1].child();
for(usize i=0;i<size;++i) {
// check node type, only identifier is allowed
if (ids[i]->get_type()!=ast_id) {
die("cannot call identifier in multi-definition", ids[i]->get_location());
continue;
}
auto& ids = node->get_variables()->get_variables();
usize size = ids.size();
if (node->get_value()->get_type()==expr_type::ast_tuple) { // (var a,b,c)=(c,b,a);
auto& vals = ((tuple_expr*)node->get_value())->get_elements();
if (ids.size()<vals.size()) {
die("lack values in multi-definition", node->get_value()->get_location());
} else if (ids.size()>vals.size()) {
die("too many values in multi-definition", node->get_value()->get_location());
}
for(usize i = 0; i<size; ++i) {
calc_gen(vals[i]);
const std::string& str=ids[i].str();
const auto& str = ids[i]->get_name();
local.empty()?
gen(op_loadg, global_find(str), ids[i]->get_location().begin_line):
gen(op_loadl, local_find(str), ids[i]->get_location().begin_line);
}
} else { // (var a,b,c)=[0,1,2];
calc_gen(node[1]);
for(usize i=0;i<size;++i) {
// check node type, only identifier is allowed
if (ids[i]->get_type()!=ast_id) {
die("cannot call identifier in multi-definition", ids[i]->get_location());
continue;
}
gen(op_callvi, i, node[1]->get_location().begin_line);
const std::string& str=ids[i].str();
calc_gen(node->get_value());
for(usize i = 0; i<size; ++i) {
gen(op_callvi, i, node->get_value()->get_location().begin_line);
const auto& str = ids[i]->get_name();
local.empty()?
gen(op_loadg, global_find(str), ids[i]->get_location().begin_line):
gen(op_loadl, local_find(str), ids[i]->get_location().begin_line);
@ -426,14 +426,11 @@ void codegen::multi_def(definition_expr* node) {
}
void codegen::def_gen(definition_expr* node) {
if (node[0]->get_type()==expr_type::ast_id && node[1]->get_type()==expr_type::ast_tuple) {
die("cannot accept too many values", node[1]->get_location());
} else if (node[0]->get_type()==expr_type::ast_multi_id && node[1]->get_type()==expr_type::ast_tuple && node[0].size()<node[1].size()) {
die("lack values in multi-definition", node[1]->get_location());
} else if (node[0]->get_type()==expr_type::ast_multi_id && node[1]->get_type()==expr_type::ast_tuple && node[0].size()>node[1].size()) {
die("too many values in multi-definition", node[1]->get_location());
if (node->get_variable_name() &&
node->get_value()->get_type()==expr_type::ast_tuple) {
die("cannot accept too many values", node->get_value()->get_location());
}
node[0]->get_type()==expr_type::ast_id?single_def(node):multi_def(node);
node->get_variable_name()? single_def(node):multi_def(node);
}
void codegen::multi_assign_gen(multi_assign* node) {
@ -510,10 +507,17 @@ void codegen::loop_gen(expr* node) {
continue_ptr.push_front({});
break_ptr.push_front({});
switch(node->get_type()) {
case expr_type::ast_while: while_gen(node); break;
case expr_type::ast_for: for_gen(node); break;
case expr_type::ast_forindex:forindex_gen(node);break;
case expr_type::ast_foreach: foreach_gen(node); break;
case expr_type::ast_while:
while_gen((while_expr*)node); break;
case expr_type::ast_for:
for_gen((for_expr*)node); break;
case expr_type::ast_forei:
if (((forei_expr*)node)->get_loop_type()==forei_expr::forei_loop_type::forindex) {
forindex_gen((forei_expr*)node);
} else {
foreach_gen((forei_expr*)node);
}
break;
}
}
@ -530,31 +534,31 @@ void codegen::load_continue_break(i32 continue_place,i32 break_place) {
void codegen::while_gen(while_expr* node) {
usize loop_ptr=code.size();
calc_gen(node[0]);
calc_gen(node->get_condition());
usize condition_ptr=code.size();
gen(op_jf, 0, node[0]->get_location().begin_line);
gen(op_jf, 0, node->get_condition()->get_location().begin_line);
block_gen(node[1]);
gen(op_jmp, loop_ptr, node[1]->get_location().begin_line);
block_gen(node->get_code_block());
gen(op_jmp, loop_ptr, node->get_code_block()->get_location().begin_line);
code[condition_ptr].num=code.size();
load_continue_break(code.size()-1, code.size());
}
void codegen::for_gen(for_expr* node) {
expr_gen(node[0]);
expr_gen(node->get_initial());
usize jmp_place=code.size();
if (node[1]->get_type()==expr_type::ast_null) {
gen(op_pnum, num_table[1], node[1]->get_location().begin_line);
if (node->get_condition()->get_type()==expr_type::ast_null) {
gen(op_pnum, num_table[1], node->get_condition()->get_location().begin_line);
} else {
calc_gen(node[1]);
calc_gen(node->get_condition());
}
usize label_exit=code.size();
gen(op_jf, 0, node[1]->get_location().begin_line);
gen(op_jf, 0, node->get_condition()->get_location().begin_line);
block_gen(node[3]);
block_gen(node->get_code_block());
usize continue_place=code.size();
expr_gen(node[2]);
gen(op_jmp, jmp_place, node[2]->get_location().begin_line);
expr_gen(node->get_step());
gen(op_jmp, jmp_place, node->get_step()->get_location().begin_line);
code[label_exit].num=code.size();
load_continue_break(continue_place, code.size());
@ -563,30 +567,15 @@ void codegen::for_gen(for_expr* node) {
void codegen::expr_gen(expr* node) {
switch(node->get_type()) {
case expr_type::ast_null:break;
case expr_type::ast_def:def_gen(node);break;
case expr_type::ast_multi_assign:multi_assign_gen(node);break;
case expr_type::ast_addeq:case expr_type::ast_subeq:
case expr_type::ast_multeq:case expr_type::ast_diveq:case expr_type::ast_lnkeq:
case expr_type::ast_btandeq:case expr_type::ast_btoreq:case expr_type::ast_btxoreq:
calc_gen(node);
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
code.back().num=1;
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
code.back().op=code.back().op-op_addeqc+op_addecp;
} else {
gen(op_pop, 0, node->get_location().begin_line);
}
break;
case expr_type::ast_def:
def_gen((definition_expr*)node);break;
case expr_type::ast_multi_assign:
multi_assign_gen((multi_assign*)node);break;
case expr_type::ast_nil:case expr_type::ast_num:case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_vec:case expr_type::ast_hash:case expr_type::ast_func:case expr_type::ast_call:
case expr_type::ast_neg:case expr_type::ast_lnot:case expr_type::ast_bnot:
case expr_type::ast_bitor:case expr_type::ast_bitxor:case expr_type::ast_bitand:
case expr_type::ast_add:case expr_type::ast_sub:case expr_type::ast_mult:case expr_type::ast_div:case expr_type::ast_link:
case expr_type::ast_cmpeq:case expr_type::ast_neq:
case expr_type::ast_leq:case expr_type::ast_less:
case expr_type::ast_geq:case expr_type::ast_grt:
case expr_type::ast_or:case expr_type::ast_and:
case expr_type::ast_trino:
case expr_type::ast_unary:
case expr_type::ast_binary:
case expr_type::ast_ternary:
calc_gen(node);
gen(op_pop, 0, node->get_location().begin_line);
break;
@ -611,21 +600,33 @@ void codegen::expr_gen(expr* node) {
}
}
break;
case expr_type::ast_addeq:case expr_type::ast_subeq:
case expr_type::ast_multeq:case expr_type::ast_diveq:case expr_type::ast_lnkeq:
case expr_type::ast_btandeq:case expr_type::ast_btoreq:case expr_type::ast_btxoreq:
calc_gen(node);
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
code.back().num=1;
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
code.back().op=code.back().op-op_addeqc+op_addecp;
} else {
gen(op_pop, 0, node->get_location().begin_line);
}
break;
}
}
void codegen::forindex_gen(forei_expr* node) {
calc_gen(node[1]);
gen(op_cnt, 0, node[1]->get_location().begin_line);
usize ptr=code.size();
calc_gen(node->get_value());
gen(op_cnt, 0, node->get_value()->get_location().begin_line);
usize ptr = code.size();
gen(op_findex, 0, node->get_location().begin_line);
if (node[0]->get_type()==expr_type::ast_iter) { // define a new iterator
const std::string& str=node[0][0].str();
if (node->get_iterator()->get_name()) { // define a new iterator
const auto& str = node->get_iterator()->get_name()->get_name();
local.empty()?
gen(op_loadg, global_find(str), node[0][0]->get_location().begin_line):
gen(op_loadl, local_find(str), node[0][0]->get_location().begin_line);
gen(op_loadg, global_find(str), node->get_iterator()->get_name()->get_location().begin_line):
gen(op_loadl, local_find(str), node->get_iterator()->get_name()->get_location().begin_line);
} else { // use exist variable as the iterator
mcall(node[0]);
mcall((call_expr*)node->get_iterator()->get_call());
if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else if (code.back().op==op_mcalll) {
@ -633,31 +634,31 @@ void codegen::forindex_gen(forei_expr* node) {
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
gen(op_meq, 1, node[0]->get_location().begin_line);
gen(op_meq, 1, node->get_iterator()->get_location().begin_line);
}
}
++in_iterloop.top();
block_gen(node[2]);
block_gen(node->get_code_block());
--in_iterloop.top();
gen(op_jmp, ptr, node->get_location().begin_line);
code[ptr].num=code.size();
load_continue_break(code.size()-1, code.size());
gen(op_pop, 0, node[1]->get_location().begin_line);// pop vector
gen(op_pop, 0, node->get_value()->get_location().begin_line);// pop vector
gen(op_pop, 0, node->get_location().begin_line);// pop iterator
}
void codegen::foreach_gen(forei_expr* node) {
calc_gen(node[1]);
calc_gen(node->get_value());
gen(op_cnt, 0, node->get_location().begin_line);
usize ptr=code.size();
usize ptr = code.size();
gen(op_feach, 0, node->get_location().begin_line);
if (node[0]->get_type()==expr_type::ast_iter) { // define a new iterator
const std::string& str=node[0][0].str();
if (node->get_iterator()->get_name()) { // define a new iterator
const auto& str = node->get_iterator()->get_name()->get_name();
local.empty()?
gen(op_loadg, global_find(str), node[0][0]->get_location().begin_line):
gen(op_loadl, local_find(str), node[0][0]->get_location().begin_line);
gen(op_loadg, global_find(str), node->get_iterator()->get_name()->get_location().begin_line):
gen(op_loadl, local_find(str), node->get_iterator()->get_name()->get_location().begin_line);
} else { // use exist variable as the iterator
mcall(node[0]);
mcall((call_expr*)node->get_iterator()->get_call());
if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else if (code.back().op==op_mcalll) {
@ -665,17 +666,17 @@ void codegen::foreach_gen(forei_expr* node) {
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
gen(op_meq, 1, node[0]->get_location().begin_line);
gen(op_meq, 1, node->get_iterator()->get_location().begin_line);
}
}
++in_iterloop.top();
block_gen(node[2]);
block_gen(node->get_code_block());
--in_iterloop.top();
gen(op_jmp, ptr, node->get_location().begin_line);
code[ptr].num=code.size();
load_continue_break(code.size()-1, code.size());
gen(op_pop, 0, node[1]->get_location().begin_line);// pop vector
gen(op_pop, 0, node->get_location().begin_line);// pop iterator
gen(op_pop, 0, node->get_value()->get_location().begin_line); // pop vector
gen(op_pop, 0, node->get_location().begin_line); // pop iterator
}
void codegen::or_gen(binary_operator* node) {
@ -725,15 +726,24 @@ void codegen::trino_gen(ternary_operator* node) {
void codegen::calc_gen(expr* node) {
switch(node->get_type()) {
case expr_type::ast_nil: gen(op_pnil,0,node->get_location().begin_line);break;
case expr_type::ast_num: num_gen(node); break;
case expr_type::ast_str: str_gen(node); break;
case expr_type::ast_id: call_id(node); break;
case expr_type::ast_bool: bool_gen(node); break;
case expr_type::ast_vec: vec_gen(node); break;
case expr_type::ast_hash: hash_gen(node); break;
case expr_type::ast_func: func_gen(node); break;
case expr_type::ast_call: call_gen(node); break;
case expr_type::ast_nil:
gen(op_pnil,0,node->get_location().begin_line); break;
case expr_type::ast_num:
num_gen((number_literal*)node); break;
case expr_type::ast_str:
str_gen((string_literal*)node); break;
case expr_type::ast_id:
call_id((identifier*)node); break;
case expr_type::ast_bool:
bool_gen((bool_literal*)node); break;
case expr_type::ast_vec:
vec_gen((vector_expr*)node); break;
case expr_type::ast_hash:
hash_gen((hash_expr*)node); break;
case expr_type::ast_func:
func_gen((function*)node); break;
case expr_type::ast_call:
call_gen((call_expr*)node); break;
case expr_type::ast_equal:
calc_gen(node[1]);
mcall(node[0]);
@ -809,7 +819,8 @@ void codegen::calc_gen(expr* node) {
gen(node->get_type()-ast_less+op_lessc, num_table[node[1].num()], node->get_location().begin_line);
}
break;
case expr_type::ast_trino:trino_gen(node);break;
case expr_type::ast_ternary:
trino_gen((ternary_operator*)node);break;
case expr_type::ast_neg:
calc_gen(node[0]);
gen(op_usub, 0, node->get_location().begin_line);
@ -838,20 +849,24 @@ void codegen::calc_gen(expr* node) {
gen(op_btand, 0, node->get_location().begin_line);
break;
case expr_type::ast_def:
single_def(node);
call_id(node[0]);
single_def((definition_expr*)node);
call_id(((definition_expr*)node)->get_variable_name());
break;
}
}
void codegen::block_gen(code_block* node) {
for(auto& tmp:node.child()) {
for(auto tmp : node->get_expressions()) {
switch(tmp->get_type()) {
case expr_type::ast_null:break;
case expr_type::ast_id:check_id_exist(tmp);break;
case expr_type::ast_nil:case expr_type::ast_num:case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_file:fileindex=tmp.num();break; // special node type in main block
case expr_type::ast_cond:cond_gen(tmp);break;
case expr_type::ast_id:
check_id_exist((identifier*)tmp); break;
case expr_type::ast_nil:case expr_type::ast_num:
case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_file_info:
fileindex = ((file_info*)tmp)->get_index();break; // special node type in main block
case expr_type::ast_cond:
cond_gen((condition_expr*)tmp); break;
case expr_type::ast_continue:
continue_ptr.front().push_back(code.size());
gen(op_jmp, 0, tmp->get_location().begin_line);
@ -862,43 +877,32 @@ void codegen::block_gen(code_block* node) {
break;
case expr_type::ast_while:
case expr_type::ast_for:
case expr_type::ast_forindex:
case expr_type::ast_foreach:loop_gen(tmp);break;
case expr_type::ast_equal:
case expr_type::ast_addeq:case expr_type::ast_subeq:
case expr_type::ast_multeq:case expr_type::ast_diveq:case expr_type::ast_lnkeq:
case expr_type::ast_btandeq:case expr_type::ast_btoreq:case expr_type::ast_btxoreq:
case expr_type::ast_vec:case expr_type::ast_hash:case expr_type::ast_func:case expr_type::ast_call:
case expr_type::ast_neg:case expr_type::ast_lnot:case expr_type::ast_bnot:
case expr_type::ast_bitor:case expr_type::ast_bitxor:case expr_type::ast_bitand:
case expr_type::ast_add:case expr_type::ast_sub:case expr_type::ast_mult:case expr_type::ast_div:case expr_type::ast_link:
case expr_type::ast_cmpeq:case expr_type::ast_neq:
case expr_type::ast_leq:case expr_type::ast_less:
case expr_type::ast_geq:case expr_type::ast_grt:
case expr_type::ast_or:
case expr_type::ast_and:
case expr_type::ast_trino:
case expr_type::ast_forei:
loop_gen(tmp); break;
case expr_type::ast_binary:
case expr_type::ast_vec:case expr_type::ast_hash:
case expr_type::ast_func:case expr_type::ast_call:
case expr_type::ast_unary:
case expr_type::ast_ternary:
case expr_type::ast_def:
case expr_type::ast_multi_assign:expr_gen(tmp);break;
case expr_type::ast_ret:ret_gen(tmp);break;
case expr_type::ast_multi_assign:
expr_gen(tmp); break;
case expr_type::ast_ret:
ret_gen((return_expr*)tmp); break;
}
}
}
void codegen::ret_gen(const ast& node) {
void codegen::ret_gen(return_expr* node) {
for(u32 i=0;i<in_iterloop.top();++i) {
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_location().begin_line);
}
if (node.size()) {
calc_gen(node[0]);
} else {
gen(op_pnil, 0, node->get_location().begin_line);
}
calc_gen(node->get_value());
gen(op_ret, 0, node->get_location().begin_line);
}
const error& codegen::compile(const parse& parse, const linker& import) {
const error& codegen::compile(parse& parse, linker& import) {
fileindex=0;
file=import.filelist().data();
in_iterloop.push(0);

View File

@ -93,7 +93,7 @@ private:
public:
codegen(error& e): fileindex(0), err(e), file(nullptr) {}
const error& compile(const parse&, const linker&);
const error& compile(parse&, linker&);
void print();
const std::vector<std::string>& strs() const {return str_res;}
const std::vector<f64>& nums() const {return num_res;}

View File

@ -26,6 +26,7 @@
#include <unordered_map>
#include <chrono>
#include <algorithm>
#include <thread>
#include "nasal_new_header.h"
#include "nasal_new_err.h"
@ -362,11 +363,11 @@ private:
void mark();
void mark_context(std::vector<var>&);
void mark_var(std::vector<var>&, var&);
inline void mark_vec(std::vector<var>&, nas_vec&);
inline void mark_hash(std::vector<var>&, nas_hash&);
inline void mark_func(std::vector<var>&, nas_func&);
inline void mark_upval(std::vector<var>&, nas_upval&);
inline void mark_co(std::vector<var>&, nas_co&);
void mark_vec(std::vector<var>&, nas_vec&);
void mark_hash(std::vector<var>&, nas_hash&);
void mark_func(std::vector<var>&, nas_func&);
void mark_upval(std::vector<var>&, nas_upval&);
void mark_co(std::vector<var>&, nas_co&);
void sweep();
public:

View File

@ -32,7 +32,7 @@ using u64 = std::uint64_t;
using usize = std::size_t;
using f64 = double;
const u32 STACK_DEPTH=1024;
const u32 STACK_DEPTH=4096;
f64 hex2f(const char*);
f64 oct2f(const char*);

View File

@ -907,11 +907,11 @@ forei_expr* parse::forei_loop() {
auto node = new forei_expr(toks[ptr].loc);
switch(toks[ptr].type) {
case tok::forindex:
node->set_type(forei_expr::forei_loop_type::forindex);
node->set_loop_type(forei_expr::forei_loop_type::forindex);
match(tok::forindex);
break;
case tok::foreach:
node->set_type(forei_expr::forei_loop_type::foreach);
node->set_loop_type(forei_expr::forei_loop_type::foreach);
match(tok::foreach);
break;
default: break;

View File

@ -1,10 +1,10 @@
#include "optimizer.h"
void const_string(binary_operator* node) {
void optimizer::const_string(binary_operator* node) {
}
void const_number(binary_operator* node) {
void optimizer::const_number(binary_operator* node) {
}

View File

@ -105,7 +105,7 @@ bool codegen::check_memory_reachable(const ast& node) {
die("bad left-value with function call", node.location());
return false;
}
if (tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)) {
if (tmp.type()==ast_callv && (tmp.size()!=1 || tmp[0].type()==ast_subvec)) {
die("bad left-value with subvec", node.location());
return false;
}
@ -413,16 +413,14 @@ void codegen::call_vec(const ast& node) {
}
void codegen::call_func(const ast& node) {
if (!node.size()) {
gen(op_callfv, 0, node.line());
} else if (node[0].type()==ast_pair) {
hash_gen(node);
gen(op_callfh, 0, node.line());
} else {
if (!node.size() || node[0].type()!=ast_pair) {
for(auto& child:node.child()) {
calc_gen(child);
}
gen(op_callfv, node.size(), node.line());
} else if (node[0].type()==ast_pair) {
hash_gen(node);
gen(op_callfh, 0, node.line());
}
}