Sapbot VM is a simple virtual machine designed for educational purposes and basic programming tasks. It provides a minimalistic instruction set and memory model that allows for writing and executing simple programs.
The VM is implemented in both Go and JavaScript, making it portable across different platforms. It supports basic arithmetic operations, conditional branching, memory manipulation, and input/output operations.
Note: Sapbot VM is not designed for high-performance computing or complex applications. It's primarily an educational tool to understand how virtual machines and interpreters work at a basic level.
The Sapbot VM consists of several key components:
The VM executes programs line by line, with each line containing an instruction and its operands. The program counter automatically increments after each instruction unless modified by control flow instructions.
Sapbot VM uses a simple memory model where memory is represented as a map/dictionary with integer keys (memory cell addresses) and values that can be of different types (integers, floats, strings, etc.).
type Memory map[int]interface{}
Memory cells are automatically initialized to 0 when accessed if they haven't been set before.
Sapbot VM supports several data types that can be used in instructions and stored in memory:
| Prefix | Name | Example | Description |
|---|---|---|---|
| V | Integer | V3 | Represents an integer value (3 in this case) |
| M | Memory Reference | M3 | References the value in memory cell 3 |
| T | Text | Thello | Represents a text/string value ("hello") |
| F | Float | F0.5 | Represents a floating-point number (0.5) |
Example Usage:
LOAD;V0;V5 ; Load value 5 into memory cell 0
DEBUG;TM3 ; Print the value from memory cell 3
ADD;V1;V2;M0 ; Add values 1 and 2, store result in memory cell 0
Sapbot VM provides a set of instructions for performing various operations. Each instruction follows the format:
INSTRUCTION;ARG1;ARG2;...
Where arguments can be immediate values (V, T, F) or memory references (M).
| Instruction | Format | Description | Example |
|---|---|---|---|
| LOAD | LOAD;CELL;VALUE | Stores a value in a memory cell | LOAD;V0;V3 |
| DEBUG | DEBUG;VALUE | Prints a value to the console | DEBUG;Thello |
| GOTO | GOTO;LINE | Jumps to a specific line number | GOTO;V50 |
| NOT | NOT;VALUE;TO | Logical NOT operation | NOT;V1;V3 |
| ADD | ADD;A;B;TO | Adds two values, stores result | ADD;V5;V5;V0 |
| SUB | SUB;A;B;TO | Subtracts B from A, stores result | SUB;V5;V5;V0 |
| DIV | DIV;A;B;TO | Divides A by B, stores result | DIV;V10;V2;V1 |
| MUL | MUL;A;B;TO | Multiplies A and B, stores result | MUL;V5;V5;V0 |
| MOD | MOD;A;B;TO | Modulo operation (A % B) | MOD;V7;V3;V2 |
| NOP | NOP | No operation (does nothing) | NOP |
| ALB | ALB;A;B;TO | Jump to TO if A < B (A Less than B) | ALB;V0;V5;V30 |
| AQB | AQB;A;B;TO | Jump to TO if A == B (A equals B) | AQB;V0;V5;V30 |
| ABB | ABB;A;B;TO | Jump to TO if A > B (A greater than B) | ABB;V0;V5;V30 |
| AND | AND;A;B;TO | Logical AND operation | AND;V1;V1;V3 |
| OR | OR;A;B;TO | Logical OR operation | OR;V0;V1;V3 |
| DEBINP | DEBINP;CELL | Prompts for user input, stores in cell | DEBINP;V3 |
| PARSEINT | PARSEINT;IN;OUT | Parses a string as integer | PARSEINT;M0;V1 |
| RND | RND;MAX;TO | Generates random number (0 to MAX-1) | RND;V100;V0 |
Note: All instructions that perform comparisons or jumps (ALB, AQB, ABB) will jump to the specified line number if the condition is true. The program counter is automatically incremented after each instruction unless explicitly changed by a GOTO or jump instruction.
Sapbot VM programs can be written in two formats:
Each line number is a key in a JSON object, with the instruction as the value:
{
"10": "DEBUG;THello, World!",
"20": "LOAD;V0;V5",
"30": "DEBUG;M0"
}
Instructions are listed in an array, with implicit line numbers starting from 0:
[
"DEBUG;THello, World!",
"LOAD;V0;V5",
"DEBUG;M0"
]
Example (fibonacci.svm):
{
"10":"LOAD;V0;V0",
"20":"LOAD;V1;V1",
"30":"LOAD;V2;V0",
"40":"ADD;M2;V1;V2",
"50":"DEBUG;M1",
"60":"ADD;M0;M1;V3",
"70":"LOAD;V0;M1",
"80":"LOAD;V1;M3",
"90":"ALB;M2;V20;V40"
}
Note: The JSON object format allows for non-sequential line numbers, which is useful for programs with jumps and branches. The array format is simpler but requires sequential execution.
The simplest program that prints "Hello, World!":
[
"DEBUG;THello, World!"
]
A program that calculates and prints Fibonacci numbers:
{
"10":"LOAD;V0;V0", ; Initialize first Fibonacci number (0)
"20":"LOAD;V1;V1", ; Initialize second Fibonacci number (1)
"30":"LOAD;V2;V0", ; Initialize counter
"40":"ADD;M2;V1;V2", ; Calculate next Fibonacci number
"50":"DEBUG;M1", ; Print current Fibonacci number
"60":"ADD;M0;M1;V3", ; Update previous number
"70":"LOAD;V0;M1", ; Load current into M0
"80":"LOAD;V1;M3", ; Load next into M1
"90":"ALB;M2;V20;V40" ; Loop if counter < 20
}
A simple game where the user guesses a random number:
{
"10": "RND;V100;V0", ; Generate random number (1-100)
"20": "ADD;M0;M0;V1", ; Increment to make range 1-100
"30": "DEBUG;TGuess a number between 1 and 100:",
"40": "DEBINP;V3", ; Get user input
"50": "PARSEINT;M3;V4", ; Convert input to integer
"60": "AQB;M4;M0;V200", ; Check if guess equals target
"70": "ALB;M4;M0;V300", ; Check if guess is less than target
"80": "DEBUG;TToo high! Try again.",
"90": "GOTO;V30", ; Try again
"200": "DEBUG;TCongratulations! You guessed the number!",
"210": "GOTO;V9999", ; End program
"300": "DEBUG;TToo low! Try again.",
"310": "GOTO;V30" ; Try again
}
Sapbot VM has been implemented in two languages:
The Go implementation provides the core VM functionality with these key components:
type SVM struct {
pc int
mem Memory
code map[int]string
}
Key features:
The JavaScript implementation uses Node.js and provides similar functionality:
var mem = new Proxy({}, {
get: function(target, prop) {
return prop in target ? target[prop] : 0;
}
});
Key features:
Note: Both implementations can run the same programs, though there might be minor differences in error handling and edge cases.
| Feature | Sapbot VM | Brainfuck | Scratch | Lua | C | Python | Java VM | HTML5 |
|---|---|---|---|---|---|---|---|---|
| Educational Value | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Performance | ⭐ | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Complexity | ⭐ | ⭐ | ⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
| Difficulty to Write Code | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ | ⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Difficulty to Write Runtime | ⭐ | ⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Extensibility | ⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
Best Use Cases: Sapbot VM is ideal for educational purposes, teaching basic computing concepts, and simple programming experiments. It's not suitable for production applications or complex software development.
Sapbot VM is a simple yet powerful educational tool for understanding how virtual machines and interpreters work. Its minimalistic design makes it easy to learn and experiment with basic computing concepts like memory management, control flow, and arithmetic operations.
The VM's dual implementation in Go and JavaScript demonstrates how the same virtual machine design can be realized in different programming languages, each with their own idioms and approaches.
While not suitable for production use or complex applications, Sapbot VM serves as an excellent platform for:
As we've seen in the Advantages and Disadvantages section, Sapbot VM excels in educational value and simplicity, making it ideal for teaching fundamental computing concepts. Its limitations, such as the lack of functions, limited error handling, and basic memory model, are outweighed by its benefits as a learning tool.
For those interested in extending Sapbot VM, potential improvements could include:
Despite its limitations, Sapbot VM provides a solid foundation for understanding computational concepts and can be extended with additional features as needed. It serves as an excellent starting point for those interested in computer architecture, virtual machines, and interpreter design.