OILS / core / value.asdl View on Github | oilshell.org

183 lines, 74 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 LiteralBlock Func
12 NameType
13 EggexFlag
14 }
15
16 use core runtime {
17 Cell
18 }
19
20 IntBox = (int i)
21
22 ProcDefaults = (
23 List[value]? for_word, # all of them are value.Str
24 List[value]? for_typed,
25 Dict[str, value]? for_named,
26 value? for_block,
27 )
28
29 LeftName = (str name, loc blame_loc)
30
31 # for setvar, and value.Place
32 y_lvalue =
33 # e.g. read (&x)
34 Local %LeftName
35 # e.g. &a[0][1].key -- we evaluate a[0][1] first
36 | Container(value obj, value index)
37
38 # An sh_lvalue is for things mutation that happen with dynamic scope
39 #
40 # - sh_expr_eval uses this for unset / printf -v
41 # - word_eval uses this for ${a[0]=}
42 # - expr_eval / cmd_eval use this for setvar a[i] = 42
43 sh_lvalue =
44 Var %LeftName
45 | Indexed(str name, int index, loc blame_loc)
46 | Keyed(str name, str key, loc blame_loc)
47
48 eggex_ops =
49 # for BASH_REMATCH or ~ with a string
50 No
51 # These lists are indexed by group number, and will have None entries
52 | Yes(List[value?] convert_funcs, List[Token?] convert_toks,
53 List[str?] capture_names)
54
55 RegexMatch = (str s, List[int] indices, eggex_ops ops)
56
57 regex_match =
58 No
59 | Yes %RegexMatch
60
61 # Arbitrary objects, where attributes are looked up on the prototype chain.
62 Obj = (Obj? prototype, Dict[str, value] d)
63
64 # Commands, words, and expressions from syntax.asdl are evaluated to a VALUE.
65 # value_t instances are stored in state.Mem().
66 value =
67 # Only used for val_ops.StdinIterator. (It would be nice if we could
68 # express iter_value.{Eof,Interrupted,Str,Int,...} in ASDL)
69 Interrupted
70 | Stdin
71
72 # Methods on state.Mem return value.Undef, but it's not visible in YSH.
73 #
74 # A var bound to Undef is different than no binding because of dynamic
75 # scope. Undef can shadow values lower on the stack.
76 | Undef
77
78 | Str(str s)
79
80 # "holes" in the array are represented by None
81 | BashArray(List[str] strs)
82 # TODO: Switch to this more efficient representation?
83 # max_index makes append-sparse workload faster, and normal append loops too
84 | SparseArray(Dict[BigInt, str] d, BigInt max_index)
85
86 | BashAssoc(Dict[str, str] d)
87
88 # DATA model for YSH follows JSON. Note: YSH doesn't have 'undefined' and
89 # 'null' like JavaScript, just 'null'.
90 | Null
91 | Bool(bool b)
92 | Int(BigInt i)
93 #| Int(int i)
94 | Float(float f)
95 | List(List[value] items)
96 | Dict(Dict[str, value] d)
97
98 # for polymorphism - should replace value.{IO,Module} too
99 # because they have attributes (functions), methods - not just methods
100 | Obj %Obj
101
102 # CODE types
103 # unevaluated: Eggex, Expr, Template, Command/Block
104 # callable, in separate namespaces: Func, BoundFunc, Proc
105
106 # expr is spliced
107 # / d+; ignorecase / -> '[[:digit:]]+' REG_ICASE
108 | Eggex(re spliced, str canonical_flags,
109 List[value?] convert_funcs, List[Token?] convert_toks,
110 # str? is because some groups are not named
111 str? as_ere, List[str?] capture_names)
112
113 # The indices list has 2 * (num_group + 1) entries. Group 0 is the whole
114 # match, and each group has both a start and end index.
115 # It's flat to reduce allocations. The group() start() end() funcs/methods
116 # provide a nice interface.
117 | Match %RegexMatch
118
119 # ^[42 + a[i]]
120 | Expr(expr e)
121
122 # ^(echo 1; echo 2) and cd { echo 1; echo 2 }
123 | Command(command c)
124
125 # for Hay to get the backing lines
126 # TODO: Consolidate value.Command and value.LiteralBlock. All Command
127 # instance should have backing lines.
128
129 # TODO: ASDL doesn't support shared variant across module
130 # This would be more efficient
131 # | LiteralBlock %LiteralBlock
132 | Block(LiteralBlock block)
133
134 # A place has an additional stack frame where the value is evaluated.
135 # The frame MUST be lower on the stack at the time of use.
136 | Place(y_lvalue lval, Dict[str, Cell] frame)
137
138 # for Flags/flag and Flags/arg?
139 # for json read/write ?
140 # Possibly unify Hay and modules/namespaces
141 | Module(Dict[str, value] defs)
142
143 # The ability to use operating system functions. Right now some functions
144 # leak, like glob().
145 # TODO: Removed 'unused' after ASDL in Python makes value.IO a type
146 | IO(any unused)
147
148 # Do we need this?
149 # _guts->heapId() can be used to detect object cycles.
150 # It's considered impure; it depends on VM implementation details. The =
151 # operator and 'pp value' also print the heap ID.
152 | Guts(any vm)
153
154 # callable is vm._Callable.
155 # TODO: ASDL needs some kind of "extern" to declare vm._Callable and
156 # cmd_eval.CommandEvaluator. I think it would just generate a forward
157 # declaration.
158 | BuiltinFunc(any callable)
159 | BoundFunc(value me, value func)
160
161 # command.ShFunction and command.Proc evaluate to value.Proc
162 # They each have name, name_tok, and body.
163 #
164 # YSH procs disable dynamic scope, have default args to evaluate, and
165 # different @ARGV.
166
167 | Proc(str name, Token name_tok, proc_sig sig, command body,
168 ProcDefaults? defaults, bool sh_compat)
169
170 # module may be a frame where defined
171 | Func(str name, Func parsed,
172 List[value] pos_defaults, Dict[str, value] named_defaults,
173 Dict[str, Cell]? module_)
174
175 # a[3:5] a[:10] a[3:] a[:] # both ends are optional
176 | Slice(IntBox? lower, IntBox? upper)
177
178 # for i in (1:n) { echo $i } # both ends are required
179 | Range(int lower, int upper)
180}
181
182# vim: sw=2
183