compiler/compiler/__main__.py

82 lines
2.3 KiB
Python

from __future__ import annotations
import argparse
import sys
from pprint import pprint
from . import semantic, ir, optimizations
from .errors import CompilationError, CompilationWarning
from .lexer import Lexer, Tokens
from .logger import rootLogger, LogLevel
from .parser import Parser
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--mock", action="store_true", help="Use default test input")
args = parser.parse_args()
data = """
{
// let byte: uint32 = 42;
}
let byte: uint32;
2 + 8 - 1 * (byte = 3 + 5)
/ (byte = 255) + byte;
byte = byte + byte;
{
// let a: uint32 = byte;
}
// { let b: uint32; }
display(byte, 3) + 1;
"""
if not args.mock:
data = sys.stdin.read().strip()
print("Source:\n", data)
tokens = Lexer(data)
tokens = [token for token in tokens if token.kind not in [Tokens.Blank, Tokens.Newline, Tokens.Comment]]
if rootLogger.level <= LogLevel.Debug:
pprint(tokens)
parser = Parser(tokens)
try:
ast = parser.parse()
ast.pprint(depth=10)
context = semantic.BuiltinContext()
ast.semantic_analysis(context)
context.check()
intermediate_representation = ir.IR(ast, source=data)
intermediate_representation.update_location()
print("\n---\n", repr(context))
# architecture = optimizations.ArchitectureConstraints(registers=["A", "B", "C"], direct_memory_store=True)
register_alloc = optimizations.RegisterAllocation(intermediate_representation.intermediate_representation)
register_alloc.analyze()
intermediate_representation.pretty_print()
print(ir.IRRegister.get_registers())
except CompilationError as e:
e.location.source = data
print(f"{e}\n{e.location.show_in_source()}", flush=True)
if e.__cause__ is not None:
if rootLogger.level <= LogLevel.Debug:
raise e.__cause__
print(f"Caused by:\n{e.__cause__.__class__.__name__}: {e.__cause__}", flush=True)
finally:
CompilationWarning.show_warnings(data, file=sys.stdout)
if __name__ == "__main__":
main()