diff --git a/ast/nasal_new_ast.h b/ast/nasal_new_ast.h index 2051d77..f1dc306 100644 --- a/ast/nasal_new_ast.h +++ b/ast/nasal_new_ast.h @@ -66,6 +66,7 @@ public: nd_loc.begin_column = column; } const span& get_location() const {return nd_loc;} + const u32 get_line() const {return nd_loc.begin_line;} expr_type get_type() const {return nd_type;} void update_location(const span& location) { nd_loc.end_line = location.end_line; diff --git a/ast/nasal_new_codegen.cpp b/ast/nasal_new_codegen.cpp index ea80e20..abc4207 100644 --- a/ast/nasal_new_codegen.cpp +++ b/ast/nasal_new_codegen.cpp @@ -1,31 +1,12 @@ #include "nasal_new_codegen.h" -bool codegen::check_memory_reachable(expr* node) { - if (node->get_type()==expr_type::ast_call) { - const auto tmp=((call_expr*)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 && - (((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()!=expr_type::ast_id) { - die("bad left-value", node->get_location()); - return false; - } - return true; -} - void codegen::check_id_exist(identifier* node) { const auto& name = node->get_name(); - for(u32 i=0;builtin[i].name;++i) { + for(u32 i = 0; builtin[i].name; ++i) { if (builtin[i].name==name) { if (local.empty()) { - die("useless native function used in global scope", node->get_location()); + die("native function used in global scope", + node->get_location()); } return; } @@ -40,21 +21,23 @@ void codegen::check_id_exist(identifier* node) { if (global_find(name)>=0) { return; } - die("undefined symbol \"" + name + "\", and this symbol is useless here", node->get_location()); + die("undefined symbol \"" + name + + "\", and this symbol is useless here", + node->get_location()); } void codegen::regist_num(const f64 num) { if (!num_table.count(num)) { - u32 size=num_table.size(); - num_table[num]=size; + u32 size = num_table.size(); + num_table[num] = size; num_res.push_back(num); } } void codegen::regist_str(const std::string& str) { if (!str_table.count(str)) { - u32 size=str_table.size(); - str_table[str]=size; + u32 size = str_table.size(); + str_table[str] = size; str_res.push_back(str); } } @@ -64,6 +47,7 @@ void codegen::find_symbol(code_block* node) { for(const auto& i : finder->do_find(node)) { add_sym(i); } + delete finder; } void codegen::add_sym(const std::string& name) { @@ -71,63 +55,63 @@ void codegen::add_sym(const std::string& name) { if (global.count(name)) { return; } - i32 index=global.size(); - global[name]=index; + i32 index = global.size(); + global[name] = index; return; } if (local.back().count(name)) { return; } - i32 index=local.back().size(); - local.back()[name]=index; + i32 index = local.back().size(); + local.back()[name] = index; } i32 codegen::local_find(const std::string& name) { if (local.empty()) { return -1; } - return local.back().count(name)?local.back()[name]:-1; + return local.back().count(name)? local.back().at(name):-1; } i32 codegen::global_find(const std::string& name) { - return global.count(name)?global[name]:-1; + return global.count(name)? global.at(name):-1; } i32 codegen::upvalue_find(const std::string& name) { // 32768 level 65536 upvalues - i32 index=-1; - usize size=local.size(); + i32 index = -1; + usize size = local.size(); if (size<=1) { return -1; } - auto iter=local.begin(); - for(u32 i=0;icount(name)) { - index=((i<<16)|(*iter)[name]); + index = ((i<<16)|(*iter).at(name)); } } return index; } -void codegen::gen(u8 op, u32 num, u32 line) { - code.push_back({op, fileindex, num, line}); +void codegen::gen(u8 operation_code, u32 num, u32 line) { + code.push_back({operation_code, fileindex, num, line}); } void codegen::num_gen(number_literal* node) { f64 num = node->get_number(); regist_num(num); - gen(op_pnum,num_table[num], node->get_location().begin_line); + gen(op_pnum,num_table.at(num), node->get_location().begin_line); } void codegen::str_gen(string_literal* node) { regist_str(node->get_content()); - gen(op_pstr, str_table[node->get_content()], node->get_location().begin_line); + gen(op_pstr, str_table.at(node->get_content()), node->get_location().begin_line); } void codegen::bool_gen(bool_literal* node) { - f64 num = node->get_flag()?1:0; + f64 num = node->get_flag()? 1:0; regist_num(num); - gen(op_pnum, num_table[num], node->get_location().begin_line); + gen(op_pnum, num_table.at(num), node->get_location().begin_line); } void codegen::vec_gen(vector_expr* node) { @@ -141,9 +125,9 @@ void codegen::hash_gen(hash_expr* node) { gen(op_newh, 0, node->get_location().begin_line); for(auto child : node->get_members()) { calc_gen(child->get_value()); - const std::string& str=child->get_name(); - regist_str(str); - gen(op_happ, str_table[str], child->get_location().begin_line); + const auto& field_name = child->get_name(); + regist_str(field_name); + gen(op_happ, str_table.at(field_name), child->get_location().begin_line); } } @@ -151,26 +135,34 @@ void codegen::func_gen(function* node) { // parameter list format check bool checked_default = false; bool checked_dynamic = false; - std::unordered_map argname; + std::unordered_map argname; for(auto tmp : node->get_parameter_list()) { - if (tmp->get_parameter_type()==parameter::param_type::default_parameter) { + if (tmp->get_parameter_type()== + parameter::param_type::default_parameter) { checked_default=true; - } else if (tmp->get_parameter_type()==parameter::param_type::dynamic_parameter) { + } else if (tmp->get_parameter_type()== + parameter::param_type::dynamic_parameter) { checked_dynamic=true; } // check default parameter and dynamic parameter - if (checked_default && tmp->get_parameter_type()!=parameter::param_type::default_parameter) { - die("must use default parameters here", tmp->get_location()); + if (checked_default && + tmp->get_parameter_type()!= + parameter::param_type::default_parameter) { + die("must use default parameter here", + tmp->get_location()); } - if (checked_dynamic && tmp!=node->get_parameter_list().back()) { - die("dynamic parameter must be the last one", tmp->get_location()); + if (checked_dynamic && + tmp!=node->get_parameter_list().back()) { + die("dynamic parameter must be the last one", + tmp->get_location()); } // check redefinition const auto& name = tmp->get_parameter_name(); if (argname.count(name)) { - die("redefinition of parameter: "+name, tmp->get_location()); + die("redefinition of parameter: " + name, + tmp->get_location()); } else { - argname[name]=true; + argname[name] = true; } } @@ -187,29 +179,30 @@ void codegen::func_gen(function* node) { local.push_back({{"me", 0}}); // generate parameter list - for(auto& tmp : node->get_parameter_list()) { - const auto& str = tmp->get_parameter_name(); - if (str=="me") { - die("\"me\" should not be a parameter", tmp->get_location()); + for(auto tmp : node->get_parameter_list()) { + const auto& name = tmp->get_parameter_name(); + if (name=="me") { + die("\"me\" should not be a parameter", + tmp->get_location()); } - regist_str(str); + regist_str(name); switch(tmp->get_parameter_type()) { case parameter::param_type::normal_parameter: - gen(op_para, str_table[str], tmp->get_location().begin_line); + gen(op_para, str_table.at(name), tmp->get_location().begin_line); break; case parameter::param_type::default_parameter: calc_gen(tmp->get_default_value()); - gen(op_deft, str_table[str], tmp->get_location().begin_line); + gen(op_deft, str_table.at(name), tmp->get_location().begin_line); break; case parameter::param_type::dynamic_parameter: - gen(op_dyn, str_table[str], tmp->get_location().begin_line); + gen(op_dyn, str_table.at(name), tmp->get_location().begin_line); break; } - add_sym(str); + add_sym(name); } - code[newf].num=code.size()+1; // entry - usize jmp_ptr=code.size(); + code[newf].num = code.size()+1; // entry + usize jmp_ptr = code.size(); gen(op_jmp, 0, node->get_location().begin_line); auto block = node->get_code_block(); @@ -219,9 +212,10 @@ void codegen::func_gen(function* node) { in_iterloop.push(0); block_gen(block); in_iterloop.pop(); - code[lsize].num=local.back().size(); + code[lsize].num = local.back().size(); if (local.back().size()>=STACK_DEPTH) { - die("too many local variants: "+std::to_string(local.back().size()), block->get_location()); + die("too many local variants: " + + std::to_string(local.back().size()), block->get_location()); } local.pop_back(); @@ -230,7 +224,7 @@ void codegen::func_gen(function* node) { gen(op_pnil, 0, block->get_location().begin_line); gen(op_ret, 0, block->get_location().begin_line); } - code[jmp_ptr].num=code.size(); + code[jmp_ptr].num = code.size(); } void codegen::call_gen(call_expr* node) { @@ -249,11 +243,12 @@ void codegen::call_gen(call_expr* node) { void codegen::call_id(identifier* node) { const auto& name = node->get_name(); - for(u32 i=0; builtin[i].name; ++i) { + 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()); + die("should warp native function in local scope", + node->get_location()); } return; } @@ -276,7 +271,7 @@ void codegen::call_id(identifier* node) { void codegen::call_hash_gen(call_hash* node) { regist_str(node->get_field()); - gen(op_callh, str_table[node->get_field()], node->get_location().begin_line); + gen(op_callh, str_table.at(node->get_field()), node->get_location().begin_line); } void codegen::call_vec(call_vector* node) { @@ -287,7 +282,7 @@ void codegen::call_vec(call_vector* node) { gen(op_callv, 0, node->get_slices()[0]->get_location().begin_line); return; } - gen(op_slcbeg,0,node->get_location().begin_line); + gen(op_slcbeg, 0, node->get_location().begin_line); for(auto tmp : node->get_slices()) { if (!tmp->get_end()) { calc_gen(tmp->get_begin()); @@ -307,9 +302,9 @@ void codegen::call_func(call_function* node) { 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); + const auto& field_name = ((hash_pair*)child)->get_name(); + regist_str(field_name); + gen(op_happ, str_table.at(field_name), child->get_location().begin_line); } gen(op_callfh, 0, node->get_location().begin_line); } else { @@ -328,34 +323,41 @@ void codegen::call_func(call_function* node) { * so we use another way to avoid gc-caused SIGSEGV: reserve m-called value on stack. * you could see the notes in `vm::opr_mcallv()`. */ -void codegen::mcall(call_expr* node) { - if (!check_memory_reachable(node)) { +void codegen::mcall(expr* node) { + if (node->get_type()!=expr_type::ast_id && + node->get_type()!=expr_type::ast_call) { + die("bad left-value", node->get_location()); return; } - if (node->get_first()->get_type()==expr_type::ast_id && - !node->get_calls().size()) { - mcall_id((identifier*)node->get_first()); + if (node->get_type()==expr_type::ast_id) { + mcall_id((identifier*)node); + return; } - calc_gen(node->get_first()); - for(usize i = 0; iget_calls().size()-1; ++i) { - auto tmp = node->get_calls()[i]; + auto call_node = (call_expr*)node; + calc_gen(call_node->get_first()); + for(usize i = 0; iget_calls().size()-1; ++i) { + auto tmp = call_node->get_calls()[i]; switch(tmp->get_type()) { 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; } } - auto tmp = node->get_calls().back(); + auto tmp = call_node->get_calls().back(); if (tmp->get_type()==expr_type::ast_callh) { mcall_hash((call_hash*)tmp); } else if (tmp->get_type()==expr_type::ast_callv) { mcall_vec((call_vector*)tmp); + } else if (tmp->get_type()==expr_type::ast_callf) { + die("bad left-value: function call", tmp->get_location()); + } else { + die("bad left-value: unknown call", tmp->get_location()); } } void codegen::mcall_id(identifier* node) { const auto& name = node->get_name(); - for(u32 i=0;builtin[i].name;++i) { + for(u32 i = 0; builtin[i].name; ++i) { if (builtin[i].name==name) { die("cannot modify native function", node->get_location()); return; @@ -378,13 +380,22 @@ void codegen::mcall_id(identifier* node) { } void codegen::mcall_vec(call_vector* node) { - calc_gen(node->get_slices()[0]); + if (node->get_slices().size()>1) { + die("bad left-value: subvec call", node->get_location()); + return; + } + auto call = node->get_slices()[0]; + if (call->get_end()) { + die("bad left-value: subvec call", node->get_location()); + return; + } + calc_gen(call->get_begin()); gen(op_mcallv, 0, node->get_location().begin_line); } void codegen::mcall_hash(call_hash* node) { regist_str(node->get_field()); - gen(op_mcallh, str_table[node->get_field()], node->get_location().begin_line); + gen(op_mcallh, str_table.at(node->get_field()), node->get_location().begin_line); } void codegen::single_def(definition_expr* node) { @@ -396,30 +407,30 @@ void codegen::single_def(definition_expr* node) { } void codegen::multi_def(definition_expr* node) { - auto& ids = node->get_variables()->get_variables(); - usize size = ids.size(); + auto& identifiers = node->get_variables()->get_variables(); + usize size = identifiers.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()get_value()->get_location()); - } else if (ids.size()>vals.size()) { + } else if (identifiers.size()>vals.size()) { die("too many values in multi-definition", node->get_value()->get_location()); } for(usize i = 0; iget_name(); + const auto& name = identifiers[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); + gen(op_loadg, global_find(name), identifiers[i]->get_location().begin_line): + gen(op_loadl, local_find(name), identifiers[i]->get_location().begin_line); } } else { // (var a,b,c)=[0,1,2]; calc_gen(node->get_value()); for(usize i = 0; iget_value()->get_location().begin_line); - const auto& str = ids[i]->get_name(); + const auto& name = identifiers[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); + gen(op_loadg, global_find(name), identifiers[i]->get_location().begin_line): + gen(op_loadl, local_find(name), identifiers[i]->get_location().begin_line); } gen(op_pop, 0, node->get_location().begin_line); } @@ -437,14 +448,14 @@ void codegen::assignment_gen(assignment_expr* node) { switch(node->get_assignment_type()) { case assignment_expr::assign_type::equal: calc_gen(node->get_right()); - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); gen(op_meq, 0, node->get_location().begin_line); break; case assignment_expr::assign_type::add_equal: if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); } - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { gen(op_addeq, 0, node->get_location().begin_line); } else { @@ -457,7 +468,7 @@ void codegen::assignment_gen(assignment_expr* node) { if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); } - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { gen(op_subeq, 0, node->get_location().begin_line); } else { @@ -470,7 +481,7 @@ void codegen::assignment_gen(assignment_expr* node) { if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); } - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { gen(op_muleq, 0, node->get_location().begin_line); } else { @@ -483,7 +494,7 @@ void codegen::assignment_gen(assignment_expr* node) { if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); } - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { gen(op_diveq, 0, node->get_location().begin_line); } else { @@ -496,7 +507,7 @@ void codegen::assignment_gen(assignment_expr* node) { if (node->get_right()->get_type()!=expr_type::ast_str) { calc_gen(node->get_right()); } - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_str) { gen(op_lnkeq, 0, node->get_location().begin_line); } else { @@ -507,17 +518,17 @@ void codegen::assignment_gen(assignment_expr* node) { break; case assignment_expr::assign_type::bitwise_and_equal: calc_gen(node->get_right()); - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); gen(op_btandeq, 0, node->get_location().begin_line); break; case assignment_expr::assign_type::bitwise_or_equal: calc_gen(node->get_right()); - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); gen(op_btoreq, 0, node->get_location().begin_line); break; case assignment_expr::assign_type::bitwise_xor_equal: calc_gen(node->get_right()); - mcall((call_expr*)node->get_left()); + mcall(node->get_left()); gen(op_btxoreq, 0, node->get_location().begin_line); break; } @@ -576,12 +587,12 @@ void codegen::multi_assign_gen(multi_assign* node) { } i32 size = node->get_tuple()->get_elements().size(); if (node->get_value()->get_type()==expr_type::ast_tuple) { - for(i32 i=size-1;i>=0;--i) { + for(i32 i = size-1; i>=0; --i) { calc_gen(((tuple_expr*)node->get_value())->get_elements()[i]); } auto& tuple = node->get_tuple()->get_elements(); - for(i32 i=0;iget_value()); auto& tuple = node->get_tuple()->get_elements(); - for(i32 i=0;iget_value()->get_location().begin_line); // multi assign user loadl and loadg to avoid meq's stack-- // and this operation changes local and global value directly - mcall((call_expr*)tuple[i]); + mcall(tuple[i]); if (code.back().op==op_mcalll) { code.back().op=op_loadl; } else if (code.back().op==op_mupval) { @@ -622,6 +633,11 @@ void codegen::cond_gen(condition_expr* node) { auto ptr = code.size(); gen(op_jf, 0, node->get_if_statement()->get_location().begin_line); block_gen(node->get_if_statement()->get_code_block()); + if (node->get_elsif_stataments().size() || + node->get_else_statement()) { + jmp_label.push_back(code.size()); + gen(op_jmp, 0, node->get_if_statement()->get_location().begin_line); + } code[ptr].num = code.size(); for(auto tmp : node->get_elsif_stataments()) { @@ -655,7 +671,8 @@ void codegen::loop_gen(expr* node) { 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) { + if (((forei_expr*)node)->get_loop_type()== + forei_expr::forei_loop_type::forindex) { forindex_gen((forei_expr*)node); } else { foreach_gen((forei_expr*)node); @@ -664,45 +681,46 @@ void codegen::loop_gen(expr* node) { } } -void codegen::load_continue_break(i32 continue_place,i32 break_place) { - for(auto i:continue_ptr.front()) { - code[i].num=continue_place; +void codegen::load_continue_break(i32 continue_place, i32 break_place) { + for(auto i : continue_ptr.front()) { + code[i].num = continue_place; } - for(auto i:break_ptr.front()) { - code[i].num=break_place; + for(auto i : break_ptr.front()) { + code[i].num = break_place; } continue_ptr.pop_front(); break_ptr.pop_front(); } void codegen::while_gen(while_expr* node) { - usize loop_ptr=code.size(); + usize loop_ptr = code.size(); calc_gen(node->get_condition()); - usize condition_ptr=code.size(); + usize condition_ptr = code.size(); gen(op_jf, 0, node->get_condition()->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(); + code[condition_ptr].num = code.size(); load_continue_break(code.size()-1, code.size()); } void codegen::for_gen(for_expr* node) { expr_gen(node->get_initial()); - usize jmp_place=code.size(); + usize jmp_place = code.size(); if (node->get_condition()->get_type()==expr_type::ast_null) { - gen(op_pnum, num_table[1], node->get_condition()->get_location().begin_line); + regist_num(1); + gen(op_pnum, num_table.at(1), node->get_condition()->get_location().begin_line); } else { calc_gen(node->get_condition()); } - usize label_exit=code.size(); + usize label_exit = code.size(); gen(op_jf, 0, node->get_condition()->get_location().begin_line); block_gen(node->get_code_block()); - usize continue_place=code.size(); + usize continue_place = code.size(); expr_gen(node->get_step()); gen(op_jmp, jmp_place, node->get_step()->get_location().begin_line); - code[label_exit].num=code.size(); + code[label_exit].num = code.size(); load_continue_break(continue_place, code.size()); } @@ -714,6 +732,8 @@ void codegen::expr_gen(expr* node) { def_gen((definition_expr*)node); break; case expr_type::ast_multi_assign: multi_assign_gen((multi_assign*)node); break; + case expr_type::ast_assign: + assign_statement((assignment_expr*)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: @@ -724,8 +744,6 @@ void codegen::expr_gen(expr* node) { calc_gen(node); gen(op_pop, 0, node->get_location().begin_line); break; - case expr_type::ast_assign: - assign_statement((assignment_expr*)node); break; } } @@ -740,7 +758,7 @@ void codegen::forindex_gen(forei_expr* node) { 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((call_expr*)node->get_iterator()->get_call()); + mcall(node->get_iterator()->get_call()); if (code.back().op==op_mcallg) { code.back().op=op_loadg; } else if (code.back().op==op_mcalll) { @@ -772,7 +790,7 @@ void codegen::foreach_gen(forei_expr* node) { 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((call_expr*)node->get_iterator()->get_call()); + mcall(node->get_iterator()->get_call()); if (code.back().op==op_mcallg) { code.back().op=op_loadg; } else if (code.back().op==op_mcalll) { @@ -813,14 +831,14 @@ void codegen::and_gen(binary_operator* node) { calc_gen(node->get_left()); gen(op_jt, code.size()+2, node->get_left()->get_location().begin_line); - usize lfalse=code.size(); + usize lfalse = code.size(); gen(op_jmp, 0, node->get_left()->get_location().begin_line); gen(op_pop, 0, node->get_right()->get_location().begin_line);// jt jumps here calc_gen(node->get_right()); gen(op_jt, code.size()+3, node->get_right()->get_location().begin_line); - code[lfalse].num=code.size(); + code[lfalse].num = code.size(); gen(op_pop, 0, node->get_right()->get_location().begin_line); gen(op_pnil, 0, node->get_right()->get_location().begin_line); // jt jumps here @@ -881,7 +899,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_addc, num_table[num], node->get_location().begin_line); + gen(op_addc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::sub: @@ -892,7 +910,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_subc, num_table[num], node->get_location().begin_line); + gen(op_subc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::mult: @@ -903,7 +921,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_mulc, num_table[num], node->get_location().begin_line); + gen(op_mulc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::div: @@ -914,7 +932,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_divc, num_table[num], node->get_location().begin_line); + gen(op_divc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::concat: @@ -925,10 +943,9 @@ void codegen::binary_gen(binary_operator* node) { } else { const auto& str = ((string_literal*)node->get_right())->get_content(); regist_str(str); - gen(op_lnkc, str_table[str], node->get_location().begin_line); + gen(op_lnkc, str_table.at(str), node->get_location().begin_line); } break; - // ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) case binary_operator::binary_type::less: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { @@ -937,7 +954,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_lessc, num_table[num], node->get_location().begin_line); + gen(op_lessc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::leq: @@ -948,7 +965,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_leqc, num_table[num], node->get_location().begin_line); + gen(op_leqc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::grt: @@ -959,7 +976,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_grtc, num_table[num], node->get_location().begin_line); + gen(op_grtc, num_table.at(num), node->get_location().begin_line); } return; case binary_operator::binary_type::geq: @@ -970,7 +987,7 @@ void codegen::binary_gen(binary_operator* node) { } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_geqc, num_table[num], node->get_location().begin_line); + gen(op_geqc, num_table.at(num), node->get_location().begin_line); } return; } @@ -978,14 +995,14 @@ void codegen::binary_gen(binary_operator* node) { void codegen::trino_gen(ternary_operator* node) { calc_gen(node->get_condition()); - usize lfalse=code.size(); + usize lfalse = code.size(); gen(op_jf, 0, node->get_condition()->get_location().begin_line); calc_gen(node->get_left()); - usize lexit=code.size(); + usize lexit = code.size(); gen(op_jmp, 0, node->get_left()->get_location().begin_line); - code[lfalse].num=code.size(); + code[lfalse].num = code.size(); calc_gen(node->get_right()); - code[lexit].num=code.size(); + code[lexit].num = code.size(); } void codegen::calc_gen(expr* node) { @@ -1017,6 +1034,7 @@ void codegen::calc_gen(expr* node) { case expr_type::ast_binary: binary_gen((binary_operator*)node); break; case expr_type::ast_def: + // definition in calculation only should be single def single_def((definition_expr*)node); call_id(((definition_expr*)node)->get_variable_name()); break; @@ -1032,7 +1050,7 @@ void codegen::block_gen(code_block* node) { 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 + 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: @@ -1053,6 +1071,7 @@ void codegen::block_gen(code_block* node) { case expr_type::ast_unary: case expr_type::ast_ternary: case expr_type::ast_def: + case expr_type::ast_assign: case expr_type::ast_multi_assign: expr_gen(tmp); break; case expr_type::ast_ret: @@ -1062,7 +1081,7 @@ void codegen::block_gen(code_block* node) { } void codegen::ret_gen(return_expr* node) { - for(u32 i=0;iget_location().begin_line); gen(op_pop, 0, node->get_location().begin_line); } @@ -1071,8 +1090,8 @@ void codegen::ret_gen(return_expr* node) { } const error& codegen::compile(parse& parse, linker& import) { - fileindex=0; - file=import.filelist().data(); + fileindex = 0; + file = import.filelist().data(); in_iterloop.push(0); find_symbol(parse.tree()); // search symbols first gen(op_intg, global.size(), 0); @@ -1105,21 +1124,21 @@ void codegen::print() { std::stack festk; // print const numbers - for(auto& num:num_res) { + for(auto num : num_res) { std::cout<<" .number "<;\n"; // avoid two empty lines @@ -1133,7 +1152,7 @@ void codegen::print() { // get function begin index and end index if (c.op==op_newf) { std::cout<:\n"; - for(u32 j=i;j> local; - bool check_memory_reachable(expr*); void check_id_exist(identifier*); void die(const std::string& info, const span& loc) { @@ -68,7 +67,7 @@ private: void call_hash_gen(call_hash*); void call_vec(call_vector*); void call_func(call_function*); - void mcall(call_expr*); + void mcall(expr*); void mcall_id(identifier*); void mcall_vec(call_vector*); void mcall_hash(call_hash*); diff --git a/ast/nasal_new_parse.cpp b/ast/nasal_new_parse.cpp index fd680c7..e83a6a8 100644 --- a/ast/nasal_new_parse.cpp +++ b/ast/nasal_new_parse.cpp @@ -939,14 +939,21 @@ iter_expr* parse::iter_gen() { if (lookahead(tok::var)) { match(tok::var); node->set_name(id()); - } else { - auto tmp = new call_expr(toks[ptr].loc); - tmp->set_first(id()); - while(is_call(toks[ptr].type)) { - tmp->add_call(call_scalar()); - } - node->set_call(tmp); + update_location(node); + return node; } + auto id_node = id(); + if (!is_call(toks[ptr].type)) { + node->set_name(id_node); + update_location(node); + return node; + } + auto tmp = new call_expr(id_node->get_location()); + tmp->set_first(id()); + while(is_call(toks[ptr].type)) { + tmp->add_call(call_scalar()); + } + node->set_call(tmp); update_location(node); return node; } diff --git a/ast/nasal_new_vm.h b/ast/nasal_new_vm.h index 5c686fd..9bfe4c9 100644 --- a/ast/nasal_new_vm.h +++ b/ast/nasal_new_vm.h @@ -144,6 +144,7 @@ protected: void o_mcallv(); void o_mcallh(); void o_ret(); + public: /* constructor of vm instance */