Skip to content

Commit dbf61c9

Browse files
Add support for the tuple datatype
1 parent 0b88b35 commit dbf61c9

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

src/irx/builders/llvmliteir.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,64 @@ def visit(self, node: astx.LiteralList) -> None:
16451645
"are supported"
16461646
)
16471647

1648+
@dispatch # type: ignore[no-redef]
1649+
def visit(self, node: astx.LiteralTuple) -> None:
1650+
"""Lower a LiteralTuple to LLVM IR.
1651+
1652+
Representation
1653+
--------------
1654+
- Empty tuple -> constant ``{}`` (empty literal struct).
1655+
- All-constant elements -> constant literal struct ``{T0, T1, …}``.
1656+
- Otherwise -> alloca of the struct in the function
1657+
entry block with each field stored; pushes the *pointer*.
1658+
1659+
Tuples are heterogeneous and ordered, so they are modelled as a
1660+
literal struct rather than an array.
1661+
"""
1662+
# 1) Lower every element
1663+
llvm_vals: list[ir.Value] = []
1664+
for elem in node.elements:
1665+
self.visit(elem)
1666+
v = self.result_stack.pop()
1667+
if v is None:
1668+
raise Exception("LiteralTuple: failed to lower an element.")
1669+
llvm_vals.append(v)
1670+
1671+
n = len(llvm_vals)
1672+
1673+
# 2) Empty tuple -> constant {} (empty struct)
1674+
if n == 0:
1675+
struct_ty = ir.LiteralStructType([])
1676+
self.result_stack.append(ir.Constant(struct_ty, []))
1677+
return
1678+
1679+
# 3) Build the struct type from element value types
1680+
elem_tys = [v.type for v in llvm_vals]
1681+
struct_ty = ir.LiteralStructType(elem_tys)
1682+
1683+
# 4) All-constant fast path -> constant struct
1684+
if all(isinstance(v, ir.Constant) for v in llvm_vals):
1685+
self.result_stack.append(ir.Constant(struct_ty, llvm_vals))
1686+
return
1687+
1688+
# 5) Non-constant path: alloca + store each field
1689+
entry_bb = self._llvm.ir_builder.function.entry_basic_block
1690+
cur_bb = self._llvm.ir_builder.block
1691+
self._llvm.ir_builder.position_at_start(entry_bb)
1692+
alloca = self._llvm.ir_builder.alloca(struct_ty, name="tuple.lit")
1693+
self._llvm.ir_builder.position_at_end(cur_bb)
1694+
1695+
i32 = ir.IntType(32)
1696+
for idx, v in enumerate(llvm_vals):
1697+
field_ptr = self._llvm.ir_builder.gep(
1698+
alloca,
1699+
[ir.Constant(i32, 0), ir.Constant(i32, idx)],
1700+
inbounds=True,
1701+
)
1702+
self._llvm.ir_builder.store(v, field_ptr)
1703+
1704+
self.result_stack.append(alloca)
1705+
16481706
def _create_string_concat_function(self) -> ir.Function:
16491707
"""Create a string concatenation function."""
16501708
func_name = "string_concat"

0 commit comments

Comments
 (0)