def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        cte_value = None
        ir_register = None

        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value, ir_register = self.ids_defined[name]

                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined variable '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array, ir_registers_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined array '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

                array_index_cte, array_index_ir = self.visit(ctx.array())
                if array_index_cte != None:
                    if array_index_cte < 0 or array_index_cte >= array_length:
                        err("ERROR:  array '" + name +
                            "' index out of bounds in line " +
                            str(token.line) + " and column " +
                            str(token.column) + "\n")
                        exit(-1)
                    else:
                        cte_value = cte_values_array[array_index_cte]
                        ir_register = ir_registers_array[array_index_cte]

            elif ctx.function_call() != None:
                tyype, cte_value, ir_register = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))
                if tyype == Type.VOID:
                    err("ERROR: unary operator '" + text +
                        "' used on type void in line " + str(token.line) +
                        " and column " + str(token.column) + "\n")
                    exit(-1)
                elif cte_value != None:
                    if text == '-':
                        cte_value = -cte_value

                if ir_register != None and text == '-':
                    out = "    %" + str(self.next_ir_register) + " = "
                    self.filee.write(out)
                    out = "sub nsw " + llvm_type(tyype) + " 0, %" + str(
                        ir_register) + "\n"
                    self.filee.write(out)
                    ir_register = self.next_ir_register

                    self.next_ir_register += 1

            else:  # parentheses
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left_type, left_cte_value, left_ir_register = self.visit(
                ctx.expression(0))
            right_type, right_cte_value, right_ir_register = self.visit(
                ctx.expression(1))
            if left_type == Type.VOID or right_type == Type.VOID:
                err("ERROR: binary operator '" + text +
                    "' used on type void in line " + str(token.line) +
                    " and column " + str(token.column) + "\n")
                exit(-1)

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left_type == Type.FLOAT or right_type == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                if left_ir_register != None or right_ir_register != None:
                    out = "    %" + str(self.next_ir_register) + " = "
                    self.filee.write(out)
                    ir_register = self.next_ir_register
                    self.next_ir_register += 1

                    if text == '*':
                        if left_ir_register != None and right_ir_register != None:
                            out = "mul nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)
                        elif left_ir_register != None and right_ir_register == None:
                            out = "mul nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", " + str(
                                    right_cte_value) + "\n"
                            self.filee.write(out)
                        elif left_ir_register == None and right_ir_register != None:
                            out = "mul nsw " + llvm_type(tyype) + " " + str(
                                left_cte_value) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)

                    elif text == '/':
                        if left_ir_register != None and right_ir_register != None:
                            out = "sdiv nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)
                        elif left_ir_register != None and right_ir_register == None:
                            out = "sdiv nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", " + str(
                                    right_cte_value) + "\n"
                            self.filee.write(out)
                        elif left_ir_register == None and right_ir_register != None:
                            out = "sdiv nsw " + llvm_type(tyype) + " " + str(
                                left_cte_value) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)

                    elif text == '+':
                        if left_ir_register != None and right_ir_register != None:
                            out = "add nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)
                        elif left_ir_register != None and right_ir_register == None:
                            out = "add nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", " + str(
                                    right_cte_value) + "\n"
                            self.filee.write(out)
                        elif left_ir_register == None and right_ir_register != None:
                            out = "add nsw " + llvm_type(tyype) + " " + str(
                                left_cte_value) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)

                    elif text == '-':
                        if left_ir_register != None and right_ir_register != None:
                            out = "sub nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)
                        elif left_ir_register != None and right_ir_register == None:
                            out = "sub nsw " + llvm_type(tyype) + " %" + str(
                                left_ir_register) + ", " + str(
                                    right_cte_value) + "\n"
                            self.filee.write(out)
                        elif left_ir_register == None and right_ir_register != None:
                            out = "sub nsw " + llvm_type(tyype) + " " + str(
                                left_cte_value) + ", %" + str(
                                    right_ir_register) + "\n"
                            self.filee.write(out)

                if left_cte_value != None and right_cte_value != None:
                    if text == '*':
                        cte_value = left_cte_value * right_cte_value
                    elif text == '/':
                        cte_value = left_cte_value / right_cte_value
                    elif text == '+':
                        cte_value = left_cte_value + right_cte_value
                    elif text == '-':
                        cte_value = left_cte_value - right_cte_value
                else:
                    cte_value = None
            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == '<':
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>':
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '==':
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '!=':
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '<=':
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>=':
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                else:
                    cte_value = None

        #err(tyype + ": " + str(cte_value) + ", " + str(ir_register) + "\n")
        return tyype, cte_value, ir_register
Пример #2
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        print('Visiting an expression')
        # ids_defined[self.visitIdentifier()] = [self.visitTyype]
        #   quando checar uma expression devo verificar a exsitencia das variaveis, se elas nao exxistirem eu emito um erro.
        tyype = Type.VOID
        if len(ctx.expression()) == 0:
            if ctx.integer() != None:
                text = ctx.integer().getText()
                token = ctx.integer().INTEGER().getPayload()
                print('integer ' + text + ':' + str(token.line) + '.' +
                      str(token.column))
                tyype = Type.INT
                #print(ids_defined)

            elif ctx.floating() != None:
                text = ctx.floating().getText()
                token = ctx.floating().FLOATING().getPayload()
                print('floating ' + text + ':' + str(token.line) + '.' +
                      str(token.column))
                tyype = Type.FLOAT

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                text = ctx.identifier().getText()
                token = ctx.identifier().IDENTIFIER().getPayload()
                print('identifier ' + text + ':' + str(token.line) + '.' +
                      str(token.column))
                # try: #se for acessar usa sempre o try
                tyype = self.ids_defined[text]
                print(self.ids_defined)
                print('Imprimindo o dicionario')
                # except:
                # print('Identifier nao existe?')

            elif ctx.array() != None:
                print('éntrou')
                print(ctx.array().identifier().getText() + '[]')
                # tyype = self.visitArray(ctx.array())
                tyype = self.visit(ctx.array())

            elif ctx.function_call() != None:
                print("Function call  " +
                      ctx.function_call().identifier().getText() + '()')
                for i in range(len(ctx.function_call().expression())):
                    arg_type = self.visit(ctx.function_call().expression(i))
                    print('arg[' + str[i] + ']')
                    print(arg_type)
                    tyype = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:
            if ctx.OP != None:  #binary operators
                text = ctx.OP.text
                token = ctx.OP
                print('Operador unario ' + text + ':' + str(token.line) + '.' +
                      str(token.column))
                tyype = self.visit(ctx.expression(0))

            else:  #parenteses
                print('(')
                tyype = self.visit(ctx.expression(1))
                print(')')

        elif len(ctx.expression()) == 2:  # operadores binarios
            text = ctx.OP.text
            token = ctx.OP
            print('Operador binario ' + text + ':' + str(token.line) + '.' +
                  str(token.column))
            left = self.visit(ctx.expression(0))
            right = self.visit(ctx.expression(1))
            if left != right:
                if left == Type.INT and right == Type.FLOAT:
                    return Type.FLOAT
                elif left == Type.FLOAT and right == Type.INT:
                    return Type.FLOAT
                else:
                    print("Erro de tipo nas operacoes")
            else:
                right = left
        else:
            print(
                'Atencao: Numero de operadores é maior que 2 ou diferente do range [0..2]'
            )
        return tyype
