Пример #1
0
    def __init__(self):
        super(GenerateCode, self).__init__()

        # version diccionario para temporales
        self.versions = defaultdict(int)

        # El código generado (lista de tuplas)
        self.code = BasicBlock()
        self.start_block = self.code

        # Una lista de declaraciones externas (y tipos)
        self.externs = []
Пример #2
0
 def visit_WhileStatement(self, node):
     while_block = WhileBlock()
     self.code.next_block = while_block
     # condition
     self.switch_block(while_block)
     self.visit(node.condition)
     while_block.test = node.condition.gen_location
     # body
     while_block.body = BasicBlock()
     self.switch_block(while_block.body)
     self.visit(node.body)
     while_block.next_block = BasicBlock()
     self.switch_block(while_block.next_block)
Пример #3
0
 def visit_IfStatement(self, node):
     if_block = IfBlock()
     self.code.next_block = if_block
     # condition
     self.switch_block(if_block)
     self.visit(node.condition)
     if_block.test = node.condition.gen_location
     # then branch
     if_block.if_branch = BasicBlock()
     self.switch_block(if_block.if_branch)
     self.visit(node.then_b)
     # else branch
     if node.else_b:
         if_block.else_branch = BasicBlock()
         self.switch_block(if_block.else_branch)
         self.visit(node.else_b)
     # fija el siguiente bloque
     if_block.next_block = BasicBlock()
     self.switch_block(if_block.next_block)
