def c_gen_code(self): before_expr_label = CodeGenManager.get_label('for_loop_expr') done_for_label = CodeGenManager.get_label('for_loop_done') init_code = [] if self.init is not None: init_code = self.init.c_gen_code() expr_code = [] if self.expression is not None: expr_code = common.if_false(self.expression, done_for_label) update_code = [] if self.update is not None: update_code = self.update.c_gen_code() body_code = [] if self.statement is not None: body_code = self.statement.c_gen_code() return [ '; for loop', '; init code', init_code, '; expression', '{0}:'.format(before_expr_label), expr_code, '; body: ', body_code, '; update', update_code, 'jmp {0}'.format(before_expr_label), '{0}:'.format(done_for_label), ]
def c_gen_code(self): before_expr_label = CodeGenManager.get_label('while_loop_expr') done_label = CodeGenManager.get_label('while_loop_done') body_code = [] if self.statement is not None: body_code = self.statement.c_gen_code() return [ '; while loop', '; expression', '{0}:'.format(before_expr_label), common.if_false(self.expression, done_label), body_code, 'jmp {0}'.format(before_expr_label), '{0}:'.format(done_label), ]
def c_gen_code(self): if_body_code = [] if self.if_statement is not None: if_body_code = self.if_statement.c_gen_code() else_body_code = [] if self.else_statement is not None: else_body_code = self.else_statement.c_gen_code() false_label = CodeGenManager.get_label('if_block_false') if_end_label = CodeGenManager.get_label('if_block_end') return [ '; if condition', common.if_false(self.expression, false_label), if_body_code, 'jmp {0}'.format(if_end_label), '{0}:'.format(false_label), else_body_code, '{0}:'.format(if_end_label), ]
def c_gen_code(self): # Quickly handle string concat to avoid multiple code gens of children. if self.operator == '+' and str(self.expr_type) == 'java.lang.String': import code_gen.string return code_gen.string.string_concat(self) # We provide the code to generate the value of each operand separately as # some operators (e.g. &&) will not necessarily evaluate both. left_operand = common.store_param(self.left_expr) right_operand = common.store_param(self.right_expr) lazy_ops = { '+': '_add_int', '-': '_sub_int', '*': '_mult_int', '/': '_divide_int', '%': '_mod_int', '&': '_eager_and', '|': '_eager_or', '>': '_greater_than', '>=': '_greater_than_eq', '<': '_less_than', '<=': '_less_than_eq', } if self.operator in lazy_ops.keys(): op_function = lazy_ops[self.operator] return [ left_operand, right_operand, 'call {0}'.format(op_function), 'pop ebx ; pop second param', 'pop ebx ; pop first param', '; eax contains a pointer to the result' ] elif self.operator == '&&': done_eval = manager.CodeGenManager.get_label('done_and_and_operator') return [ '; start &&', common.if_false(self.left_expr, done_eval), self.right_expr.c_gen_code(), '{0}:'.format(done_eval), '; eax contains a pointer to the result', '; end &&', ] elif self.operator == '||': done_eval = manager.CodeGenManager.get_label('done_or_or_operator') return [ '; start ||', common.if_true(self.left_expr, done_eval), self.right_expr.c_gen_code(), '{0}:'.format(done_eval), '; eax contains a pointer to the result', '; end ||', ] elif self.operator == '==' or self.operator == '!=': # For == and !=, we have to handle primitive types and references types # differently. equality_ops = { '==': ['_equals_prim', '_equals_ref'], '!=': ['_not_equals_prim', '_not_equals_ref'], } if self.left_expr.expr_type.is_primitive: op_function = equality_ops[self.operator][0] else: op_function = equality_ops[self.operator][1] return [ left_operand, right_operand, 'call {0}'.format(op_function), 'pop ebx ; pop second param', 'pop ebx ; pop first param', '; eax contains a pointer to the result' ] return []