Пример #3
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        value = None
        is_constant = True
        function_type = None
        params = []
        #pegamos os paramentros pra checar se a variavel foi declarada nos args
        if self.inside_what_function != "":
            function_type, params = self.ids_defined.get(
                self.inside_what_function)
        # print(params)
        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING
                value = ctx.string().getText()

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, value, is_constant = self.ids_defined[name]

                except:
                    try:
                        #se n tiver no ids_defined é pra estar nos parametros né
                        tyype = params[name]

                        is_constant = False
                    except:
                        token = ctx.identifier().IDENTIFIER().getPayload()
                        print("ERROR: undefined variable '" + name +
                              "' in line " + str(token.line) + " and column " +
                              str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                tyype, array_length = None, None
                try:
                    tyype, array_length, array_values = self.ids_defined[name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))
                array_index = self.visit(ctx.array())

                if array_index < 0 or array_index >= array_length:
                    print("ERROR:  array '" + name +
                          "' index out of bounds in line " + str(token.line) +
                          " and column " + str(token.column))
                else:
                    tyype, value, is_constant = array_values[array_index]
                #print("array index = " + str(array_index))

            elif ctx.function_call() != None:
                tyype = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, old_value, is_constant = self.visit(ctx.expression(0))

                #se ja nao for constante é xau xau
                if is_constant == False:
                    return tyype, None, False

                if text == '-':
                    value = -old_value
                else:
                    value = old_value
                print("line {} Expression {} {} simplified to: {}".format(
                    str(token.line), str(text), str(old_value), str(value)))

                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text +
                          "' used on type void in line " + str(token.line) +
                          " and column " + str(token.column))

            else:  # parentheses
                tyype, value, is_constant = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP

            left_tyype, left_value, left_constant = self.visit(
                ctx.expression(0))
            right_tyype, right_value, right_constant = self.visit(
                ctx.expression(1))

            is_constant = left_constant and right_constant

            if left_tyype == Type.VOID or right_tyype == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left_tyype == Type.FLOAT or right_tyype == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT
                # print("my type = ", tyype)
                # print(left_value, text, right_value)
                # print(ctx.getText())

            else:
                tyype = Type.INT

            #se ja nao for constante é xau xau não é pra nem se dar o trabalho
            if left_value == None or right_value == None:
                return tyype, None, False

            if text == '*':
                value = left_value * right_value
            elif text == '/':
                value = left_value / right_value
            elif text == '+':
                value = left_value + right_value
            elif text == '-':
                value = left_value - right_value
            elif text == '<':
                value = int(left_value < right_value)
            elif text == '<=':
                value = int(left_value <= right_value)
            elif text == '>':
                value = int(left_value > right_value)
            elif text == '>=':
                value = int(left_value >= right_value)
            elif text == '==':
                value = int(left_value == right_value)
            elif text == '!=':
                value = int(left_value != right_value)
            # print("final value = ", value)

            if is_constant:
                print("line {} Expression {} {} {} simplified to: {}".format(
                    str(token.line), str(left_value), str(text),
                    str(right_value), str(value)))

        # print("final final value = ", value)
        return tyype, value, is_constant
