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

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