Skip to content

Commit fa16977

Browse files
committed
Add instructions for list matching
1 parent f90c8f1 commit fa16977

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

ir.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ def op(idx: int) -> str:
446446
if isinstance(value, String):
447447
string_repr = json.dumps(value.value)
448448
return _handle(f"mkstring(heap, {string_repr}, {len(value.value)})")
449+
if isinstance(value, List):
450+
if not value.items:
451+
return _decl("struct object*", "empty_list()")
452+
raise NotImplementedError("const", type(value))
449453
if isinstance(instr, IntAdd):
450454
operands = ", ".join(gvn.name(op) for op in instr.operands)
451455
return _handle(f"num_add({operands})")
@@ -470,6 +474,16 @@ def op(idx: int) -> str:
470474
return _handle(f"record_get({op(0)}, {instr.name})")
471475
if isinstance(instr, GuardNonNull):
472476
return f"if ({op(0)} == NULL) {{ abort(); }}\n" + _handle(op(0))
477+
if isinstance(instr, ListCons):
478+
return _handle(f"list_cons({op(0)}, {op(1)})")
479+
if isinstance(instr, ListFirst):
480+
return _handle(f"list_first({op(0)})")
481+
if isinstance(instr, ListRest):
482+
return _handle(f"list_rest({op(0)})")
483+
if isinstance(instr, IsList):
484+
return _decl("bool", f"is_list({op(0)})")
485+
if isinstance(instr, IsEmptyList):
486+
return _decl("bool", f"{op(0)} == empty_list()")
473487
raise NotImplementedError(type(instr))
474488

475489
def _to_c(self, f: io.StringIO, block: Block, gvn: InstrId) -> None:
@@ -828,6 +842,18 @@ def run(self) -> dict[Instr, ConstantLattice]:
828842
new_type = CBool(True)
829843
case _:
830844
new_type = CBool()
845+
elif isinstance(instr, IsList):
846+
match self.type_of(instr.operands[0]):
847+
case CList(_):
848+
new_type = CBool(True)
849+
case _:
850+
new_type = CBool()
851+
elif isinstance(instr, IsEmptyList):
852+
new_type = CBool()
853+
elif isinstance(instr, ListFirst):
854+
new_type = CTop()
855+
elif isinstance(instr, ListRest):
856+
new_type = CTop()
831857
else:
832858
raise NotImplementedError(f"SCCP {instr}")
833859
old_type = self.type_of(instr)
@@ -1921,6 +1947,10 @@ def test_match_int(self) -> None:
19211947
def test_call_match_int(self) -> None:
19221948
self.assertEqual(_run("(| 1 -> 2) 1"), "2\n")
19231949

1950+
def test_match_list(self) -> None:
1951+
self.assertEqual(_run("f [1, 2] . f = | [1, 2] -> 3 | [4, 5] -> 6"), "3\n")
1952+
self.assertEqual(_run("f [4, 5] . f = | [1, 2] -> 3 | [4, 5] -> 6"), "6\n")
1953+
19241954
def test_var(self) -> None:
19251955
self.assertEqual(_run("a . a = 1"), "1\n")
19261956

0 commit comments

Comments
 (0)