Implement match/case statement code generation
- Add _emit_match() using LLVM switch instruction - Handle value patterns and wildcard (case _:) patterns - Each case gets its own basic block with branch to end - Wildcard case becomes default label in switch - All tests passing (30/30) - Tabs.wasm size: 1908 → 3185 bytes
This commit is contained in:
1 parent
e18baf3106
commit
cd89f75c1c
4 files changed
+346
-113
No files matched your search
Binary file not shown.
@@ -225,6 +225,8 @@ class SignalLLVMIRGenerator:
|
||||
return self._emit_yield(stmt)
|
||||
elif stmt["type"] == "if":
|
||||
return self._emit_if(stmt)
|
||||
elif stmt["type"] == "match":
|
||||
return self._emit_match(stmt)
|
||||
return None
|
||||
|
||||
def _emit_if(self, stmt: dict[str, Any]) -> str | None:
|
||||
@@ -267,6 +269,59 @@ class SignalLLVMIRGenerator:
|
||||
|
||||
return None
|
||||
|
||||
def _emit_match(self, stmt: dict[str, Any]) -> str | None:
|
||||
"""Emit a match/case statement using LLVM switch."""
|
||||
# Generate unique labels
|
||||
match_id = self._new_var()
|
||||
|
||||
# Evaluate subject expression
|
||||
subject_var = self._emit_expr(stmt["subject"])
|
||||
|
||||
# Create labels for each case and the end
|
||||
case_labels = [f"match.case{i}.{match_id}" for i in range(len(stmt["cases"]))]
|
||||
end_label = f"match.end.{match_id}"
|
||||
default_label = f"match.default.{match_id}"
|
||||
|
||||
# Build switch instruction
|
||||
# Find wildcard case (case _:) to use as default
|
||||
default_case_idx = None
|
||||
switch_cases = []
|
||||
for i, case in enumerate(stmt["cases"]):
|
||||
pattern = case["pattern"]
|
||||
if pattern["type"] == "wildcard":
|
||||
default_case_idx = i
|
||||
elif pattern["type"] == "value":
|
||||
# Extract the constant value
|
||||
value = pattern["value"]["value"]
|
||||
switch_cases.append(f"i32 {value}, label %{case_labels[i]}")
|
||||
|
||||
# Emit switch
|
||||
if default_case_idx is not None:
|
||||
self.lines.append(f" switch i32 %{subject_var}, label %{case_labels[default_case_idx]} [")
|
||||
else:
|
||||
self.lines.append(f" switch i32 %{subject_var}, label %{default_label} [")
|
||||
|
||||
for case_spec in switch_cases:
|
||||
self.lines.append(f" {case_spec}")
|
||||
self.lines.append(" ]")
|
||||
|
||||
# Emit each case body
|
||||
for i, case in enumerate(stmt["cases"]):
|
||||
self.lines.append(f"{case_labels[i]}:")
|
||||
for case_stmt in case["body"]:
|
||||
self._emit_statement(case_stmt)
|
||||
self.lines.append(f" br label %{end_label}")
|
||||
|
||||
# Emit default case if needed (no wildcard)
|
||||
if default_case_idx is None:
|
||||
self.lines.append(f"{default_label}:")
|
||||
self.lines.append(f" br label %{end_label}")
|
||||
|
||||
# Emit end label
|
||||
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":
|
||||
|
||||
Reference in new issue
Block a user