# SapbotVM

This document has description and information on how to use and code in Sapbot VM.

## Syntax

Sapbot VM has BASIC-like syntax, and separates by two formats: `.svm` and `.svm2`.

`.svm2` is generally considered superior, by having comments and easier readability.

### `.svm`

`.svm` format is based on JSON, and have following format:

```json
{
    "LINE_NUMBER":"FUNC_NAME;ARGUMENTS;SEPARATED;BY;SEMICOLON"
}
```

And again, following format DOES NOT HAVE COMMENTS!!! JSON will not parse all kind of `//` or `#` comments like in `.svm2`. Do not create syntax errors by adding comments into `.svm`.

### `.svm2`

`.svm2` format has a custom parser, comments, and way easier readability.

```
# Comment
LINE_NUMBER FUNC_NAME;ARGUMENTS;SEPARATED;BY;SEMICOLON # Inline comment
```

### Minimal working program

`.svm2`'s minimal working program is just empty file. `.svm`'s minimal working program is `{}`.

### Full types list

| Prefix | Name | Example | Result |
| :--- | :--- | :--- | :--- |
| M | Memory | M3 | Value from memory cell 3 |
| V | Integer | V3 | 3 |
| T | Text | Thello World | hello World |
| F | Float | F0.5 | 0.5 |
| S | Stack | S1:3 | Value at index 3 in stack 1 |
| H | Heap | H1:5 | Value at address 5 in heap 1 |
| A | Array | A10:3 | Value at index 3 in the array starting at memory cell 10 |

### Full function list

| Function | Arguments | Description |
| :--- | :--- | :--- |
| `LOAD` | `MEM_CELL, VALUE` | Set memory cell to value |
| `DEBUG` | `TEXT` | Print text to debug console |
| `GOTO` | `PC` | Set program counter to value |
| `NOT` | `A, TO` | Fill `TO` with 1 if `A` != 1, else 0 |
| `ADD` | `A, B, TO` | `A + B` save to `TO` |
| `SUB` | `A, B, TO` | `A - B` save to `TO` |
| `DIV` | `A, B, TO` | `A / B` save to `TO` |
| `MUL` | `A, B, TO` | `A * B` save to `TO` |
| `MOD` | `A, B, TO` | `A mod B` save to `TO` |
| `NOP` | None | No operation |
| `ALB` | `A, B, TO` | Jump to `TO` if `A < B` |
| `AQB` | `A, B, TO` | Jump to `TO` if `A == B` |
| `ABB` | `A, B, TO` | Jump to `TO` if `A > B` |
| `AND` | `A, B, TO` | Fill `TO` with 1 if `A == 1` and `B == 1`, else 0 |
| `OR` | `A, B, TO` | Fill `TO` with 1 if `A == 1` or `B == 1`, else 0 |
| `DEBINP` | `MEMORY_CELL` | Prompt user and store answer in memory cell |
| `PARSEINT` | `IN, OUT` | Parse integer from `IN` to `OUT` |
| `RND` | `MAX, TO` | Generate random number [0, MAX-1] and store in `TO` |
| `STACK_CREATE`| `TO` | Create stack and store ID in `TO` |
| `STACK_PUSH` | `STACK_ID, VALUE` | Push value onto stack |
| `STACK_POP` | `STACK_ID, TO` | Pop value from stack and store in `TO` |
| `HEAP_CREATE` | `TO` | Create heap and store ID in `TO` |
| `HEAP_SET` | `HEAP_ID, ADDR, VAL` | Set value `VAL` at `ADDR` in heap |
| `HEAP_GET` | `HEAP_ID, ADDR, TO` | Get value from `ADDR` in heap and store in `TO` |
| `ARRAY_SET` | `BASE, INDEX, VAL` | Set value `VAL` at `INDEX` in array starting at `BASE` |
| `ARRAY_GET` | `BASE, INDEX, TO` | Get value from `INDEX` in array and store in `TO` |
| `CALL` | `ADDRESS` | Jump to specified address (function call) |
| `RET` | None | Return from function call |
| `STRSPLIT` | `TEXT, DELIM, BASE` | Split `TEXT` by `DELIM`, store in array starting at `BASE` |
| `STRCONCAT` | `BASE, LEN, TO` | Concatenate `LEN` strings from `BASE` array and store in `TO` |
| `STRTOASCII` | `TEXT, BASE` | Convert string to ASCII codes and store in array starting at `BASE` |
| `ASCIITOSTR` | `BASE, LEN, TO` | Convert `LEN` ASCII codes from `BASE` to string and store in `TO` |
| `GPU_CREATE` | `W, H, TO` | Create GPU context (WxH) and store ID in `TO` |
| `GPU_CLEAR` | `GPU_ID, COLOR` | Clear GPU context with hex color |
| `GPU_DOT` | `GPU_ID, X, Y, COL` | Draw dot at (X, Y) |
| `GPU_LINE` | `GPU_ID, X1, Y1, X2, Y2, COL` | Draw line from (X1, Y1) to (X2, Y2) |
| `GPU_RECT` | `GPU_ID, X, Y, W, H, COL` | Draw rectangle outline |
| `GPU_FILL_RECT`| `GPU_ID, X, Y, W, H, COL` | Draw filled rectangle |
| `GPU_CIRCLE` | `GPU_ID, X, Y, R, COL` | Draw circle outline with radius R |
| `GPU_FILL_CIRC`| `GPU_ID, X, Y, R, COL` | Draw filled circle |
| `GPU_TEXT` | `GPU_ID, X, Y, TXT, COL, SZ` | Draw text at (X, Y) with size SZ |
| `GPU_DISPLAY` | `GPU_ID` | Display GPU context on screen |
| `GPU_SAVE` | `GPU_ID, FILE` | Save GPU context to file |
| `MONITOR_COUNT`| `TO` | Get number of monitors and store in `TO` |
| `MONITOR_RES` | `ID, W_TO, H_TO` | Get resolution of monitor `ID` (W -> W_TO, H -> H_TO) |
| `MONITOR_PRIM` | `TO` | Get primary monitor ID and store in `TO` |

