https://github.com/crowdagger/rscheme
A toy scheme interpreter written in Rust
https://github.com/crowdagger/rscheme
Last synced: about 1 year ago
JSON representation
A toy scheme interpreter written in Rust
- Host: GitHub
- URL: https://github.com/crowdagger/rscheme
- Owner: crowdagger
- License: gpl-2.0
- Created: 2015-05-22T18:37:49.000Z (about 11 years ago)
- Default Branch: master
- Last Pushed: 2015-05-27T20:26:08.000Z (about 11 years ago)
- Last Synced: 2025-01-11T19:14:07.002Z (over 1 year ago)
- Language: Rust
- Size: 273 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
README
# rscheme
A toy scheme interpreter written in Rust.
Dependencies
------------
You'll need the Rust compiler and
Cargo. [See there](http://www.rust-lang.org/install.html).
Usage
-----
`$ cargo run`
should build and run rscheme. Running the program just launches a
pseudo-scheme REPL, then you can enter (pseudo-)scheme code.
The file `data/init.scm` is loaded when `rscheme` is launched. If you
run it from another directory, it won't work as well and you'll miss
some features.
Features
--------
### Numbers ###
Integers and Floats only (corresponding to `i64` and `f64`
respectively).
`_+`, `_-`, `_*`, `_/`, `_=` are builtin; `init.scm` also provides
wrappers `+`, `-`, `*`, `/`, `=`. This is so these functions can be
used as first class functions (which isn't possible for primitives).
### List ###
Building a list is possible either with `cons` or `'`.
`car` and `cdr` are also available.
### Lambdas ###
`(lambda (args) body)`
Body can only be one expression.
### def ###
Def is a builtin primitive allowing to map variables to values:
`(def x 42)`
`(def f (lambda (x) (* 2 x)))`
`(f x) ; returns 84`
There is also the more standard `(define (name arg1 ... argn) expr1
... exprn)`, but it is implemented via a macro.
### Macros ###
There is support for macros. E.g., `if` is a builtin, but `cond`
isn't. So let's implement it:
```scheme
(defmacro cond (preds)
`(if ,(car (car preds))
,(cadr (car preds))
,(if (nil? (cdr preds))
()
`(cond ,(cdr preds)))))
```
### Let ###
Another example of macro usage is the definition of `let`, which isn't a
primitive but is built as a macro. So
```scheme
(let ((x 2)
(y 3))
(+ x y))
```
will be expanded to:
```scheme
((lambda (x y) (+ x y)) 2 3)
```
Variadic arguments
-------------------
It is possible to define functions taking an arbitrary number of
arguments. Syntax is a bit different than classic Scheme, though it is
roughly the same principle:
```scheme
(define (f x1 x2 &xs)
(println x1)
(println x2)
(println xs))
```
`(f 1 2 3 4 5)` will print `1`, `2`, and `(3 4 5)` (on different
lines).
It's the same syntax for declaring as first parameter in lambdas:
`(lambda (& args) (println args)`
Input/output
------------
There is one print primitive, called `_print`. The function `println`
uses it, as can other functions do. It simply prints a string to
standard output.
There is not yet support of input.
Not implemented (yet?)
----------------------
* input
* including another file
Well, it's only a toy project, to learn Rust, right ? You want some
real Scheme/Lisp interpreter, there's plenty to find :)
License
--------
GNU General Public License, 2 or later. [See license.](LICENSE)
ChangeLog
---------
Current version is 1.0.0. [See ChangeLog.](ChangeLog.md)