2929# Eventually we may want to separate expression visitors and statement-like visitors at
3030# the type level but until then returning INVALID_REGISTER from a statement-like visitor
3131# seems acceptable.
32- INVALID_REGISTER = Register (- 1 )
32+ INVALID_REGISTER = Register (- 99999 )
3333
3434
3535# Similarly this is used for placeholder labels which aren't assigned yet (but will
3636# be eventually. Its kind of a hack.
37- INVALID_LABEL = Label (- 1 )
37+ INVALID_LABEL = Label (- 88888 )
3838
3939
4040def c_module_name (module_name : str ):
@@ -255,6 +255,23 @@ def __repr__(self) -> str:
255255 return '<UserRType %s>' % self .name
256256
257257
258+ class OptionalRType (PyObjectRType ):
259+ """Optional[x]"""
260+
261+ def __init__ (self , value_type : RType ) -> None :
262+ self .name = 'optional'
263+ self .value_type = value_type
264+
265+ def __repr__ (self ) -> str :
266+ return '<OptionalRType %s>' % self .value_type
267+
268+ def __eq__ (self , other : object ) -> bool :
269+ return isinstance (other , OptionalRType ) and other .value_type == self .value_type
270+
271+ def __hash__ (self ) -> int :
272+ return hash (('optional' , self .value_type ))
273+
274+
258275class Environment :
259276 """Keep track of names and types of registers."""
260277
@@ -361,9 +378,10 @@ class Branch(Op):
361378 INT_GT = 14
362379 INT_GE = 15
363380
364- # Unlike the above, a unary operation so it only uses the "left" register
381+ # Unlike the above, these are unary operations so they only uses the "left" register
365382 # ("right" should be INVALID_REGISTER).
366- BOOL_EXPR = 16
383+ BOOL_EXPR = 100
384+ IS_NONE = 101
367385
368386 op_names = {
369387 INT_EQ : ('==' , 'int' ),
@@ -374,6 +392,11 @@ class Branch(Op):
374392 INT_GE : ('>=' , 'int' ),
375393 }
376394
395+ unary_op_names = {
396+ BOOL_EXPR : ('%r' , 'bool' ),
397+ IS_NONE : ('%r is None' , 'object' ),
398+ }
399+
377400 def __init__ (self , left : Register , right : Register , true_label : Label ,
378401 false_label : Label , op : int ) -> None :
379402 self .left = left
@@ -384,24 +407,24 @@ def __init__(self, left: Register, right: Register, true_label: Label,
384407 self .negated = False
385408
386409 def sources (self ) -> List [Register ]:
387- return [self .left , self .right ]
410+ if self .right != INVALID_REGISTER :
411+ return [self .left , self .right ]
412+ else :
413+ return [self .left ]
388414
389415 def to_str (self , env : Environment ) -> str :
390416 # Right not used for BOOL_EXPR
391- if self .op != Branch . BOOL_EXPR :
417+ if self .op in self . op_names :
392418 if self .negated :
393419 fmt = 'not %r {} %r'
394420 else :
395421 fmt = '%r {} %r'
396422 op , typ = self .op_names [self .op ]
397423 fmt = fmt .format (op )
398-
399424 else :
425+ fmt , typ = self .unary_op_names [self .op ]
400426 if self .negated :
401- fmt = 'not %r'
402- else :
403- fmt = '%r'
404- typ = 'bool'
427+ fmt = 'not {}' .format (fmt )
405428
406429 cond = env .format (fmt , self .left , self .right )
407430 fmt = 'if {} goto %l else goto %l :: {}' .format (cond , typ )
@@ -674,7 +697,7 @@ def sources(self) -> List[Register]:
674697
675698 def to_str (self , env : Environment ) -> str :
676699 params = {} # type: Dict[str, Any]
677- if self .dest is not None :
700+ if self .dest is not None and self . dest != INVALID_REGISTER :
678701 params ['dest' ] = env .format ('%r' , self .dest )
679702 args = [env .format ('%r' , arg ) for arg in self .args ]
680703 params ['args' ] = args
0 commit comments