@@ -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