Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 41 additions & 35 deletions builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,36 @@
import orjson
from colorama import init, Fore, Back, Style
from mathParser.mathProcessor import process as process_expression

init()


class IRBuilder:
"""
An LLVM IR builder.
"""
def __init__(self, module_name: str):
self.module_name = module_name
self.footer = ""
self.function_imported = set()
self.main_function = ""
self.header = ""

def define_string(self):
pass

def print_message(self, message):
if not "puts" in self.function_imported:
self.footer += "declare i32 @puts(i8*)"
self.function_imported.add("puts")
self.header += f"@.gtempstr_{len(self.main_function)} = private unnamed_addr constant [{len(message) + 1} x i8] c\"{message}\\00\"\n"
self.main_function += f"%temp_str_{len(self.main_function)} = getelementptr [{len(message) + 1} x i8], [{len(message) + 1} x i8]* @.gtempstr_{len(self.main_function)}, i32 0, i32 0\n\tcall i32 @puts(i8* %temp_str_{len(self.main_function)})\n"

def buildIR(self):
lb = "{"
rb = "}"
ir = f"""; ModuleID = \"{self.module_name}\"
"""
An LLVM IR builder.
"""

def __init__(self, module_name: str):
self.module_name = module_name
self.footer = ""
self.function_imported = set()
self.main_function = ""
self.header = ""

def define_string(self):
pass

def print_message(self, message):
if not "puts" in self.function_imported:
self.footer += "declare i32 @puts(i8*)"
self.function_imported.add("puts")
self.header += f'@.gtempstr_{len(self.main_function)} = private unnamed_addr constant [{len(message) + 1} x i8] c"{message}\\00"\n'
self.main_function += f"%temp_str_{len(self.main_function)} = getelementptr [{len(message) + 1} x i8], [{len(message) + 1} x i8]* @.gtempstr_{len(self.main_function)}, i32 0, i32 0\n\tcall i32 @puts(i8* %temp_str_{len(self.main_function)})\n"

def buildIR(self):
lb = "{"
rb = "}"
ir = f"""; ModuleID = \"{self.module_name}\"
; LLVM IR generated by SSLLVM

{self.header}
Expand All @@ -42,21 +45,24 @@ def buildIR(self):