## Examples

### .svm

Fibonacci:
```json
{
    "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"
}
```

Hello World:
```json
[
    "DEBUG;THello, World!"
]
```

Guess Game:
```json
{
    "10": "RND;V100;V0",
    "20": "ADD;M0;M0;V1",
    "30": "DEBUG;TGuess a number between 1 and 100:",
    "40": "DEBINP;V3",
    "50": "PARSEINT;M3;V4",
    "60": "AQB;M4;M0;V200",
    "70": "ALB;M4;M0;V300",
    "80": "DEBUG;TToo high! Try again.",
    "90": "GOTO;V30",
    "200": "DEBUG;TCongratulations! You guessed the number!",
    "210": "GOTO;V9999",
    "300": "DEBUG;TToo low! Try again.",
    "310": "GOTO;V30"
}
```

### .svm2

Fibonacci:
```
# Fibonacci sequence calculator in SVM2 format
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
```

Hello World:
```
# Simple Hello World program in SVM2 format
10 DEBUG;Thello World
```

Graphics Example:
```
# Graphics example in SVM2 format
# This program demonstrates the new 2D graphics capabilities

10 DEBUG;T=== Graphics Example ===

20 DEBUG;T1. Creating GPU context...
30 GPU_CREATE;V800;V600;V100  # Create 800x600 GPU context
40 DEBUG;TGPU context created with ID:
50 DEBUG;M100

60 DEBUG;T

70 DEBUG;T2. Clearing screen with blue background...
80 GPU_CLEAR;M100;V0x0000FF  # Clear with blue color

90 DEBUG;T

100 DEBUG;T3. Drawing basic shapes...
110 GPU_DOT;M100;V100;V100;V0xFF0000  # Red dot at (100,100)
120 GPU_LINE;M100;V50;V50;V200;V200;V0x00FF00  # Green line from (50,50) to (200,200)
130 GPU_RECT;M100;V300;V200;V100;V80;V0xFF00FF  # Purple rectangle at (300,200) size 100x80
140 GPU_FILL_RECT;M100;V450;V200;V100;V80;V0xFFFF00  # Yellow filled rectangle at (450,200) size 100x80
150 GPU_CIRCLE;M100;V600;V200;V50;V0x00FFFF  # Cyan circle at (600,200) radius 50
160 GPU_FILL_CIRCLE;M100;V700;V200;V50;V0xFF00FF  # Purple filled circle at (700,200) radius 50

170 DEBUG;T

180 DEBUG;T4. Drawing text...
190 GPU_TEXT;M100;V100;V350;TSapbot VM Graphics Demo;V0xFFFFFF;V24  # White text at (100,350) size 24

200 DEBUG;T

210 DEBUG;T5. Displaying monitor information...
220 MONITOR_COUNT;V200  # Get monitor count
230 DEBUG;TNumber of monitors:
240 DEBUG;M200

250 MONITOR_RESOLUTION;V0;V201;V202  # Get primary monitor resolution
260 DEBUG;TPrimary monitor resolution:
270 DEBUG;M201
280 DEBUG;Tx
290 DEBUG;M202

300 DEBUG;T

310 DEBUG;T6. Displaying GPU context...
320 GPU_DISPLAY;M100  # Display the GPU context

330 DEBUG;T

340 DEBUG;T7. Saving GPU context to file...
350 GPU_SAVE;M100;Tgraphics_output.png  # Save to file

360 DEBUG;T=== Graphics Example Complete ===
370 GOTO;V9999  # End program
```

