def exitExpresion(self, ctx: AangParser.ExpresionContext): if ctx.Y_SIMBOLO() != None or ctx.O_SIMBOLO() != None: operator = self.PilaOper.pop() leftOperand = self.PilaO.pop() rightOperand = self.PilaO.pop() Type = SemanticCube().cube[rightOperand[1], leftOperand[1], operator] if Type == Types().ERROR: raise Exception(Types().ERROR) elif Type == Types().INT: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getEntera())) elif Type == Types().CHAR: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getChar())) elif Type == Types().BOOL: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getBooleanos())) result = self.PilaO.top() quad = Quadruple(operator, rightOperand[0], leftOperand[0], result[0]) self.FilaQuads.append(quad) quad2 = Quadruple(operator, rightOperand[2], leftOperand[2], result[2]) self.FilaQuadsMemoria.append(quad2)
def enterFc(self, ctx: AangParser.FcContext): operator = "GOSUB" rightOperand = self.PilaFuncParam.top() leftOperand = None result = None quad = Quadruple(operator, rightOperand, leftOperand, result) quad2 = Quadruple(operator, rightOperand, leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) if not self.functionDirectory.checkVoid(self.PilaFuncParam.top()): operator = "=*" rightOperand = self.PilaFuncParam.top() leftOperand = None Type = self.functionDirectory.getReturnType( self.PilaFuncParam.top()) # self.PilaO.push((self.Avail.newElement(), Type, self.memoriaGlobal.getTemporales())) if Type == Types().INT: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getEntera())) elif Type == Types().CHAR: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getChar())) elif Type == Types().BOOL: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getBooleanos())) result = self.PilaO.top() quad = Quadruple(operator, rightOperand, leftOperand, result[0]) quad2 = Quadruple(operator, rightOperand, leftOperand, result[2]) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) self.PilaFuncParam.pop() pass
def exitFactor(self, ctx: AangParser.FactorContext): if ctx.D_PARENTESIS() != None: self.PilaOper.pop() if (self.PilaOper.top() == '/' or self.PilaOper.top() == '*'): operator = str(self.PilaOper.pop()) rightOperand = self.PilaO.pop() leftOperand = self.PilaO.pop() Type = SemanticCube().cube[rightOperand[1], leftOperand[1], operator] if Type == Types().ERROR: raise Exception(Types().ERROR) elif Type == Types().INT: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getEntera())) elif Type == Types().CHAR: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getChar())) elif Type == Types().BOOL: self.PilaO.push((self.Avail.newElement(), Type, self.memoriaTemporal.getBooleanos())) result = self.PilaO.top() quad = Quadruple(operator, leftOperand[0], rightOperand[0], result[0]) self.FilaQuads.append(quad) quad2 = Quadruple(operator, leftOperand[2], rightOperand[2], result[2]) self.FilaQuadsMemoria.append(quad2)
def desde_incremento_quad(self): constant_dir = VirtualMemory().addConstant(1, 'int') result = VirtualMemory().getDir(self.scope, True, 'int') quad = Quadruple('+', self.p_operands.pop(), constant_dir, result) self.quadruples.append(quad) quad = Quadruple('=', result, None, self.p_operands.pop()) self.quadruples.append(quad)
def enterPintar(self, ctx: AangParser.PintarContext): operator = "pintar" rightOperand = None leftOperand = None result = None quad = Quadruple(operator, rightOperand, leftOperand, result) quad2 = Quadruple(operator, rightOperand, leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2)
def exitEscribir(self, ctx: AangParser.EscribirContext): operator = self.PilaOper.pop() leftOperand = self.PilaO.pop() rightOperand = None result = None quad = Quadruple(operator, leftOperand[0], rightOperand, result) self.FilaQuads.append(quad) quad2 = Quadruple(operator, leftOperand[2], rightOperand, result) self.FilaQuadsMemoria.append(quad2) pass
def enterColor(self, ctx: AangParser.ColorContext): operator = "color" rightOperand = str(ctx.HEXADECIMAL()) leftOperand = None result = None quad = Quadruple(operator, rightOperand, leftOperand, result) quad2 = Quadruple(operator, rightOperand, leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) pass
def exitMover(self, ctx: AangParser.MoverContext): operator = "mover" rightOperand = self.PilaO.pop() leftOperand = None result = None quad = Quadruple(operator, rightOperand[0], leftOperand, result) quad2 = Quadruple(operator, rightOperand[2], leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) pass
def enterPrograma(self, ctx: AangParser.ProgramaContext): operator = "Goto" rightOperand = None leftOperand = None result = "vacio" quad = Quadruple(operator, rightOperand, leftOperand, result) quad2 = Quadruple(operator, rightOperand, leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) pass
def p_crea_else_cuadruplo(p): '''crea_else_cuadruplo : ''' quadruple = Quadruple(edjo.quadruple_number, 'GOTO', None, None, None) edjo.quadruple_list.append(quadruple) quadruple_number_to_fill = edjo.jump_list.pop() quadruple = edjo.quadruple_list[quadruple_number_to_fill] edjo.jump_list.append(edjo.quadruple_number - 1) edjo.quadruple_number += 1 quadruple.fill_quadruple_jump(edjo.quadruple_number)
def p_go_sub(p): ''' go-sub :''' c_function = symbol_table.get_scope().current_function quad = Quadruple("GOSUB", c_function.name, None, c_function.func_start) quad_stack.push_quad(quad) var_table = symbol_table.get_scope().get_var(c_function.name) if (var_table.var_type != 'void'): temp = Avail.get_instance().next(var_table.var_type) exp_handler.push_operand(temp, var_table.var_type) quad = Quadruple("=", var_table.address, None, temp) quad_stack.push_quad(quad)
def attempt_assignment_quadruple(var_id): var_table = symbol_table.get_scope().get_var(var_id) result, result_type = exp_handler.pop_operand() if var_table.var_type == result_type: if var_table.is_array: arr_address, var_type = exp_handler.pop_operand() quad = Quadruple("=", result, None, arr_address) quad_stack.push_quad(quad) else: quad = Quadruple("=", result, None, var_table.address) quad_stack.push_quad(quad) else: raise SemanticError("TYPE MISMATCH: can't assign: {} to: {}".format( result_type, var_table.var_type))
def generate_quad(self): '''Metodo para genera cuadruplos''' # Checa si el op es uno de los siguientes operadores''' op = self.popper.top if op in ['+=', '-=', '*=', '/=']: self.generate_assignment_op_quad() return op = self.popper.pop() # Voltea operandos para un cuadruplo de asignacion simple if op == '=': left_operand = self.pile_o.pop() right_operand = self.pile_o.pop() else: right_operand = self.pile_o.pop() left_operand = self.pile_o.pop() # Verfica la validez sematica res = semantic_cube[right_operand.get_type()][left_operand.get_type()][op] # Si la sematica es valida if res != 'Error': # Obtiene el nombre o valor de los operandoss name_left = left_operand.get_name() name_right = right_operand.get_name() if name_left == 'constant': name_left = left_operand.get_value() if name_right == 'constant': name_right = right_operand.get_value() # Genera cuadruplo if op == '=': quad = Quadruple(self.cont, op, name_left, '', name_right) else: # Genera variable temporal temp_name = get_var_type(res) + get_var_scope(self.scope) + 't' + str(self.temporal_id) temp = Variable(temp_name, None, res, self.scope, 1) # Aumenta id de temporales self.temporal_id += 1 quad = Quadruple(self.cont, op, name_left, name_right, temp.get_name()) # pushea temporal a pila de operandos self.pile_o.push(temp) # Insert cuadruplo en la lista de cuadruplos self.quadruples.append(quad) self.cont += 1 else: left_type = left_operand.get_type() right_type = right_operand.get_type() msg = 'Error 4001: Type missmatch ' + left_type + ' and ' + right_type + ' for operator: ' + str(op) raise TypeError(msg)
def enterCiclo2(self, ctx: AangParser.Ciclo2Context): if (self.PilaO.top()[1] != 'bool'): raise Exception( "El resultado del la condicion del if no es booleano") operator = "GotoF" rightOperand = self.PilaO.pop() leftOperand = None result = "vacio" quad = Quadruple(operator, rightOperand[0], leftOperand, result) self.FilaQuads.append(quad) quad2 = Quadruple(operator, rightOperand[2], leftOperand, result) self.FilaQuadsMemoria.append(quad2) self.PSaltos.push(len(self.FilaQuads)) pass
def enterAgregar_args(self, ctx: AangParser.Agregar_argsContext): self.ParameterCounter = self.ParameterCounter - 1 Result = self.PilaO.top() operator = "PARAMETER" rightOperand = Result[2] leftOperand = None result = ("Par" + str( self.functionDirectory.numOfParameters(self.PilaFuncParam.top()) - (self.ParameterCounter))) quad = Quadruple(operator, Result[0], leftOperand, result) quad2 = Quadruple(operator, rightOperand, leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) pass
def exitFuncion(self, ctx: AangParser.FuncionContext): self.functionDirectory.setLocalVariables(self.PilaFunc.top(), len(self.localVarTable.vars)) self.functionDirectory.setTemporalVariables(self.PilaFunc.top(), self.memoriaGlobal.t) self.PilaFunc.pop() operator = "EndFunc" rightOperand = None leftOperand = None result = None quad = Quadruple(operator, rightOperand, leftOperand, result) quad2 = Quadruple(operator, rightOperand, leftOperand, result) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2)
def quad_gosub(self, quad_func, func_type): return_value = None if func_type != 'void': return_value = VirtualMemory().getDir(self.scope, True, func_type) quad = Quadruple('GOSUB', return_value, None, quad_func) self.p_operands.append(return_value) self.quadruples.append(quad)
def p_pfc_move_forward(p): '''pfc_move_forward : ''' operand = edjo.operand_stack.pop() quadruple = Quadruple(edjo.quadruple_number, 'MOVE_FORWARD', operand, None, None) edjo.quadruple_list.append(quadruple) edjo.quadruple_number += 1
def exitFun_regresar(self, ctx: AangParser.Fun_regresarContext): if self.PilaO.top()[1] == self.functionDirectory.getReturnType( self.PilaFunc.top()): operator = "RETURN" rightOperand = None leftOperand = None result = self.PilaO.pop() quad = Quadruple(operator, rightOperand, leftOperand, result[0]) quad2 = Quadruple(operator, rightOperand, leftOperand, result[2]) self.FilaQuads.append(quad) self.FilaQuadsMemoria.append(quad2) else: raise Exception( "The return type does not match with the function {}".format( self.PilaFunc.top())) pass
def p_pfc_turn_left(p): '''pfc_turn_left : ''' operand = edjo.operand_stack.pop() quadruple = Quadruple(edjo.quadruple_number, 'TURN_LEFT', operand, None, None) edjo.quadruple_list.append(quadruple) edjo.quadruple_number += 1
def p_pfc_draw_circle(p): '''pfc_draw_circle : ''' operand = edjo.operand_stack.pop() quadruple = Quadruple(edjo.quadruple_number, 'DRAW_CIRCLE', operand, None, None) edjo.quadruple_list.append(quadruple) edjo.quadruple_number += 1
def p_crea_print(p): '''crea_print : ''' operand = edjo.operand_stack.pop() quadruple = Quadruple(edjo.quadruple_number, 'PRINT', operand, None, None) edjo.quadruple_list.append(quadruple) edjo.quadruple_number += 1
def generate_gosub(self, name, func_type): res_type = get_var_type(func_type) initial_address = self.func_counter.get(name, '_')[0] quad = Quadruple(self.cont, 'Gosub', res_type + 'g' + name, '', initial_address) self.quadruples.append(quad) self.cont += 1
def p_fin_func_quad(p): '''fin_func_quad : ''' function_type = p[-10] if function_type == 'void' and edjo.return_flag: print( 'Function {0} of type {1} should not have return statement'.format( edjo.current_scope, function_type)) sys.exit() elif function_type != 'void' and not edjo.return_flag: print('Function {0} of type {1} should have return statement'.format( edjo.current_scope, function_type)) sys.exit() else: quadruple = Quadruple(edjo.quadruple_number, 'ENDPROC', None, None, None) edjo.quadruple_list.append(quadruple) if edjo.return_flag: while edjo.return_list: quadruple_number_to_fill = edjo.return_list.pop() edjo.quadruple_list[quadruple_number_to_fill - 1].fill_quadruple_jump(edjo.quadruple_number) edjo.quadruple_number += 1 edjo.return_flag = False edjo.current_scope = edjo.global_scope edjo.memory.reset_temporal_memory()
def p_loop_end(p): ''' loop-end :''' end = jumps_stack.pop_quad() returning = jumps_stack.pop_quad() quad = Quadruple("GOTO", None, None, returning.result().id) quad_stack.push_quad(quad) end.set_jump(QuadrupleStack.next_quad_id())
def p_else_jump(p): ''' else-jump :''' inconditional_jump = Quadruple("GOTO", None, None, PendingJump()) quad_stack.push_quad(inconditional_jump) pending_jump_quad = jumps_stack.pop_quad() pending_jump_quad.set_jump(QuadrupleStack.next_quad_id()) jumps_stack.push_quad(inconditional_jump)
def p_pfc_set_position(p): '''pfc_set_position : ''' y = edjo.operand_stack.pop() x = edjo.operand_stack.pop() quadruple = Quadruple(edjo.quadruple_number, 'SET_POSITION', x, y, None) edjo.quadruple_list.append(quadruple) edjo.quadruple_number += 1
def end_mientras(self): end = self.p_jumps.pop() return_goto = self.p_jumps.pop() quad = Quadruple('GOTO', None, None, return_goto) self.quadruples.append(quad) self.quadruples[end].result = len(self.quadruples) + 1
def generate_param(self, argument, param): if argument.get_name() == 'constant': argument = argument.get_value() else: argument = argument.get_name() quad = Quadruple(self.cont, 'Param', argument, '', createParam(param)) self.quadruples.append(quad) self.cont += 1
def quad_arit_cond(self, var_table={}): dim_arr1 = [] dim_arr2 = [] operator = self.p_operators.pop() right_operando = self.p_operands.pop() left_operando = self.p_operands.pop() right_type_copy = right_type = self.p_types.pop() left_type_copy = left_type = self.p_types.pop() if var_table != {}: for var_data in var_table.values(): if right_operando == var_data['dir']: if 'is_array' in var_data: if var_data['is_array']: right_type_copy = 'array' for dim in var_data['dimensions']: dim_arr1.append(dim['dims']) if left_operando == var_data['dir']: if 'is_array' in var_data: if var_data['is_array']: left_type_copy = 'array' for dim in var_data['dimensions']: dim_arr2.append(dim['dims']) result_type = self.sc.cube[operator][right_type][left_type] if result_type == 'err': raise TypeError( f"Tipo de operandos no comptabile para operador {operator}: '{left_type}' y '{right_type}'" ) if dim_arr1 != dim_arr2 and operator in ['-', '+']: raise TypeError( "Ambas matrices/arreglos tienen que ser del mismo tamaño") if right_type_copy == 'array' and left_type_copy == 'array': if result_type not in ['int', 'float']: raise TypeError( f"Tipo de operandos no comptabile para operador {operator}: '{left_type}' y '{right_type}'" ) right_operando = (right_operando, dim_arr1) left_operando = (left_operando, dim_arr2) if operator == '+': operator = '+arr' elif operator == '-': operator = '-arr' else: operator = '*arr' result = VirtualMemory().getDir(self.scope, True, result_type) quad = Quadruple(operator, left_operando, right_operando, result) self.p_operands.append(result) self.p_types.append(result_type) self.quadruples.append(quad)