1 | #!/usr/bin/python
|
2 | """
|
3 | meta.py
|
4 |
|
5 | Another "thin waist" of the interpreter. It can be happen at compile time!
|
6 |
|
7 | We are following the code <-> data pattern, and this is the "data" module.
|
8 | id_kind and asdl are the "code" modules.
|
9 |
|
10 | Usage:
|
11 | from osh.meta import Id, Kind, ast, ID_SPEC
|
12 | """
|
13 |
|
14 | from asdl import py_meta
|
15 | from asdl import asdl_ as asdl
|
16 |
|
17 | from core import id_kind
|
18 | from core import util
|
19 |
|
20 |
|
21 | class Id(object):
|
22 | """Token and op type.
|
23 |
|
24 | The evaluator must consider all Ids.
|
25 |
|
26 | NOTE: We add a bunch of class attributes that are INSTANCES of this class,
|
27 | e.g. Id.Lit_Chars.
|
28 | """
|
29 | def __init__(self, enum_value):
|
30 | self.enum_value = enum_value
|
31 |
|
32 | def __repr__(self):
|
33 | return IdName(self)
|
34 |
|
35 |
|
36 | class Kind(object):
|
37 | """A coarser version of Id, used to make parsing decisions."""
|
38 |
|
39 | # TODO: The Kind type should be folded into ASDL. It can't print itself,
|
40 | # which is inconsistent with Id.
|
41 | pass
|
42 |
|
43 |
|
44 | class _AsdlModule(object):
|
45 | """Dummy object to copy attributes onto."""
|
46 | pass
|
47 |
|
48 |
|
49 | _ID_TO_KIND = {} # int -> Kind
|
50 |
|
51 | def LookupKind(id_):
|
52 | return _ID_TO_KIND[id_.enum_value]
|
53 |
|
54 |
|
55 | _ID_NAMES = {} # int -> string
|
56 |
|
57 | def IdName(id_):
|
58 | return _ID_NAMES[id_.enum_value]
|
59 |
|
60 |
|
61 | # Keep one instance of each Id, to save memory and enable comparison by
|
62 | # OBJECT IDENTITY.
|
63 | # Do NOT create any any more instances of them! Always used IdInstance().
|
64 |
|
65 | # TODO: Fold Id into ASDL, which will enforce uniqueness?
|
66 |
|
67 | _ID_INSTANCES = {} # int -> Id
|
68 |
|
69 | def IdInstance(i):
|
70 | return _ID_INSTANCES[i]
|
71 |
|
72 |
|
73 | #
|
74 | # Instantiate osh/types.asdl
|
75 | #
|
76 |
|
77 | f = util.GetResourceLoader().open('osh/types.asdl')
|
78 | _asdl_module, _type_lookup = asdl.LoadSchema(f, {}) # no app_types
|
79 |
|
80 | types = _AsdlModule()
|
81 | if 0:
|
82 | py_meta.MakeTypes(_asdl_module, types, _type_lookup)
|
83 | else:
|
84 | # Exported for the generated code to use
|
85 | TYPES_TYPE_LOOKUP = _type_lookup
|
86 |
|
87 | # Get the types from elsewhere
|
88 | from _devbuild.gen import types_asdl
|
89 | py_meta.AssignTypes(types_asdl, types)
|
90 |
|
91 | f.close()
|
92 |
|
93 |
|
94 | # Id -> bool_arg_type_e
|
95 | BOOL_ARG_TYPES = {} # type: dict
|
96 |
|
97 | # Used by test_builtin.py
|
98 | TEST_UNARY_LOOKUP = {}
|
99 | TEST_BINARY_LOOKUP = {}
|
100 | TEST_OTHER_LOOKUP = {}
|
101 |
|
102 |
|
103 | #
|
104 | # Instantiate the spec
|
105 | #
|
106 |
|
107 | ID_SPEC = id_kind.IdSpec(Id, Kind,
|
108 | _ID_NAMES, _ID_INSTANCES, _ID_TO_KIND,
|
109 | BOOL_ARG_TYPES)
|
110 |
|
111 | id_kind.AddKinds(ID_SPEC)
|
112 | id_kind.AddBoolKinds(ID_SPEC, Id, types.bool_arg_type_e) # must come second
|
113 | id_kind.SetupTestBuiltin(Id, Kind, ID_SPEC,
|
114 | TEST_UNARY_LOOKUP, TEST_BINARY_LOOKUP,
|
115 | TEST_OTHER_LOOKUP,
|
116 | types.bool_arg_type_e)
|
117 |
|
118 | # Debug
|
119 | _kind_sizes = ID_SPEC.kind_sizes
|
120 |
|
121 |
|
122 | APP_TYPES = {'id': asdl.UserType(Id)}
|
123 |
|
124 | #
|
125 | # Instantiate osh/osh.asdl
|
126 | #
|
127 |
|
128 | f = util.GetResourceLoader().open('osh/osh.asdl')
|
129 | _asdl_module, _type_lookup = asdl.LoadSchema(f, APP_TYPES)
|
130 |
|
131 | ast = _AsdlModule()
|
132 | if 0:
|
133 | py_meta.MakeTypes(_asdl_module, ast, _type_lookup)
|
134 | else:
|
135 | # Exported for the generated code to use
|
136 | OSH_TYPE_LOOKUP = _type_lookup
|
137 |
|
138 | # Get the types from elsewhere
|
139 | from _devbuild.gen import osh_asdl
|
140 | py_meta.AssignTypes(osh_asdl, ast)
|
141 |
|
142 | f.close()
|
143 |
|
144 | #
|
145 | # Instantiate core/runtime.asdl
|
146 | #
|
147 |
|
148 | f = util.GetResourceLoader().open('core/runtime.asdl')
|
149 | _asdl_module, _type_lookup = asdl.LoadSchema(f, APP_TYPES)
|
150 |
|
151 | runtime = _AsdlModule()
|
152 | if 0:
|
153 | py_meta.MakeTypes(_asdl_module, runtime, _type_lookup)
|
154 | else:
|
155 | # Exported for the generated code to use
|
156 | RUNTIME_TYPE_LOOKUP = _type_lookup
|
157 |
|
158 | # Get the types from elsewhere
|
159 | from _devbuild.gen import runtime_asdl
|
160 | py_meta.AssignTypes(runtime_asdl, runtime)
|
161 |
|
162 | f.close()
|
163 |
|
164 | #
|
165 | # Redirect Tables associated with IDs
|
166 | #
|
167 | # These might be osh specific.
|
168 | #
|
169 |
|
170 | REDIR_DEFAULT_FD = {
|
171 | # filename
|
172 | Id.Redir_Less: 0, # cat <input.txt means cat 0<input.txt
|
173 | Id.Redir_Great: 1,
|
174 | Id.Redir_DGreat: 1,
|
175 | Id.Redir_Clobber: 1,
|
176 | Id.Redir_LessGreat: 1, # TODO: What does echo <>foo do?
|
177 |
|
178 | # descriptor
|
179 | Id.Redir_GreatAnd: 1, # echo >&2 means echo 1>&2
|
180 | Id.Redir_LessAnd: 0, # echo <&3 means echo 0<&3, I think
|
181 |
|
182 | Id.Redir_TLess: 0, # here word
|
183 |
|
184 | # here docs included
|
185 | Id.Redir_DLess: 0,
|
186 | Id.Redir_DLessDash: 0,
|
187 | }
|
188 |
|
189 | redir_arg_type_e = types.redir_arg_type_e
|
190 |
|
191 | REDIR_ARG_TYPES = {
|
192 | # filename
|
193 | Id.Redir_Less: redir_arg_type_e.Path,
|
194 | Id.Redir_Great: redir_arg_type_e.Path,
|
195 | Id.Redir_DGreat: redir_arg_type_e.Path,
|
196 | Id.Redir_Clobber: redir_arg_type_e.Path,
|
197 | Id.Redir_LessGreat: redir_arg_type_e.Path,
|
198 |
|
199 | # descriptor
|
200 | Id.Redir_GreatAnd: redir_arg_type_e.Desc,
|
201 | Id.Redir_LessAnd: redir_arg_type_e.Desc,
|
202 |
|
203 | Id.Redir_TLess: redir_arg_type_e.Here, # here word
|
204 | # note: here docs aren't included
|
205 | }
|