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)
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
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
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
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 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 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: 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
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
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 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): 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
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
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
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