Пример #4
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        cte_value = None
        ir_register = None

        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value, ir_register = self.ids_defined[name]
                    modifier = "%"
                    if name in self.global_vars:
                        modifier = "@"
                        cte_value = None
                        ir_register = None
                    search_register = [
                        b for a, b in self.ids_defined[
                            self.inside_what_function][3]
                        if a == ctx.getText()
                    ]
                    if search_register:
                        ir_register = search_register[0]
                    elif not cte_value:
                        f.write("\t%" + str(self.next_ir_register) +
                                " = load " + llvm_type(tyype) + ", " +
                                llvm_type(tyype) + "* " + modifier +
                                ctx.getText() + ", align 4\n")
                        self.ids_defined[self.inside_what_function][3].append(
                            (ctx.getText(), self.next_ir_register))
                        ir_register = self.next_ir_register
                        self.next_ir_register += 1
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined variable '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array, ir_registers_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined array '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

                array_index_cte, array_index_ir = self.visit(ctx.array())
                if array_index_cte != None:
                    if array_index_cte < 0 or array_index_cte >= array_length:
                        err("ERROR:  array '" + name +
                            "' index out of bounds in line " +
                            str(token.line) + " and column " +
                            str(token.column) + "\n")
                        exit(-1)
                    else:
                        cte_value = cte_values_array[array_index_cte]
                        ir_register = ir_registers_array[array_index_cte]

            elif ctx.function_call() != None:
                tyype, cte_value, ir_register = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))
                if tyype == Type.VOID:
                    err("ERROR: unary operator '" + text +
                        "' used on type void in line " + str(token.line) +
                        " and column " + str(token.column) + "\n")
                    exit(-1)
                elif cte_value != None:
                    if text == "-":
                        cte_value = -cte_value

            else:  # parentheses
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left_type, left_cte_value, left_ir_register = self.visit(
                ctx.expression(0))
            right_type, right_cte_value, right_ir_register = self.visit(
                ctx.expression(1))
            if left_type == Type.VOID or right_type == Type.VOID:
                err("ERROR: binary operator '" + text +
                    "' used on type void in line " + str(token.line) +
                    " and column " + str(token.column) + "\n")
                exit(-1)

            if text == "*" or text == "/" or text == "+" or text == "-":
                if left_type == Type.FLOAT or right_type == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                if text == "*":
                    cte_value, ir_register = process_operations(
                        self, "mul", cte_value, left_type, right_type,
                        left_ir_register, right_ir_register, left_cte_value,
                        right_cte_value, tyype, ctx)
                elif text == "/":
                    cte_value, ir_register = process_operations(
                        self, "div", cte_value, left_type, right_type,
                        left_ir_register, right_ir_register, left_cte_value,
                        right_cte_value, tyype, ctx)
                elif text == "+":
                    cte_value, ir_register = process_operations(
                        self, "add", cte_value, left_type, right_type,
                        left_ir_register, right_ir_register, left_cte_value,
                        right_cte_value, tyype, ctx)
                elif text == "-":
                    cte_value, ir_register = process_operations(
                        self, "sub", cte_value, left_type, right_type,
                        left_ir_register, right_ir_register, left_cte_value,
                        right_cte_value, tyype, ctx)
                if not (left_cte_value != None and right_cte_value != None):
                    cte_value = None

            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == "<":
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == ">":
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == "==":
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == "!=":
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == "<=":
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == ">=":
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                else:
                    cte_value = None

        return tyype, cte_value, ir_register
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        token = None
        cte_value = None  # RETORNAR OS VALORES DAS CONTANTES, OU NONE SE NAO FOR CONSTANTE
        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING
                cte_value = str(ctx.string().getText())

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined variable '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))
                array_index = self.visit(ctx.array())

                if array_index != None and array_length != None:
                    if (array_index > array_length - 1):
                        token = ctx.array().identifier().IDENTIFIER(
                        ).getPayload()
                        print("ERROR: array index out of bounds '" + name +
                              "' in line " + str(token.line) + " and column " +
                              str(token.column))
                    elif cte_values_array is not None:
                        cte_value = cte_values_array[array_index]
            elif ctx.function_call() != None:
                tyype, cte_value = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value = self.visit(ctx.expression(0))
                cte_value = eval("{}{}".format(text, cte_value))
                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text +
                          "' used on type void in line " + str(token.line) +
                          " and column " + str(token.column))

            else:  # parentheses
                tyype, cte_value = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left, left_cte_value = self.visit(ctx.expression(0))
            right, right_cte_value = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT
            else:
                tyype = Type.INT

            if left_cte_value != None and right_cte_value != None and left != Type.STRING and right != Type.STRING:
                #print("{} {} {}".format(left_cte_value, text, right_cte_value))
                cte_value = eval("{} {} {}".format(left_cte_value, text,
                                                   right_cte_value))
                if isinstance(cte_value, bool):
                    cte_value = int(cte_value)

        #if token is not None:
        #  print(str(tyype) + ": " + str(cte_value) + ' - at: ' + str(token.line))
        #else:
        print(str(tyype) + ": " + str(cte_value))

        return tyype, cte_value
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        if len(ctx.expression()) == 0:
            if ctx.integer() != None:
                text = ctx.integer().getText()
                token = ctx.integer().INTEGER().getPayload()
                #print("Integer: '" + text + "' => line: " + str(token.line) + " , col: " + str(token.column))
                tyype = Type.INT
            elif ctx.floating() != None:
                text = ctx.floating().getText()
                token = ctx.floating().FLOATING().getPayload()
                #print("Floating: '" + text + "' => line: " + str(token.line) + " , col: " + str(token.column))
                tyype = Type.FLOAT
            elif ctx.string() != None:
                tyype = Type.STRING
            elif ctx.identifier() != None:
                text = ctx.identifier().getText()
                token = ctx.identifier().IDENTIFIER().getPayload()
                #print("Identifier: '" + text + "' => line: " + str(token.line) + " , col: " + str(token.column))
                #print(self.ids_defined)
                tyype = self.ids_defined.get(text, Type.VOID)
            elif ctx.array() != None:
                text = ctx.array().identifier().getText()
                token = ctx.array().identifier().IDENTIFIER().getPayload()
                tyype = self.ids_defined.get(text, Type.VOID)
                #print("Array Identifier: '" + ctx.array().identifier().getText() + "[]' => line: " + str(token.line) + " , col: " + str(token.column))
                #print("Array type: [{}]".format(tyype))
            elif ctx.function_call() != None:
                #print("Function Call: '" + ctx.function_call().identifier().getText() + "()'")

                for i in range(len(ctx.function_call().expression())):
                    arg_type = self.visit(ctx.function_call().expression(i))
                    #print("arg[" + str(i) + "]")

        elif len(ctx.expression()) == 1:
            if ctx.OP != None:
                text = ctx.OP.text
                token = ctx.OP
                #print("Unary Operator: '" + text + "' => line : " + str(token.line) + ", col: " + str(token.column))
                tyype = self.visit(ctx.expression(0))
            else:
                #print("(")
                tyype = self.visit(ctx.expression(0))
                #print(")")

        elif len(ctx.expression()) == 2:
            text = ctx.OP.text
            token = ctx.OP
            #print("Binary Operator: '" + text + "' => line: " + str(token.line) + " , col: " + str(token.column))
            left = self.visit(ctx.expression(0))
            right = self.visit(ctx.expression(1))
            if ctx.OP.text in ['<', '<=', '==', '>=', '>', '!=']:
                if left != right:
                    print(
                        "[ERROR]::[Good lord, what were you thinking trying to do a '{} {} {}' operation? Please, fix that type error. But do it right this time, yes?] ({},{})"
                        .format(left, ctx.OP.text, right, str(token.line),
                                str(token.column)))

            elif ctx.OP.text in ['+', '-', '*', '/']:
                if not (left == right or
                        (left == Type.INT and right == Type.FLOAT)):
                    #print("left = {}".format(left))
                    #print("right = {}".format(right))
                    #print(self.ids_defined)
                    print(
                        "[ERROR]::[Good lord, what were you thinking trying to do a '{} {} {}' operation? Please, fix that type error. But do it right this time, yes?] ({},{})"
                        .format(left, ctx.OP.text, right, str(token.line),
                                str(token.column)))
            tyype = right
        return tyype
