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
This commit is contained in:
1 parent
a3cd1df40a
commit
044eda2293
3 files changed
+61
No files matched your search
Binary file not shown.
@@ -188,8 +188,69 @@ class SignalLLVMIRGenerator:
|
|||||||
return self._emit_with(stmt)
|
return self._emit_with(stmt)
|
||||||
elif stmt["type"] == "yield":
|
elif stmt["type"] == "yield":
|
||||||
return self._emit_yield(stmt)
|
return self._emit_yield(stmt)
|
||||||
|
elif stmt["type"] == "if":
|
||||||
|
return self._emit_if(stmt)
|
||||||
return None
|
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:
|
def _emit_with(self, stmt: dict[str, Any]) -> str:
|
||||||
"""Emit a 'with Element()' block."""
|
"""Emit a 'with Element()' block."""
|
||||||
element_info = stmt["element"]
|
element_info = stmt["element"]
|
||||||
|
|||||||
Binary file not shown.
Reference in new issue
Block a user