Interpreter for the Racket programming language written in Rust.
cargo run <filename>
Rusty Racket is a Turing complete purely functional language. The name comes from the fact that its interpreter is written in Rust. Rusty Racket is a dialect of the programming language Racket which is a dialect of Scheme which is a dialect of Lisp.
The language includes essential features such as conditionals, user-defined functions, lists, and more. It also comes with a standard library that offers built-in numerical and list functions.
The interpreter is created using a conventional approach. The process is as follows:
- Preprocessor: Resolves module includes.
- Tokenizer: Converts the program string into a list of tokens.
- Parser: Transforms the tokens into an abstract syntax tree.
- Interpreter: Evaluates the abstract syntax tree to produce the final result.
All of these examples and more can be found in the /examples
folder
Fibonacci: computes the nth Fibonacci number.
(define (fibonacci n)
(cond
[(= n 0) 0]
[(= n 1) 1]
[true (+ (fibonacci (- n 1)) (fibonacci (- n 2)))]))
(define (main) (fibonacci 10)) ; produces 55
List Sum: computes the sum of the elements of a list.
(define (list-sum lst)
(cond
[(empty? lst) 0]
[true (+ (car lst) (list-sum (cdr lst)))]))
(define (main) (list-sum (list 1 2 3 4 5))) ; produces 15
List Sort: sorts a given list using merge sort.
(include stdlib::list)
(define (__list::sorted-merge-helper lst1 lst2 acc)
(cond
[(empty? lst1) (list::append (list::reverse acc) lst2)]
[(empty? lst2) (list::append (list::reverse acc) lst1)]
[(< (car lst1) (car lst2)) (__list::sorted-merge-helper (cdr lst1) lst2 (cons (car lst1) acc))]
[true (__list::sorted-merge-helper lst1 (cdr lst2) (cons (car lst2) acc))]))
(define (__list::sorted-merge lst1 lst2) (__list::sorted-merge-helper lst1 lst2 empty))
(define (list::sort lst)
(cond
[(| (empty? lst) (empty? (cdr lst))) lst]
[(empty? (cdr (cdr lst)))
(__list::sorted-merge (list (car lst)) (cdr lst))]
[true
(__list::sorted-merge (list::sort (list::take lst (/ (list::length lst) 2)))
(list::sort (list::drop lst (/ (list::length lst) 2))))]))
(define (main) (list::sort (list 5 1 4 2 3))) ; produces (list 1 2 3 4 5)
A program consists of module includes and function definitions. One of the functions must be named main and take no arguments. The result of the program is the output produced by executing the main function.
There are 2 available standard library modules: stdlib::num
and stdlib::list
.
(include stdlib::num)
(include stdlib::list)
Since Rusty Racket is purely functional, every function returns exactly one value and produces no side effects.
(define (<function name> ...arguments) <result>)
(define (add a b) (+ a b))
Available numerical operators are +
, -
, /
, *
, and %
(modulo).
Available boolean operators are |
(or), &
(and), !
(not), =
, <
, and >
.
(define (main) (+ 1 2)) ; 3
(define (main) (| true false)) ; true
(define (main) (< 5 10)) ; true
The conditional expression works the same as in Racket. To create an else branch, the condition true
can be used.
(cond
[condition1 expression1]
[condition2 expression2]
[condition3 expression3]
...)
(define (max a b)
(cond
[(> a b) a] ; if a > b, return a
[true b])) ; else return b
As with other functional programming languages, lists are linked lists with a head and rest. The empty list is represented by empty
. Lists can be constructed in 2 ways. Using the list
function or with cons
.
(list 1 2 3)
(cons 1 (cons 2 (cons 3 empty)))
To get the head of the list, use car
. To get the rest of the list use cdr
.
(car (list 1 2 3)) ; produces 1
(cdr (list 1 2 3)) ; produces (list 2 3)
To determine if a list is empty, use the empty?
function.
(empty? empty) ; true
(empty? (list 1 2 3)) ; false
To determine if a value is a list, use the list?
function.
(list? (list 1 2 3)) ; true
(list? 1) ; false
- Add support for comments
- Add more helpers for nums and bools to alias operations like add, or lteq, gteq
- Create a let* statement or with statemement that supports (with ([x 1] [y (+ x 1)] y))
- Support functions as first class citizens
- Implement closures
- Let functions be returned from other functions
- Let functions be a parameter into another function
- Support command line arguments into the rusty racket programs
- Variadic functions
- If there is exactly a single argument using the keyword argslist