Пример #7
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        llvm_tyype = llvm_type(tyype)
        cte_value = None
        ir_register = None
        is_inside = self.inside_what_function != ""
        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()

                try:
                    tyype, _, cte_value, ir_register = self.ids_defined[name]
                    if ir_register == None and cte_value == None:
                        temp = list(self.ids_defined[name])
                        temp[3] = self.next_ir_register
                        self.ids_defined[name] = tuple(temp)

                        ir_register = self.next_ir_register

                        printLoad(self.next_ir_register,
                                  tyype,
                                  name,
                                  tyype,
                                  4,
                                  has_tab=is_inside)
                        self.next_ir_register += 1
                    # elif cte_value != None:
                    #     ir_register = name

                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined variable '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array, ir_registers_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined array '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

                array_index_cte, array_index_ir = self.visit(ctx.array())
                if array_index_cte != None:
                    if array_index_cte < 0 or array_index_cte >= array_length:
                        err("ERROR:  array '" + name +
                            "' index out of bounds in line " +
                            str(token.line) + " and column " +
                            str(token.column) + "\n")
                        exit(-1)
                    else:
                        cte_value = cte_values_array[array_index_cte]
                        ir_register = ir_registers_array[array_index_cte]

            elif ctx.function_call() != None:
                tyype, cte_value, ir_register = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))
                ll_oper = "sub"
                llvm_tyype = llvm_type(tyype)

                if tyype == Type.VOID:
                    err("ERROR: unary operator '" + text +
                        "' used on type void in line " + str(token.line) +
                        " and column " + str(token.column) + "\n")
                    exit(-1)
                elif tyype == Type.FLOAT:
                    ll_oper = "fsub"
                elif cte_value != None:
                    if text == '-':
                        cte_value = -cte_value
                elif text == '-':
                    printOper(ll_oper,
                              self.next_ir_register,
                              llvm_tyype,
                              0,
                              ir_register,
                              has_tab=True,
                              r1_is_constant=True,
                              r2_is_constant=False)

                    ir_register = self.next_ir_register

                    self.next_ir_register += 1

            else:  # parentheses
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            llvm_op = None
            token = ctx.OP
            left_type, left_cte_value, left_ir_register = self.visit(
                ctx.expression(0))
            right_type, right_cte_value, right_ir_register = self.visit(
                ctx.expression(1))
            if left_type == Type.VOID or right_type == Type.VOID:
                err("ERROR: binary operator '" + text +
                    "' used on type void in line " + str(token.line) +
                    " and column " + str(token.column) + "\n")
                exit(-1)

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left_type == Type.FLOAT or right_type == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                if left_type == Type.INT and tyype == Type.FLOAT and left_cte_value == None:
                    printIntToFloat(self.next_ir_register,
                                    left_ir_register,
                                    has_tab=True)
                    left_ir_register = self.next_ir_register
                    self.next_ir_register += 1

                if right_type == Type.INT and tyype == Type.FLOAT and right_cte_value == None:
                    printIntToFloat(self.next_ir_register,
                                    right_ir_register,
                                    has_tab=True)
                    right_ir_register = self.next_ir_register
                    self.next_ir_register += 1

                if left_cte_value != None and right_cte_value != None:
                    if text == '*':
                        cte_value = left_cte_value * right_cte_value
                    elif text == '/':
                        cte_value = left_cte_value / right_cte_value
                    elif text == '+':
                        cte_value = left_cte_value + right_cte_value
                    elif text == '-':
                        cte_value = left_cte_value - right_cte_value
                else:
                    cte_value = None

                    left_cte_value_str = str(left_cte_value)
                    right_cte_value_str = str(right_cte_value)

                    if (left_type == Type.FLOAT) or (right_type == Type.FLOAT):
                        if left_cte_value != None:
                            left_cte_value_str = float_to_hex(
                                float(left_cte_value))
                        if right_cte_value != None:
                            right_cte_value_str = float_to_hex(
                                float(right_cte_value))

                    if text == '+':
                        if (left_type == Type.FLOAT
                                or right_type == Type.FLOAT):
                            llvm_op = "fadd"
                        else:
                            llvm_op = "add"

                    elif text == '-':
                        if (left_type == Type.FLOAT
                                or right_type == Type.FLOAT):
                            llvm_op = "fsub"
                        else:
                            llvm_op = "sub"

                    elif text == '*':
                        if (left_type == Type.FLOAT
                                or right_type == Type.FLOAT):
                            llvm_op = "fmul"
                        else:
                            llvm_op = "mul"

                    elif text == '/':
                        if (left_type == Type.INT and right_type == Type.INT):
                            llvm_op = "sdiv"
                        elif (left_type == Type.FLOAT
                              or right_type == Type.FLOAT):
                            llvm_op = "fdiv"
                        else:
                            llvm_op = "udiv"

                    if left_cte_value != None and right_cte_value == None:
                        printOper(llvm_op, self.next_ir_register, tyype,
                                  left_cte_value_str, right_ir_register,
                                  is_inside, True, False)
                    elif left_cte_value == None and right_cte_value != None:
                        printOper(llvm_op, self.next_ir_register, tyype,
                                  left_ir_register, right_cte_value_str,
                                  is_inside, False, True)
                    elif left_cte_value == None and right_cte_value == None:
                        printOper(llvm_op, self.next_ir_register, tyype,
                                  left_ir_register, right_ir_register,
                                  is_inside, False, False)

                    ir_register = self.next_ir_register
                    self.next_ir_register += 1

            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == '<':
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>':
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '==':
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '!=':
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '<=':
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>=':
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                else:
                    cte_value = None

        return tyype, cte_value, ir_register
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT

            elif ctx.floating() != None:
                tyype = Type.FLOAT

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _ = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined variable '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                tyype, array_length = 0, 0
                try:
                    tyype, array_length = self.ids_defined[name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))
                self.visit(ctx.array())

                #print("array index = " + str(array_index))

            elif ctx.function_call() != None:
                tyype = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype = self.visit(ctx.expression(0))
                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text +
                          "' used on type void in line " + str(token.line) +
                          " and column " + str(token.column))

            else:  # parentheses
                tyype = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left = self.visit(ctx.expression(0))
            right = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT
            else:
                tyype = Type.INT

        return tyype
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        const_value = None
        if len(ctx.expression()) == 0:

            if ctx.integer():
                tyype = Type.INT
                # forced a cast type
                const_value = int(ctx.integer().getText())

            elif ctx.floating():
                tyype = Type.FLOAT
                const_value = float(ctx.floating().getText())

            elif ctx.string():
                tyype = Type.STRING
                const_value = str(ctx.string().getText())

            elif ctx.identifier():
                name = ctx.identifier().getText()
                try:
                    tyype, _, const_value = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined variable '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))

            elif ctx.array():
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, const_array_values = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))
                array_index = self.visit(ctx.array())
                if array_index and array_length:
                    if array_index < 0 or array_index >= array_length:
                        token = ctx.array().identifier().IDENTIFIER(
                        ).getPayload()
                        print("ERROR:  array '" + name +
                              "' index out of bounds in line " +
                              str(token.line) + " and column " +
                              str(token.column))
                    elif const_array_values:
                        const_value = const_array_values[array_index]

            elif ctx.function_call() != None:
                tyype, const_value = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:
            if ctx.OP != None:  # unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, unary_expression_const_value = self.visit(
                    ctx.expression(0))
                const_value = eval(f"{text} unary_expression_const_value")

                print(
                    f"line {token.line} Expression {text} {unary_expression_const_value} "
                    f"simplified to: {const_value}")

                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text +
                          "' used on type void in line " + str(token.line) +
                          " and column " + str(token.column))

            else:  # parentheses
                tyype, const_value = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left, left_const_value = self.visit(ctx.expression(0))
            right, right_const_value = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT
            else:
                tyype = Type.INT
            # check if both is not string
            if Type.STRING not in [left, right]:
                if left_const_value and right_const_value:
                    const_value = eval(
                        f"left_const_value {text} right_const_value")
                    # if const_value is a boolean just convert it to int
                    if isinstance(const_value, bool):
                        const_value = int(const_value)
                    print(
                        f"line {token.line} Expression {left_const_value} {text} {right_const_value} "
                        f"simplified to: {const_value}")
                # anything * 0 = 0
                elif 0 in [left_const_value, right_const_value
                           ] and text in ["*"]:
                    const_value = 0
                    print(
                        f"line {token.line} Expression {left_const_value} {text} {right_const_value} "
                        f"simplified to: {const_value}")
        return tyype, const_value
