diff --git a/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc b/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc index 8f50720..db4317a 100644 Binary files a/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc and b/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc differ 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 f426526..0f3a9b5 100644 Binary files a/tests/__pycache__/test_parser.cpython-313-pytest-8.4.2.pyc and b/tests/__pycache__/test_parser.cpython-313-pytest-8.4.2.pyc differ