@@ -142,7 +142,7 @@ def method(self, name: str) -> Optional[Union["Function", FunctionTemplate]]:
142
142
143
143
def is_concrete (self ) -> bool :
144
144
return True
145
-
145
+
146
146
def is_addressable (self ) -> bool :
147
147
return True
148
148
@@ -163,8 +163,10 @@ class RefType(Type):
163
163
164
164
def __init__ (self , element : Type ) -> None :
165
165
super ().__init__ ()
166
- assert element .is_addressable (), f"RefType element { element } is not addressable"
167
- assert not isinstance (element , (OpaqueType , RefType , FunctionType ,TypeConstructorType ))
166
+ assert element .is_addressable (), f"RefType element {
167
+ element } is not addressable"
168
+ assert not isinstance (
169
+ element , (OpaqueType , RefType , FunctionType , TypeConstructorType ))
168
170
self .element = element
169
171
self .methods = element .methods
170
172
@@ -189,18 +191,19 @@ def member(self, field: Any) -> Optional['Type']:
189
191
ty = self .element .member (field )
190
192
if ty is None :
191
193
return None
192
- if isinstance (ty ,FunctionType ):
194
+ if isinstance (ty , FunctionType ):
193
195
return ty
194
196
return RefType (ty )
195
197
196
198
@override
197
199
def method (self , name : str ) -> Optional [Union ["Function" , FunctionTemplate ]]:
198
200
return self .element .method (name )
199
-
201
+
200
202
@override
201
203
def is_addressable (self ) -> bool :
202
204
return False
203
205
206
+
204
207
class LiteralType (Type ):
205
208
value : Any
206
209
@@ -221,7 +224,7 @@ def is_concrete(self) -> bool:
221
224
@override
222
225
def is_addressable (self ) -> bool :
223
226
return False
224
-
227
+
225
228
def __eq__ (self , value : object ) -> bool :
226
229
return isinstance (value , LiteralType ) and value .value == self .value
227
230
@@ -349,6 +352,7 @@ def is_concrete(self) -> bool:
349
352
def is_addressable (self ) -> bool :
350
353
return False
351
354
355
+
352
356
class GenericIntType (ScalarType ):
353
357
@override
354
358
def __eq__ (self , value : object ) -> bool :
@@ -382,6 +386,7 @@ def is_concrete(self) -> bool:
382
386
def is_addressable (self ) -> bool :
383
387
return False
384
388
389
+
385
390
class FloatType (ScalarType ):
386
391
bits : int
387
392
@@ -695,6 +700,7 @@ def __repr__(self) -> str:
695
700
def __str__ (self ) -> str :
696
701
return f"~{ self .name } @{ self .ctx_name } "
697
702
703
+
698
704
class OpaqueType (Type ):
699
705
name : str
700
706
extra_args : List [Any ]
@@ -722,7 +728,7 @@ def __str__(self) -> str:
722
728
@override
723
729
def is_concrete (self ) -> bool :
724
730
return False
725
-
731
+
726
732
@override
727
733
def is_addressable (self ) -> bool :
728
734
return False
@@ -800,18 +806,19 @@ def __eq__(self, value: object) -> bool:
800
806
801
807
def __hash__ (self ) -> int :
802
808
return hash ((ParametricType , tuple (self .params ), self .body ))
803
-
809
+
804
810
def __str__ (self ) -> str :
805
811
return f"{ self .body } [{ ', ' .join (str (p ) for p in self .params )} ]"
806
812
807
813
@override
808
814
def is_concrete (self ) -> bool :
809
815
return self .body .is_concrete ()
810
-
816
+
811
817
@override
812
818
def is_addressable (self ) -> bool :
813
819
return self .body .is_addressable ()
814
820
821
+
815
822
class BoundType (Type ):
816
823
"""
817
824
An instance of a parametric type, e.g. Foo[int]
@@ -841,7 +848,7 @@ def __eq__(self, value: object) -> bool:
841
848
842
849
def __hash__ (self ):
843
850
return hash ((BoundType , self .generic , tuple (self .args )))
844
-
851
+
845
852
def __str__ (self ) -> str :
846
853
return f"{ self .generic } [{ ', ' .join (str (a ) for a in self .args )} ]"
847
854
@@ -862,11 +869,12 @@ def method(self, name) -> Optional[Union["Function", FunctionTemplate]]:
862
869
@override
863
870
def is_addressable (self ) -> bool :
864
871
return self .generic .is_addressable ()
865
-
872
+
866
873
@override
867
874
def is_concrete (self ) -> bool :
868
875
return self .generic .is_concrete ()
869
876
877
+
870
878
class TypeConstructorType (Type ):
871
879
inner : Type
872
880
@@ -910,6 +918,7 @@ def size(self) -> int:
910
918
def align (self ) -> int :
911
919
raise RuntimeError ("FunctionType has no align" )
912
920
921
+
913
922
class Node :
914
923
"""
915
924
Base class for all nodes in the HIR. A node could be a value, a reference, or a statement.
@@ -999,13 +1008,15 @@ def __init__(
999
1008
self .name = name
1000
1009
self .semantic = semantic
1001
1010
1011
+
1002
1012
class VarValue (Value ):
1003
1013
var : Var
1004
1014
1005
1015
def __init__ (self , var : Var , span : Optional [Span ]) -> None :
1006
1016
super ().__init__ (var .type , span )
1007
1017
self .var = var
1008
1018
1019
+
1009
1020
class VarRef (Value ):
1010
1021
var : Var
1011
1022
@@ -1155,6 +1166,8 @@ def __str__(self) -> str:
1155
1166
return f"Template matching error:\n \t { self .message } "
1156
1167
return f"Template matching error at { self .span } :\n \t { self .message } "
1157
1168
1169
+ class ComptimeCallStack :
1170
+ pass
1158
1171
1159
1172
class SpannedError (Exception ):
1160
1173
span : Span | None
@@ -1200,7 +1213,8 @@ class Assign(Node):
1200
1213
value : Value
1201
1214
1202
1215
def __init__ (self , ref : Value , value : Value , span : Optional [Span ] = None ) -> None :
1203
- assert not isinstance (value .type , (FunctionType , TypeConstructorType , RefType ))
1216
+ assert not isinstance (
1217
+ value .type , (FunctionType , TypeConstructorType , RefType ))
1204
1218
if not isinstance (ref .type , RefType ):
1205
1219
raise ParsingError (
1206
1220
ref , f"cannot assign to a non-reference variable" )
@@ -1209,6 +1223,24 @@ def __init__(self, ref: Value, value: Value, span: Optional[Span] = None) -> Non
1209
1223
self .value = value
1210
1224
1211
1225
1226
+ class Assert (Node ):
1227
+ cond : Value
1228
+ msg : List [Union [Value , str ]]
1229
+
1230
+ def __init__ (self , cond : Value , msg : List [Union [Value , str ]], span : Optional [Span ] = None ) -> None :
1231
+ super ().__init__ (span )
1232
+ self .cond = cond
1233
+ self .msg = msg
1234
+
1235
+
1236
+ class Print (Node ):
1237
+ args : List [Union [Value , str ]]
1238
+
1239
+ def __init__ (self , args : List [Union [Value , str ]], span : Optional [Span ] = None ) -> None :
1240
+ super ().__init__ (span )
1241
+ self .args = args
1242
+
1243
+
1212
1244
class Terminator (Node ):
1213
1245
pass
1214
1246
@@ -1559,6 +1591,7 @@ def __init__(self, func: Function, args: List[Value], body: BasicBlock, span: Op
1559
1591
self .mapping [param ] = arg
1560
1592
for v in func .locals :
1561
1593
if v in self .mapping :
1594
+ # skip function parameters
1562
1595
continue
1563
1596
assert v .type
1564
1597
assert v .type .is_addressable ()
@@ -1631,6 +1664,33 @@ def do():
1631
1664
self .mapping [intrin ] = body .append (
1632
1665
Intrinsic (intrin .name , args , intrin .type , node .span ))
1633
1666
do ()
1667
+ case If ():
1668
+ cond = self .mapping .get (node .cond )
1669
+ assert isinstance (cond , Value )
1670
+ then_body = BasicBlock ()
1671
+ else_body = BasicBlock ()
1672
+ merge = BasicBlock ()
1673
+ body .append (If (cond , then_body , else_body , merge ))
1674
+ self .do_inline (node .then_body , then_body )
1675
+ if node .else_body :
1676
+ self .do_inline (node .else_body , else_body )
1677
+ body .append (merge )
1678
+ case Loop ():
1679
+ prepare = BasicBlock ()
1680
+ if node .cond :
1681
+ cond = self .mapping .get (node .cond )
1682
+ else :
1683
+ cond = None
1684
+ assert cond is None or isinstance (cond , Value )
1685
+ body_ = BasicBlock ()
1686
+ update = BasicBlock ()
1687
+ merge = BasicBlock ()
1688
+ body .append (Loop (prepare , cond , body_ , update , merge ))
1689
+ self .do_inline (node .prepare , prepare )
1690
+ self .do_inline (node .body , body_ )
1691
+ if node .update :
1692
+ self .do_inline (node .update , update )
1693
+ body .append (merge )
1634
1694
case Return ():
1635
1695
if self .ret is not None :
1636
1696
raise InlineError (node , "multiple return statement" )
@@ -1646,6 +1706,9 @@ def do():
1646
1706
@staticmethod
1647
1707
def inline (func : Function , args : List [Value ], body : BasicBlock , span : Optional [Span ] = None ) -> Value :
1648
1708
inliner = FunctionInliner (func , args , body , span )
1709
+ assert func .return_type
1710
+ if func .return_type == UnitType ():
1711
+ return Unit ()
1649
1712
assert inliner .ret
1650
1713
return inliner .ret
1651
1714
0 commit comments