From 044eda2293662a3fe61646be6d6fe6bdab2225dd Mon Sep 17 00:00:00 2001 From: Aaron Sinclair Date: Sat, 15 Nov 2025 03:28:44 -0800 Subject: [PATCH] Implement basic if statement rendering in LLVM IR - Add _emit_if() method to handle if statements - Add _emit_expr() to evaluate signal references and constants - Create basic blocks for then/else/merge - Convert condition to i1 and branch - Test passing: test_if_statement_codegen --- .../llvm_codegen_signals.cpython-313.pyc | Bin 18119 -> 20618 bytes ritz/llvm_codegen_signals.py | 61 ++++++++++++++++++ .../test_parser.cpython-313-pytest-8.4.2.pyc | Bin 13002 -> 13004 bytes 3 files changed, 61 insertions(+) diff --git a/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc b/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc index 8f50720773dc0c6fa1ecf75725d0b1001ce2d27d..db4317ae62bbfcd1a1fc6d4eefc94c217ac799b9 100644 GIT binary patch delta 2518 zcmaJ@T}&I<6`t$yjA!hz4QpeAiOoO&|0HX(H7O1YBqY#fH`)9!c)J7=7w|xwnjyKK zY=Wx>R$6VGmD+&rLyWXi9reYnRw@w>9WN^PZzbfZ4>VcUDh zb_jXsNIw4VIp^N*oa=MW_;)`7A3X-PudP-yg`YpnG^SclKd~(vzzTY3=!<$K&O_ZW zLbK$RcpX_VGV4gd$f6@FMuLuPk{5krP|+otKl+NUaY&9yW|EyWbsHGWAYt5Xl$^TF ziM~fSm>P84fClL1i!L3zB=;m+^=#BN?iVyox~5UL8zhguYO1c9^_53D0-NVdLEpw- zY1#|^v+;KkvW5bMp86cTXJ1O32~cTp}d&}*$< z>3lGmAKSLJmL2X#{j2>2=eDD>By^VT4k+MlGX^Yb4~GGbKVK^}`X|#SDh3I}4K^xj zP-w|eMMjCPA_lFtxLi0JBgy6js2roPacUHx|3;gE30>x0=o72cEirMEjgr_ni=`>b zRGpD{+Vdt?+u08Sl_SWVP$D&9sV*tZ!M(^K@x32Vl)}Zi=Q}zms>UWtW}VFvr!ku) zZp0a|H4>4!*j{tA9d<+(vA0d%BSZ}c{+QfK$Q{&(6O;1jR=3;1AK2e^QIrLTTRT;h zY;lHM+JVapapK>q=GaCelV0Z16RmQY2^Z=*#+yazWg4zVgX+cZCBk_4s5yJEF557S z>qneY#MG>qQKwXSURKm_mP^fs)$6iSL2^1HhqETEla*vxGpce%g%@zf**dXbOwG*S z6ct%aMZYC>Wa;B#m&PtYvImmd$?~E&4VT2!YuL&k7t>SIa$4-rKri$Yvp~!>?S-HT zN?2PfZ29g@2bUF5SSsACLTPH%p;gY0@qABYAH4Q8?4Cu z9GCbqwa-%Z4Uep=R%FjHWp_(~$=@k8_;cn%*yYX3`R|sT9XTFva5g?VwR)=1U1T5k zZ9BShTt$Z)5}nF%Wlnf#eqi3^nzp#6{MiDR&z6EGHv^lV&!Q#I8#_zfNX0+48q1Gt zJ34k9gP$BNCf8#>Q?^6>pMkB=V2=Bv#ZeaO9=`S9tzE&pC3p*bF;MiZpWM8%dHxH& zG&)(je6{4e_N9>6`+sf|rOT5g-_;%A8s_A!B(SAwWLNU%i=gBQ?QqA+P2T+M$47E+ zV#-}X+!Dk>(^tZ=r!?j1+&h%c`C?PiQu1`~a3}uFQiAhvjGlr}94z_5J3^%FZ7l>o zzP7@b>zuoF?OS#2h4HWIBKXJ&-|@pC3&ru`xsoroBb98l;PFQNd3hoc z{~(|3sr4J7lrx#sf`Yp*DMDGj4HXgB9)_9QX;s8knVOnT%c3$hFNYzSWAIfXj$?6E zZ$EeuLk)E4b&R`LQDG0(1R3}WaU_j&&^#KAn>J{yw9I?N)Jwz|78xTJq_`_(eFF`4 zwMIyQ{~$)?`bpzWlehEv8MU>ALb$+J?D)bP zo6FTV%av`b|1S>Likg38^@q4HOF{>!RQJXgf!7%@ij3hC3|zzv=xq2)JAT_yL9@oB z7w*UqO2{8MWrA6(gyU#F;$!a-xP(?CzW~!X$PVz$#$4AL3loi2c#xG-#W{J0UOn-3> z_cegojfuWSz`*ZgHM-j$Veb=r8?jpx_yTtZ#EDKDT>|L0&5JsNlwNR=Tmz=7Kv ze;XL0!F?1yGYEc)Zk|~NKiGJB<{bczppl_rkVQWpdcB=YHkc&h1`*Rl%n+eRP6+YE z{CTJsTtdF#_pfk_voKV26laQ!k1y;~c)6b09D9;|M&Q1)lX2$93P%f>LSXIMK82U- z^m_7%`5A%xmq0z^&Z~v9MMq&|?cP3xm+MELk+1zu^y%=2r+dbM38?AdI4!%-~2-Ic3K{QpQ8`H(`~=U0RO)zB6X+#0VuMGbpQYW delta 660 zcmYk3PiPZC6o>P6vzwTIEoRefwowsmlSOQ#rXJClO4l#2Qb1-ueb24)ib20O13jX05 zj;K{T%mObK`0fcWb4iotMNOC&N!P~`-+xILOS)K})BLRR|EpwH$yz`Ulx=Faal*FNg~n8^n!rW|Swpx5rbkf#1j1V92OlngLL7?{XSe(3L%> z(BGsND2fzp&>FQIE@#hz51(h(kBNfxbhPDdEw<#X?7oGRyY-jT?bTmY_d9WY;z4Me q95O{R4w*{l=@(v5uHP(SPOtp{ diff --git a/ritz/llvm_codegen_signals.py b/ritz/llvm_codegen_signals.py index 35e7451..46d640f 100644 --- a/ritz/llvm_codegen_signals.py +++ b/ritz/llvm_codegen_signals.py @@ -188,8 +188,69 @@ class SignalLLVMIRGenerator: return self._emit_with(stmt) elif stmt["type"] == "yield": return self._emit_yield(stmt) + elif stmt["type"] == "if": + return self._emit_if(stmt) return None + def _emit_if(self, stmt: dict[str, Any]) -> str | None: + """Emit an if statement.""" + # Generate unique labels for this if statement + if_id = self._new_var() + then_label = f"if.then.{if_id}" + else_label = f"if.else.{if_id}" + end_label = f"if.end.{if_id}" + + # Evaluate condition + test_var = self._emit_expr(stmt["test"]) + + # Convert to i1 (boolean) + cond_var = self._new_var() + self.lines.append(f" %{cond_var} = icmp ne i32 %{test_var}, 0") + + # Branch based on whether there's an else + has_else = stmt.get("orelse") and len(stmt["orelse"]) > 0 + if has_else: + self.lines.append(f" br i1 %{cond_var}, label %{then_label}, label %{else_label}") + else: + self.lines.append(f" br i1 %{cond_var}, label %{then_label}, label %{end_label}") + + # Emit then block + self.lines.append(f"{then_label}:") + for then_stmt in stmt["body"]: + self._emit_statement(then_stmt) + self.lines.append(f" br label %{end_label}") + + # Emit else block if present + if has_else: + self.lines.append(f"{else_label}:") + for else_stmt in stmt["orelse"]: + self._emit_statement(else_stmt) + self.lines.append(f" br label %{end_label}") + + # Emit merge block + self.lines.append(f"{end_label}:") + + return None + + def _emit_expr(self, expr: dict[str, Any]) -> str: + """Emit an expression and return the result variable name.""" + if expr["type"] == "name": + # Load signal value + signal_name = expr["id"] + if signal_name in self.signals: + load_var = self._new_var() + self.lines.append(f" %{load_var} = load i32, i32* @signal_{signal_name}") + return load_var + else: + # Unknown variable + return "0" + elif expr["type"] == "constant": + # Return constant inline + return str(expr["value"]) + else: + # Unknown expression type + return "0" + def _emit_with(self, stmt: dict[str, Any]) -> str: """Emit a 'with Element()' block.""" element_info = stmt["element"] diff --git a/tests/__pycache__/test_parser.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_parser.cpython-313-pytest-8.4.2.pyc index f426526b1040ed7fe27c419ca8e34a3810cff726..0f3a9b5d1d6f60dd5c85f64ac9a2444adabcb029 100644 GIT binary patch delta 113 zcmX?=dM1_kGcPX}0}vP`OJwS9V1 delta 111 zcmX?;dMcIoGcPX}0}$~0NMvenr_}`(=@~*`;v%>7brvYP b#3J2c1>s#mFfW7D!qvbTK;g~d!lm*6i9;gf