Skip to content

rafiyamo/pyraf-interpreter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyRaf

PyRaf is a Python-inspired interpreted language implemented in Python. It includes a complete language pipeline — lexer → Pratt parser → AST → interpreter — plus a bytecode compiler and stack-based VM and a disassembler.


Features

  • Lexer with line/column tracking, strings, numbers, keywords, and // comments
  • Pratt parser (expression precedence) producing an AST
  • AST interpreter with:
    • lexical scoping and block environments
    • if/else, while
    • user-defined functions + return
    • closures / nested functions
    • runtime error formatting + stack traces
  • Bytecode compiler (AST → bytecode)
  • Stack-based VM runtime (bytecode execution)
  • Disassembler (pyraf dis) to inspect emitted bytecode
  • Tests + CI: unit tests for lexer/parser/evaluator and VM tests
  • Imports/modules: import "path/file.raf"; with caching
  • Bytecode tooling: dis command and stack-based VM execution (run --vm)
  • Diagnostics: runtime errors include source context and call stack traces

Quickstart

Run a file (AST interpreter)

python -m pyraf.cli run examples/demo.raf

Run a file (bytecode VM)

python -m pyraf.cli run --vm examples/demo.raf

Disassemble to bytecode

python -m pyraf.cli dis examples/demo.raf

Start the REPL

python -m pyraf.cli repl

Language overview

Statements

Assignment

x = 3;

If / else

if (x >= 10) { print("ok"); } else { print("no"); }

While

i = 0;
while (i < 3) {
  print(i);
  i = i + 1;
}

Functions + return

def add(a, b) { return a + b; }
print(add(2, 5));

Closures / nested functions

def make_adder(x) {
  def add(y) { return x + y; }
  return add;
}

add5 = make_adder(5);
print(add5(3)); // 8

Imports (modules)

import "lib/math.raf";
print(square(9));

Expressions

  • Arithmetic: + - * / %
  • Comparisons: == != < <= > >=
  • Logical: and or not (short-circuiting in the compiler)
  • Calls: f(1, 2)
  • Lists + indexing: [10, 20, 30], lst[1]

Examples

  • examples/demo.raf — assignments, arithmetic, and if/else
  • examples/closure.raf — closures (nested function capturing outer variable)
  • examples/fizzbuzz.raf — loops and conditionals
  • examples/mandelbrot_ascii.raf — ASCII fractal demo

Run:

python -m pyraf.cli run examples/closure.raf
python -m pyraf.cli run --vm examples/closure.raf

Project structure

pyraf/
  lexer.py        # source -> tokens
  tokens.py       # token definitions
  parser.py       # tokens -> AST (Pratt parser)
  ast.py          # AST node definitions
  runtime.py      # environments + function objects
  interpreter.py  # AST execution + stack traces
  bytecode.py     # instruction model + disassembler
  compiler.py     # AST -> bytecode
  vm.py           # stack-based bytecode VM
  cli.py          # command-line interface (run/dis/repl)

tests/
  test_lexer.py
  test_parser.py
  test_eval.py    # AST interpreter tests
  test_vm.py      # VM execution tests

Running tests

python -m pytest

Notes on design

  • The AST interpreter is the reference execution model.
  • The bytecode VM executes compiled code using a simple stack machine.
  • Closures work by capturing the current lexical environment as a function’s closure.
  • Runtime errors are formatted with source context and include a lightweight stack trace.

About

PyRaf: a Python-inspired interpreter with a custom lexer, parser, AST, and REPL.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages