sylt_common/
op.rs

1/// Ops are operations that the virtual
2/// machine carries out when running the
3/// "byte-code".
4///
5#[derive(Debug, Copy, Clone)]
6pub enum Op {
7    /// This instruction should never be run.
8    /// Finding it in a program is a critical error.
9    Illegal,
10
11    /// Pops one value from the stack.
12    ///
13    /// {A, B} - Pop - {A}
14    Pop,
15    /// Assumes the value on the top of the
16    /// stack has an upvalue, and closes that
17    /// upvalue.
18    ///
19    /// {A, B} - Pop - {A}
20    PopUpvalue,
21    /// Copies the N values on the top of the stack
22    /// and puts them on top of the stack.
23    ///
24    /// {A, B} - Copy(2) - {A, B, A, B}
25    Copy(usize),
26    /// Swaps the two top stack elements.
27    ///
28    /// {A, B} - Swap(2) - {B, A}
29    Swap,
30    /// Adds the value indexed in the `constants-vector` to the top of the stack.
31    /// Also links upvalues if the value is a function.
32    ///
33    /// {A} - Constant(B) - {A, B}
34    Constant(usize),
35
36    /// Creates a new [Value::Tuple] with the given size and place it on the top
37    /// of the stack.
38    ///
39    /// {A, B, C} - Tuple(3) - {D(A, B, C)}
40    Tuple(usize),
41    /// Creates a new [Value::List] with the given size and place it on the top
42    /// of the stack.
43    ///
44    /// {A, B, C} - List(3) - {D(A, B, C)}
45    List(usize),
46    /// Creates a new [Value::Set] with the given elements and place it on the top
47    /// of the stack.
48    ///
49    /// {A, B, A} - Set(3) - {D(A, B)}
50    Set(usize),
51    /// Creates a new [Value::Dict] with the given elements and place it on the top
52    /// of the stack.
53    ///
54    /// {A, B, C, D, A, E} - Dict(6) - {D(A:E, C:D)}
55    Dict(usize),
56
57    /// Indexes something indexable,
58    /// and adds that element to the stack.
59    ///
60    /// {T, I} - Index - {T[I]}
61    GetIndex,
62    /// Indexes something indexable with a constant integer,
63    /// and adds that element to the stack.
64    ///
65    /// {T} - Index(I) - {T[I]}
66    GetConstIndex(i64),
67    /// Assigns the indexes of something indexable.
68    /// T[I] = V
69    ///
70    /// {T, I, V} - Index - {}
71    AssignIndex,
72    /// Looks up a field by the given name
73    /// and replaces the parent with it.
74    /// Currently only expects [Value::Blob].
75    /// (name is looked up in the internal string-list)
76    ///
77    /// {O} - Get(F) - {O.F}
78    Contains,
79    /// Checks if the given value is inside the container.
80    /// Pushes a bool to the stack.
81    ///
82    /// {I, A} - Contains - {I in A}
83    GetField(usize),
84    /// Looks up a field by the given name
85    /// and replaces the current value in the object.
86    /// Currently only expects [Value::Blob].
87    /// (name is looked up in the internal string-list)
88    ///
89    /// {O} - Set(F) - {}
90    AssignField(usize),
91
92    /// Adds the two top elements on the stack,
93    /// using the function [op::add]. The result
94    /// is the pushed.
95    ///
96    /// {A, B} - Add - {A + B}
97    Add,
98    /// Sub the two top elements on the stack,
99    /// using the function [op::sub]. The result
100    /// is the pushed.
101    ///
102    /// {A, B} - Sub - {A - B}
103    Sub,
104    /// Multiples the two top elements on the stack,
105    /// using the function [op::mul]. The result
106    /// is the pushed.
107    ///
108    /// {A, B} - Mul - {A - B}
109    Mul,
110    /// Divides the two top elements on the stack,
111    /// using the function [op::div]. The result
112    /// is the pushed.
113    ///
114    /// {A, B} - Div - {A / B}
115    Div,
116    /// Negates the top element on the stack.
117    ///
118    /// {A} - Neg - {-A}
119    Neg,
120
121    /// Performs a boolean and on the
122    /// top 2 stack elements using [op::and].
123    ///
124    /// {A, B} - And - {A && B}
125    And,
126    /// Performs a boolean or on the
127    /// top 2 stack elements using [op::or].
128    ///
129    /// {A, B} - Or - {A || B}
130    Or,
131    /// Performs a boolean not on the
132    /// top stack element using [op::not].
133    ///
134    /// {A} - Not - {!A}
135    Not,
136
137    /// Checks if the type of the value on the left
138    /// is the type on the right.
139    ///
140    /// {A, B} - Is - {A is B}
141    Is,
142
143    /// Sets the instruction pointer
144    /// to the given value.
145    ///
146    /// Does not affect the stack.
147    Jmp(usize),
148    /// Sets the instruction pointer
149    /// to the given value, if the
150    /// topmost value is false, also
151    /// pops this value.
152    ///
153    /// {A} - JmpFalse(n) - {}
154    JmpFalse(usize),
155    /// Sets the instruction pointer
156    /// to the given value and pops
157    /// the given amount of values.
158    ///
159    /// Used for 'break' and 'continue'.
160    ///
161    /// {A, B, C} - JmpNPop(n, 2) - {A}
162    JmpNPop(usize, usize),
163
164    /// Compares the two topmost elements
165    /// on the stack for equality, and pushes
166    /// the result. Compares using [op::eq].
167    ///
168    /// {A, B} - Equal - {A == B}
169    Equal,
170    /// Compares the two topmost elements
171    /// on the stack for order, and pushes the result.
172    /// Compares using [op::less].
173    ///
174    /// {A, B} - Less - {A < B}
175    Less,
176    /// Compares the two topmost elements
177    /// on the stack for order, and pushes the result.
178    /// Compares using [op::less].
179    ///
180    /// {A, B} - Greater - {B < A}
181    Greater,
182
183    /// Pops the top value of the stack, and
184    /// crashes the program if it is false.
185    ///
186    /// {A} - Assert - {}
187    Assert,
188    /// This instruction should not be executed.
189    /// If it is the program crashes.
190    ///
191    /// Does not affect the stack.
192    Unreachable,
193
194    /// Reads the value counted from the
195    /// bottom of the stack and adds it
196    /// to the top.
197    ///
198    /// {A, B} - ReadLocal(0) - {A, B, A}
199    ReadLocal(usize),
200    /// Sets the value at the given index
201    /// of the stack, to the topmost value.
202    /// Pops the topsmost element.
203    ///
204    /// {A, B} - AssignLocal(0) - {B}
205    AssignLocal(usize),
206
207    /// Reads the upvalue, and adds it
208    /// to the top of the stack.
209    ///
210    /// {} - ReadUpvalue(0) - {A}
211    ReadUpvalue(usize),
212    /// Sets the given upvalue, and pops
213    /// the topmost element.
214    ///
215    /// {A} - AssignUpvalue(0) - {}
216    AssignUpvalue(usize),
217
218    /// Reads the global, and adds it
219    /// to the top of the stack.
220    ///
221    /// Globals are stored at the bottom
222    /// of the stack and initalized when
223    /// the program starts.
224    ///
225    /// {} - ReadGlobal(0) - {C}
226    ReadGlobal(usize),
227    /// Sets the given constant, and pops
228    /// the topmost element.
229    ///
230    /// {A} - AssignGlobal(0) - {}
231    AssignGlobal(usize),
232
233    /// A helper instruction for the type checker.
234    /// *Makes sure* that the top value on the stack
235    /// is of the given type, and is meant to signal
236    /// that the "variable" is added.
237    /// (The type is looked up in the constants vector.)
238    ///
239    /// Does not affect the stack.
240    Define(usize),
241    /// A helper instruction for the typechecker,
242    /// *assumes* top value on the stack
243    /// is of the given type. Usefull for helping the
244    /// type system where it just can't do it.
245    /// (The type is looked up in the constants vector)
246    ///
247    /// Does not affect the stack.
248    Force(usize),
249    /// A helper instruction for the typechecker,
250    /// *combines* the two top value on the stack
251    /// into a union type.
252    ///
253    /// Skipped in the runtime.
254    /// In the typechecker:
255    /// {A, B} - Union - {A | B}
256    Union,
257
258    /// Links the upvalues for the given constant
259    /// function. This updates the constant stack.
260    ///
261    /// Does not affect the stack.
262    Link(usize),
263
264    /// Calls "something" with the given number
265    /// of arguments. The callable value is
266    /// then replaced with the result.
267    ///
268    /// Callable things are: [Value::Blob], [Value::Function],
269    /// and [Value::ExternFunction].
270    ///
271    /// {F, A, B} - Call(2) - {F(A, B)}
272    Call(usize),
273
274    /// Prints and pops the top value on the stack.
275    ///
276    /// {A} - Print - {}
277    Print,
278
279    /// Pops the current stackframe and replaces
280    /// slot 0 with the top value. Also pops
281    /// upvalues.
282    ///
283    /// {F, A, B} - Return - {..., B}
284    Return,
285
286    /// Temporarily stops execution and returns
287    /// to the call site.
288    ///
289    /// Does not affect the stack.
290    Yield,
291}
292
293#[derive(Eq, PartialEq)]
294pub enum OpResult {
295    Yield,
296    Done,
297
298    // Will never be returned.
299    #[doc(hidden)]
300    Continue,
301}
302