| 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 | }
 |