def visit_UnaryOperator(self, node: UnaryOperator) -> Constant: """Performs Unary Operations according to the arithmetic operator (PLUS and MINUS) transforming them into a LLVM IR Constant. Args: node (UnaryOperator): node containing the variables (or numbers) and the arithmetic operators (PLUS and MINUS) Returns: Constant: a LLVM IR Constant representing the number or variable. """ operator = node.operator.type if operator == TokenType.PLUS: expression = self.visit(node.expression) return Constant(DoubleType(), float(+expression.constant)) elif operator == TokenType.MINUS: expression = self.visit(node.expression) return Constant(DoubleType(), float(-expression.constant))
def visit_Num(self, node: Num) -> Constant: """Set the Double Type to a specific number. Args: node (Num): a token represeting a number (constant) Returns: Constant: a LLVM IR Constant representing the number. """ return Constant(DoubleType(), float(node.value))
def visit_Var(self, node: Var) -> VarSymbol: """Search for the variable in the Symbol Table and define the Double Type. Args: node (Var): variable token Returns: VarSymbol: a variable symbol with updated type """ var_name = node.value var_symbol = self.symbol_table.get_token(var_name) var_symbol.type = DoubleType() return var_symbol
def _create_instruct(self, typ: str, is_printf: bool = False) -> None: """Create a new Function instruction and attach it to a new Basic Block Entry. Args: typ (str): node type. is_printf (bool, optional): Defaults to False. """ if is_printf or typ in ["String", "ArrayType"]: self.str_counter += 1 self.func_name = f"_{typ}.{self.str_counter}" func_type = FunctionType(VoidType(), []) elif typ == "Boolean": self.bool_counter += 1 self.func_name = f"_{typ}.{self.bool_counter}" func_type = FunctionType(IntType(1), []) else: self.expr_counter += 1 self.func_name = f"_{typ}_Expr.{self.expr_counter}" func_type = FunctionType(DoubleType(), []) main_func = Function(self.module, func_type, self.func_name) bb_entry = main_func.append_basic_block("entry") self.builder = IRBuilder(bb_entry)
Module, Function, FunctionType, IntType, Constant, IRBuilder ) mod = Module('hello') hello_func = Function(mod, FunctionType(IntType(32), []), name='hello') block = hello_func.append_basic_block('entry') builder = IRBuilder(block) builder.ret(Constant(IntType(32), 37)) # A user-defined function from llvmlite.ir import DoubleType ty_double = DoubleType() dsquared_func = Function(mod, FunctionType(ty_double, [ty_double, ty_double]), name='dsquared') block = dsquared_func.append_basic_block('entry') builder = IRBuilder(block) # Get the function args x, y = dsquared_func.args # Compute temporary values for x*x and y*y xsquared = builder.fmul(x, x) ysquared = builder.fmul(y, y) # Sum the values and return the result d2 = builder.fadd(xsquared, ysquared)
def check_repr(val, expected): c = Constant(DoubleType(), val) self.assertEqual(str(c), expected)
from llvmlite.ir import Constant, FloatType, DoubleType import math print(Constant(FloatType(), math.pi)) print(Constant(DoubleType(), math.pi)) print(Constant(FloatType(), float('+inf'))) print(Constant(DoubleType(), float('+inf'))) print(Constant(FloatType(), float('-inf'))) print(Constant(DoubleType(), float('-inf')))
from collections import ChainMap from functools import partialmethod # LLVM imports. Don't change this. from llvmlite.ir import (Module, IRBuilder, Function, IntType, DoubleType, VoidType, Constant, GlobalVariable, FunctionType) # Declare the LLVM type objects that you want to use for the low-level # in our intermediate code. Basically, you're going to need to # declare the integer, float, and char types here. These correspond # to the types being used the intermediate code being created by # the ircode.py file. int_type = IntType(32) # 32-bit integer float_type = DoubleType() # 64-bit float byte_type = IntType(8) # 8-bit integer void_type = VoidType() # Void type. This is a special type # used for internal functions returning # no value LLVM_TYPE_MAPPING = { 'I': int_type, 'F': float_type, 'B': byte_type, None: void_type } # The following class is going to generate the LLVM instruction stream. # The basic features of this class are going to mirror the experiments