bool compiler::compile_return_stmt(codegen & cg, return_stmt * rs) { FKLOG("[compiler] compile_return_stmt %p", rs); if (rs->returnlist) { if (!compile_node(cg, rs->returnlist)) { FKERR("[compiler] compile_return_stmt ret fail"); return false; } cg.push(MAKE_OPCODE(OPCODE_RETURN), rs->lineno()); cg.push(MAKE_POS(rs->returnlist->returnlist.size()), rs->lineno()); for (int i = 0; i < (int)rs->returnlist->returnlist.size(); i++) { cg.push(m_cur_addrs[i], rs->lineno()); } } else { cg.push(MAKE_OPCODE(OPCODE_RETURN), rs->lineno()); cg.push(MAKE_POS(0), rs->lineno()); } FKLOG("[compiler] compile_return_stmt %p OK", rs); return true; }
bool compiler::compile_continue_stmt(codegen & cg, continue_stmt * cs) { FKLOG("[compiler] compile_continue_stmt %p", cs); if (m_loop_continue_pos_stack.empty()) { FKERR("[compiler] compile_continue_stmt no loop to continue"); compile_seterror(cs, m_fk, efk_compile_loop_error, "no loop to continue"); return false; } int continuepos = m_loop_continue_pos_stack[m_loop_continue_pos_stack.size() - 1]; cg.push(MAKE_OPCODE(OPCODE_JMP), cs->lineno()); cg.push(MAKE_POS(continuepos), cs->lineno()); if (continuepos == -1) { // 一会统一设置 int pos = cg.byte_code_size() - 1; continue_end_pos_list & cplist = m_continue_end_pos_stack[m_continue_end_pos_stack.size() - 1]; cplist.push_back(pos); } FKLOG("[compiler] compile_continue_stmt %p OK", cs); return true; }
bool compiler::compile_assign_stmt(codegen & cg, assign_stmt * as) { FKLOG("[compiler] compile_assign_stmt %p", as); command var = 0; command value = 0; if (!compile_node(cg, as->value)) { FKERR("[compiler] compile_assign_stmt value fail"); return false; } value = m_cur_addr; FKLOG("[compiler] compile_assign_stmt value = %d", m_cur_addr); m_new_var = as->isnew; if (!compile_node(cg, as->var)) { FKERR("[compiler] compile_assign_stmt var fail"); return false; } m_new_var = false; var = m_cur_addr; FKLOG("[compiler] compile_assign_stmt var = %d", m_cur_addr); cg.push(MAKE_OPCODE(OPCODE_ASSIGN), as->lineno()); cg.push(var, as->lineno()); cg.push(value, as->lineno()); FKLOG("[compiler] compile_assign_stmt %p OK", as); return true; }
bool compiler::compile_break_stmt(codegen & cg, break_stmt * bs) { FKLOG("[compiler] compile_break_stmt %p", bs); cg.push(MAKE_OPCODE(OPCODE_JMP), bs->lineno()); cg.push(EMPTY_CMD, bs->lineno()); // 先塞个位置 int jmppos = cg.byte_code_size() - 1; beak_pos_list & bplist = m_loop_break_pos_stack[m_loop_break_pos_stack.size() - 1]; bplist.push_back(jmppos); FKLOG("[compiler] compile_break_stmt %p OK", bs); return true; }
extern void quit(long exit_code) { long msec = msec_time_stamp(); if (timing_info) { printf("\nExecution took %ld.%2ld seconds\n",msec/1000,msec%1000); #ifdef INSTRUMENT_OPS if (1) { extern int opcount[]; int i; for (i=0; i<=OPCODE_APPLY; i++) { printf("%d\t%s\n", opcount[i], opcode_name(MAKE_OPCODE(i))); } } #endif } /* close all open files */ exit((int)exit_code); }
bool compiler::compile_multi_assign_stmt(codegen & cg, multi_assign_stmt * as) { FKLOG("[compiler] compile_multi_assign_stmt %p", as); // 目前多重赋值只支持a,b,c = myfunc1(),需要告诉func1多返回几个值 m_func_ret_num = as->varlist->varlist.size(); // 编译value if (!compile_node(cg, as->value)) { FKERR("[compiler] compile_multi_assign_stmt value fail"); return false; } // 挨个编译var std::vector<command> varlist; for (int i = 0; i < (int)as->varlist->varlist.size(); i++) { m_new_var = as->isnew; if (!compile_node(cg, as->varlist->varlist[i])) { FKERR("[compiler] compile_multi_assign_stmt var fail"); return false; } m_new_var = false; varlist.push_back(m_cur_addr); } // 挨个赋值 for (int i = 0; i < (int)as->varlist->varlist.size(); i++) { command var = 0; command value = 0; var = varlist[i]; value = m_cur_addrs[i]; cg.push(MAKE_OPCODE(OPCODE_ASSIGN), as->lineno()); cg.push(var, as->lineno()); cg.push(value, as->lineno()); } FKLOG("[compiler] compile_multi_assign_stmt %p OK", as); return true; }
bool compiler::compile_yield_stmt(codegen & cg, yield_stmt * ys) { FKLOG("[compiler] compile_yield_stmt %p", ys); // 编译time command time = 0; if (!compile_node(cg, ys->time)) { FKERR("[compiler] compile_sleep_stmt time fail"); return false; } time = m_cur_addr; cg.push(MAKE_OPCODE(OPCODE_YIELD), ys->lineno()); cg.push(time, ys->lineno()); FKLOG("[compiler] compile_yield_stmt %p OK", ys); return true; }
bool compiler::compile_cmp_stmt(codegen & cg, cmp_stmt * cs) { FKLOG("[compiler] compile_cmp_stmt %p", cs); int deps = m_cmp_deps; m_cmp_deps++; command oper = 0; command left = 0; command right = 0; command dest = 0; if (cs->cmp != "not") { // oper if (cs->cmp == "&&") { oper = !deps ? MAKE_OPCODE(OPCODE_AND_JNE) : MAKE_OPCODE(OPCODE_AND); } else if (cs->cmp == "||") { oper = !deps ? MAKE_OPCODE(OPCODE_OR_JNE) : MAKE_OPCODE(OPCODE_OR); } else if (cs->cmp == "<") { oper = !deps ? MAKE_OPCODE(OPCODE_LESS_JNE) : MAKE_OPCODE(OPCODE_LESS); } else if (cs->cmp == ">") { oper = !deps ? MAKE_OPCODE(OPCODE_MORE_JNE) : MAKE_OPCODE(OPCODE_MORE); } else if (cs->cmp == "==") { oper = !deps ? MAKE_OPCODE(OPCODE_EQUAL_JNE) : MAKE_OPCODE(OPCODE_EQUAL); } else if (cs->cmp == ">=") { oper = !deps ? MAKE_OPCODE(OPCODE_MOREEQUAL_JNE) : MAKE_OPCODE(OPCODE_MOREEQUAL); } else if (cs->cmp == "<=") { oper = !deps ? MAKE_OPCODE(OPCODE_LESSEQUAL_JNE) : MAKE_OPCODE(OPCODE_LESSEQUAL); } else if (cs->cmp == "!=") { oper = !deps ? MAKE_OPCODE(OPCODE_NOTEQUAL_JNE) : MAKE_OPCODE(OPCODE_NOTEQUAL); } else if (cs->cmp == "true") { variant v; V_SET_REAL((&v), 1); int pos = cg.getconst(v); m_cur_addr = MAKE_ADDR(ADDR_CONST, pos); m_cmp_deps--; m_cmp_jne = false; return true; } else if (cs->cmp == "false") { variant v; V_SET_REAL((&v), 0); int pos = cg.getconst(v); m_cur_addr = MAKE_ADDR(ADDR_CONST, pos); m_cmp_deps--; m_cmp_jne = false; return true; } else if (cs->cmp == "is") { // left if (!compile_node(cg, cs->left)) { FKERR("[compiler] compile_cmp_stmt left fail"); return false; } m_cmp_deps--; m_cmp_jne = false; return true; } else { FKERR("[compiler] compile_cmp_stmt cmp error %s", cs->cmp.c_str()); compile_seterror(cs, m_fk, efk_compile_cmp_error, "cmp error %s", cs->cmp.c_str()); return false; } // left if (!compile_node(cg, cs->left)) { FKERR("[compiler] compile_cmp_stmt left fail"); return false; } left = m_cur_addr; // right if (!compile_node(cg, cs->right)) { FKERR("[compiler] compile_cmp_stmt right fail"); return false; } right = m_cur_addr; // result int despos = cg.alloc_stack_identifier(); dest = MAKE_ADDR(ADDR_STACK, despos); m_cur_addr = dest; cg.push(oper, cs->lineno()); cg.push(left, cs->lineno()); cg.push(right, cs->lineno()); cg.push(dest, cs->lineno()); } /* "not" */ else { oper = !deps ? MAKE_OPCODE(OPCODE_NOT_JNE) : MAKE_OPCODE(OPCODE_NOT); // left if (!compile_node(cg, cs->left)) { FKERR("[compiler] compile_cmp_stmt left fail"); return false; } left = m_cur_addr; int despos = cg.alloc_stack_identifier(); dest = MAKE_ADDR(ADDR_STACK, despos); m_cur_addr = dest; cg.push(oper, cs->lineno()); cg.push(left, cs->lineno()); cg.push(dest, cs->lineno()); } m_cmp_deps--; if (!deps) { m_cmp_jne = true; } FKLOG("[compiler] compile_cmp_stmt %p OK", cs); return true; }
bool compiler::compile_math_assign_stmt(codegen & cg, math_assign_stmt * ms) { FKLOG("[compiler] compile_math_assign_stmt %p", ms); command oper = 0; command var = 0; command value = 0; if (ms->oper == "+=") { oper = MAKE_OPCODE(OPCODE_PLUS_ASSIGN); } else if (ms->oper == "-=") { oper = MAKE_OPCODE(OPCODE_MINUS_ASSIGN); } else if (ms->oper == "*=") { oper = MAKE_OPCODE(OPCODE_MULTIPLY_ASSIGN); } else if (ms->oper == "/=") { oper = MAKE_OPCODE(OPCODE_DIVIDE_ASSIGN); } else if (ms->oper == "%=") { oper = MAKE_OPCODE(OPCODE_DIVIDE_MOD_ASSIGN); } else { FKERR("[compiler] compile_math_assign_stmt error oper type fail"); compile_seterror(ms, m_fk, efk_compile_math_type_error, "compile math assign oper type %s error", ms->oper.c_str()); return false; } // value if (!compile_node(cg, ms->value)) { FKERR("[compiler] compile_math_assign_stmt value fail"); return false; } value = m_cur_addr; FKLOG("[compiler] compile_math_assign_stmt value = %d", m_cur_addr); // var if (!compile_node(cg, ms->var)) { FKERR("[compiler] compile_math_assign_stmt var fail"); return false; } var = m_cur_addr; FKLOG("[compiler] compile_math_assign_stmt var = %d", m_cur_addr); cg.push(oper, ms->lineno()); cg.push(var, ms->lineno()); cg.push(value, ms->lineno()); FKLOG("[compiler] compile_math_assign_stmt %p OK", ms); return true; }
bool compiler::compile_if_stmt(codegen & cg, if_stmt * is) { FKLOG("[compiler] compile_if_stmt %p", is); int jnepos = 0; std::vector<int> jmpifpos; // 条件 cg.push_stack_identifiers(); if (!compile_node(cg, is->cmp)) { FKERR("[compiler] compile_if_stmt cmp fail"); return false; } cg.pop_stack_identifiers(); // cmp与jne结合 if (m_cmp_jne) { cg.push(EMPTY_CMD, is->cmp->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; } else { cg.push(MAKE_OPCODE(OPCODE_JNE), is->lineno()); cg.push(m_cur_addr, is->lineno()); cg.push(EMPTY_CMD, is->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; } m_cmp_deps = 0; m_cmp_jne = false; // if块 if (is->block) { cg.push_stack_identifiers(); if (!compile_node(cg, is->block)) { FKERR("[compiler] compile_if_stmt block fail"); return false; } cg.pop_stack_identifiers(); } // 跳出if块 if (is->elseifs || (is->elses && is->elses->block)) { cg.push(MAKE_OPCODE(OPCODE_JMP), is->lineno()); cg.push(EMPTY_CMD, is->lineno()); // 先塞个位置 jmpifpos.push_back(cg.byte_code_size() - 1); } // 开始处理elseif的 if (is->elseifs) { stmt_node_list & list = is->elseifs->stmtlist; for (int i = 0; i < (int)list.size(); i++) { elseif_stmt * eis = dynamic_cast<elseif_stmt *>(list[i]); // 跳转到else if cg.set(jnepos, MAKE_POS(cg.byte_code_size())); // 条件 cg.push_stack_identifiers(); if (!compile_node(cg, eis->cmp)) { FKERR("[compiler] compile_if_stmt cmp fail"); return false; } cg.pop_stack_identifiers(); // cmp与jne结合 if (m_cmp_jne) { cg.push(EMPTY_CMD, eis->cmp->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; } else { cg.push(MAKE_OPCODE(OPCODE_JNE), eis->lineno()); cg.push(m_cur_addr, eis->lineno()); cg.push(EMPTY_CMD, eis->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; } m_cmp_deps = 0; m_cmp_jne = false; // else if块 if (eis->block) { cg.push_stack_identifiers(); if (!compile_node(cg, eis->block)) { FKERR("[compiler] compile_if_stmt block fail"); return false; } cg.pop_stack_identifiers(); } // 跳出if块 cg.push(MAKE_OPCODE(OPCODE_JMP), eis->lineno()); cg.push(EMPTY_CMD, eis->lineno()); // 先塞个位置 jmpifpos.push_back(cg.byte_code_size() - 1); } } // 跳转到else cg.set(jnepos, MAKE_POS(cg.byte_code_size())); // else块 if (is->elses && is->elses->block) { cg.push_stack_identifiers(); if (!compile_node(cg, is->elses->block)) { FKERR("[compiler] compile_if_stmt else block fail"); return false; } cg.pop_stack_identifiers(); } // 跳转到结束 for (int i = 0; i < (int)jmpifpos.size(); i++) { cg.set(jmpifpos[i], MAKE_POS(cg.byte_code_size())); } FKLOG("[compiler] compile_if_stmt %p OK", is); return true; }
bool compiler::compile_while_stmt(codegen & cg, while_stmt * ws) { FKLOG("[compiler] compile_while_stmt %p", ws); int startpos = 0; int jnepos = 0; m_loop_break_pos_stack.push_back(beak_pos_list()); startpos = cg.byte_code_size(); m_loop_continue_pos_stack.push_back(startpos); // 条件 cg.push_stack_identifiers(); if (!compile_node(cg, ws->cmp)) { FKERR("[compiler] compile_while_stmt cmp fail"); return false; } cg.pop_stack_identifiers(); // cmp与jne结合 if (m_cmp_jne) { cg.push(EMPTY_CMD, ws->cmp->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; } else { cg.push(MAKE_OPCODE(OPCODE_JNE), ws->lineno()); cg.push(m_cur_addr, ws->lineno()); cg.push(EMPTY_CMD, ws->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; } m_cmp_deps = 0; m_cmp_jne = false; // block块 if (ws->block) { cg.push_stack_identifiers(); if (!compile_node(cg, ws->block)) { FKERR("[compiler] compile_while_stmt block fail"); return false; } cg.pop_stack_identifiers(); } // 跳回判断地方 cg.push(MAKE_OPCODE(OPCODE_JMP), ws->lineno()); cg.push(MAKE_POS(startpos), ws->lineno()); // 跳转出block块 cg.set(jnepos, MAKE_POS(cg.byte_code_size())); // 替换掉break beak_pos_list & bplist = m_loop_break_pos_stack[m_loop_break_pos_stack.size() - 1]; for (int i = 0; i < (int)bplist.size(); i++) { cg.set(bplist[i], MAKE_POS(cg.byte_code_size())); } m_loop_break_pos_stack.pop_back(); m_loop_continue_pos_stack.pop_back(); FKLOG("[compiler] compile_while_stmt %p OK", ws); return true; }
bool compiler::compile_for_loop_stmt(codegen & cg, for_loop_stmt * fs) { FKLOG("[compiler] compile_for_loop_stmt %p", fs); int startpos = 0; int jnepos = 0; int continuepos = 0; m_loop_break_pos_stack.push_back(beak_pos_list()); m_continue_end_pos_stack.push_back(continue_end_pos_list()); // 初始值 if (!compile_node(cg, fs->begin)) { FKERR("[compiler] compile_for_loop_stmt begin fail"); return false; } command begin = m_cur_addr; // 循环变量,这个作用域是全for都有效的 cg.push_stack_identifiers(); if (!compile_node(cg, fs->var)) { FKERR("[compiler] compile_for_loop_stmt var fail"); return false; } command var = m_cur_addr; // 最大值 if (!compile_node(cg, fs->end)) { FKERR("[compiler] compile_for_loop_stmt end fail"); return false; } command end = m_cur_addr; // 变化值 if (!compile_node(cg, fs->add)) { FKERR("[compiler] compile_for_loop_stmt add fail"); return false; } command add = m_cur_addr; // 塞for头 cg.push(MAKE_OPCODE(OPCODE_FORBEGIN), fs->lineno()); cg.push(var, fs->lineno()); cg.push(begin, fs->lineno()); cg.push(end, fs->lineno()); cg.push(add, fs->lineno()); cg.push(EMPTY_CMD, fs->lineno()); // 先塞个位置 jnepos = cg.byte_code_size() - 1; // 需要continue end m_loop_continue_pos_stack.push_back(-1); startpos = cg.byte_code_size(); // block块 if (fs->block) { cg.push_stack_identifiers(); if (!compile_node(cg, fs->block)) { FKERR("[compiler] compile_for_loop_stmt block fail"); return false; } cg.pop_stack_identifiers(); } continuepos = cg.byte_code_size(); // 最大值 if (!compile_node(cg, fs->end)) { FKERR("[compiler] compile_for_loop_stmt end fail"); return false; } end = m_cur_addr; // 变化值 if (!compile_node(cg, fs->add)) { FKERR("[compiler] compile_for_loop_stmt add fail"); return false; } add = m_cur_addr; // 塞for loop cg.push(MAKE_OPCODE(OPCODE_FORLOOP), fs->lineno()); cg.push(var, fs->lineno()); cg.push(end, fs->lineno()); cg.push(add, fs->lineno()); cg.push(MAKE_POS(startpos), fs->lineno()); // 跳转出block块 cg.set(jnepos, MAKE_POS(cg.byte_code_size())); // 替换掉break beak_pos_list & bplist = m_loop_break_pos_stack[m_loop_break_pos_stack.size() - 1]; for (int i = 0; i < (int)bplist.size(); i++) { cg.set(bplist[i], MAKE_POS(cg.byte_code_size())); } m_loop_break_pos_stack.pop_back(); // 替换掉continue continue_end_pos_list & cplist = m_continue_end_pos_stack[m_continue_end_pos_stack.size() - 1]; for (int i = 0; i < (int)cplist.size(); i++) { cg.set(cplist[i], MAKE_POS(continuepos)); } m_continue_end_pos_stack.pop_back(); m_loop_continue_pos_stack.pop_back(); // 离开作用域 cg.pop_stack_identifiers(); FKLOG("[compiler] compile_for_loop_stmt %p OK", fs); return true; }
bool compiler::compile_switch_stmt(codegen & cg, switch_stmt * ss) { FKLOG("[compiler] compile_switch_stmt %p", ss); command caseleft; command caseresult; cg.push_stack_identifiers(); // caseleft if (!compile_node(cg, ss->cmp)) { FKERR("[compiler] compile_switch_stmt cmp fail"); return false; } caseleft = m_cur_addr; // caseresult int despos = cg.alloc_stack_identifier(); caseresult = MAKE_ADDR(ADDR_STACK, despos); switch_caselist_node * scln = dynamic_cast<switch_caselist_node *>(ss->caselist); std::vector<int> jmpswitchposlist; // 挨个和case的比较 for (int i = 0; i < (int)scln->list.size(); i++) { command oper = MAKE_OPCODE(OPCODE_EQUAL); command left = caseleft; command right = 0; command dest = caseresult; switch_case_node * scn = dynamic_cast<switch_case_node *>(scln->list[i]); // right if (!compile_node(cg, scn->cmp)) { FKERR("[compiler] compile_switch_stmt case cmp fail"); return false; } right = m_cur_addr; // push case cg.push(oper, scn->lineno()); cg.push(left, scn->lineno()); cg.push(right, scn->lineno()); cg.push(dest, scn->lineno()); // push jmp cg.push(MAKE_OPCODE(OPCODE_JNE), scn->lineno()); cg.push(dest, scn->lineno()); cg.push(EMPTY_CMD, scn->lineno()); // 先塞个位置 int jnepos = cg.byte_code_size() - 1; // build block if (scn->block) { cg.push_stack_identifiers(); if (!compile_node(cg, scn->block)) { FKERR("[compiler] compile_switch_stmt block fail"); return false; } cg.pop_stack_identifiers(); } // 跳出switch块 cg.push(MAKE_OPCODE(OPCODE_JMP), scn->lineno()); cg.push(EMPTY_CMD, scn->lineno()); // 先塞个位置 int jmpswitchpos = cg.byte_code_size() - 1; jmpswitchposlist.push_back(jmpswitchpos); // 跳转出case块 cg.set(jnepos, MAKE_POS(cg.byte_code_size())); } // default if (ss->def) { cg.push_stack_identifiers(); if (!compile_node(cg, ss->def)) { FKERR("[compiler] compile_switch_stmt default fail"); return false; } cg.pop_stack_identifiers(); } cg.pop_stack_identifiers(); // 塞跳出的 for (int i = 0; i < (int)jmpswitchposlist.size(); i++) { cg.set(jmpswitchposlist[i], MAKE_POS(cg.byte_code_size())); } FKLOG("[compiler] compile_switch_stmt %p OK", ss); return true; }
bool compiler::compile_math_expr_node(codegen & cg, math_expr_node * mn) { FKLOG("[compiler] compile_math_expr_node %p", mn); command oper = 0; command left = 0; command right = 0; command dest = 0; if (mn->oper == "+") { oper = MAKE_OPCODE(OPCODE_PLUS); } else if (mn->oper == "-") { oper = MAKE_OPCODE(OPCODE_MINUS); } else if (mn->oper == "*") { oper = MAKE_OPCODE(OPCODE_MULTIPLY); } else if (mn->oper == "/") { oper = MAKE_OPCODE(OPCODE_DIVIDE); } else if (mn->oper == "%") { oper = MAKE_OPCODE(OPCODE_DIVIDE_MOD); } else if (mn->oper == "..") { oper = MAKE_OPCODE(OPCODE_STRING_CAT); } else { FKERR("[compiler] compile_math_expr_node error oper type fail"); compile_seterror(mn, m_fk, efk_compile_math_type_error, "compile math oper type %s error", mn->oper.c_str()); return false; } // left if (!compile_node(cg, mn->left)) { FKERR("[compiler] compile_math_expr_node left fail"); return false; } left = m_cur_addr; // right if (!compile_node(cg, mn->right)) { FKERR("[compiler] compile_math_expr_node left fail"); return false; } right = m_cur_addr; // result int despos = cg.alloc_stack_identifier(); dest = MAKE_ADDR(ADDR_STACK, despos); m_cur_addr = dest; cg.push(oper, mn->lineno()); cg.push(left, mn->lineno()); cg.push(right, mn->lineno()); cg.push(dest, mn->lineno()); FKLOG("[compiler] compile_math_expr_node %p OK", mn); return true; }
bool compiler::compile_function_call_node(codegen & cg, function_call_node * fn) { FKLOG("[compiler] compile_function_call_node %p", fn); fake * fk = m_fk; myflexer * mf = m_mf; int ret_num = m_func_ret_num; m_func_ret_num = 1; // 参数 std::vector<command> arglist; if (fn->arglist) { for (int i = 0; i < (int)fn->arglist->arglist.size(); i++) { syntree_node* sn = fn->arglist->arglist[i]; if (!compile_node(cg, sn)) { FKERR("[compiler] compile_function_call_node arg fail"); return false; } arglist.push_back(m_cur_addr); } } // 调用位置 command callpos; if (!fn->prefunc) { String func = fn->fuc; // 1 检查变量 int pos = cg.getvariable(func); if (pos != -1) { // 是用变量来调用函数 callpos = MAKE_ADDR(ADDR_STACK, pos); } // 2 检查struct else if (mf->is_have_struct(func)) { // 直接替换成map variant v; v = fk->sh.allocsysstr(MAP_FUNC_NAME); pos = cg.getconst(v); callpos = MAKE_ADDR(ADDR_CONST, pos); } // 3 检查本地函数 else if (mf->is_have_func(func)) { // 申请字符串变量 variant v; // 拼上包名 String pname = fkgen_package_name(mf->get_package(), func); v = fk->sh.allocsysstr(pname.c_str()); pos = cg.getconst(v); callpos = MAKE_ADDR(ADDR_CONST, pos); } // 4 直接字符串使用 else { // 申请字符串变量 variant v; v = fk->sh.allocsysstr(func.c_str()); pos = cg.getconst(v); callpos = MAKE_ADDR(ADDR_CONST, pos); } } else { if (!compile_node(cg, fn->prefunc)) { FKERR("[compiler] compile_function_call_node arg fail"); return false; } callpos = m_cur_addr; } // oper command oper; oper = MAKE_OPCODE(OPCODE_CALL); // 调用类型 command calltype; if (fn->fakecall) { calltype = MAKE_POS(CALL_FAKE); } else if (fn->classmem_call) { calltype = MAKE_POS(CALL_CLASSMEM); } else { calltype = MAKE_POS(CALL_NORMAL); } // 参数个数 command argnum; argnum = MAKE_POS(arglist.size()); if (arglist.size() > MAX_FAKE_PARAM_NUM) { FKERR("[compiler] compile_function_call_node arg too much"); compile_seterror(fn, m_fk, efk_compile_variable_not_found, "arg too much"); return false; } // 返回值个数 command retnum; retnum = MAKE_POS(ret_num); // 返回值 std::vector<command> ret; for (int i = 0; i < ret_num; i++) { int retpos = cg.alloc_stack_identifier(); ret.push_back(MAKE_ADDR(ADDR_STACK, retpos)); m_cur_addrs[i] = ret[i]; } m_cur_addr = ret[0]; cg.push(oper, fn->lineno()); cg.push(calltype, fn->lineno()); cg.push(callpos, fn->lineno()); cg.push(retnum, fn->lineno()); for (int i = 0; i < ret_num; i++) { cg.push(ret[i], fn->lineno()); } cg.push(argnum, fn->lineno()); for (int i = 0; i < (int)arglist.size(); i++) { cg.push(arglist[i], fn->lineno()); } FKLOG("[compiler] compile_function_call_node %p OK", fn); return true; }