https://github.com/divs1210/toyvm
ToyVM: Bytecode VM for a simple lisp
https://github.com/divs1210/toyvm
bytecode-compiler bytecode-interpreter clojure lisp virtual-machine
Last synced: about 2 months ago
JSON representation
ToyVM: Bytecode VM for a simple lisp
- Host: GitHub
- URL: https://github.com/divs1210/toyvm
- Owner: divs1210
- License: other
- Created: 2020-12-05T12:55:47.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2020-12-27T19:21:39.000Z (over 4 years ago)
- Last Synced: 2025-01-16T21:52:22.199Z (3 months ago)
- Topics: bytecode-compiler, bytecode-interpreter, clojure, lisp, virtual-machine
- Language: Clojure
- Homepage:
- Size: 30.3 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ToyVM
**Bytecode VM for a simple lisp**
* At the REPL, all forms are converted to bytecode, which is interpreted
* Possible to AOT compile a lisp file to bytecode
* Possible to directly interpret a bytecode fileHeavily inspired by [this blogpost](https://bernsteinbear.com/blog/bytecode-interpreters/)
by **Max Bernstein** with the following changes:
* `lambda` is called `fn`
* `recfn` is for creating recursive lambdas
* `define` not required
* written in Clojure in a functional manner
* stackless evaluation using [xodarap](https://github.com/divs1210/xodarap)## Usage
### Start a REPL
$ rlwrap lein do clean, run
==================
=== ToyVM REPL ===
==================> (def dec
(fn (x)
(- x 1)))
nil> (dec 43)
42### Compile to bytecode
Compile the example file:
$ cat factorial.edn
[(def dec
(fn (n)
(- n 1)))(def fact
(recfn fact (n)
(if (< n 2)
1
(* n (fact (dec n))))))(print (fact 5))
]
$ lein bcompile factorial.edn
$ cat out.edn
[[:push-const (n)]
[:push-const
[[:push-name -]
[:push-name n]
[:push-const 1]
[:call-function 2]]]
[:make-function 1]
[:store-name dec]
[:push-const fact]
[:push-const (n)]
[:push-const
[[:push-name <]
[:push-name n]
[:push-const 2]
[:call-function 2]
[:relative-jump-if-true 9]
[:push-name *]
[:push-name n]
[:push-name fact]
[:push-name dec]
[:push-name n]
[:call-function 1]
[:call-function 1]
[:call-function 2]
[:relative-jump 1]
[:push-const 1])]
[:make-recursive-function 1]
[:store-name fact]
[:push-name print]
[:push-name fact]
[:push-const 5]
[:call-function 1]
[:call-function 1]]### Run bytecode file
Interpret the compiled output:
$ lein binterpret out.edn
120### Compile and run in one go
$ lein do clean, bcompile factorial.edn, binterpret out.edn
120## License
Copyright © 2020 Divyansh Prakash
This program and the accompanying materials are made available under the
terms of the Eclipse Public License 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0.This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the Eclipse
Public License, v. 2.0 are satisfied: GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or (at your
option) any later version, with the GNU Classpath Exception which is available
at https://www.gnu.org/software/classpath/license.html.