Пример #10
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        token = None
        cte_value = None
        if len(ctx.expression()) == 0:
            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING
                cte_value = str(ctx.string().getText())

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                if name in self.global_variables:
                    try:
                        tyype, _ = self.ids_defined[name]
                    except:
                        token = ctx.identifier().IDENTIFIER().getPayload()
                        print("ERROR: undefined variable '" + name +
                              "' in line " + str(token.line) + " and column " +
                              str(token.column))
                else:
                    try:
                        tyype, _, cte_value = self.ids_defined[name]
                    except:
                        token = ctx.identifier().IDENTIFIER().getPayload()
                        print("ERROR: undefined variable '" + name +
                              "' in line " + str(token.line) + " and column " +
                              str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))
                array_index = self.visit(ctx.array())

            elif ctx.function_call() != None:
                tyype, cte_value = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:
                name = ctx.expression(0)
                print(name)
                if name in self.global_variables:
                    text = ctx.OP.text
                    token = ctx.OP
                    tyype = self.visit(ctx.expression(0))
                    if tyype == Type.VOID:
                        print("ERROR: unary operator '" + text +
                              "' used on type void in line " +
                              str(token.line) + " and column " +
                              str(token.column))
                else:
                    text = ctx.OP.text
                    token = ctx.OP
                    tyype, cte_value = self.visit(ctx.expression(0))
                    cte_value = eval("{}{}".format(text, cte_value))
                    if tyype == Type.VOID:
                        print("ERROR: unary operator '" + text +
                              "' used on type void in line " +
                              str(token.line) + " and column " +
                              str(token.column))

            else:
                tyype, cte_value = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:
            text = ctx.OP.text
            token = ctx.OP
            left, left_cte_value = self.visit(ctx.expression(0))
            right, right_cte_value = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT
            else:
                tyype = Type.INT

            if left_cte_value != None and right_cte_value != None and left != Type.STRING and right != Type.STRING:
                cte_value = eval("{} {} {}".format(left_cte_value, text,
                                                   right_cte_value))
                if isinstance(cte_value, bool):
                    cte_value = int(cte_value)

        if token is not None:
            if cte_value is not None:
                print('line ' + str(token.line) + ' Expression ' +
                      'simplified to ' + str(cte_value))

        return tyype, cte_value
 def visitExpression(self, ctx: GrammarParser.ExpressionContext):
     if len(ctx.expression()) == 0:
         if ctx.integer() != None:
             return Type.INT
         elif ctx.floating() != None:
             return Type.FLOAT
         elif ctx.string() != None:
             return Type.STRING
         elif ctx.identifier() != None:
             variable_name = ctx.identifier().getText()
             return self._variable_type(variable_name)
         elif ctx.array() != None:
             return self.visit(ctx.array())
         elif ctx.function_call() != None:
             function_call = self.visit(ctx.function_call())
             return function_call
     elif len(ctx.expression()) == 1:
         return self.visit(ctx.expression()[0])
     elif len(ctx.expression()) == 2:
         left = self.visit(ctx.expression()[0])
         right = self.visit(ctx.expression()[1])
         # print("hello: ",left, right)
         if (left == Type.FLOAT or right == Type.FLOAT):
             return Type.FLOAT
         elif (left == Type.VOID or right == Type.VOID):
             OP = ctx.OP.text
             token = ctx.OP
             line = token.line
             column = token.column
             print(
                 f"ERROR: binary operator '{OP}' used on type void in line {line} and column {column}"
             )
         return Type.INT
     return self.visitChildren(ctx)
Пример #12
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = None
        token = None
        cte_value = None
        if len(ctx.expression()) == 0:
            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined variable '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()

                try:
                    tyype, array_length, cte_values_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))

                array_index = self.visit(ctx.array())

            elif ctx.function_call() != None:
                tyype, cte_value = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value = self.visit(ctx.expression(0))

                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text +
                          "' used on type void in line " + str(token.line) +
                          " and column " + str(token.column))
                elif cte_value != None:
                    if text == '-':
                        cte_value = -cte_value
                else:
                    cte_value = None

            else:
                tyype, cte_value = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:
            text = ctx.OP.text
            token = ctx.OP
            left, left_cte_value = self.visit(ctx.expression(0))
            right, right_cte_value = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                if left_cte_value != None and right_cte_value != None:
                    if text == '*':
                        cte_value = left_cte_value * right_cte_value
                    elif text == '/':
                        cte_value = left_cte_value / right_cte_value
                    elif text == '+':
                        cte_value = left_cte_value + right_cte_value
                    elif text == '-':
                        cte_value = left_cte_value - right_cte_value
            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == '<':
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>':
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '==':
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '!=':
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '<=':
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>=':
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                else:
                    cte_value = None

        return tyype, cte_value
    def visitExpression(self, ctx:GrammarParser.ExpressionContext):
        tyype = Type.VOID
        cte_value = None
        ir_register = None

        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, val, cte_value, ir_register = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined variable '" + name + "' in line " + str(token.line) + " and column " + str(token.column) + "\n")
                    exit(-1)
                if (not name in self.in_expr and cte_value == None) or name in self.global_var:
                    if self.func_count[self.inside_what_function] == None:
                        self.func_count[self.inside_what_function] = 1


                    self.func_count[self.inside_what_function] += 1
                    print('   ' +"%"+str(self.func_count[self.inside_what_function])+" = load "+str(llvm_type(tyype))+", "+str(llvm_type(tyype))+"* %"+str(name)+", align 4")
                    #print(val)
                    self.in_expr += [name]
                    ir_register = self.func_count[self.inside_what_function]
                    cte_value = None if name in self.global_var else cte_value
                    self.ids_defined[name] = tyype, val, cte_value, ir_register
                    #print(self.in_expr)


            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array, ir_registers_array = self.ids_defined[name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined array '" + name + "' in line " + str(token.line) + " and column " + str(token.column) + "\n")
                    exit(-1)

                array_index_cte, array_index_ir = self.visit(ctx.array())
                if array_index_cte != None:
                    if array_index_cte < 0 or array_index_cte >= array_length:
                        err("ERROR:  array '" + name + "' index out of bounds in line " + str(token.line) + " and column " + str(token.column) + "\n")
                        exit(-1)
                    else:
                        cte_value = cte_values_array[array_index_cte]
                        ir_register = ir_registers_array[array_index_cte]

            elif ctx.function_call() != None:
                tyype, cte_value, ir_register, name, params = self.visit(ctx.function_call())

                if(self.func_count[name] == None):
                    self.func_count[name] = 1
                # params: pares = tipos, ímpares = valores
                #print('ir '+ str(self.next_ir_register))

                if(tyype == Type.VOID):
                    print('   ' +'call',tyype + ' @'+name +" (",end="")

                else:
                    self.func_count[self.inside_what_function] += 1
                    print('   ' +'%'+ str(self.func_count[self.inside_what_function]) +' = call',tyype + ' @'+name +" (",end="")
                    self.func_count[name] = self.func_count[name] + 1
                    ir_register = self.func_count[self.inside_what_function]

                    #%1 = call float @ResDiv(float 0x4079000000000000, float 0x4072c00000000000)

                for i, p in enumerate(params):
                    if(i < len(params)-1):
                        if(p[0] == Type.FLOAT):
                            print('   ' + str(llvm_type(p[0]))+' '+ str(float_to_hex(p[1]))+', ', end="")
                        else:
                            print('   ' + str(llvm_type(p[0]))+' '+ str(p[1])+', ', end="")
                    else:
                        if(p[0] == Type.FLOAT):
                            print('   ' + str(llvm_type(p[0]))+' '+ str(float_to_hex(p[1])), end="")
                        else:
                            print('   ' + str(llvm_type(p[0]))+' '+ str(p[1]), end="")
                print(')')



               # print('aqui ',params)
                #print('call', tyype +' @' + name , + str(llvm_type(tyype)) + ' @'+name +' (', end="")
                #call void @splash(i32 8)

        elif len(ctx.expression()) == 1:

            if ctx.OP != None: #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))
                #print(text,cte_value)
                if tyype == Type.VOID:
                    err("ERROR: unary operator '" + text + "' used on type void in line " + str(token.line) + " and column " + str(token.column) + "\n")
                    exit(-1)
                
                elif cte_value != None:
                    if text == '-':
                        cte_value = -cte_value
                   
                if cte_value == None:
                    cte_value = 0
                    self.func_count[self.inside_what_function] += 1
                    print('   ' +"%"+str(self.func_count[self.inside_what_function])+" = sub "+str(llvm_type(tyype))+" "+str(cte_value)+(', %'+str(ir_register)))
                    #%5 = sub i32 0, %4
            else: # parentheses
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))


        elif len(ctx.expression()) == 2: # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left_type, left_cte_value, left_ir_register = self.visit(ctx.expression(0))
            right_type, right_cte_value, right_ir_register = self.visit(ctx.expression(1))
            if left_type == Type.VOID or right_type == Type.VOID:
                err("ERROR: binary operator '" + text + "' used on type void in line " + str(token.line) + " and column " + str(token.column) + "\n")
                exit(-1)

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left_type == Type.FLOAT or right_type == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                

                if (left_type == Type.INT and right_type == Type.FLOAT) and (left_ir_register != None):
                    print('   ' +"%"+str(self.func_count[self.inside_what_function] + 1)+" = sitofp "+str(llvm_type(Type.INT))+" "+'%'+str(left_ir_register) + ' to float')
                    self.func_count[self.inside_what_function] += 1
                    ir_register = self.func_count[self.inside_what_function]
                    left_ir_register = ir_register
                    #%4 = sitofp i32 %3 to float
                

                if left_cte_value != None and right_cte_value != None:
                    if text == '*':
                        cte_value = left_cte_value * right_cte_value
                    elif text == '/':
                        cte_value = left_cte_value / right_cte_value
                    elif text == '+':
                        cte_value = left_cte_value + right_cte_value
                    elif text == '-':
                        cte_value = left_cte_value - right_cte_value
                else:
                    if text == '*':
                        if tyype == Type.INT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = mul "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                        elif tyype == Type.FLOAT:
                            self.func_count[self.inside_what_function] += 1
                            #print(ir_register)
                            ir_register = self.func_count[self.inside_what_function]
                            #print(ir_register)
                            print('   ' +"%"+str(ir_register)+" = fmul "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                    elif text == '/':
                        if tyype == Type.INT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = sdiv "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                        elif tyype == Type.FLOAT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = fdiv "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                    elif text == '+':
                        if tyype == Type.INT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = add "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                        elif tyype == Type.FLOAT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = fadd "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                    elif text == '-':
                        if tyype == Type.INT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = sub "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                        elif tyype == Type.FLOAT:
                            self.func_count[self.inside_what_function] += 1
                            ir_register = self.func_count[self.inside_what_function]
                            print('   ' +"%"+str(ir_register)+" = fsub "+str(llvm_type(tyype))+" "+('%'+str(left_ir_register) if left_ir_register != None else str(left_cte_value if left_type == Type.INT else left_cte_value))+", "+('%'+str(right_ir_register) if right_ir_register != None else str(right_cte_value if right_type == Type.INT else right_cte_value)))
                    cte_value = None
            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == '<':
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>':
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '==':
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '!=':
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '<=':
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>=':
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                else:
                    cte_value = None
        return tyype, cte_value, ir_register
Пример #14
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        cte_value = None  # RETORNAR OS VALORES DAS CONTANTES, OU NONE SE NAO FOR CONSTANTE
        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                text = ctx.integer().getText()
                cte_value = int(text)

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                text = ctx.floating().getText()
                cte_value = float(text)

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined variable '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " +
                          str(token.line) + " and column " + str(token.column))
                array_index = self.visit(ctx.array())

                if array_index >= 0 and array_index < array_length:
                    cte_value = cte_values_array[array_index]

            elif ctx.function_call() != None:
                tyype, cte_value = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value = self.visit(ctx.expression(0))
                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text +
                          "' used on type void in line " + str(token.line) +
                          " and column " + str(token.column))
                if text == '-':
                    if cte_value != None:
                        cte_value *= -1

            else:  # parentheses
                tyype, cte_value = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left, left_cte_value = self.visit(ctx.expression(0))
            right, right_cte_value = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text +
                      "' used on type void in line " + str(token.line) +
                      " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                if left_cte_value != None and right_cte_value != None:
                    if text == '*':
                        cte_value = left_cte_value * right_cte_value
                    elif text == '/':
                        cte_value = left_cte_value / right_cte_value
                    elif text == '+':
                        cte_value = left_cte_value + right_cte_value
                    else:
                        cte_value = left_cte_value - right_cte_value

            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == '==':
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0

                    elif text == '!-':
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0

                    elif text == '>=':
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0

                    elif text == '<=':
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0

                    elif text == '>':
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0

                    if text == '<':
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0

        print(str(tyype) + ": " + str(cte_value))
        return tyype, cte_value
