codegen.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import src.zelkelc.ast.types as types
  2. class IRTable:
  3. structs: str
  4. struct_functions: str
  5. global_functions: str
  6. def __init__(self):
  7. self.structs = ""
  8. self.struct_functions = ""
  9. self.global_functions = ""
  10. class Codegen:
  11. ast: list[types.FunctionDeclaration | types.ClassDeclaration]
  12. ir: IRTable
  13. temp_counter: int
  14. def __init__(self, ast: list[types.FunctionDeclaration | types.ClassDeclaration]):
  15. self.ast = ast
  16. self.ir = IRTable()
  17. self.temp_counter = 0
  18. def generate(self):
  19. for node in self.ast:
  20. match node:
  21. case types.StructDeclaration():
  22. self.gen_struct_declaration(node)
  23. case types.ClassDeclaration():
  24. self.gen_class_declaration(node)
  25. case types.FunctionDeclaration():
  26. self.ir.global_functions += self.gen_function_declaration(node)
  27. case _:
  28. print(f"Invalid node found during codegen {type(node)}")
  29. exit(1)
  30. return self.ir.structs + "\n" + self.ir.struct_functions + "\n" + self.ir.global_functions
  31. def gen_struct_declaration(self, node: types.StructDeclaration):
  32. members_str = ""
  33. for i, m in enumerate(node.members):
  34. members_str += f"{", " if i != 0 else ""}{m.typ.to_llvm()}"
  35. self.ir.structs += f"\n%{node.irname} = type " + "{ " + members_str + " }"
  36. def gen_class_declaration(self, node: types.ClassDeclaration):
  37. members_str = ""
  38. for i, m in enumerate(node.members):
  39. members_str += f"{", " if i != 0 else ""}{m.typ.to_llvm()}"
  40. self.ir.structs += f"\n%{node.irname} = type " + "{ " + members_str + " }"
  41. for func in node.methods:
  42. self.ir.struct_functions += self.gen_function_declaration(func)
  43. def gen_function_declaration(self, node: types.FunctionDeclaration) -> str:
  44. args_str = ""
  45. for i, (name, typ) in enumerate(node.args.items()):
  46. args_str += f"{", " if i != 0 else ""}{typ.to_llvm()} %{name}"
  47. ir = f"\ndefine {str(node.typ.to_llvm())} @{node.irname}({args_str}) " + "{"
  48. ir += "\nentry:"
  49. for child_node in node.body:
  50. match child_node:
  51. case types.ValueDeclaration():
  52. ir += self.gen_value_declaration(child_node)
  53. case _:
  54. continue
  55. return ir + "\n}"
  56. def gen_value_declaration(self, node: types.ValueDeclaration) -> str:
  57. ir = ""
  58. count, expr = self.gen_expression(node.expr)
  59. ir += expr
  60. match node.typ:
  61. case types.Integer64:
  62. if node.mutable == True:
  63. ir += f"\n%{node.irname} = alloca i64, align 8" # TODO: this would only work for i64s, just testing
  64. ir += f"\nstore i64 %{count}, i64* %{node.irname}, align 8"
  65. else:
  66. ir += f"\n%{node.irname} = add i64 %{count}, 0"
  67. case _:
  68. print(f"gen_value_declaration() for {type(node.typ)} is unimplemented")
  69. exit(1)
  70. return ir
  71. def gen_expression(self, node: types.Expression) -> tuple[str, str]:
  72. ir = ""
  73. match type(node):
  74. case types.BinaryExpression:
  75. left_irname, left = self.gen_expression(node.left)
  76. right_irname, right = self.gen_expression(node.right)
  77. ir += left + right
  78. op = ""
  79. match node.op:
  80. case '+':
  81. op = "add"
  82. case '-':
  83. op = "sub"
  84. case '*':
  85. op = "mul"
  86. case '/':
  87. print("gen_expression() for BinaryExpression for operator '/' is unimplemented")
  88. exit(1)
  89. case _:
  90. print(f"gen_expression() for BinaryExpression for operator '{node.op}' is unimplemented")
  91. exit(1)
  92. match node.left.typ:
  93. case types.Integer64:
  94. ir += f"\n%{self.temp_counter} = {op} i64 %{left_irname}, %{right_irname}"
  95. self.temp_counter += 1
  96. case _:
  97. print(f"gen_expression() for BinaryExpression for {node.left.typ}")
  98. exit(1)
  99. case types.UnaryExpression:
  100. print("gen_expression() for UnaryExpression unimplemented")
  101. exit(1)
  102. case types.PrimaryExpression:
  103. match type(node.value):
  104. case types.Integer64:
  105. ir += f"\n%{self.temp_counter} = add i64 {node.value.value}, 0"
  106. self.temp_counter += 1
  107. case types.VariableRef:
  108. return node.value.irname, ir
  109. case _:
  110. print(f"gen_expression() for PrimaryExpression for {type(node.value)}")
  111. exit(1)
  112. case _:
  113. print(f"Invalid expression types found during codegen: {node}")
  114. exit(1)
  115. return str(self.temp_counter - 1), ir