OILS / core / value.asdl View on Github | oils.pub

230 lines, 88 significant
1# Runtime value
2
3module value
4{
5 # import from frontend/syntax.asdl
6 use frontend syntax {
7 loc Token
8 expr command
9 DoubleQuoted
10 re proc_sig
11 Func
12 NameType
13 EggexFlag
14 BraceGroup SourceLine
15 debug_frame
16 ShFunction
17 cmd_frag
18 }
19
20 use core runtime {
21 Cell
22 }
23
24 # Probably need to export 'class vm' declarations in
25 # _gen/bin/oils_for_unix.mycpp.h, or another header
26 #
27 # extern [ core vm _Builtin ] # for value.BuiltinProc, below
28 # extern [ core vm _Callable ] # for value.BuiltinFunc, below
29
30 IntBox = (int i)
31
32 InitializerValue = (str? key, str rval, bool plus_eq)
33
34 ProcDefaults = (
35 List[value]? for_word, # all of them are value.Str
36 List[value]? for_typed,
37 Dict[str, value]? for_named,
38 value? for_block,
39 )
40
41 LeftName = (str name, loc blame_loc)
42
43 # for setvar, and value.Place
44 y_lvalue =
45 # e.g. read (&x)
46 Local %LeftName
47 # e.g. &a[0][1].key -- we evaluate a[0][1] first
48 | Container(value obj, value index)
49
50 # An sh_lvalue is for things mutation that happen with dynamic scope
51 #
52 # - sh_expr_eval uses this for unset / printf -v
53 # - word_eval uses this for ${a[0]=}
54 # - expr_eval / cmd_eval use this for setvar a[i] = 42
55 sh_lvalue =
56 Var %LeftName
57 | Indexed(str name, int index, loc blame_loc)
58 | Keyed(str name, str key, loc blame_loc)
59
60 eggex_ops =
61 # for BASH_REMATCH or ~ with a string
62 No
63 # These lists are indexed by group number, and will have None entries
64 | Yes(List[value?] convert_funcs, List[Token?] convert_toks,
65 List[str?] capture_names)
66
67 RegexMatch = (str s, List[int] indices, eggex_ops ops)
68
69 regex_match =
70 No
71 | Yes %RegexMatch
72
73 # Arbitrary objects, where attributes are looked up on the prototype chain.
74 Obj = (Obj? prototype, Dict[str, value] d)
75
76 # Commands, words, and expressions from syntax.asdl are evaluated to a VALUE.
77 # value_t instances are stored in state.Mem().
78 value =
79 #
80 # Implementation details
81 #
82
83 # Only used for io.stdin aka val_ops.StdinIterator. (It would be nice if
84 # we could express iter_value.{Eof,Interrupted,Str,Int,...} in ASDL)
85 Interrupted
86 | Stdin
87 # Can't be instantiated by users
88 # a[3:5] a[:10] a[3:] a[:] # both ends are optional
89 | Slice(IntBox? lower, IntBox? upper)
90
91 #
92 # OSH/Bash types
93 #
94
95 # Methods on state::Mem return value.Undef, but it's not visible in YSH.
96 # Note: A var bound to Undef is different than no binding because of
97 # dynamic scope. Undef can shadow values lower on the stack.
98 | Undef
99
100 | Str(str s)
101
102 | InitializerList(List[InitializerValue] assigns)
103
104 # "holes" in the array are represented by None
105 | InternalStringArray(List[str] strs)
106 # TODO: Switch to this more efficient representation. max_index makes
107 # append-sparse workload faster, and normal append loops too
108 | BashArray(Dict[BigInt, str] d, BigInt max_index)
109
110 | BashAssoc(Dict[str, str] d)
111
112 # The DATA model for YSH follows JSON. Note: YSH doesn't have 'undefined'
113 # and 'null' like JavaScript, just 'null'.
114 | Null
115 | Bool(bool b)
116 | Int(BigInt i)
117 | Float(float f)
118 | List(List[value] items)
119 | Dict(Dict[str, value] d)
120
121 # Possible types
122 # value.Htm8 - a string that can be queried, with lazily materialized "views"
123 # value.Tsv8 - ditto
124 # value.Json8 - some kind of jq or JSONPath query language
125
126 # Objects are for for polymorphism
127 | Obj %Obj
128
129 # for i in (0 .. n) { echo $i } # both ends are required
130 # TODO: BigInt
131 | Range(int lower, int upper)
132
133 # expr is spliced
134 # / d+; ignorecase / -> '[[:digit:]]+' REG_ICASE
135 | Eggex(re spliced, str canonical_flags,
136 List[value?] convert_funcs, List[Token?] convert_toks,
137 # str? is because some groups are not named
138 str? as_ere, List[str?] capture_names)
139
140 # The indices list has 2 * (num_group + 1) entries. Group 0 is the whole
141 # match, and each group has both a start and end index.
142 # It's flat to reduce allocations. The group() start() end() funcs/methods
143 # provide a nice interface.
144 | Match %RegexMatch
145
146 # A place has an additional stack frame where the value is evaluated.
147 # The frame MUST be lower on the stack at the time of use.
148 | Place(y_lvalue lval, Dict[str, Cell] frame)
149
150 # for io->evalToDict(), which uses ctx_FrontFrame(), which is distinct from
151 # ctx_Eval()
152 # TODO: ASDL should let us "collapse" this Dict directly into value_t
153 | Frame(Dict[str, Cell] frame)
154 | DebugFrame(debug_frame frame)
155
156 #
157 # Code units: BoundFunc, BuiltinFunc, Func, BuiltinProc, Proc
158 #
159
160 # for obj.method and obj->mutatingMethod
161 | BoundFunc(value me, value func)
162 # callable is vm._Callable.
163 # TODO: ASDL needs some kind of "extern" to declare vm._Callable,
164 # vm._Builtin. I think it would just generate a forward declaration.
165 | BuiltinFunc(any callable)
166
167 | Func(str name, Func parsed,
168 List[value] pos_defaults, Dict[str, value] named_defaults,
169 Dict[str, Cell] captured_frame,
170 # module is where "global" lookups happen
171 Dict[str, Cell] module_frame)
172
173 # command.ShFunction and command.Proc evaluate to value.Proc
174 # They each have name, name_tok, and body.
175 #
176 # YSH procs disable dynamic scope, have default args to evaluate, and
177 # different @ARGV.
178
179 # builtin is vm._Builtin, this can be introspected
180 | BuiltinProc(any builtin)
181 | Proc(str name, Token name_tok, proc_sig sig, command body,
182 ProcDefaults? defaults, bool sh_compat,
183 Dict[str, Cell] captured_frame,
184 # module is where "global" lookups happen
185 Dict[str, Cell] module_frame,
186 str? code_str)
187
188 #
189 # Unevaluated CODE types: ExprFrag, Expr, CommandFrag, Command
190 #
191
192 # This can be the output of parseExpr()?
193 #| ExprFrag(expr e)
194
195 # var x = ^[42 + a[i]]
196 # my-ls | where [size > 10]
197 | Expr(expr e,
198 Dict[str, Cell] captured_frame,
199 Dict[str, Cell] module_frame)
200
201 # This is an UNBOUND command, like
202 # ^(echo 1; echo 2) and cd { echo 1; echo 2 }
203 | CommandFrag(command c)
204
205 # Bound command
206 | Command(cmd_frag frag,
207 Dict[str, Cell] captured_frame,
208 Dict[str, Cell] module_frame)
209
210 # Other introspection
211 # __builtins__ - Dict[str, value_t] - I would like to make this read-only
212 # __modules__ - Dict[str, Obj] - read-only to prevent non-Obj
213 # __sh_funcs__ - Dict[str, value.Proc] - read-only to prevent non-Proc
214 # __traps__ - Dict[str, command_t] ?
215 # __builtin_procs__ - Dict[str, BuiltinProc] - builtin commands - special
216 # and non-special? and assignment?
217 # __aliases__ - Dict[str, str]
218 # __jobs__ - maybe nicer that jobs -p
219 # __stack__ - replaces pp stacks_, frame_vars_
220 #
221 # More:
222 # - dir stack pushd/popd - read-only variable
223 # - there is a hidden mem.pwd, in addition to $PWD
224 # - completion hooks and spec
225 # - getopts state
226 # - command cache - hash builtin
227}
228
229# vim: sw=2
230