OILS / demo / shedskin / runtime.py View on Github | oilshell.org

170 lines, 75 significant
1"""
2runtime.py: Objects and types needed at runtime.
3
4asdl/front_end.py and asdl/asdl_.py should not be shipped with the binary.
5They are only needed for the gen_python.py compiler.
6"""
7from __future__ import print_function
8
9#import posix
10
11import cStringIO
12Buffer = cStringIO.StringIO
13
14
15# Type Descriptors
16#
17# These are more convenient than using the AST directly, since it still has
18# string type names?
19#
20# Although we share Product and Sum.
21
22class _RuntimeType(object):
23 """A node hierarchy that exists at runtime."""
24 pass
25
26
27class StrType(_RuntimeType):
28 def __repr__(self):
29 return '<Str>'
30
31
32class IntType(_RuntimeType):
33 def __repr__(self):
34 return '<Int>'
35
36
37class BoolType(_RuntimeType):
38 def __repr__(self):
39 return '<Bool>'
40
41
42class DictType(_RuntimeType):
43 def __repr__(self):
44 return '<Dict>'
45
46
47class ArrayType(_RuntimeType):
48 def __init__(self, desc):
49 self.desc = desc
50
51 def __repr__(self):
52 return '<Array %s>' % self.desc
53
54
55class MaybeType(_RuntimeType):
56 def __init__(self, desc):
57 self.desc = desc # another descriptor
58
59 def __repr__(self):
60 return '<Maybe %s>' % self.desc
61
62
63class UserType(_RuntimeType):
64 def __init__(self, typ):
65 assert isinstance(typ, type), typ
66 self.typ = typ
67
68 def __repr__(self):
69 return '<UserType %s>' % self.typ
70
71
72class SumType(_RuntimeType):
73 """Dummy node that doesn't require any reflection.
74
75 obj.ASDL_TYPE points directly to the constructor, which you reflect on.
76 """
77 def __init__(self, is_simple):
78 self.is_simple = is_simple # for type checking
79 self.cases = [] # list of _RuntimeType for type checking
80
81 def __repr__(self):
82 # We need an entry for this but we don't use it?
83 return '<SumType with %d cases at %d>' % (
84 len(self.cases), id(self))
85
86
87class CompoundType(_RuntimeType):
88 """A product or Constructor instance. Both have fields."""
89 def __init__(self, fields):
90 # List of (name, _RuntimeType) tuples.
91 # NOTE: This list may be mutated after its set.
92 self.fields = fields
93
94 def __repr__(self):
95 return '<CompoundType %s>' % self.fields
96
97 def GetFieldNames(self):
98 for field_name, _ in self.fields:
99 yield field_name
100
101 def GetFields(self):
102 for field_name, descriptor in self.fields:
103 yield field_name, descriptor
104
105 def LookupFieldType(self, field_name):
106 """
107 NOTE: Only used by py_meta.py.
108 """
109 for n, descriptor in self.fields:
110 if n == field_name:
111 return descriptor
112 raise TypeError('Invalid field %r' % field_name)
113
114
115BUILTIN_TYPES = {
116 'string': StrType(),
117 'int': IntType(),
118 'bool': BoolType(),
119 'dict': DictType(),
120}
121
122
123
124
125class Obj(object):
126 # NOTE: We're using CAPS for these static fields, since they are constant at
127 # runtime after metaprogramming.
128 ASDL_TYPE = None # Used for type checking
129
130
131class SimpleObj(Obj):
132 """An enum value.
133
134 Other simple objects: int, str, maybe later a float.
135 """
136 def __init__(self, enum_id, name):
137 self.enum_id = enum_id
138 self.name = name
139
140 # TODO: Why is __hash__ needed? Otherwise native/fastlex_test.py fails.
141 # util.Enum required it too. I thought that instances would hash by
142 # identity?
143 #
144 # Example:
145 # class bool_arg_type_e(py_meta.SimpleObj):
146 # ASDL_TYPE = TYPE_LOOKUP['bool_arg_type']
147 # bool_arg_type_e.Undefined = bool_arg_type_e(1, 'Undefined')
148
149 def __hash__(self):
150 # Could it be the integer self.enum_id?
151 return hash(self.__class__.__name__ + self.name)
152
153 def __repr__(self):
154 return '<%s %s %s>' % (self.__class__.__name__, self.name, self.enum_id)
155
156
157NUM_TYPE_CHECKS = 0
158
159class CompoundObj(Obj):
160 # TODO: Remove tag?
161 # The tag is always set for constructor types, which are subclasses of sum
162 # types. Never set for product types.
163 tag = None
164
165
166# Other possible dynamic checking:
167# - CheckUnassigned in the constructor? Fields should be all initialized or
168# none.
169# - Maybe spids should never be mutated? It can only be appended to?
170# - SimpleObj could deny all __setattr__?