From 72fad0d4e2bf9c5be50a63415e9ee0e0bd072065 Mon Sep 17 00:00:00 2001 From: yuvi-mittal Date: Thu, 11 Dec 2025 22:43:37 +0530 Subject: [PATCH] add tuple datatype --- .DS_Store | Bin 0 -> 8196 bytes src/irx/builders/llvmliteir.py | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7962528ce9a8669a7dbf7cb463992de8ca89a084 GIT binary patch literal 8196 zcmeHLziSjh6n=BN@eX1j#KM4zTUaQ97_dlrh6~yV!l8vo^nS$TFqe&&i$Mh0!X|}9 z{(wL#>tLsaU=d@dHkyAyEJU#r(eKSna&K;LO|B6oGhyc)^S-z5d*ANP<}DGaiKY4& z(I^oWaIhU7#MEQ3pO4hY*_G3<3h^{IGghv}&4m=wFL(vK0$u^HfLFjP@UJL2x*vQ(VwTZFtU?>v`YeJQ6 zF_a0%dSr1$YZGHlI4RqFD4SW?4n^tgIDe$!q>9G+*(=}`NGrg-dr0SKh8om%`uFz6 zw)8dQQmHx@SFu+3F#c;~{od9^*I)mme_>X98~Bb$qWn%?nx!SGI@#&!mo!3hI5BzQ z=cDVIL)UqlafeAZ%HcyB%x46A8ni$UXr8Kci)!FCjrlItVtD4MO^Yr|y1d^w$^Fu^ zp{cj;U$cJu$|)=AH`c9F?~a40vxzFXQm(RMDwUN5t81HJmw}YEtS(m`9zLtDLngX& zJ@!URzQN}NBs7Z_?vOk9%iv3N0&@;iBR>zp@Fi^$s2&rs?~34f#!lEd*=PgYj8^mXYvk7SaKa`>2kA_DMfQO&sq z!OUV;Bi0Tq_Yr3sL>y>*H{_u3JT+c literal 0 HcmV?d00001 diff --git a/src/irx/builders/llvmliteir.py b/src/irx/builders/llvmliteir.py index e978b70..0ceb608 100644 --- a/src/irx/builders/llvmliteir.py +++ b/src/irx/builders/llvmliteir.py @@ -1241,6 +1241,67 @@ def visit(self, node: astx.LiteralInt8) -> None: result = ir.Constant(self._llvm.INT8_TYPE, node.value) self.result_stack.append(result) + @dispatch # type: ignore[no-redef] + def visit(self, node: astx.LiteralTuple) -> None: + """Lower a LiteralTuple to LLVM IR. + + Notes + ----- + - Tuples are heterogeneous and ordered, + so we model them as a struct, not an array. + - The constant path yields a struct *value*; + the non-constant path yields a pointer to the struct. + """ + # Lower elements and collect LLVM values + llvm_vals: list[ir.Value] = [] + for elem in node.elements: + self.visit(elem) + try: + v = self.result_stack.pop() + except IndexError: + v = None + if v is None: + raise Exception("LiteralTuple: failed to lower an element.") + llvm_vals.append(v) + + n = len(llvm_vals) + + # Empty tuple -> empty literal struct constant + if n == 0: + struct_ty = ir.LiteralStructType([]) + const_empty = ir.Constant(struct_ty, []) + self.result_stack.append(const_empty) + return + + elem_tys = [v.type for v in llvm_vals] + struct_ty = ir.LiteralStructType(elem_tys) + + if all(isinstance(v, ir.Constant) for v in llvm_vals): + const_struct = ir.Constant(struct_ty, llvm_vals) + self.result_stack.append(const_struct) + return + + entry_bb = self._llvm.ir_builder.function.entry_basic_block + cur_bb = self._llvm.ir_builder.block + + self._llvm.ir_builder.position_at_start(entry_bb) + alloca = self._llvm.ir_builder.alloca(struct_ty, name="tuple.lit") + + self._llvm.ir_builder.position_at_end(cur_bb) + + i32 = self._llvm.INT32_TYPE + for idx, v in enumerate(llvm_vals): + # GEP to the field: [0, idx] + field_ptr = self._llvm.ir_builder.gep( + alloca, + [ir.Constant(i32, 0), ir.Constant(i32, idx)], + inbounds=True, + ) + self._llvm.ir_builder.store(v, field_ptr) + + # Push the pointer to the tuple struct + self.result_stack.append(alloca) + @dispatch # type: ignore[no-redef] def visit(self, expr: astx.LiteralUTF8Char) -> None: """Handle ASCII string literals."""