예제 #1
0
 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)
예제 #2
0
 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
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
 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)
예제 #6
0
 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
예제 #7
0
 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
예제 #8
0
 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
예제 #9
0
 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
예제 #10
0
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)
예제 #11
0
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)
예제 #12
0
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))
예제 #13
0
    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)
예제 #14
0
 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
예제 #15
0
 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
예제 #16
0
 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)
예제 #17
0
 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)
예제 #18
0
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
예제 #19
0
 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
예제 #20
0
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
예제 #21
0
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
예제 #22
0
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
예제 #23
0
    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
예제 #24
0
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()
예제 #25
0
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())
예제 #26
0
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)
예제 #27
0
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
예제 #28
0
    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
예제 #29
0
 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
예제 #30
0
    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)