Skip to content

Commit 39bf7e7

Browse files
committed
Add virtual machine documentation
1 parent 56f740a commit 39bf7e7

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

docs/Virtual machine.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
\page virtualMachine Virtual machine
2+
3+
Scratch projects are compiled to bytecode which is interpreted by the
4+
\link libscratchcpp::VirtualMachine VirtualMachine \endlink class.
5+
6+
The opcodes are defined in the \link libscratchcpp::vm::Opcode Opcode \endlink enumeration.
7+
8+
## Start instruction
9+
10+
The first instruction of the bytecode is \link libscratchcpp::vm::OP_START OP_START \endlink.
11+
12+
## End instruction
13+
The bytecode ends with the \link libscratchcpp::vm::OP_HALT OP_HALT \endlink opcode
14+
which can be also used to stop the script from anywhere in the code.
15+
16+
## Constant values
17+
To load a constant value, the \link libscratchcpp::vm::OP_CONST OP_CONST \endlink opcode can
18+
be used.
19+
```
20+
OP_CONST
21+
0
22+
```
23+
`0` is the index of the constant value.
24+
The array of constant values can be set using \link libscratchcpp::VirtualMachine::setConstValues setConstValues() \endlink
25+
26+
To load a null value (zero), use \link libscratchcpp::vm::OP_NULL OP_NULL \endlink without any arguments.
27+
28+
## If statements
29+
If statements can be implemented using \link libscratchcpp::vm::OP_IF OP_IF \endlink,
30+
\link libscratchcpp::vm::OP_ELSE OP_ELSE \endlink and \link libscratchcpp::vm::OP_ENDIF OP_ENDIF \endlink.
31+
```
32+
(evaluate the condition here)
33+
OP_IF
34+
...
35+
OP_ELSE
36+
...
37+
OP_ENDIF
38+
```
39+
\note \link libscratchcpp::vm::OP_ELSE OP_ELSE \endlink is optional.
40+
41+
## Loops
42+
All loops end with \link libscratchcpp::vm::OP_LOOP_END OP_LOOP_END \endlink.
43+
44+
### Repeat n times
45+
The repeat loop can be implemented using \link libscratchcpp::vm::OP_REPEAT_LOOP OP_REPEAT_LOOP \endlink.
46+
```
47+
(load the amount of periods here)
48+
OP_REPEAT_LOOP
49+
...
50+
OP_LOOP_END
51+
```
52+
53+
### Repeat until
54+
Scratch has a while loop, but until is used more frequently, so the VM doesn't support the while loop.
55+
56+
The repeat until loop can be implemented using \link libscratchcpp::vm::OP_REPEAT_UNTIL OP_REPEAT_UNTIL \endlink
57+
and \link libscratchcpp::vm::OP_BEGIN_UNTIL_LOOP OP_BEGIN_UNTIL_LOOP \endlink.
58+
```
59+
OP_REPEAT_UNTIL
60+
(evaluate the condition here)
61+
OP_BEGIN_UNTIL_LOOP
62+
...
63+
OP_LOOP_END
64+
```
65+
\note The condition is evaluated after \link libscratchcpp::vm::OP_REPEAT_UNTIL OP_REPEAT_UNTIL \endlink and the loop
66+
starts with \link libscratchcpp::vm::OP_BEGIN_UNTIL_LOOP OP_BEGIN_UNTIL_LOOP \endlink.
67+
68+
### Forever
69+
The forever loop can be implemented using \link libscratchcpp::vm::OP_FOREVER_LOOP OP_FOREVER_LOOP \endlink.
70+
```
71+
OP_FOREVER_LOOP
72+
...
73+
OP_LOOP_END
74+
```
75+
76+
This is equivalent to:
77+
```
78+
OP_REPEAT_UNTIL
79+
OP_NULL
80+
OP_BEGIN_UNTIL_LOOP
81+
...
82+
OP_LOOP_END
83+
```
84+
\link libscratchcpp::vm::OP_NULL OP_NULL \endlink will be evaluated as `false`.
85+
86+
## Operators
87+
### Arithmetic operators
88+
- \link libscratchcpp::vm::OP_ADD OP_ADD \endlink
89+
- \link libscratchcpp::vm::OP_SUBTRACT OP_SUBTRACT \endlink
90+
- \link libscratchcpp::vm::OP_MULTIPLY OP_MULTIPLY \endlink
91+
- \link libscratchcpp::vm::OP_DIVIDE OP_DIVIDE \endlink
92+
93+
### Relational operators
94+
- \link libscratchcpp::vm::OP_GREATER_THAN OP_GREATER_THAN \endlink
95+
- \link libscratchcpp::vm::OP_LESS_THAN OP_LESS_THAN \endlink
96+
- \link libscratchcpp::vm::OP_EQUALS OP_EQUALS \endlink
97+
98+
### Logical operators
99+
- \link libscratchcpp::vm::OP_AND OP_ADD \endlink
100+
- \link libscratchcpp::vm::OP_OR OP_OR \endlink
101+
- \link libscratchcpp::vm::OP_NOT OP_NOT \endlink
102+
103+
## Example
104+
Add 5 and 3:
105+
```
106+
OP_CONST
107+
0
108+
OP_CONST
109+
1
110+
OP_ADD
111+
(use the result in another instruction)
112+
```
113+
List of constant values: `5`, `3`
114+
115+
## Variables
116+
Variables are stored in an array similar to constant values.
117+
118+
It can be set using \link libscratchcpp::VirtualMachine::setVariables setVariables() \endlink.
119+
120+
Set variable at index 0 to loaded value:
121+
```
122+
(load the value here)
123+
OP_SET_VAR
124+
0
125+
```
126+
127+
Change variable at index 0 by loaded value:
128+
```
129+
(load the value here)
130+
OP_CHANGE_VAR
131+
0
132+
```
133+
134+
Read the variable at index 0:
135+
```
136+
OP_READ_VAR
137+
0
138+
(use the value in another instruction)
139+
```
140+
141+
## Lists
142+
Lists are stored in an array just like variables. The array can be set using \link libscratchcpp::VirtualMachine::setLists setLists() \endlink.
143+
144+
Opcodes for lists can be found in the \link libscratchcpp::vm::Opcode Opcode \endlink enumeration.
145+
146+
## Custom functions
147+
Custom functions can be called using \link libscratchcpp::vm::OP_EXEC OP_EXEC \endlink.
148+
149+
Function pointers are stored in an array which can be set using \link libscratchcpp::VirtualMachine::setFunctions setFunctions() \endlink.
150+
151+
Example: print function
152+
```
153+
OP_CONST
154+
0
155+
OP_EXEC
156+
0
157+
```
158+
159+
```cpp
160+
unsigned int print(VirtualMachine *vm) {
161+
std::cout << vm->getInput(0, 1)->toString() << std::endl;
162+
return 1;
163+
}
164+
```
165+
166+
`getInput(0, 1)` returns the value at index 0 and `1` is the number of arguments
167+
168+
The function returns the number of arguments.
169+
170+
\note This is just an example. The \link libscratchcpp::vm::OP_PRINT OP_PRINT \endlink opcode can be used to print a string.

0 commit comments

Comments
 (0)