Guess Game:
```
# Number guessing game in SVM2 format
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
```

String Example:
```
# String manipulation example in SVM2 format
# This program demonstrates the new string manipulation instructions

10 DEBUG;T=== String Manipulation Example ===

20 DEBUG;T1. String Splitting Example:
30 STRSPLIT;Tapple,banana,orange;T,;V100  # Split string by comma
40 DEBUG;TResulting parts:
50 DEBUG;M100  # Print first part
60 DEBUG;M101  # Print second part
70 DEBUG;M102  # Print third part

80 DEBUG;T

90 DEBUG;T2. String Concatenation Example:
100 LOAD;V100;THello  # Store "Hello" in memory cell 100
110 LOAD;V101;T,  # Store "," in memory cell 101
120 LOAD;V102;Tworld  # Store "world" in memory cell 102
130 LOAD;V103;T!  # Store "!" in memory cell 103
140 STRCONCAT;V100;V4;V200  # Concatenate 4 strings starting at 100
150 DEBUG;TConcatenated result:
160 DEBUG;M200  # Print the concatenated string

170 DEBUG;T

180 DEBUG;T3. String to ASCII Conversion Example:
190 STRTOASCII;Thello;V300  # Convert "hello" to ASCII codes
200 DEBUG;TASCII codes for "hello":
210 DEBUG;M300  # Print first ASCII code
220 DEBUG;M301  # Print second ASCII code
230 DEBUG;M302  # Print third ASCII code
240 DEBUG;M303  # Print fourth ASCII code
250 DEBUG;M304  # Print fifth ASCII code

260 DEBUG;T

270 DEBUG;T4. ASCII to String Conversion Example:
280 ASCIITOSTR;V300;V5;V400  # Convert ASCII codes back to string
290 DEBUG;TConverted back to string:
300 DEBUG;M400  # Print the converted string

310 DEBUG;T=== Example Complete ===
320 GOTO;V9999  # End program
```

## Installing interpreter

1. Download and unzip somewhere [THIS](https://cows.info.gf/games/Openjs%20Nodejs/S/Sapbot%20VM%20v0.9.11%20(Unknown)%5BRomarchive%5D.zip)
2. Run in this folder `node run.js <software>.<svm/svm2/svmbin>`
Please note: if you want to run application with sdl, you will need to add `--sdl` flag (linux-only)
If you have some custom architecture, compile with gcc and SDL2 installed `sdl_viewer.c` to `sdl_viewer`

## Compiling to binary

Sapbot VM v0.9+ includes `compiler.js`, which compiles `.svm` and `.svm2` programs into `.svmbin` — a fully binary, compact format that loads significantly faster than the text-based formats.

Usage:
```
node compiler.js <input.svm|input.svm2> <output.svmbin>
node run.js <output.svmbin>
```

AI assistants should compile their programs to `.svmbin` for faster interpretation. The `.svmbin` format eliminates the need for text parsing on every load and is the recommended distribution format for Sapbot VM programs. See `SVMBIN.md` for the full format specification.
