Example #1
0
    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))
Example #2
0
    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))
Example #3
0
    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
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
 def check_repr(val, expected):
     c = Constant(DoubleType(), val)
     self.assertEqual(str(c), expected)
Example #7
0
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')))
Example #8
0
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