Пример #15
0
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        # tyype = Type.VOID

        #print("expression: "+ctx.getText())

        if len(ctx.expression()) == 0:
            if ctx.integer() != None:
                return Type.INT

            elif ctx.string() != None:
                return Type.STRING

            elif ctx.floating() != None:
                return Type.FLOAT

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                token = ctx.identifier().IDENTIFIER().getPayload()

                def_variable = self.ids_defined.get(name)

                if def_variable == None:
                    print(
                        "ERROR: trying to use a non-defined variable '{}' in expression in line {} and column {}"
                        .format(name, str(token.line), str(token.column)))
                    return None

                tyype = def_variable[0]
                return tyype

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                tyype = None
                token = ctx.array().identifier().IDENTIFIER().getPayload()
                givenIndex = ctx.array().expression().getText()

                if (self.ids_defined.get(name) == None):
                    print(
                        "ERROR: undefined array '{}' in line {} and column {}".
                        format(name, str(token.line), str(token.column)))
                    if givenIndex != None:
                        print(
                            "ERROR: array '{}' index out of bounds in line {} and column {}"
                            .format(name, token.line, token.column))

                if (self.ids_defined.get(name) != None):
                    tyype = self.ids_defined[name][0]
                    indexType = self.visit(ctx.array().expression())
                    if (indexType != Type.INT) or (
                            int(givenIndex) >= self.ids_defined.get(name)[1]):
                        print(tyype)
                        print(
                            "ERROR: array '{}' index out of bounds in line {} and column {}"
                            .format(name, token.line, token.column))

                return tyype

            elif ctx.function_call() != None:
                return self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:
            if ctx.OP == None:
                # caso do parenteses
                return self.visitExpression(ctx.expression(0))
            op = ctx.OP.text
            token = ctx.OP.getTokenSource()
            tyype = self.visitExpression(ctx.expression(0))
            if tyype == None:
                return None

            if tyype == Type.INT or tyype == Type.FLOAT:
                return tyype
            elif tyype == Type.VOID:
                return (
                    "ERROR: trying to use '{}' operator in variable of type void, in line {} and column {}"
                    .format(op, str(token.line), str(token.column)))
            else:
                print(
                    "ERROR: trying to use '{}' operator in variable of type '{}', in line {} and column {}"
                    .format(op, tyype, str(token.line), str(token.column)))
                return None
        elif len(ctx.expression()) == 2:
            token = ctx.OP.getTokenSource()
            op = ctx.OP.text
            tyype1 = self.visitExpression(ctx.expression(0))
            tyype2 = self.visitExpression(ctx.expression(1))

            if tyype1 == None or tyype2 == None:
                return None

            if (tyype1 == Type.FLOAT
                    or tyype1 == Type.INT) and (tyype2 == Type.FLOAT
                                                or tyype2 == Type.INT):
                if tyype1 == tyype2:
                    return tyype1
                else:
                    return Type.FLOAT
            else:
                print(
                    "ERROR: trying to use '{}' operator between variables of types '{}' and '{}', in line {} and column {}"
                    .format(op, tyype1, tyype2, str(token.line),
                            str(token.column)))
                return None

        return Type.VOID
    def visitExpression(self, ctx: GrammarParser.ExpressionContext):
        tyype = Type.VOID
        cte_value = None
        ir_register = None

        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                tyype = Type.INT
                cte_value = int(ctx.integer().getText())

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText())

            elif ctx.string() != None:
                tyype = Type.STRING

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value, ir_register = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined variable '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    tyype, array_length, cte_values_array, ir_registers_array = self.ids_defined[
                        name]
                except:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    err("ERROR: undefined array '" + name + "' in line " +
                        str(token.line) + " and column " + str(token.column) +
                        "\n")
                    exit(-1)

                array_index_cte, array_index_ir = self.visit(ctx.array())
                if array_index_cte != None:
                    if array_index_cte < 0 or array_index_cte >= array_length:
                        err("ERROR:  array '" + name +
                            "' index out of bounds in line " +
                            str(token.line) + " and column " +
                            str(token.column) + "\n")
                        exit(-1)
                    else:
                        cte_value = cte_values_array[array_index_cte]
                        ir_register = ir_registers_array[array_index_cte]

            elif ctx.function_call() != None:
                tyype, cte_value, ir_register = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None:  #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))
                if tyype == Type.VOID:
                    err("ERROR: unary operator '" + text +
                        "' used on type void in line " + str(token.line) +
                        " and column " + str(token.column) + "\n")
                    exit(-1)
                elif cte_value != None:
                    if text == '-':
                        cte_value = -cte_value
                else:
                    self_ir_register_before_operation = ir_register
                    ir_register = self.next_ir_register
                    self.next_ir_register += 1
                    printf("  %%%s = sub nsw %s %s, %%%s\n", ir_register,
                           llvm_type(tyype), 0,
                           self_ir_register_before_operation)
                    cte_value = None

            else:  # parentheses
                tyype, cte_value, ir_register = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:  # binary operators
            text = ctx.OP.text
            token = ctx.OP
            left_type, left_cte_value, left_ir_register = self.visit(
                ctx.expression(0))
            right_type, right_cte_value, right_ir_register = self.visit(
                ctx.expression(1))
            if left_type == Type.VOID or right_type == Type.VOID:
                err("ERROR: binary operator '" + text +
                    "' used on type void in line " + str(token.line) +
                    " and column " + str(token.column) + "\n")
                exit(-1)

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left_type == Type.FLOAT or right_type == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT

                if left_cte_value != None and right_cte_value != None:
                    if text == '*':
                        cte_value = left_cte_value * right_cte_value
                    elif text == '/':
                        cte_value = left_cte_value / right_cte_value
                    elif text == '+':
                        cte_value = left_cte_value + right_cte_value
                    elif text == '-':
                        cte_value = left_cte_value - right_cte_value
                else:
                    left_something = (str(left_cte_value)
                                      if left_cte_value is not None else
                                      "%{}".format(left_ir_register))
                    right_something = (str(right_cte_value)
                                       if right_cte_value is not None else
                                       "%{}".format(right_ir_register))
                    ir_register = self.next_ir_register
                    self.next_ir_register += 1
                    if text == '*':
                        printf("  %%%s = mul nsw %s %s, %s\n", ir_register,
                               llvm_type(tyype), left_something,
                               right_something)
                    elif text == '/':
                        printf("  %%%s = sdiv %s %s, %s\n", ir_register,
                               llvm_type(tyype), left_something,
                               right_something)
                    elif text == '+':
                        printf("  %%%s = add nsw %s %s, %s\n", ir_register,
                               llvm_type(tyype), left_something,
                               right_something)
                    elif text == '-':
                        printf("  %%%s = sub nsw %s %s, %s\n", ir_register,
                               llvm_type(tyype), left_something,
                               right_something)
                    cte_value = None
            else:
                tyype = Type.INT
                if left_cte_value != None and right_cte_value != None:
                    if text == '<':
                        if left_cte_value < right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>':
                        if left_cte_value > right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '==':
                        if left_cte_value == right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '!=':
                        if left_cte_value != right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '<=':
                        if left_cte_value <= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                    elif text == '>=':
                        if left_cte_value >= right_cte_value:
                            cte_value = 1
                        else:
                            cte_value = 0
                else:
                    cte_value = None
        return tyype, cte_value, ir_register
    def visitExpression(self, ctx:GrammarParser.ExpressionContext):
        #print("EXP")
        tyype = Type.VOID
        cte_value = None # RETORNAR OS VALORES DAS CONTANTES, OU NONE SE NAO FOR CONSTANTE
        if len(ctx.expression()) == 0:
            if ctx.integer() != None:
                tyype = Type.INT    
                cte_value = int(ctx.integer().getText()) #coloquei

            elif ctx.floating() != None:
                tyype = Type.FLOAT
                cte_value = float(ctx.floating().getText()) #coloquei

            elif ctx.string() != None:
                tyype = Type.STRING
                cte_value = str(ctx.string().getText()) #coloquei

            elif ctx.identifier() != None:
                name = ctx.identifier().getText()
                try:
                    tyype, _, cte_value = self.ids_defined[name]
                except:
                    token = ctx.identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined variable '" + name + "' in line " + str(token.line) + " and column " + str(token.column))

            elif ctx.array() != None:
                name = ctx.array().identifier().getText()
                try:
                    # print("entrou no try do array do visit expression")
                    tyype, array_length, cte_values_array = self.ids_defined[name]
                    # print(cte_values_array, "valores pegando aqui dentro do visitexpression")
                except:
                    # print("entrou no expection do array")
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("ERROR: undefined array '" + name + "' in line " + str(token.line) + " and column " + str(token.column))
                array_index = self.visit(ctx.array())
                # print(array_index, array_length)
                if array_index < array_length:
                    # print(array_index, "indice do array") 
                    # print(ctx.array().getText())
                    # print(self.ids_defined['tk'][2][2], "uhuuu")
                    if(tyype == Type.FLOAT):
                        cte_value = float(self.ids_defined[name][2][array_index])
                    elif(tyype == Type.INT):
                        cte_value = int(self.ids_defined[name][2][array_index])
                    else:
                        print("Erro voce ta acessando o array que nao é inteiro nem float para alguma operacao [aritmetica possivelmente]")
                else:
                    token = ctx.array().identifier().IDENTIFIER().getPayload()
                    print("Erro aqui no index do array, indice fora do comprimento do array " + name + " in line " + str(token.line) +  " and column " + str(token.column))
            
            elif ctx.function_call() != None:
                tyype, cte_value = self.visit(ctx.function_call())

        elif len(ctx.expression()) == 1:

            if ctx.OP != None: #unary operators
                text = ctx.OP.text
                token = ctx.OP
                tyype, cte_value = self.visit(ctx.expression(0)) #caso vem sem operacao unario tipo 3 != +3 ou -3
                if(text == '-'):
                    cte_value =  -cte_value # é negativo categoricamente
                elif (text == '+'):
                    cte_value = cte_value #é positivo categoricamente
                else:
                    print("Erro operador unario negativos e positivos")


                if tyype == Type.VOID:
                    print("ERROR: unary operator '" + text + "' used on type void in line " + str(token.line) + " and column " + str(token.column))

            else: # parentheses
                tyype, cte_value = self.visit(ctx.expression(0))


        elif len(ctx.expression()) == 2: # binary operators
            # print("PRINT 1")
            text = ctx.OP.text
            token = ctx.OP
            left, left_cte_value = self.visit(ctx.expression(0))
            right, right_cte_value = self.visit(ctx.expression(1))
            if left == Type.VOID or right == Type.VOID:
                print("ERROR: binary operator '" + text + "' used on type void in line " + str(token.line) + " and column " + str(token.column))

            if text == '*' or text == '/' or text == '+' or text == '-':
                if left == Type.FLOAT or right == Type.FLOAT:
                    tyype = Type.FLOAT
                else:
                    tyype = Type.INT
            else:
                tyype = Type.INT

            # print("TEXT", text)
            
            if(left_cte_value != None and right_cte_value != None):
                if text == '/':
                    cte_value = eval(str(left_cte_value)) / eval(str(right_cte_value))
                    #print(left_cte_value, right_cte_value, "valores")
                elif text == '*':
                    cte_value = eval(str(left_cte_value)) * eval(str(right_cte_value))
                    #print(left_cte_value, right_cte_value, "valores")
                elif text == '+':
                    cte_value = eval(str(left_cte_value)) + eval(str(right_cte_value))
                    #print(left_cte_value, right_cte_value, "valores")
                elif text == '-':
                    cte_value = eval(str(left_cte_value)) - eval(str(right_cte_value))
                    #print(left_cte_value, right_cte_value, "valores")
                elif text == '<':
                    if left_cte_value < right_cte_value:
                        cte_value = 1
                    else:
                        cte_value = 0
                elif text == '>':
                    if left_cte_value > right_cte_value:
                        cte_value = 1
                    else:
                        cte_value = 0
                elif text == '<=':
                    if left_cte_value <= right_cte_value:
                        cte_value = 1
                    else:
                        cte_value = 0
                elif text == '>=':
                    if left_cte_value >= right_cte_value:
                        cte_value = 1
                    else:
                        cte_value = 0
                elif text == '==':
                    if left_cte_value == right_cte_value:
                        cte_value = 1
                    else:
                        cte_value = 0
                elif text == '!=':
                    if left_cte_value != right_cte_value:
                        cte_value = 1
                    else:
                        cte_value = 0
                else:
                    print("ERRO: nao é uma operacao valida")
        

        print(str(tyype) + ": " + str(cte_value))
        #print(self.ids_defined)
        return tyype, cte_value