{self.footer}
"""
return ir
return ir


# How many time the build IR function has run, Use to make a unique module name
runtimes = 0


def buildIRFromCache(commands: list):
""" Build LLVM IR from StoryScript Cache """
irb = IRBuilder(f"main")
for i in commands:
tc = i.split()
if tc[0] == "CALL":
if tc[1] == "print":
irb.print_message(" ".join(tc[2:]))
return irb.buildIR()
"""Build LLVM IR from StoryScript Cache"""
irb = IRBuilder(f"main")
for i in commands:
tc = i.split()
if tc[0] == "CALL":
if tc[1] == "print":
irb.print_message(" ".join(tc[2:]))
return irb.buildIR()


def buildIRFromSource(commands: list):
""" Build LLVM IR from Source code directly. """
pass
"""Build LLVM IR from Source code directly."""
pass
27 changes: 14 additions & 13 deletions llvmtypes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from llvmlite import ir

# Integers
int_sbyte = ir.IntType(8) # Signed byte
int_short = ir.IntType(16) # Short
int_integer = ir.IntType(32) # Standard Integer
int_long = ir.IntType(64) # Long
int_sbyte = ir.IntType(8) # Signed byte
int_short = ir.IntType(16) # Short
int_integer = ir.IntType(32) # Standard Integer
int_long = ir.IntType(64) # Long

# Type Size reference: C# Type byte size

Expand All @@ -13,17 +13,18 @@
double_double = ir.DoubleType()

# Special types
void_void = ir.VoidType() # Return type for methods
void_void = ir.VoidType() # Return type for methods

# Arrays
def InitializeArray(valtype, size):
"""
Initialize an Array.
"""
return ir.ArrayType(valtype, size)
"""
Initialize an Array.
"""
return ir.ArrayType(valtype, size)


def InitializeList(valtype, start_size):
"""
Initialize a Vector. (Dynamic Array)
"""
return ir.VectorType(valtype, start_size)
"""
Initialize a Vector. (Dynamic Array)
"""
return ir.VectorType(valtype, start_size)
104 changes: 56 additions & 48 deletions processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,33 @@
from ctypes import CFUNCTYPE, c_int
from argparse import ArgumentParser


def create_execution_engine():
"""
Create an ExecutionEngine suitable for JIT code generation on
the host CPU. The engine is reusable for an arbitrary number of
modules.
"""
"""
Create an ExecutionEngine suitable for JIT code generation on
the host CPU. The engine is reusable for an arbitrary number of
modules.
"""

# Create a target machine representing the host
target = llvm.Target.from_default_triple()
target_machine = target.create_target_machine()
# And an execution engine with an empty backing module
backing_mod = llvm.parse_assembly("")
engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
llvm.check_jit_execution()
return engine

# Create a target machine representing the host
target = llvm.Target.from_default_triple()
target_machine = target.create_target_machine()
# And an execution engine with an empty backing module
backing_mod = llvm.parse_assembly("")
engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
llvm.check_jit_execution()
return engine

def init():
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
version = llvm.llvm_version_info
print(f"[DEBUG] Running on LLVM v{version[0]}.{version[1]}.{version[2]}")
global engine
engine = create_execution_engine()
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
version = llvm.llvm_version_info
print(f"[DEBUG] Running on LLVM v{version[0]}.{version[1]}.{version[2]}")
global engine
engine = create_execution_engine()


def compile_ir(llvm_ir):
"""
Expand All @@ -42,36 +45,41 @@ def compile_ir(llvm_ir):
engine.run_static_constructors()
return mod


if __name__ == "__main__":
parser = ArgumentParser(description="JITed version of StoryScript.")
parser.add_argument("-i", "--input", help="The input file.")
parser.add_argument("--emit-ir", help="Emit LLVM IR to a file or not.", action="store_true")
args = parser.parse_args()
init()
# Enter the REPL If the input is not specified.
if not args.input:
print("// SSLLVM / IR Generation from Cache testing / v0.0.1a //")
print("Type .help to see all REPL commands.")
commands = []
while True:
command = input("> ")
if command == ".buildAndGetIR":
print(buildIRFromCache(commands))
elif command.startswith(".buildToFile"):
file = command.split()[1]
with open(file, "w") as f:
f.write(buildIRFromCache(commands))
elif command == ".buildAndRun":
compile_ir(buildIRFromCache(commands))
parser = ArgumentParser(description="JITed version of StoryScript.")
parser.add_argument("-i", "--input", help="The input file.")
parser.add_argument(
"--emit-ir", help="Emit LLVM IR to a file or not.", action="store_true"
)
args = parser.parse_args()
init()
# Enter the REPL If the input is not specified.
if not args.input:
print("// SSLLVM / IR Generation from Cache testing / v0.0.1a //")
print("Type .help to see all REPL commands.")
commands = []
while True:
command = input("> ")
if command == ".buildAndGetIR":
print(buildIRFromCache(commands))
elif command.startswith(".buildToFile"):
file = command.split()[1]
with open(file, "w") as f:
f.write(buildIRFromCache(commands))
elif command == ".buildAndRun":
compile_ir(buildIRFromCache(commands))

cfunc = CFUNCTYPE(restype=c_int)(engine.get_function_address("main"))
cfunc()
elif command == ".help":
print(""".help - Print this help message
cfunc = CFUNCTYPE(restype=c_int)(engine.get_function_address("main"))
cfunc()
elif command == ".help":
print(
""".help - Print this help message
.buildandGetIR - Build the IR
.buildToFile file - Build the IR to the specified file
.buildAndRun - Build the IR and run""")
else:
commands.append(command)
.buildAndRun - Build the IR and run"""
)
else:
commands.append(command)

llvm.shutdown()
llvm.shutdown()