diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 8d078d1..11fc253 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -307,7 +307,9 @@ var builtin_substr(var* local, gc& ngc) { var builtin_streq(var* local, gc& ngc) { var a = local[1]; var b = local[2]; - return var::num(f64((a.type!=vm_str || b.type!=vm_str)? 0:(a.str()==b.str()))); + return var::num(static_cast( + (a.type!=vm_str || b.type!=vm_str)? 0:(a.str()==b.str()) + )); } var builtin_left(var* local, gc& ngc) { @@ -410,9 +412,11 @@ var builtin_sleep(var* local, gc& ngc) { #if defined(_WIN32) && !defined(_GLIBCXX_HAS_GTHREADS) // mingw-w64 win32 thread model has no std::this_thread // also msvc will use this - Sleep(i64(val.num()*1e3)); + Sleep(static_cast(val.num()*1e3)); #else - std::this_thread::sleep_for(std::chrono::microseconds(i64(val.num()*1e6))); + std::this_thread::sleep_for( + std::chrono::microseconds(static_cast(val.num()*1e6)) + ); #endif return nil; } @@ -469,7 +473,7 @@ std::string md5(const std::string& src) { usize buffsize = num<<4; buff.resize(buffsize,0); for(usize i = 0; i>2] |= ((u8)src[i])<<((i&0x3)<<3); + buff[i>>2] |= (static_cast(src[i]))<<((i&0x3)<<3); } buff[src.length()>>2] |= 0x80<<(((src.length()%4))<<3); buff[buffsize-2] = (src.length()<<3)&0xffffffff; diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index f2a8649..bb3224f 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -133,44 +133,47 @@ i32 codegen::upvalue_find(const std::string& name) { return index; } -void codegen::gen(u8 operation_code, u32 num, const span& loc) { - code.push_back({operation_code, - static_cast(file_map.at(loc.file)), - num, loc.begin_line}); +void codegen::emit(u8 operation_code, u32 immediate_num, const span& location) { + code.push_back({ + operation_code, + static_cast(file_map.at(location.file)), + immediate_num, + location.begin_line + }); } void codegen::num_gen(number_literal* node) { f64 num = node->get_number(); regist_num(num); - gen(op_pnum, const_number_map.at(num), node->get_location()); + emit(op_pnum, const_number_map.at(num), node->get_location()); } void codegen::str_gen(string_literal* node) { const auto& str = node->get_content(); regist_str(str); - gen(op_pstr, const_string_map.at(str), node->get_location()); + emit(op_pstr, const_string_map.at(str), node->get_location()); } void codegen::bool_gen(bool_literal* node) { f64 num = node->get_flag()? 1:0; regist_num(num); - gen(op_pnum, const_number_map.at(num), node->get_location()); + emit(op_pnum, const_number_map.at(num), node->get_location()); } void codegen::vec_gen(vector_expr* node) { for(auto child : node->get_elements()) { calc_gen(child); } - gen(op_newv, node->get_elements().size(), node->get_location()); + emit(op_newv, node->get_elements().size(), node->get_location()); } void codegen::hash_gen(hash_expr* node) { - gen(op_newh, 0, node->get_location()); + emit(op_newh, 0, node->get_location()); for(auto child : node->get_members()) { calc_gen(child->get_value()); const auto& field_name = child->get_name(); regist_str(field_name); - gen(op_happ, const_string_map.at(field_name), child->get_location()); + emit(op_happ, const_string_map.at(field_name), child->get_location()); } } @@ -210,9 +213,9 @@ void codegen::func_gen(function* node) { } usize newf=code.size(); - gen(op_newf, 0, node->get_location()); + emit(op_newf, 0, node->get_location()); usize lsize=code.size(); - gen(op_intl, 0, node->get_location()); + emit(op_intl, 0, node->get_location()); // add special keyword 'me' into symbol table // this symbol is only used in local scope(function's scope) @@ -231,14 +234,14 @@ void codegen::func_gen(function* node) { regist_str(name); switch(tmp->get_parameter_type()) { case parameter::param_type::normal_parameter: - gen(op_para, const_string_map.at(name), tmp->get_location()); + emit(op_para, const_string_map.at(name), tmp->get_location()); break; case parameter::param_type::default_parameter: calc_gen(tmp->get_default_value()); - gen(op_deft, const_string_map.at(name), tmp->get_location()); + emit(op_deft, const_string_map.at(name), tmp->get_location()); break; case parameter::param_type::dynamic_parameter: - gen(op_dyn, const_string_map.at(name), tmp->get_location()); + emit(op_dyn, const_string_map.at(name), tmp->get_location()); break; } add_symbol(name); @@ -246,7 +249,7 @@ void codegen::func_gen(function* node) { code[newf].num = code.size()+1; // entry usize jmp_ptr = code.size(); - gen(op_jmp, 0, node->get_location()); + emit(op_jmp, 0, node->get_location()); auto block = node->get_code_block(); // search symbols first, must use after loading parameters @@ -279,8 +282,8 @@ void codegen::func_gen(function* node) { if (!block->get_expressions().size() || block->get_expressions().back()->get_type()!=expr_type::ast_ret) { - gen(op_pnil, 0, block->get_location()); - gen(op_ret, 0, block->get_location()); + emit(op_pnil, 0, block->get_location()); + emit(op_ret, 0, block->get_location()); } code[jmp_ptr].num = code.size(); } @@ -303,7 +306,7 @@ void codegen::call_gen(call_expr* node) { void codegen::call_id(identifier* node) { const auto& name = node->get_name(); if (native_function_mapper.count(name)) { - gen(op_callb, + emit(op_callb, static_cast(native_function_mapper.at(name)), node->get_location()); if (local.empty()) { @@ -315,15 +318,15 @@ void codegen::call_id(identifier* node) { i32 index; if ((index=local_find(name))>=0) { - gen(op_calll, index, node->get_location()); + emit(op_calll, index, node->get_location()); return; } if ((index=upvalue_find(name))>=0) { - gen(op_upval, index, node->get_location()); + emit(op_upval, index, node->get_location()); return; } if ((index=global_find(name))>=0) { - gen(op_callg, index, node->get_location()); + emit(op_callg, index, node->get_location()); return; } die("undefined symbol \"" + name + "\"", node->get_location()); @@ -331,7 +334,7 @@ void codegen::call_id(identifier* node) { void codegen::call_hash_gen(call_hash* node) { regist_str(node->get_field()); - gen(op_callh, const_string_map.at(node->get_field()), node->get_location()); + emit(op_callh, const_string_map.at(node->get_field()), node->get_location()); } void codegen::call_vector_gen(call_vector* node) { @@ -339,39 +342,39 @@ void codegen::call_vector_gen(call_vector* node) { 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()); + emit(op_callv, 0, node->get_slices()[0]->get_location()); return; } - gen(op_slcbeg, 0, node->get_location()); + emit(op_slcbeg, 0, node->get_location()); for(auto tmp : node->get_slices()) { if (!tmp->get_end()) { calc_gen(tmp->get_begin()); - gen(op_slc, 0, tmp->get_location()); + emit(op_slc, 0, tmp->get_location()); } else { calc_gen(tmp->get_begin()); calc_gen(tmp->get_end()); - gen(op_slc2, 0, tmp->get_location()); + emit(op_slc2, 0, tmp->get_location()); } } - gen(op_slcend, 0, node->get_location()); + emit(op_slcend, 0, node->get_location()); } void codegen::call_func_gen(call_function* node) { if (node->get_argument().size() && node->get_argument()[0]->get_type()==expr_type::ast_pair) { - gen(op_newh, 0, node->get_location()); + emit(op_newh, 0, node->get_location()); for(auto child : node->get_argument()) { calc_gen(((hash_pair*)child)->get_value()); const auto& field_name = ((hash_pair*)child)->get_name(); regist_str(field_name); - gen(op_happ, const_string_map.at(field_name), child->get_location()); + emit(op_happ, const_string_map.at(field_name), child->get_location()); } - gen(op_callfh, 0, node->get_location()); + emit(op_callfh, 0, node->get_location()); } else { for(auto child : node->get_argument()) { calc_gen(child); } - gen(op_callfv, node->get_argument().size(), node->get_location()); + emit(op_callfv, node->get_argument().size(), node->get_location()); } } @@ -425,15 +428,15 @@ void codegen::mcall_id(identifier* node) { i32 index; if ((index=local_find(name))>=0) { - gen(op_mcalll, index, node->get_location()); + emit(op_mcalll, index, node->get_location()); return; } if ((index=upvalue_find(name))>=0) { - gen(op_mupval, index, node->get_location()); + emit(op_mupval, index, node->get_location()); return; } if ((index=global_find(name))>=0) { - gen(op_mcallg, index, node->get_location()); + emit(op_mcallg, index, node->get_location()); return; } die("undefined symbol \"" + name + "\"", node->get_location()); @@ -450,20 +453,22 @@ void codegen::mcall_vec(call_vector* node) { return; } calc_gen(call->get_begin()); - gen(op_mcallv, 0, node->get_location()); + emit(op_mcallv, 0, node->get_location()); } void codegen::mcall_hash(call_hash* node) { regist_str(node->get_field()); - gen(op_mcallh, const_string_map.at(node->get_field()), node->get_location()); + emit(op_mcallh, const_string_map.at(node->get_field()), node->get_location()); } void codegen::single_def(definition_expr* node) { const auto& str = node->get_variable_name()->get_name(); calc_gen(node->get_value()); - local.empty()? - gen(op_loadg, global_find(str), node->get_location()): - gen(op_loadl, local_find(str), node->get_location()); + if (local.empty()) { + emit(op_loadg, global_find(str), node->get_location()); + } else { + emit(op_loadl, local_find(str), node->get_location()); + } } void codegen::multi_def(definition_expr* node) { @@ -474,30 +479,32 @@ void codegen::multi_def(definition_expr* node) { auto& vals = node->get_tuple()->get_elements(); if (identifiers.size()get_tuple()->get_location()); + node->get_tuple()->get_location() + ); } else if (identifiers.size()>vals.size()) { die("too many values in multi-definition", - node->get_tuple()->get_location()); + node->get_tuple()->get_location() + ); } for(usize i = 0; iget_name(); local.empty()? - gen(op_loadg, global_find(name), identifiers[i]->get_location()): - gen(op_loadl, local_find(name), identifiers[i]->get_location()); + emit(op_loadg, global_find(name), identifiers[i]->get_location()): + emit(op_loadl, local_find(name), identifiers[i]->get_location()); } return; } // (var a,b,c) = [0,1,2]; calc_gen(node->get_value()); for(usize i = 0; iget_value()->get_location()); + emit(op_callvi, i, node->get_value()->get_location()); const auto& name = identifiers[i]->get_name(); local.empty()? - gen(op_loadg, global_find(name), identifiers[i]->get_location()): - gen(op_loadl, local_find(name), identifiers[i]->get_location()); + emit(op_loadg, global_find(name), identifiers[i]->get_location()): + emit(op_loadl, local_find(name), identifiers[i]->get_location()); } - gen(op_pop, 0, node->get_location()); + emit(op_pop, 0, node->get_location()); } void codegen::def_gen(definition_expr* node) { @@ -512,7 +519,7 @@ void codegen::assignment_expression(assignment_expr* node) { case assignment_expr::assign_type::equal: calc_gen(node->get_right()); mcall(node->get_left()); - gen(op_meq, 0, node->get_location()); + emit(op_meq, 0, node->get_location()); break; case assignment_expr::assign_type::add_equal: if (node->get_right()->get_type()!=expr_type::ast_num) { @@ -520,11 +527,11 @@ void codegen::assignment_expression(assignment_expr* node) { } mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { - gen(op_addeq, 0, node->get_location()); + emit(op_addeq, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_addeqc, const_number_map[num], node->get_location()); + emit(op_addeqc, const_number_map[num], node->get_location()); } break; case assignment_expr::assign_type::sub_equal: @@ -533,11 +540,11 @@ void codegen::assignment_expression(assignment_expr* node) { } mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { - gen(op_subeq, 0, node->get_location()); + emit(op_subeq, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_subeqc, const_number_map[num], node->get_location()); + emit(op_subeqc, const_number_map[num], node->get_location()); } break; case assignment_expr::assign_type::mult_equal: @@ -546,11 +553,11 @@ void codegen::assignment_expression(assignment_expr* node) { } mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { - gen(op_muleq, 0, node->get_location()); + emit(op_muleq, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_muleqc, const_number_map[num], node->get_location()); + emit(op_muleqc, const_number_map[num], node->get_location()); } break; case assignment_expr::assign_type::div_equal: @@ -559,11 +566,11 @@ void codegen::assignment_expression(assignment_expr* node) { } mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { - gen(op_diveq, 0, node->get_location()); + emit(op_diveq, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_diveqc, const_number_map[num], node->get_location()); + emit(op_diveqc, const_number_map[num], node->get_location()); } break; case assignment_expr::assign_type::concat_equal: @@ -572,53 +579,63 @@ void codegen::assignment_expression(assignment_expr* node) { } mcall(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_str) { - gen(op_lnkeq, 0, node->get_location()); + emit(op_lnkeq, 0, node->get_location()); } else { const auto& str = ((string_literal*)node->get_right())->get_content(); regist_str(str); - gen(op_lnkeqc, const_string_map[str], node->get_location()); + emit(op_lnkeqc, const_string_map[str], node->get_location()); } break; case assignment_expr::assign_type::bitwise_and_equal: calc_gen(node->get_right()); mcall(node->get_left()); - gen(op_btandeq, 0, node->get_location()); + emit(op_btandeq, 0, node->get_location()); break; case assignment_expr::assign_type::bitwise_or_equal: calc_gen(node->get_right()); mcall(node->get_left()); - gen(op_btoreq, 0, node->get_location()); + emit(op_btoreq, 0, node->get_location()); break; case assignment_expr::assign_type::bitwise_xor_equal: calc_gen(node->get_right()); mcall(node->get_left()); - gen(op_btxoreq, 0, node->get_location()); + emit(op_btxoreq, 0, node->get_location()); break; } } +void codegen::gen_assignment_equal_statement(assignment_expr* node) { + // if is not symbol load type assignment, use calc_gen directly + // what is symbol load assignment? example: + // a = 1; # this is symbol load + // a.foo = "bar"; # this is not symbol load + if (node->get_left()->get_type()!=expr_type::ast_id) { + calc_gen(node); + if (code.back().op==op_meq) { + code.back().num = 1; // 1 means need pop after op_meq + } else { + emit(op_pop, 0, node->get_location()); + } + return; + } + + // generate symbol load + calc_gen(node->get_right()); + // get memory space of left identifier + mcall_id((identifier*)node->get_left()); + // check memory get operand type and replace it with load operand + switch(code.back().op) { + case op_mcallg: code.back().op = op_loadg; break; + case op_mcalll: code.back().op = op_loadl; break; + case op_mupval: code.back().op = op_loadu; break; + default: die("unexpected operand to replace", node->get_location()); + } +} + void codegen::assignment_statement(assignment_expr* node) { switch(node->get_assignment_type()) { case assignment_expr::assign_type::equal: - if (node->get_left()->get_type()==expr_type::ast_id) { - calc_gen(node->get_right()); - mcall_id((identifier*)node->get_left()); - // only the first mcall_id can use load - if (code.back().op==op_mcalll) { - code.back().op=op_loadl; - } else if (code.back().op==op_mupval) { - code.back().op=op_loadu; - } else { - code.back().op=op_loadg; - } - } else { - calc_gen(node); - if (code.back().op==op_meq) { - code.back().num=1; - } else { - gen(op_pop, 0, node->get_location()); - } - } + gen_assignment_equal_statement(node); break; case assignment_expr::assign_type::add_equal: case assignment_expr::assign_type::sub_equal: @@ -634,7 +651,7 @@ void codegen::assignment_statement(assignment_expr* node) { } 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()); + emit(op_pop, 0, node->get_location()); } break; } @@ -659,13 +676,13 @@ void codegen::multi_assign_gen(multi_assign* node) { // multi assign user loadl and loadg to avoid meq's stack-- // and this operation changes local and global value directly if (code.back().op==op_mcalll) { - code.back().op=op_loadl; + code.back().op = op_loadl; } else if (code.back().op==op_mupval) { - code.back().op=op_loadu; + code.back().op = op_loadu; } else if (code.back().op==op_mcallg) { - code.back().op=op_loadg; + code.back().op = op_loadg; } else { - gen(op_meq, 1, tuple[i]->get_location()); + emit(op_meq, 1, tuple[i]->get_location()); } } return; @@ -673,46 +690,46 @@ void codegen::multi_assign_gen(multi_assign* node) { calc_gen(node->get_value()); auto& tuple = node->get_tuple()->get_elements(); for(i32 i = 0; iget_value()->get_location()); + emit(op_callvi, i, node->get_value()->get_location()); // multi assign user loadl and loadg to avoid meq's stack-- // and this operation changes local and global value directly mcall(tuple[i]); if (code.back().op==op_mcalll) { - code.back().op=op_loadl; + code.back().op = op_loadl; } else if (code.back().op==op_mupval) { - code.back().op=op_loadu; + code.back().op = op_loadu; } else if (code.back().op==op_mcallg) { - code.back().op=op_loadg; + code.back().op = op_loadg; } else { - gen(op_meq, 1, tuple[i]->get_location()); + emit(op_meq, 1, tuple[i]->get_location()); } } - gen(op_pop, 0, node->get_location()); + emit(op_pop, 0, node->get_location()); } void codegen::cond_gen(condition_expr* node) { std::vector jmp_label; calc_gen(node->get_if_statement()->get_condition()); auto ptr = code.size(); - gen(op_jf, 0, node->get_if_statement()->get_location()); + emit(op_jf, 0, node->get_if_statement()->get_location()); 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()); + emit(op_jmp, 0, node->get_if_statement()->get_location()); } code[ptr].num = code.size(); for(auto tmp : node->get_elsif_stataments()) { calc_gen(tmp->get_condition()); ptr = code.size(); - gen(op_jf, 0, tmp->get_location()); + emit(op_jf, 0, tmp->get_location()); block_gen(tmp->get_code_block()); // the last condition doesn't need to jmp if (tmp!=node->get_elsif_stataments().back() || node->get_else_statement()) { jmp_label.push_back(code.size()); - gen(op_jmp, 0, tmp->get_location()); + emit(op_jmp, 0, tmp->get_location()); } code[ptr].num=code.size(); } @@ -729,12 +746,9 @@ 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((while_expr*)node); break; - case expr_type::ast_for: - for_gen((for_expr*)node); break; - case expr_type::ast_forei: - forei_gen((forei_expr*)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: forei_gen((forei_expr*)node); break; default: break; } } @@ -754,10 +768,10 @@ void codegen::while_gen(while_expr* node) { usize loop_ptr = code.size(); calc_gen(node->get_condition()); usize condition_ptr = code.size(); - gen(op_jf, 0, node->get_condition()->get_location()); + emit(op_jf, 0, node->get_condition()->get_location()); block_gen(node->get_code_block()); - gen(op_jmp, loop_ptr, node->get_code_block()->get_location()); + emit(op_jmp, loop_ptr, node->get_code_block()->get_location()); code[condition_ptr].num = code.size(); load_continue_break(code.size()-1, code.size()); } @@ -767,17 +781,17 @@ void codegen::for_gen(for_expr* node) { usize jmp_place = code.size(); if (node->get_condition()->get_type()==expr_type::ast_null) { regist_num(1); - gen(op_pnum, const_number_map.at(1), node->get_condition()->get_location()); + emit(op_pnum, const_number_map.at(1), node->get_condition()->get_location()); } else { calc_gen(node->get_condition()); } usize label_exit = code.size(); - gen(op_jf, 0, node->get_condition()->get_location()); + emit(op_jf, 0, node->get_condition()->get_location()); block_gen(node->get_code_block()); usize continue_place = code.size(); statement_generation(node->get_step()); - gen(op_jmp, jmp_place, node->get_step()->get_location()); + emit(op_jmp, jmp_place, node->get_step()->get_location()); code[label_exit].num = code.size(); load_continue_break(continue_place, code.size()); @@ -785,39 +799,39 @@ void codegen::for_gen(for_expr* node) { void codegen::forei_gen(forei_expr* node) { calc_gen(node->get_value()); - gen(op_cnt, 0, node->get_value()->get_location()); + emit(op_cnt, 0, node->get_value()->get_location()); usize ptr = code.size(); if (node->get_loop_type()==forei_expr::forei_loop_type::forindex) { - gen(op_findex, 0, node->get_location()); + emit(op_findex, 0, node->get_location()); } else { - gen(op_feach, 0, node->get_location()); + emit(op_feach, 0, node->get_location()); } if (node->get_iterator()->get_name()) { // define a new iterator auto name_node = node->get_iterator()->get_name(); const auto& str = name_node->get_name(); local.empty()? - gen(op_loadg, global_find(str), name_node->get_location()): - gen(op_loadl, local_find(str), name_node->get_location()); + emit(op_loadg, global_find(str), name_node->get_location()): + emit(op_loadl, local_find(str), name_node->get_location()); } else { // use exist variable as the iterator mcall(node->get_iterator()->get_call()); if (code.back().op==op_mcallg) { - code.back().op=op_loadg; + code.back().op = op_loadg; } else if (code.back().op==op_mcalll) { - code.back().op=op_loadl; + code.back().op = op_loadl; } else if (code.back().op==op_mupval) { - code.back().op=op_loadu; + code.back().op = op_loadu; } else { - gen(op_meq, 1, node->get_iterator()->get_location()); + emit(op_meq, 1, node->get_iterator()->get_location()); } } ++in_loop_level.back(); block_gen(node->get_code_block()); --in_loop_level.back(); - gen(op_jmp, ptr, node->get_location()); + emit(op_jmp, ptr, node->get_location()); code[ptr].num=code.size(); load_continue_break(code.size()-1, code.size()); - gen(op_pop, 0, node->get_value()->get_location());// pop vector - gen(op_pop, 0, node->get_location());// pop iterator + emit(op_pop, 0, node->get_value()->get_location());// pop vector + emit(op_pop, 0, node->get_location());// pop iterator } void codegen::statement_generation(expr* node) { @@ -841,7 +855,7 @@ void codegen::statement_generation(expr* node) { case expr_type::ast_binary: case expr_type::ast_ternary: calc_gen(node); - gen(op_pop, 0, node->get_location()); + emit(op_pop, 0, node->get_location()); break; default: break; } @@ -850,33 +864,33 @@ void codegen::statement_generation(expr* node) { void codegen::or_gen(binary_operator* node) { calc_gen(node->get_left()); usize label_jump_true_1 = code.size(); - gen(op_jt, 0, node->get_left()->get_location()); + emit(op_jt, 0, node->get_left()->get_location()); - gen(op_pop, 0, node->get_left()->get_location()); + emit(op_pop, 0, node->get_left()->get_location()); calc_gen(node->get_right()); usize label_jump_true_2 = code.size(); - gen(op_jt, 0, node->get_right()->get_location()); + emit(op_jt, 0, node->get_right()->get_location()); - gen(op_pop, 0, node->get_right()->get_location()); - gen(op_pnil, 0, node->get_right()->get_location()); + emit(op_pop, 0, node->get_right()->get_location()); + emit(op_pnil, 0, node->get_right()->get_location()); code[label_jump_true_1].num = code[label_jump_true_2].num = code.size(); } void codegen::and_gen(binary_operator* node) { calc_gen(node->get_left()); - gen(op_jt, code.size()+2, node->get_left()->get_location()); + emit(op_jt, code.size()+2, node->get_left()->get_location()); usize lable_jump_false = code.size(); - gen(op_jmp, 0, node->get_left()->get_location()); - gen(op_pop, 0, node->get_right()->get_location()); // jt jumps here + emit(op_jmp, 0, node->get_left()->get_location()); + emit(op_pop, 0, node->get_right()->get_location()); // jt jumps here calc_gen(node->get_right()); - gen(op_jt, code.size()+3, node->get_right()->get_location()); + emit(op_jt, code.size()+3, node->get_right()->get_location()); code[lable_jump_false].num = code.size(); - gen(op_pop, 0, node->get_right()->get_location()); - gen(op_pnil, 0, node->get_right()->get_location()); + emit(op_pop, 0, node->get_right()->get_location()); + emit(op_pnil, 0, node->get_right()->get_location()); // jt jumps here, avoid pop and pnil } @@ -890,11 +904,11 @@ void codegen::unary_gen(unary_operator* node) { calc_gen(node->get_value()); switch(node->get_operator_type()) { case unary_operator::unary_type::negative: - gen(op_usub, 0, node->get_location()); break; + emit(op_usub, 0, node->get_location()); break; case unary_operator::unary_type::logical_not: - gen(op_lnot, 0, node->get_location()); break; + emit(op_lnot, 0, node->get_location()); break; case unary_operator::unary_type::bitwise_not: - gen(op_bnot, 0, node->get_location()); break; + emit(op_bnot, 0, node->get_location()); break; } } @@ -918,27 +932,27 @@ void codegen::binary_gen(binary_operator* node) { case binary_operator::binary_type::cmpeq: calc_gen(node->get_left()); calc_gen(node->get_right()); - gen(op_eq, 0, node->get_location()); + emit(op_eq, 0, node->get_location()); return; case binary_operator::binary_type::cmpneq: calc_gen(node->get_left()); calc_gen(node->get_right()); - gen(op_neq, 0, node->get_location()); + emit(op_neq, 0, node->get_location()); return; case binary_operator::binary_type::bitwise_or: calc_gen(node->get_left()); calc_gen(node->get_right()); - gen(op_btor, 0, node->get_location()); + emit(op_btor, 0, node->get_location()); return; case binary_operator::binary_type::bitwise_xor: calc_gen(node->get_left()); calc_gen(node->get_right()); - gen(op_btxor, 0, node->get_location()); + emit(op_btxor, 0, node->get_location()); return; case binary_operator::binary_type::bitwise_and: calc_gen(node->get_left()); calc_gen(node->get_right()); - gen(op_btand, 0, node->get_location()); + emit(op_btand, 0, node->get_location()); return; default: break; } @@ -947,99 +961,99 @@ void codegen::binary_gen(binary_operator* node) { calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_add, 0, node->get_location()); + emit(op_add, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_addc, const_number_map.at(num), node->get_location()); + emit(op_addc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::sub: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_sub, 0, node->get_location()); + emit(op_sub, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_subc, const_number_map.at(num), node->get_location()); + emit(op_subc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::mult: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_mul, 0, node->get_location()); + emit(op_mul, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_mulc, const_number_map.at(num), node->get_location()); + emit(op_mulc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::div: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_div, 0, node->get_location()); + emit(op_div, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_divc, const_number_map.at(num), node->get_location()); + emit(op_divc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::concat: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_str) { calc_gen(node->get_right()); - gen(op_lnk, 0, node->get_location()); + emit(op_lnk, 0, node->get_location()); } else { const auto& str = ((string_literal*)node->get_right())->get_content(); regist_str(str); - gen(op_lnkc, const_string_map.at(str), node->get_location()); + emit(op_lnkc, const_string_map.at(str), node->get_location()); } break; case binary_operator::binary_type::less: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_less, 0, node->get_location()); + emit(op_less, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_lessc, const_number_map.at(num), node->get_location()); + emit(op_lessc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::leq: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_leq, 0, node->get_location()); + emit(op_leq, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_leqc, const_number_map.at(num), node->get_location()); + emit(op_leqc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::grt: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_grt, 0, node->get_location()); + emit(op_grt, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_grtc, const_number_map.at(num), node->get_location()); + emit(op_grtc, const_number_map.at(num), node->get_location()); } return; case binary_operator::binary_type::geq: calc_gen(node->get_left()); if (node->get_right()->get_type()!=expr_type::ast_num) { calc_gen(node->get_right()); - gen(op_geq, 0, node->get_location()); + emit(op_geq, 0, node->get_location()); } else { auto num = ((number_literal*)node->get_right())->get_number(); regist_num(num); - gen(op_geqc, const_number_map.at(num), node->get_location()); + emit(op_geqc, const_number_map.at(num), node->get_location()); } return; default: break; @@ -1049,10 +1063,10 @@ void codegen::binary_gen(binary_operator* node) { void codegen::trino_gen(ternary_operator* node) { calc_gen(node->get_condition()); usize label_jump_false = code.size(); - gen(op_jf, 0, node->get_condition()->get_location()); + emit(op_jf, 0, node->get_condition()->get_location()); calc_gen(node->get_left()); usize label_jump_to_exit = code.size(); - gen(op_jmp, 0, node->get_left()->get_location()); + emit(op_jmp, 0, node->get_left()->get_location()); code[label_jump_false].num = code.size(); calc_gen(node->get_right()); code[label_jump_to_exit].num = code.size(); @@ -1061,7 +1075,7 @@ 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()); break; + emit(op_pnil, 0, node->get_location()); break; case expr_type::ast_num: num_gen((number_literal*)node); break; case expr_type::ast_str: @@ -1109,11 +1123,11 @@ void codegen::block_gen(code_block* node) { 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()); + emit(op_jmp, 0, tmp->get_location()); break; case expr_type::ast_break: break_ptr.front().push_back(code.size()); - gen(op_jmp, 0, tmp->get_location()); + emit(op_jmp, 0, tmp->get_location()); break; case expr_type::ast_while: case expr_type::ast_for: @@ -1139,11 +1153,11 @@ void codegen::block_gen(code_block* node) { void codegen::ret_gen(return_expr* node) { for(u32 i = 0; iget_location()); - gen(op_pop, 0, node->get_location()); + emit(op_pop, 0, node->get_location()); + emit(op_pop, 0, node->get_location()); } calc_gen(node->get_value()); - gen(op_ret, 0, node->get_location()); + emit(op_ret, 0, node->get_location()); } const error& codegen::compile(parse& parse, linker& import) { @@ -1159,23 +1173,24 @@ const error& codegen::compile(parse& parse, linker& import) { // search global symbols first find_symbol(parse.tree()); - gen(op_intg, global.size(), parse.tree()->get_location()); // generate main block block_gen(parse.tree()); // generate exit operand, vm stops here - gen(op_exit, 0, parse.tree()->get_location()); + emit(op_exit, 0, parse.tree()->get_location()); // size out of bound check if (const_number_table.size()>0xffffff) { err.err("code", "too many constant numbers: " + - std::to_string(const_number_table.size())); + std::to_string(const_number_table.size()) + ); } if (const_string_table.size()>0xffffff) { err.err("code", "too many constant strings: " + - std::to_string(const_string_table.size())); + std::to_string(const_string_table.size()) + ); } // check global variables size diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 7756d22..e6a8e8d 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -83,7 +83,7 @@ private: i32 global_find(const std::string&); i32 upvalue_find(const std::string&); - void gen(u8, u32, const span&); + void emit(u8, u32, const span&); void num_gen(number_literal*); void str_gen(string_literal*); @@ -104,6 +104,7 @@ private: void single_def(definition_expr*); void def_gen(definition_expr*); void assignment_expression(assignment_expr*); + void gen_assignment_equal_statement(assignment_expr*); void assignment_statement(assignment_expr*); void multi_assign_gen(multi_assign*); void cond_gen(condition_expr*); diff --git a/src/nasal_misc.cpp b/src/nasal_misc.cpp index c35670d..f529db8 100644 --- a/src/nasal_misc.cpp +++ b/src/nasal_misc.cpp @@ -183,7 +183,7 @@ f64 str2num(const char* str) { i32 utf8_hdchk(const char head) { // RFC-2279 but now we use RFC-3629 so nbytes is less than 4 - const u8 c = (u8)head; + const auto c = static_cast(head); if ((c>>5)==0x06) { // 110x xxxx (10xx xxxx)^1 return 1; } diff --git a/src/nasal_opcode.h b/src/nasal_opcode.h index 812e0e5..b2cb1ff 100644 --- a/src/nasal_opcode.h +++ b/src/nasal_opcode.h @@ -9,7 +9,7 @@ namespace nasal { enum op_code_type:u8 { op_exit, // stop the virtual machine - op_intg, // init global scope + op_intg, // [deprecated] init global scope op_intl, // local scope size op_loadg, // load global value op_loadl, // load local value diff --git a/src/nasal_parse.h b/src/nasal_parse.h index 2d9f6dd..1bcf508 100644 --- a/src/nasal_parse.h +++ b/src/nasal_parse.h @@ -150,11 +150,7 @@ public: public: parse(): ptr(0), in_func(0), in_loop(0), toks(nullptr), root(nullptr) {} - ~parse() { - if (root) { - delete root; - } - } + ~parse() {delete root;} const error& compile(const lexer&); static void easter_egg(); }; diff --git a/src/nasal_vm.cpp b/src/nasal_vm.cpp index 49999a4..9a182b4 100644 --- a/src/nasal_vm.cpp +++ b/src/nasal_vm.cpp @@ -55,7 +55,7 @@ void vm::context_and_global_init() { ctx.canary = ctx.stack+STACK_DEPTH-1; /* nothing is on stack */ - ctx.top = ctx.stack; + ctx.top = ctx.stack - 1; /* clear main stack and global */ for(u32 i = 0; i(ctx.top[-1].tonum())| - static_cast(ctx.top[0].tonum())); + static_cast(ctx.top[-1].tonum())| + static_cast(ctx.top[0].tonum()) + ); --ctx.top; } inline void vm::o_btxor() { ctx.top[-1] = var::num( - static_cast(ctx.top[-1].tonum())^ - static_cast(ctx.top[0].tonum())); + static_cast(ctx.top[-1].tonum())^ + static_cast(ctx.top[0].tonum()) + ); --ctx.top; } inline void vm::o_btand() { ctx.top[-1] = var::num( - static_cast(ctx.top[-1].tonum())& - static_cast(ctx.top[0].tonum())); + static_cast(ctx.top[-1].tonum())& + static_cast(ctx.top[0].tonum()) + ); --ctx.top; } @@ -388,25 +387,36 @@ inline void vm::o_subeq() {op_calc_eq(-);} inline void vm::o_muleq() {op_calc_eq(*);} inline void vm::o_diveq() {op_calc_eq(/);} inline void vm::o_lnkeq() { - ctx.top[-1] = ctx.memr[0] = ngc.newstr(ctx.memr[0].tostr()+ctx.top[-1].tostr()); + ctx.top[-1] = ctx.memr[0] = ngc.newstr( + ctx.memr[0].tostr()+ctx.top[-1].tostr() + ); ctx.memr = nullptr; ctx.top -= imm[ctx.pc]+1; } inline void vm::o_bandeq() { - ctx.top[-1] = ctx.memr[0] = var::num(i32(ctx.memr[0].tonum())&i32(ctx.top[-1].tonum())); + ctx.top[-1] = ctx.memr[0] = var::num( + static_cast(ctx.memr[0].tonum())& + static_cast(ctx.top[-1].tonum()) + ); ctx.memr = nullptr; ctx.top -= imm[ctx.pc]+1; } inline void vm::o_boreq() { - ctx.top[-1] = ctx.memr[0] = var::num(i32(ctx.memr[0].tonum())|i32(ctx.top[-1].tonum())); + ctx.top[-1] = ctx.memr[0] = var::num( + static_cast(ctx.memr[0].tonum())| + static_cast(ctx.top[-1].tonum()) + ); ctx.memr = nullptr; ctx.top -= imm[ctx.pc]+1; } inline void vm::o_bxoreq() { - ctx.top[-1] = ctx.memr[0] = var::num(i32(ctx.memr[0].tonum())^i32(ctx.top[-1].tonum())); + ctx.top[-1] = ctx.memr[0] = var::num( + static_cast(ctx.memr[0].tonum())^ + static_cast(ctx.top[-1].tonum()) + ); ctx.memr = nullptr; ctx.top -= imm[ctx.pc]+1; } @@ -439,7 +449,9 @@ inline void vm::o_subecp() {op_calc_eq_const_and_pop(-);} inline void vm::o_mulecp() {op_calc_eq_const_and_pop(*);} inline void vm::o_divecp() {op_calc_eq_const_and_pop(/);} inline void vm::o_lnkecp() { - ctx.top[0] = ctx.memr[0] = ngc.newstr(ctx.memr[0].tostr()+cstr[imm[ctx.pc]]); + ctx.top[0] = ctx.memr[0] = ngc.newstr( + ctx.memr[0].tostr()+cstr[imm[ctx.pc]] + ); ctx.memr = nullptr; --ctx.top; } @@ -461,12 +473,12 @@ inline void vm::o_eq() { if (val1.type==vm_nil && val2.type==vm_nil) { ctx.top[0] = one; } else if (val1.type==vm_str && val2.type==vm_str) { - ctx.top[0] = (val1.str()==val2.str())?one:zero; + ctx.top[0] = (val1.str()==val2.str())? one:zero; } else if ((val1.type==vm_num || val2.type==vm_num) && val1.type!=vm_nil && val2.type!=vm_nil) { - ctx.top[0] = (val1.tonum()==val2.tonum())?one:zero; + ctx.top[0] = (val1.tonum()==val2.tonum())? one:zero; } else { - ctx.top[0] = (val1==val2)?one:zero; + ctx.top[0] = (val1==val2)? one:zero; } } @@ -476,12 +488,12 @@ inline void vm::o_neq() { if (val1.type==vm_nil && val2.type==vm_nil) { ctx.top[0] = zero; } else if (val1.type==vm_str && val2.type==vm_str) { - ctx.top[0] = (val1.str()!=val2.str())?one:zero; + ctx.top[0] = (val1.str()!=val2.str())? one:zero; } else if ((val1.type==vm_num || val2.type==vm_num) && val1.type!=vm_nil && val2.type!=vm_nil) { - ctx.top[0] = (val1.tonum()!=val2.tonum())?one:zero; + ctx.top[0] = (val1.tonum()!=val2.tonum())? one:zero; } else { - ctx.top[0] = (val1!=val2)?one:zero; + ctx.top[0] = (val1!=val2)? one:zero; } } @@ -597,7 +609,9 @@ inline void vm::o_callv() { die("out of range:"+std::to_string(val.tonum())); return; } - ctx.top[0] = var::num(f64((u8)str[num>=0? num:num+len])); + ctx.top[0] = var::num( + static_cast(static_cast(str[num>=0? num:num+len])) + ); } else if (vec.type==vm_map) { if (val.type!=vm_str) { die("must use string as the key"); diff --git a/src/optimizer.cpp b/src/optimizer.cpp index 3b785f4..25bd769 100644 --- a/src/optimizer.cpp +++ b/src/optimizer.cpp @@ -32,11 +32,11 @@ void optimizer::const_number( case binary_operator::binary_type::grt: res = left>right; break; case binary_operator::binary_type::geq: res = left>=right; break; case binary_operator::binary_type::bitwise_or: - res = i32(left)|i32(right); break; + res = static_cast(left)|static_cast(right); break; case binary_operator::binary_type::bitwise_xor: - res = i32(left)^i32(right); break; + res = static_cast(left)^static_cast(right); break; case binary_operator::binary_type::bitwise_and: - res = i32(left)&i32(right); break; + res = static_cast(left)&static_cast(right); break; default: return; } if (std::isinf(res) || std::isnan(res)) { @@ -51,9 +51,12 @@ void optimizer::const_number( number_literal* value_node) { auto res = value_node->get_number(); switch(node->get_operator_type()) { - case unary_operator::unary_type::negative: res = -res; break; - case unary_operator::unary_type::bitwise_not: res = ~i32(res); break; - case unary_operator::unary_type::logical_not: res = !res; break; + case unary_operator::unary_type::negative: + res = -res; break; + case unary_operator::unary_type::bitwise_not: + res = ~static_cast(res); break; + case unary_operator::unary_type::logical_not: + res = !res; break; } if (std::isinf(res) || std::isnan(res)) { return;