Пример #18
0
    def visitExpression(self, ctx:GrammarParser.ExpressionContext):

        tyype = Type.VOID
        if len(ctx.expression()) == 0:

            if ctx.integer() != None:
                text = ctx.integer().getText()
                token = ctx.integer().INTEGER().getPayload()

                tyype = Type.INT

            elif ctx.floating() != None:
                text = ctx.floating().getText()
                token = ctx.floating().FLOATING().getPayload()

                tyype = Type.FLOAT

            elif ctx.string() != None:
                typpe = Type.STRING 

            elif ctx.identifier() != None:
                text = ctx.identifier().getText()
                token = ctx.identifier().IDENTIFIER().getPayload()

                if (text in GrammarCheckerVisitor.ids_defined) == True:
                    tyype = GrammarCheckerVisitor.ids_defined[text]
                else:
                    raise NameError("identifier '" + text + "' linha: "+ str(token.line) + " ,não foi definido ainda.")

            elif ctx.array() != None:
                text = ctx.array().identifier().getText()
                token = ctx.array().identifier().IDENTIFIER().getPayload()

                if (text in GrammarCheckerVisitor.ids_defined) == True:
                    tyype = GrammarCheckerVisitor.ids_defined[text]
                else:
                    raise NameError("array '" + text + "'[] linha: "+ str(token.line) + " ,não foi definido ainda.")

           
            elif ctx.function_call != None:
                text = ctx.function_call().identifier().getText()
                token = ctx.function_call().identifier().IDENTIFIER().getPayload()
                    
                if (text in GrammarCheckerVisitor.ids_defined) == True:
                    function = GrammarCheckerVisitor.ids_defined[text]
                    
                    if function[1] != len(ctx.function_call().expression()):
                        raise NameError("function call '" + text + "'() linha: "+ str(token.line) + " ,possui um número incorreto de argumentos.")


                    else:
                        for i in range(len(ctx.function_call().expression())):
                            arg_type = self.visit(ctx.function_call().expression(i))
                            arg_function = GrammarCheckerVisitor.ids_defined[function[i+2]]
                            if arg_type != arg_function:
                                if (arg_function == Type.INT and arg_type == Type.FLOAT) or (arg_function == Type.FLOAT and arg_type == Type.INT):
                                    print("WARNING: function call '" + text + "'() linha: "+ str(token.line) + " ,pode perder informações, por está passando um argumento de tipo diferente da definição da função")
                                else:
                                    raise NameError("function call '" + text + "'() linha: "+ str(token.line) + " ,está passando um argumento de tipo diferente do aceito.")


                        tyype = function[0]
               
                else:

                    for i in range(len(ctx.function_call().expression())):
                            arg_type = self.visit(ctx.function_call().expression(i))
                    
                    tyype = Type.VOID
                 
        
        elif len(ctx.expression()) == 1:

            if ctx.OP != None:
                text = ctx.OP.text
                token = ctx.OP

                tyype = self.visit(ctx.expression(0))
            
            else:
                tyype = self.visit(ctx.expression(0))

        elif len(ctx.expression()) == 2:
            text = ctx.OP.text
            token = ctx.OP
            
            left = self.visit(ctx.expression(0))
            right = self.visit(ctx.expression(1))

            listaOpA = ['+', '-', '*', '/']
            listaOpL = ['<', '<=', '==', '>=', '>', '!=']
            
            if(left == Type.INT) and (right == Type.INT) and ((text in listaOpA) or (text in listaOpL)):
                tyype = Type.INT
            elif (left == Type.FLOAT) and (right == Type.FLOAT) and (text in listaOpA):
                tyype = Type.FLOAT
            elif (((left == Type.FLOAT) and (right == Type.INT)) or ((left == Type.INT) and (right == Type.FLOAT))) and (text in listaOpA): 
                tyype = Type.FLOAT
            elif (left == Type.FLOAT) and (right == Type.FLOAT) and (text in listaOpL):
                tyype = Type.FLOAT
            else:
                raise NameError("expression '" + text + "'() linha: "+ str(token.line)+ " ,possui operadores que não são do tipo 'int' ou 'float'.")
        
        return tyype