Пример #4
0
class GenerateCode(hocast.NodeVisitor):
    '''
	Clase Visitor Node que crea secuencias de instrucciones de 3-direcciones.
	'''
    def __init__(self):
        super(GenerateCode, self).__init__()

        # version diccionario para temporales
        self.versions = defaultdict(int)

        # El código generado (lista de tuplas)
        self.code = BasicBlock()
        self.start_block = self.code

        # Una lista de declaraciones externas (y tipos)
        self.externs = []

    def new_temp(self, typeobj):
        '''
		Crea una nueva variable temporal de un tipo dado.
		'''
        name = "__%s_%d" % (typeobj.name, self.versions[typeobj.name])
        self.versions[typeobj.name] += 1
        return name

    # Debe implementar métodos visit_Nodename para todos los demas nodos
    # del AST.  En su código, se tendrá que hacer las instrucciones y
    # agregarlas a la lista self.code.
    #
    # Siguen algunos métodos de ejemplo.  Deberá ajustarlos dependiendo
    # de los nombres de los nodos AST que se haya definido.

    def visit_Literal(self, node):
        # Crea un nuevo nombre de variable temporal
        target = self.new_temp(node.type)

        # Crea el opcode SSA y lo agrega a la lista de instrucciones generadas
        inst = ('literal_' + node.type.name, node.value, target)
        self.code.append(inst)

        # Graba el nombre de la variable temporal donde el valor fue colocado
        node.gen_location = target

    def visit_BinaryOp(self, node):
        # Visita las expresiones izquierda y derecha
        self.visit(node.left)
        self.visit(node.right)

        # Crea un nuevo temporal para almacenar el resultado
        target = self.new_temp(node.type)

        # Crea opcode y agrega a la lista
        opcode = binary_ops[node.op] + "_" + node.left.type.name
        inst = (opcode, node.left.gen_location, node.right.gen_location,
                target)
        self.code.append(inst)

        # Almacena localizacion del resultado en el nodo
        node.gen_location = target

    def visit_RelationalOp(self, node):
        # Visit las expresiones izquierda y derecha
        self.visit(node.left)
        self.visit(node.right)

        # Cree un temporal nuevo para almacer el resultado
        target = self.new_temp(node.type)

        # Cree el opcode y agregarlo a la lista
        #opcode = binary_ops[node.op] + "_"+node.left.type.name
        opcode = "cmp" + "_" + node.left.type.name
        inst = (opcode, binary_ops[node.op], node.left.gen_location,
                node.right.gen_location, target)
        self.code.append(inst)

        # Almacene localizacion del resultado al nodo
        node.gen_location = target

    def visit_PrintStatement(self, node):
        # Visit la expresion print
        self.visit(node.expr)

        # Cree el opcode y agregarlo a la lista
        inst = ('print_' + node.expr.type.name, node.expr.gen_location)
        self.code.append(inst)

    def visit_Program(self, node):
        for inst in node.program:
            self.visit(inst)

    #def visit_Statements(self,node):
    #    self.visit(node.expr)
    #    inst = ('print_'+node.expr.type.name, node.expr.gen_location)
    #    self.code.append(inst)

    #def visit_Statement(self,node):
    #    self.visit(node.expr)
    #    inst = ('print_'+node.expr.type.name, node.expr.gen_location)
    #    self.code.append(inst)

    def visit_ConstDeclaration(self, node):
        # localice en memoria
        inst = ('alloc_' + node.type.name, node.id)
        self.code.append(inst)
        # almacene valor inicial
        self.visit(node.value)
        inst = ('store_' + node.type.name, node.value.gen_location, node.id)
        self.code.append(inst)

    def visit_VarDeclaration(self, node):
        # localice en memoria
        inst = ('alloc_' + node.type.name, node.id)
        self.code.append(inst)
        # almacene pot. val inicial
        if node.value:
            self.visit(node.value)
            inst = ('store_' + node.type.name, node.value.gen_location,
                    node.id)
            self.code.append(inst)

    def visit_LoadLocation(self, node):
        target = self.new_temp(node.type)
        inst = ('load_' + node.type.name, node.name, target)
        self.code.append(inst)
        node.gen_location = target

    def visit_FuncCall(self, node):
        arglist_gen_locations = []
        if node.arglist:
            self.visit(node.arglist)
            for arg in node.arglist.arglist:
                arglist_gen_locations.append(arg.gen_location)
        target = self.new_temp(node.type)
        inst = ('call_' + node.type.name, node.id, *arglist_gen_locations,
                target)
        self.code.append(inst)
        node.gen_location = target

    def visit_Arglist(self, node):
        for arg in node.arglist:
            self.visit(arg)

    #def visit_Extern(self,node):
    #    self.visit(node.expr)
    #    inst = ('print_'+node.expr.type.name, node.expr.gen_location)
    #    self.code.append(inst)

    #def visit_FuncPrototype(self,node):
    #    self.visit(node.expr)
    #    inst = ('print_'+node.expr.type.name, node.expr.gen_location)
    #    self.code.append(inst)

    #def visit_Parameters(self,node):
    #    self.visit(node.expr)
    #    inst = ('print_'+node.expr.type.name, node.expr.gen_location)
    #    self.code.append(inst)
    #    node.gen_location = target

    #def visit_ParamDecl(self,node):
    #    self.visit(node.expr)
    #    inst = ('print_'+node.expr.type.name, node.expr.gen_location)
    #    self.code.append(inst)

    def visit_AsgnIdExpr(self, node):
        self.visit(node.expr)

        inst = ('store_' + node.expr.type.name, node.expr.gen_location,
                node.location)
        self.code.append(inst)

    def visit_UnaryOp(self, node):
        self.visit(node.left)
        target = self.new_temp(node.type)
        opcode = unary_ops[node.op] + "_" + node.left.type.name
        inst = (opcode, node.left.gen_location, target)
        self.code.append(inst)
        node.gen_location = target

    def visit_IfStatement(self, node):
        if_block = IfBlock()
        self.code.next_block = if_block
        # condition
        self.switch_block(if_block)
        self.visit(node.condition)
        if_block.test = node.condition.gen_location
        # then branch
        if_block.if_branch = BasicBlock()
        self.switch_block(if_block.if_branch)
        self.visit(node.condition)
        self.visit(node.then_b)
        # else branch
        if node.else_b:
            if_block.else_branch = BasicBlock()
            self.switch_block(if_block.else_branch)
            self.visit(node.else_b)
        # fija el siguiente bloque
        if_block.next_block = BasicBlock()
        self.switch_block(if_block.next_block)

    def visit_WhileStatement(self, node):
        while_block = WhileBlock()
        self.code.next_block = while_block
        # condition
        self.switch_block(while_block)
        self.visit(node.condition)
        while_block.test = node.condition.gen_location
        # body
        while_block.body = BasicBlock()
        self.switch_block(while_block.body)
        self.visit(node.body)
        while_block.next_block = BasicBlock()
        self.switch_block(while_block.next_block)

    def switch_block(self, next_block):
        self.code = next_block

    def visit_Group(self, node):
        self.visit(node.expression)
        node.gen_location = node.expression.gen_location

    def visit_Expr(self, node):
        self.visit(node.expr)
        node.gen_location = node.expr.gen_location