Skip to content

Latest commit

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

TinyVM

An MVP stack-based bytecode VM

This VM runs a simplistic, Turing complete instruction set.

In ~250 LOC with extensive comments, it's meant to be simple to understand and easily reproducible in languages other than Rust.

It also includes a rudimentary compiler which can execute programs in the test_files folder.

Instructions

InstructionDescription
Push (isize)Pushes the argument to the top of the stack
PopRemoves the value on top of the stack
AddPops the top two values and pushes their sum
SubPops the top two values and pushes their difference
MulPops the top two values and pushes their product
DivPops the top two values and pushes their quotient
Jump (label)Sets the instruction pointer to the label
JNE (label)Jumps if the top of the stack is not zero
JE (label)Jumps if the top of the stack is zero
JGT (label)Jumps if the top of the stack is greater than zero
JLT (label)Jumps if the top of the stack is less than zero
JGE (label)Jumps if the top of the stack is greater than or equal to zero
JLE (label)Jumps if the top of the stack is less than or equal to zero
Call (procedure)Calls a procedure, setting the stack offset to the current s stack length
Get (usize)Gets index of the stack and copies it to the top
Set (usize)Copies value at the top of the stack to the index
GetArg (usize)Gets nth argument from top of callstack stack offset, used for procedures
SetArg (usize)Sets nth argument from top of callstack stack offset, used for procedures
NoopDoesn't do anything, used by comments to keep instruction pointers correspondent to lines
PrintPrints value at the top of the stack as an integer
PrintCPrints value at the top of the stack as an ASCII character
PrintStackPrints the whole stack, used mostly for debugging

You can also set a label with the line label $name, and you can declare a procedure by using Proc $name, Ret, and End. See test_files/procedure.bytecode or test_files/fib_recurse.bytecode for more details.

Examples

In test_files/:

hello_world.bytecode prints "Hello World"

sum.bytecode prints the sum of all integers from 0 to 100

fib.bytecode prints the first 40 fibonacci numbers

fib_recurse.bytecode recursively calculates 35th fibonacci number

Sum

Push 0
Push 0
label loop
-- [accumulator, index]
Get 0
Get 1
-- [accumulator, index, accumulator, index]
Add
-- [accumulator, index, accumulator + index]
Set 0
Pop
-- [accumulator + index, index]
-- [accumulator, index]
Incr
-- [accumulator, index + 1]
-- [accumulator, index]
Get 1
Push 100
Sub
-- [accumulator, index, index - 100]
JNE loop
Pop
Get 0
Print
Push 10
PrintC
> cargo run --release sum.bytecode
4950
>

About

An MVP stack VM

Resources

Stars

106 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages