Skip to content

Repository files navigation

Eva VM

A stack based bytecode virtual machine for the Eva programming language, implemented in Python using a functional programming approach like Lisp (no classes/OOP in the VM).

Overview

This is a complete rewrite of the Eva VM from C++ to Python, using:

  • Dictionaries and lists instead of classes
  • Pure functions instead of methods
  • Functional composition for program flow
  • Simple, readable code structure

Architecture

Core Components

  1. eva_value.py - Value system (numbers, booleans, strings, objects)
  2. opcodes.py - Bytecode instruction definitions
  3. parser.py - S-expression parser
  4. scope.py - Lexical scope analysis
  5. compiler_helpers.py - Helper functions for compilation
  6. compiler.py - AST to bytecode compiler
  7. vm.py - Virtual machine and execution engine
  8. eva-vm.py - Main entry point

Features

  • Arithmetic operations (+, -, *, /)
  • Comparison operations (<, >, ==, >=, <=, !=)
  • Variables (global and local)
  • Functions and closures
  • Control flow (if, while)
  • Classes and inheritance
  • Object properties
  • Lexical scoping with cells (for closures)

Installation

No installation required! Just needs Python 3.6+

chmod +x eva-vm.py

Usage

Run an expression:

python3 eva-vm.py -e "(+ 1 2)"

Run a file:

python3 eva-vm.py -f test.eva

Show bytecode disassembly:

python3 eva-vm.py -e "(def square (x) (* x x)) (square 5)" -d

Eva Language Examples

1. Basic Arithmetic

(+23) ; => 5
(* (+23) 4) ; => 20

2. Variables

(var x 10)
(var y 20)
(+ x y) ; => 30

3. Functions

(def square (x)
(* x x))
(square 5) ; => 25

4. Closures

(def makeCounter (start)
(begin
(var count start)
(lambda ()
(begin
(setcount (+count1))
count))))
(var counter (makeCounter 0))
(counter) ; => 1
(counter) ; => 2
(counter) ; => 3

5. Control Flow

; If statement
(if (>105)
"yes""no") ; => "yes"; While loop
(var i 0)
(while (< i 5)
(set i (+ i 1))) ; i becomes 5

6. Classes and Inheritance

(class Point null
(def constructor (self x y)
(begin
(set (prop self x) x)
(set (prop self y) y)))
(def calc (self)
(+ (prop self x) (prop self y))))
(class Point3D Point
(def constructor (self x y z)
(begin
((prop (super Point3D) constructor) self x y)
(set (prop self z) z)))
(def calc (self)
(+ ((prop (super Point3D) calc) self) (prop self z))))
(var p (new Point3D 102030))
((prop p calc) p) ; => 60

How It Works

1. Parsing

The parser converts S-expressions into a simple AST:

  • Numbers → integers
  • Strings → strings (without quotes)
  • Symbols → strings
  • Lists → Python lists

2. Scope Analysis

Before compilation, the analyzer:

  • Identifies all variable declarations
  • Determines variable allocation (global, local, or cell)
  • Promotes captured variables to heap-allocated cells
  • Tracks free variables for closures

3. Compilation

The compiler walks the AST and:

  • Generates bytecode instructions
  • Builds constant pools
  • Creates code objects for functions
  • Handles lexical scoping

4. Execution

The VM:

  • Uses a stack for operands and local variables
  • Uses a call stack for function frames
  • Executes bytecode instructions sequentially
  • Manages closures via heap-allocated cells

Value Representation

All values are dictionaries with a 'type' field:

# Number
{'type': 'NUMBER', 'value': 42}
# Boolean
{'type': 'BOOLEAN', 'value': True}
# String object
{'type': 'OBJECT', 'obj_type': 'STRING', 'value': 'hello'}
# Function object
{'type': 'OBJECT', 'obj_type': 'FUNCTION', 'code': {...}, 'cells': [...]}

Bytecode Instructions

The VM uses a compact bytecode format:

OpcodeNameDescription
0x00HALTStop execution
0x01CONSTPush constant
0x02ADDAdd two values
0x03SUBSubtract
0x04MULMultiply
0x05DIVDivide
0x06COMPARECompare values
0x07JMP_IF_FALSEConditional jump
0x08JMPUnconditional jump
0x09GET_GLOBALGet global variable
0x0ASET_GLOBALSet global variable
0x0BPOPPop stack
0x0CGET_LOCALGet local variable
0x0DSET_LOCALSet local variable
0x0ESCOPE_EXITClean up scope
0x0FCALLCall function
0x10RETURNReturn from function
0x11GET_CELLGet cell variable
0x12SET_CELLSet cell variable
0x13LOAD_CELLLoad cell for closure
0x14MAKE_FUNCTIONCreate closure
0x15NEWCreate instance
0x16GET_PROPGet property
0x17SET_PROPSet property

Key Design Decisions

1. No Classes/OOP

Instead of classes, we use:

  • Dictionaries for structured data
  • Functions for operations
  • Closures for encapsulation

2. Explicit State Passing

VM state is explicitly passed to functions:

defpush(vm, value):
vm['stack'][vm['sp']] =valuevm['sp'] +=1

3. Functional Composition

Complex operations are built from simple functions:

defgen(state, exp):
ifis_number_ast(exp):
emit(state['co'], OP_CONST)
emit(state['co'], alloc_numeric_const(state['co'], exp))

4. Immutable Constants

The original C++ code uses static constants. In Python, we use module-level constants:

OP_HALT=0x00OP_CONST=0x01# ...

Testing

# Simple math
python3 eva-vm.py -e "(+ 2 3)"# Output: 5# Functions
python3 eva-vm.py -e "(def square (x) (* x x)) (square 5)"# Output: 25# Factorial
python3 eva-vm.py -f examples/factorial.eva
# Output: 120# Closures
python3 eva-vm.py -f examples/closure.eva
# Output: 13# Fibonacci
python3 eva-vm.py -f examples/fibonacci.eva
# Output: 55# Classes
python3 eva-vm.py -f examples/class.eva
# Output: 50# Class inheritance (original test)
python3 eva-vm.py -f test.eva
# Output: 60

Run the test file:

python3 eva-vm.py -f test.eva

Should output: 60

Run with disassembly to see bytecode:

python3 eva-vm.py -f test.eva -d

Performance

This implementation prioritizes:

  1. Readability over performance
  2. Simplicity over optimization
  3. Learning over production use

For production use, consider:

  • PyPy for JIT compilation
  • Cython for C-level performance
  • Or stick with the original C++ version

Credits

Based on the Eva VM course by Dmitry Soshnikov: http://dmitrysoshnikov.com/courses/virtual-machine/

Original C++ implementation: https://github.com/DmitrySoshnikov/eva-vm

Pwn College Yan85 emulator from it's Reverse Engineering Dojo.


About

A stack based bytecode Virtual Machine.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages