The Buzz Virtual Machine (BVM) is a stack machine that works with a custom assembly language. The instruction set is composed of 46 elements. Each command can be used either by writing Buzz Assembly code directly (in a .basm
file); most of them, have a corresponding C-function that can be used when integrating Buzz with other software.
The table below reports both the plain assembly command and the corresponding C function, along with a brief description of the effect of a command. In the description, stack(N)
stands for the N
-th element on the stack. The stack-top element is stack(1)
; the element beneath it is stack(2)
, and so on. If the stack contains K
elements, the bottom element is stack(K)
.
Command | C function | Description |
---|---|---|
nop |
No operation | |
done |
buzzvm_done(VM) |
Ends the execution |
pushnil |
buzzvm_pushnil(VM) |
Pushes nil on the current stack |
dup |
buzzvm_dup(VM) |
Pushes stack(1) on the current stack |
pop |
buzzvm_pop(VM) |
Removes stack(1) from the current stack |
ret0 |
buzzvm_ret0(VM) |
Returns from a closure call without returning a value to the caller |
ret1 |
buzzvm_ret0(VM) |
Returns from a closure call and returns the current stack(1) to the caller |
add |
buzzvm_add(VM) |
Pushes the result of stack(1) + stack(2) , pops operands |
sub |
buzzvm_sub(VM) |
Pushes the result of stack(1) - stack(2) , pops operands |
mul |
buzzvm_mul(VM) |
Pushes the result of stack(1) * stack(2) , pops operands |
div |
buzzvm_div(VM) |
Pushes the result of stack(1) / stack(2) , pops operands |
mod |
buzzvm_mod(VM) |
Pushes the result of stack(1) % stack(2) , pops operands |
pow |
buzzvm_pow(VM) |
Pushes the result of stack(1) ^ stack(2) , pops operands |
unm |
buzzvm_unm(VM) |
Pushes -stack(1) , pops operand |
and |
buzzvm_and(VM) |
Pushes the result of logical stack(1) AND stack(2) , pops operands |
or |
buzzvm_or(VM) |
Pushes the result of logical stack(1) OR stack(2) , pops operands |
not |
buzzvm_not(VM) |
Pushes the result of logical NOT stack(1) , pops operand |
eq |
buzzvm_eq(VM) |
Pushes the result of stack(1) == stack(2) , pops operands |
neq |
buzzvm_neq(VM) |
Pushes the result of stack(1) != stack(2) , pops operands |
gt |
buzzvm_gt(VM) |
Pushes the result of stack(1) > stack(2) , pops operands |
gte |
buzzvm_gte(VM) |
Pushes the result of stack(1) >= stack(2) , pops operands |
lt |
buzzvm_lt(VM) |
Pushes the result of stack(1) < stack(2) , pops operands |
lte |
buzzvm_lte(VM) |
Pushes the result of stack(1) <= stack(2) , pops operands |
gload |
buzzvm_gload(VM) |
Pushes the global variable corresponding to string at stack(1) , pops operand |
gstore |
buzzvm_gstore(VM) |
Stores stack(1) into global variable whose name is at stack(2) , pop operands |
pusht |
buzzvm_pusht(VM) |
Pushes an empty table on the current stack |
tput |
buzzvm_tput(VM) |
Performs t[k] = v ; v is stack(1) , k is stack(2) ), t is stack(3) ; pops operands |
tget |
buzzvm_tget(VM) |
Pushes t[k] on the current stack; k is stack(1) ), t is stack(2) ; pops operands |
callc |
buzzvm_callc(VM) |
Calls the closure at stack(1) as a normal closure |
calls |
buzzvm_callc(VM) |
Calls the closure at stack(1) as a swarm closure |
pushf CONST |
buzzvm_pushf(VM, CONST) |
Pushes a floating-point constant on the current stack |
pushi CONST |
buzzvm_pushi(VM, CONST) |
Pushes a 32-bit signed integer constant on the current stack |
pushs SID |
buzzvm_pushs(VM, SID) |
Pushes a string (identified by the string id SID ) on the current stack |
pushcn ADDR |
buzzvm_pushcn(VM, ADDR) |
Pushes the native closure at address ADDR on the current stack |
pushcc CID |
buzzvm_pushcc(VM, CID) |
Pushes the C closure identified by the id CID on the current stack |
pushl ADDR |
buzzvm_pushl(VM, ADDR) |
Pushes the lambda at address ADDR on the current stack |
lload IDX |
buzzvm_lload(VM, IDX) |
Pushes the local variable at index IDX on the current stack; index count starts at 1 . |
lstore IDX |
buzzvm_lstore(VM, IDX) |
Stores stack(1) into the local variable at index IDX , pops operand; index count starts at 1 |
jump POS |
Sets the program counter to POS |
|
jumpz POS |
If stack(1) == 0 , sets the program counter to POS ; pops operand |
|
jumpnz POS |
If stack(1) != 0 , sets the program counter to POS ; pops operand |
To make human-readable error reporting possible, assembly code can be annotated with extra information. Debugging annotations are added to each assembly code line. To mark the beginning of the information, the character |
is used; after this character, the line number, column number, and file name are reported, separated by commas. No spaces are allowed before or after the commas. Line and column counts start from 1. For example:
@__label_0
pushs 0 |7,18,/Users/myuser/test.bzz
pushi 2 |7,20,/Users/myuser/test.bzz
gstore |7,21,/Users/myuser/test.bzz
Debugging information is not mandatory for each line. In fact, the preamble of any Buzz assembly file (the part in which strings are recorded and global symbols are registered) has no associated debugging information.
- Debugging information is automatically generated by bzzparse upon compiling a Buzz script.
- bzzasm takes each assembly line and uses the assembly command to produce bytecode, and the associated debugging information to produce a debugging information file.
- bzzdeasm performs the opposite process: it takes as input a bytecode file and a debugging information file, and produces an annotated assembly code file.