OILS / opy / _regtest / src / osh / meta.py View on Github | oilshell.org

205 lines, 90 significant
1#!/usr/bin/python
2"""
3meta.py
4
5Another "thin waist" of the interpreter. It can be happen at compile time!
6
7We are following the code <-> data pattern, and this is the "data" module.
8id_kind and asdl are the "code" modules.
9
10Usage:
11 from osh.meta import Id, Kind, ast, ID_SPEC
12"""
13
14from asdl import py_meta
15from asdl import asdl_ as asdl
16
17from core import id_kind
18from core import util
19
20
21class 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
36class 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
44class _AsdlModule(object):
45 """Dummy object to copy attributes onto."""
46 pass
47
48
49_ID_TO_KIND = {} # int -> Kind
50
51def LookupKind(id_):
52 return _ID_TO_KIND[id_.enum_value]
53
54
55_ID_NAMES = {} # int -> string
56
57def 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
69def IdInstance(i):
70 return _ID_INSTANCES[i]
71
72
73#
74# Instantiate osh/types.asdl
75#
76
77f = util.GetResourceLoader().open('osh/types.asdl')
78_asdl_module, _type_lookup = asdl.LoadSchema(f, {}) # no app_types
79
80types = _AsdlModule()
81if 0:
82 py_meta.MakeTypes(_asdl_module, types, _type_lookup)
83else:
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
91f.close()
92
93
94# Id -> bool_arg_type_e
95BOOL_ARG_TYPES = {} # type: dict
96
97# Used by test_builtin.py
98TEST_UNARY_LOOKUP = {}
99TEST_BINARY_LOOKUP = {}
100TEST_OTHER_LOOKUP = {}
101
102
103#
104# Instantiate the spec
105#
106
107ID_SPEC = id_kind.IdSpec(Id, Kind,
108 _ID_NAMES, _ID_INSTANCES, _ID_TO_KIND,
109 BOOL_ARG_TYPES)
110
111id_kind.AddKinds(ID_SPEC)
112id_kind.AddBoolKinds(ID_SPEC, Id, types.bool_arg_type_e) # must come second
113id_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
122APP_TYPES = {'id': asdl.UserType(Id)}
123
124#
125# Instantiate osh/osh.asdl
126#
127
128f = util.GetResourceLoader().open('osh/osh.asdl')
129_asdl_module, _type_lookup = asdl.LoadSchema(f, APP_TYPES)
130
131ast = _AsdlModule()
132if 0:
133 py_meta.MakeTypes(_asdl_module, ast, _type_lookup)
134else:
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
142f.close()
143
144#
145# Instantiate core/runtime.asdl
146#
147
148f = util.GetResourceLoader().open('core/runtime.asdl')
149_asdl_module, _type_lookup = asdl.LoadSchema(f, APP_TYPES)
150
151runtime = _AsdlModule()
152if 0:
153 py_meta.MakeTypes(_asdl_module, runtime, _type_lookup)
154else:
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
162f.close()
163
164#
165# Redirect Tables associated with IDs
166#
167# These might be osh specific.
168#
169
170REDIR_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
189redir_arg_type_e = types.redir_arg_type_e
190
191REDIR_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}