def p_elseifs_1(self, p): r'''elseifs : elseifs elseif %prec PREC2''' p[0] = NoneTerminal(p) elseif_label = Label() back_patch_false(p[1], elseif_label) p[0].code = p[1].code + elseif_label.label + ": //elseif \n" + p[2].code + "\n"
def p_elseif(self, p): r'''elseif : ELSEIF LP exp RP block %prec PREC1''' p[0] = NoneTerminal(p) truelabel = Label() back_patch_true(p[3], truelabel) p[0].code = p[3].code + truelabel.label + ": //elseif epression\n" + p[5].code + "goto " + NEXT_LABEL + "; // next label\n\n"
def p_logical_operation_9(self, p): r'''logical_operation : exp AND exp''' p[0] = NoneTerminal(p) true_label = Label() back_patch_true(p[1], true_label) p[0].code = p[1].code + true_label.label + ": // logical calculation (AND)\n" + p[3].code
def p_logical_operation_10(self, p): r'''logical_operation : exp OR exp''' p[0] = NoneTerminal(p) false_label = Label() back_patch_false(p[1], false_label) p[0].code = p[1].code + false_label.label + ": // logical calculation (OR)\n" + p[3].code
def p_formal_argument(self, p): r'''formal_argument : return_type ID ''' p[0] = NoneTerminal(p) p[0].code = pop_variable(p[2]) ALL_VARIABLES.add(p[2]) global VARIABLES VARIABLES += [p[2]] p[0].t = 1
def p_func_body(self, p): r'''func_body : ID LP formal_arguments RP block ''' p[0] = NoneTerminal(p) return_phrase = "goto end;\n\n" if p[1] == "_main" else "" #pop_return_address() + return_code() p[0].code = p[1] + ":; //function decleration\n\n" + p[3].code + "\n // function body:\n" + p[5].code \ + "\n// function ended\n" + return_phrase
def p_if(self, p): r'''if : IF LP exp RP block elseif_blocks else_block''' p[3].code = p[3].ifexp if p[3].ifexp else p[3].code p[0] = NoneTerminal(p) p[0].true = Label() p[0].next = Label() falselabel = None #back patch true block back_patch_true(p[3], p[0].true) elsifblock = "" elseblock = "" elselabel = None #create label for else block and set next for it if p[7].code: elselabel = Label() elseblock = elselabel.label + ": //else\n" + p[7].code elseiflabel = None #check wheter there is elseif block if p[6].code: elseiflabel = Label() back_patch_false(p[3], elseiflabel) falselabel = elseiflabel back_patch_next(p[6], p[0].next) #check for else if p[7].code: back_patch_false(p[6], elselabel) else: back_patch_false(p[6], p[0].next) elsifblock = elseiflabel.label + ": //elseifs\n" + p[6].code elif p[7].code: back_patch_false(p[3], elselabel) falselabel = elselabel else: back_patch_false(p[3], p[0].next) falselabel = None true_block = p[0].true.label + ": " + p[5].code + "goto " + p[0].next.label + "; //next label\n\n" false_block = "" if falselabel: false_block = elsifblock + elseblock next_block = p[0].next.label + ":; //end of if statement - next\n" p[0].code = "// if statement\n//new\n" + p[3].code + true_block + false_block + next_block
def p_statement_var_dec(self, p): r'''statement_var_dec : return_type var_list SEMICOLON''' global VARIABLES p[0] = NoneTerminal(p) for var in p[2].vars: ALL_VARIABLES.add(var) #-- variable_decs = "\n".join([ p[1].rtype + " " + var + ";" for var in p[2].vars]) VARIABLES += p[2].vars # p[0].code = variable_decs + "\n" + p[2].code p[0].code = p[2].code
def p_while(self, p): r'''while : WHILE LP exp RP block''' p[0] = NoneTerminal(p) begin = Label() code_begin = Label() after = Label() back_patch_false(p[3], after) back_patch_true(p[3], code_begin) p[0].code = begin.label + ": // while begin\n\n" + p[3].code + code_begin.label + ": // while code begin\n" + p[5].code \ + "goto " + begin.label + "; //back to while begin\n\n" + after.label+ ": // end of while\n\n"
def p_function_call_1(self, p): r'''function_call : ID function_call_body''' global VARIABLES p[0] = NoneTerminal(p) return_label = Label() registers = Register.Registers.copy() variables = VARIABLES.copy() p[0].code = store_all_registers(registers) + store_all_variables(variables) + "// store return label\n" + push_address(return_label.label) p[0].code += "// calc and store function arguments\n"+ p[2].code + store_args(p[2].args) p[0].code += "// call function\ngoto " + p[1] + ";\n\n" p[0].code += "// return label:\n" + return_label.label + ":;\n" p[0].reg = Register("double") p[0].code += "// load return value\n" + pop_variable(p[0].reg.place) p[0].code += "// load regs and vars\n" + load_all_variables(variables) + load_all_registers(registers) p[0].place = p[0].reg.place
def p_for(self, p): r'''for : FOR LP ID IN exp TO exp STEPS exp RP block ''' p[0] = NoneTerminal(p) begin = Label() code_begin = Label() after = Label() initialization = "int " + p[3] + ";\n" + p[3] + " = " + p[5].get_value() + "; // FOR initialization\n" check_bundry = "if ( " + p[3] + " <= " + p[7].get_value() + " ) goto " + code_begin.label + "; // FOR check\n" check_bundry += "goto " + after.label + ";\n\n" iteration = p[3] + " = " + p[3] + " + " + p[9].get_value() + "; // FOR iteration\n" p[0].code = "// FOR BEGIN\n\n" + p[5].code + p[9].code + initialization \ + begin.label + ": // for begin\n\n" + p[7].code + check_bundry \ + code_begin.label + ": // for code begin\n" + p[11].code + iteration \ + "goto " + begin.label + "; //back to for begin\n\n" + after.label+ ": // end of for\n\n"
def p_program(self, p): r'''program : macros classes ''' p[0] = NoneTerminal(p) head = ''' #include <stdio.h> #include <stdlib.h> ''' registers = "" if len(Register.Registers) > 0: registers = "double " + " ,".join((reg.place for reg in Register.Registers)) + ";\n" stacks = "void* returnAddress;\ndouble * top = (double*) malloc(1000 * sizeof(double));\nvoid ** labelsTop = (void**) malloc(1000 * sizeof(void*));\ntop += 1000;\nlabelsTop += 1000;" variables = "\n".join([ "double" + " " + var + ";" for var in ALL_VARIABLES]) jump_to_main = "goto _main;\n\n" p[0].code = head + "int main()\n{\n\n" + variables + stacks + "\n" + registers + "\n" + p[2].vars + jump_to_main + p[2].funcs + "\n\nend : return 0;\n}" self.fileo.write(p[0].code)
def p_class(self, p): r'''class : CLASS ID LCB symbol_decs RCB ''' p[0] = NoneTerminal(p) p[0].vars = p[4].vars p[0].funcs = p[4].funcs
def p_function_call_body(self, p): r'''function_call_body : LP actual_arguments RP''' p[0] = NoneTerminal(p) p[0].code = p[2].code p[0].args = p[2].args
def p_function_call_2(self, p): r'''function_call : ID DOT ID function_call_body ''' p[0] = NoneTerminal(p) p[0].code = "\n\nDOTTED FUNCTION CALL!\n\n"
def p_unary_operation_3(self, p): r'''unary_operation : BITWISE_NOT exp''' p[0] = NoneTerminal(p) unary_operation_code(p)
def p_unary_operation_2(self, p): r'''unary_operation : NOT exp''' p[0] = NoneTerminal(p) unary_operation_code(p)
def p_symbol_dec_1(self, p): r'''symbol_dec : var_dec''' p[0] = NoneTerminal(p) p[0].vars = p[1].code
def p_symbol_decs_1(self, p): r'''symbol_decs : symbol_decs symbol_dec''' p[0] = NoneTerminal(p) p[0].vars = p[1].vars + p[2].vars p[0].funcs = p[1].funcs + p[2].funcs
def p_actual_arguments_list_1(self, p): r'''actual_arguments_list : actual_arguments_list COMMA exp''' p[0] = NoneTerminal(p) p[0].code = p[1].code + p[3].code p[0].args = p[1].args + [ p[3].get_value() ]
def p_actual_arguments_1(self, p): r'''actual_arguments : actual_arguments_list''' p[0] = NoneTerminal(p) p[0].code = p[1].code p[0].args = p[1].args
def p_binary_operation_8(self, p): r'''binary_operation : exp SHIFT_RIGHT exp''' p[0] = NoneTerminal(p) binary_operation_code(p)
def p_actual_arguments_2(self, p): r'''actual_arguments : empty''' p[0] = NoneTerminal(p) p[0].code = "" p[0].args = []
def p_classes_2(self, p): r'''classes : empty''' p[0] = NoneTerminal(p) p[0].vars = "" p[0].funcs = ""
def p_actual_arguments_list_2(self, p): r'''actual_arguments_list : exp''' p[0] = NoneTerminal(p) p[0].code = p[1].code p[0].args = [ p[1].get_value() ]
def p_comparison_operation_6(self, p): r'''comparison_operation : exp NE exp''' p[0] = NoneTerminal(p) comparison_operation_code(p)
def p_symbol_decs_2(self, p): r'''symbol_decs : empty''' p[0] = NoneTerminal(p) p[0].vars = "" p[0].funcs = ""
def p_bitwise_operation_2(self, p): r'''bitwise_operation : exp BITWISE_OR exp''' p[0] = NoneTerminal(p) binary_operation_code(p)
def p_symbol_dec_2(self, p): r'''symbol_dec : func_dec''' p[0] = NoneTerminal(p) p[0].funcs = p[1].code
def p_unary_operation_1(self, p): r'''unary_operation : SUBTRACTION exp''' p[0] = NoneTerminal(p) unary_operation_code(p)