#ifndef __NASAL_CODEGEN_H__ #define __NASAL_CODEGEN_H__ enum op_code { op_nop, op_load, op_pushnum,op_pushone,op_pushzero, op_pushnil, op_pushstr, op_newvec,op_newhash,op_newfunc, op_vecappend,op_hashappend, op_para,op_defaultpara,op_dynamicpara,op_funcbegin, op_unot,op_usub, op_add,op_sub,op_mul,op_div,op_lnk, op_eq,op_neq,op_less,op_leq,op_grt,op_geq, op_pop, op_jmp,op_jmptrue,op_jmpfalse, op_gccall,op_gccallvec,op_gccallhash,op_gccallfunc,op_builtincall, op_slice,op_slice2, op_memcall,op_memcallvec,op_memcallhash, op_return, op_end }; struct { int type; const char* name; }code_table[]= { {op_nop, "nop "}, {op_load, "load "}, {op_pushnum, "pnum "}, {op_pushone, "pone "}, {op_pushzero, "pzero "}, {op_pushnil, "pnil "}, {op_pushstr, "pstr "}, {op_newvec, "newv "}, {op_newhash, "newh "}, {op_newfunc, "newf "}, {op_vecappend, "vapp "}, {op_hashappend, "happ "}, {op_para, "para "}, {op_defaultpara, "deflt "}, {op_dynamicpara, "dyn "}, {op_funcbegin, "fbegin"}, {op_unot, "not "}, {op_usub, "usub "}, {op_add, "add "}, {op_sub, "sub "}, {op_mul, "mult "}, {op_div, "div "}, {op_lnk, "link "}, {op_eq, "eq "}, {op_neq, "neq "}, {op_less, "l "}, {op_leq, "leq "}, {op_grt, "g "}, {op_geq, "geq "}, {op_pop, "pop "}, {op_jmp, "jmp "}, {op_jmptrue, "jt "}, {op_jmpfalse, "jf "}, {op_gccall, "calli "}, {op_gccallvec, "callv "}, {op_gccallhash, "callh "}, {op_gccallfunc, "callf "}, {op_builtincall, "callb "}, {op_slice, "slice "}, {op_slice2, "slice2"}, {op_memcall, "mcalli"}, {op_memcallvec, "mcallv"}, {op_memcallhash, "mcallh"}, {op_return, "ret "}, {op_end, "end "}, {-1, NULL}, }; struct opcode { unsigned char op; unsigned int index; opcode(){op=op_nop;index=0;} }; // unfinished // now it can output ast but it is not byte code yet // please wait... class nasal_codegen { private: std::map number_table; std::map string_table; std::vector exec_code; int error; void nil_gen(); void number_gen(nasal_ast&); void string_gen(nasal_ast&); void vector_gen(nasal_ast&); void hash_gen(nasal_ast&); void function_gen(nasal_ast&); void call_gen(nasal_ast&); void call_id(nasal_ast&); void definition_gen(nasal_ast&); void multi_assignment_gen(nasal_ast&); void conditional_gen(nasal_ast&); void loop_gen(nasal_ast&); void calculation_gen(nasal_ast&); void block_gen(nasal_ast&); void return_gen(nasal_ast&); public: nasal_codegen(); void main_progress(nasal_ast&); void print_byte_code(); }; nasal_codegen::nasal_codegen() { error=0; number_table.clear(); string_table.clear(); return; } void nasal_codegen::nil_gen() { opcode op; op.op=op_pushnil; exec_code.push_back(op); return; } void nasal_codegen::number_gen(nasal_ast& ast) { int size=number_table.size(); double num=ast.get_num(); opcode op; if(number_table.find(num)==number_table.end()) number_table[num]=size; if(num==1) op.op=op_pushone; else if(num==0) op.op=op_pushzero; else { op.op=op_pushnum; op.index=number_table[num]; } exec_code.push_back(op); return; } void nasal_codegen::string_gen(nasal_ast& ast) { int size=string_table.size(); std::string str=ast.get_str(); opcode op; if(string_table.find(str)==string_table.end()) string_table[str]=size; op.op=op_pushstr; op.index=string_table[str]; exec_code.push_back(op); return; } void nasal_codegen::vector_gen(nasal_ast& ast) { int size=ast.get_children().size(); opcode op; op.op=op_newvec; op.index=0; exec_code.push_back(op); for(int i=0;i