added command line arguments to the compiler

This commit is contained in:
SpookyDervish
2025-10-18 07:40:47 +11:00
parent 52686fa314
commit 70bc672885

84
main.py
View File

@@ -4,22 +4,38 @@ from compiler import Compiler
from AST import Program from AST import Program
import json import json
import time import time
import sys
from argparse import ArgumentParser, Namespace
from llvmlite import ir from llvmlite import ir
import llvmlite.binding as llvm import llvmlite.binding as llvm
from ctypes import CFUNCTYPE, c_int, c_float from ctypes import CFUNCTYPE, c_int, c_float
LEXER_DEBUG: bool = False
PARSER_DEBUG: bool = False def parse_arguments() -> Namespace:
COMPILER_DEBUG: bool = False arg_parser: ArgumentParser = ArgumentParser(
RUN_CODE: bool = True "Plasma",
description="The compiler for the Plasma programming language."
)
arg_parser.add_argument("file_path", type=str, help="path to the entry point of your plasma program (ex. \"main.pla\")")
arg_parser.add_argument("--tokens", action="store_true", help="display the tokenized code")
arg_parser.add_argument("--ast", default=None, help="export the generated AST to a JSON file")
arg_parser.add_argument("--llvm", default=None, help="export the generated LLVM IR to a file")
arg_parser.add_argument("--silent", action="store_true", help="don't print anything!!!!")
return arg_parser.parse_args()
if __name__ == "__main__": if __name__ == "__main__":
with open("tests/test.pla") as f: args = parse_arguments()
if args.silent:
sys.stdout = None
with open(args.file_path) as f:
code: str = f.read() code: str = f.read()
if LEXER_DEBUG: if args.tokens:
debug_lex: Lexer = Lexer(source=code) debug_lex: Lexer = Lexer(source=code)
while debug_lex.current_char is not None: while debug_lex.current_char is not None:
print(debug_lex.next_token()) print(debug_lex.next_token())
@@ -27,56 +43,62 @@ if __name__ == "__main__":
l: Lexer = Lexer(source=code) l: Lexer = Lexer(source=code)
p: Parser = Parser(lexer=l) p: Parser = Parser(lexer=l)
parse_st: float = time.time()
program: Program = p.parse_program() program: Program = p.parse_program()
parse_et: float = time.time()
print(f"Parsed in {round((parse_et - parse_st) * 1000, 6)} ms.")
if len(p.errors) > 0: if len(p.errors) > 0:
for err in p.errors: for err in p.errors:
print(err) print(err)
exit(1) exit(1)
if PARSER_DEBUG: if args.ast:
print("===== PARSER DEBUG =====") print("===== PARSER DEBUG =====")
#program: Program = p.parse_program() #program: Program = p.parse_program()
with open("debug/ast.json", "w") as f: with open(args.ast, "w") as f:
json.dump(program.json(), f, indent=4) json.dump(program.json(), f, indent=4)
print("Wrote AST to debug/ast.json successfully.") print(f"Wrote AST to \"{args.ast}\" successfully.")
c: Compiler = Compiler() c: Compiler = Compiler()
compiler_st: float = time.time()
c.compile(program) c.compile(program)
compiler_et: float = time.time()
print(f"Compiled in {round((compiler_et - compiler_st) * 1000, 6)} ms.")
module: ir.Module = c.module module: ir.Module = c.module
module.triple = llvm.get_default_triple() module.triple = llvm.get_default_triple()
if COMPILER_DEBUG: if args.llvm:
with open("debug/ir.ll", "w") as f: with open(args.llvm, "w") as f:
f.write(str(module)) f.write(str(module))
if RUN_CODE: llvm.initialize_native_target()
#llvm.initialize() llvm.initialize_native_asmparser()
llvm.initialize_native_target() llvm.initialize_native_asmprinter()
llvm.initialize_native_asmparser()
llvm.initialize_native_asmprinter()
try: try:
llvm_ir_parsed = llvm.parse_assembly(str(module)) llvm_ir_parsed = llvm.parse_assembly(str(module))
llvm_ir_parsed.verify() llvm_ir_parsed.verify()
except Exception as e: except Exception as e:
print(e) print(e)
raise raise
target_machine = llvm.Target.from_default_triple().create_target_machine() target_machine = llvm.Target.from_default_triple().create_target_machine()
engine = llvm.create_mcjit_compiler(llvm_ir_parsed, target_machine) engine = llvm.create_mcjit_compiler(llvm_ir_parsed, target_machine)
engine.finalize_object() engine.finalize_object()
entry = engine.get_function_address("main") entry = engine.get_function_address("main")
cfunc = CFUNCTYPE(c_int)(entry) cfunc = CFUNCTYPE(c_int)(entry)
st = time.time() st = time.time()
result = cfunc() result = cfunc()
et = time.time() et = time.time()
print(f"\n\nProgram returned: {result}\n=== Executed in {round((et - st) * 1000, 6)} ms. ===") print(f"\n\nProgram returned: {result}\n=== Executed in {round((et - st) * 1000, 6)} ms. ===")