scheme

A Scheme interpreter implemented in Moonbit for teaching purposes

scheme
s-expression
interpreter
moon add FlyCloudC/scheme@0.7.0
Download zip
Author
Version
0.7.0
License
Apache-2.0
Last updated
12 days ago
Downloads
35

Dependencies

README

#FlyCloudC/scheme

A Scheme interpreter implemented in Moonbit. It will be used for teaching purposes and not too many optimizations will be added. The understandability of the code is given top priority.

Reference:

#example

///|
test {
let env = Environment::base()
env.define_vars(number_primitive)
let code =
#|(define (fact x)
#| (if (= x 0)
#| 1 ; base case
#| (* x (fact (- x 1))))) ; rec case
#|(fact 5)
let sexp : Array[Value] = parse(code)
let program : Array[CoreForm] = sexp.map(Value::to_core_form)
let inst : Array[Inst] = program.map(compile)

// make VM, load "(define (fact x) ...)" and env
let vm = VM::new(inst=inst[0], env~)

// run, add "fact" to env
vm.run_to_halt()
inspect(
vm.env.lookup(@symbol.Symbol::of("fact")),
content="#<procedure fact>",
)

// load and run "(fact 5)"
vm.next = inst[1]
vm.run_to_halt()
inspect(vm.acc, content="120")
}

#FlyCloudC/scheme

A Scheme interpreter implemented in Moonbit. It will be used for teaching purposes and not too many optimizations will be added. The understandability of the code is given top priority.

Reference:

#example

///|
test {
let env = Environment::base()
env.define_vars(number_primitive)
let code =
#|(define (fact x)
#| (if (= x 0)
#| 1 ; base case
#| (* x (fact (- x 1))))) ; rec case
#|(fact 5)
let sexp : Array[Value] = parse(code)
let program : Array[CoreForm] = sexp.map(Value::to_core_form)
let inst : Array[Inst] = program.map(compile)

// make VM, load "(define (fact x) ...)" and env
let vm = VM::new(inst=inst[0], env~)

// run, add "fact" to env
vm.run_to_halt()
inspect(
vm.env.lookup(@symbol.Symbol::of("fact")),
content="#<procedure fact>",
)

// load and run "(fact 5)"
vm.next = inst[1]
vm.run_to_halt()
inspect(vm.acc, content="120")
}

#
FromSexp

pub(open) trait FromSexp {
#as_free_fn
fn from_sexp(Value) -> Self raise FromSexpError
}

impl FromSexp for Json

#
ToSexp

pub(open) trait ToSexp {
#as_free_fn
fn to_sexp(Self) -> Value
}

impl ToSexp for Bool
impl ToSexp for Int
impl ToSexp for Double
impl ToSexp for String
impl ToSexp for FixedArray[A]
impl ToSexp for Array[A]
impl ToSexp for Iter2[A, B]
impl ToSexp for Json
impl ToSexp for Tuple2[A, B]

#
FromSexpError

pub(all) suberror FromSexpError {
FromSexpError(Value)
} derive(
Debug
)

#
ParseException

pub suberror ParseException {
UnexpectedToken(
Token
)
MoreThanOneAfterDot(
Token
)
UnexpectedEndOfInput
ReadException(
ReadException
)
} derive(
Debug
)

#
SchemeException

pub(all) suberror SchemeException {
UndefineVar(
Symbol
)
CallNonProcedure
ArgumentCount
TypeError(Int)
InvalidArgument(Int)
DevideZero
} derive(
Debug
)

#
SyntaxError

type SyntaxError

#
Closure

pub struct Closure {
env : Environment
parm_names : FixedArray[
Symbol
]
body : Inst
name :
Symbol
?
}

impl Show for Closure

#
CoreForm

impl ToSexp for CoreForm

#
CoreForm::compile

#as_free_fn
fn CoreForm::compile(self : CoreForm) -> Inst

#
Environment

pub(all) struct Environment {
binds :
HashMap
[
Symbol
, Value]
next : Environment?
closure : Closure?
}

impl Show for Environment

#
Environment::base

fn Environment::base() -> Environment

#
Environment::define_var

fn Environment::define_var(self : Environment, name :
Symbol
, new_value : Value) -> Unit

#
Environment::define_vars

fn Environment::define_vars(self : Environment, name_value : ReadOnlyArray[(
Symbol
, Value)]) -> Unit

#
Environment::extend_

fn Environment::extend_(self : Environment, names : FixedArray[
Symbol
], values : FixedArray[Value], closure : Closure) -> Environment

#
Environment::lookup

#
Environment::set_var

fn Environment::set_var(self : Environment, name :
Symbol
, new_value : Value) -> Unit raise SchemeException

#
Frame

pub struct Frame {
ret : Inst
env : Environment
rib : FixedArray[Value]
stack : Frame?
}

#
Inst

pub enum Inst {
Const(Value, Inst)
Refer(
Symbol
, Inst)
Return
Close(FixedArray[
Symbol
], Inst,
Symbol
?, Inst)
Branch(Inst, Inst)
Save(Inst, Inst)
Args(Int, Inst)
Push(Int, Inst)
Apply
Set(
Symbol
, Inst)
Define(
Symbol
, Inst)
}

#
Primitive

pub(all) enum Primitive {
Normal(name~ :
Symbol
, (FixedArray[Value]) -> Value raise SchemeException)
CallCC
Apply
}

impl Show for Primitive

#
Primitive::name

pub(all) struct VM {
acc : Value
next : Inst
env : Environment
rib : FixedArray[Value]
stack : Frame?
}

#
VM::new

fn VM::new(inst? : Inst, env? : Environment) -> VM

#
VM::run_one_step

fn VM::run_one_step(vm : VM) -> Unit raise SchemeException

#
VM::run_to_halt

fn VM::run_to_halt(vm : VM) -> Unit raise SchemeException

#
Value

pub(all) enum Value {
Nil
True
False
Pair(Value, Value)
Int(Int)
Double(Double)
Symbol(
Symbol
)
String(String)
Vector(FixedArray[Value])
Primitive(Primitive)
Closure(Closure)
Continuation(Frame?)
}

impl ToSexp for Value
impl Default for Value
impl Eq for Value
impl Show for Value

#
Value::bool

fn Value::bool(b : Bool) -> Value

#
Value::eq

fn Value::eq(self : Value, other : Value) -> Bool

#
Value::list

fn Value::list(vs : FixedArray[Value]) -> Value

#
Value::list_tail_and_length

fn Value::list_tail_and_length(self : Value) -> (Value, Int)

#
Value::symbol

fn Value::symbol(s : String) -> Value

#
Value::to_core_form

fn Value::to_core_form(self : Value) -> CoreForm raise FromSexpError

#
Value::unsafe_to_fixedarray

fn Value::unsafe_to_fixedarray(self : Value, length : Int) -> FixedArray[Value]

#
all_base_primitive

let all_base_primitive : ReadOnlyArray[(
Symbol
, Value)]

#
number_primitive

let number_primitive : ReadOnlyArray[(
Symbol
, Value)]

number?

+, -, *, /

=, >, <

#
other_primitive

let other_primitive : ReadOnlyArray[(
Symbol
, Value)]

eq?, procedure?, symbol?

call/cc, apply

#
pair_primitive

let pair_primitive : ReadOnlyArray[(
Symbol
, Value)]

cons, car, cdr

null?, pair?

#
parse

fn parse(code : StringView) -> Array[Value] raise ParseException

#
string_primitive

let string_primitive : ReadOnlyArray[(
Symbol
, Value)]

string?, string-append, string->symbol

symbol->string, number->string, value->string

#
vector_primitive

let vector_primitive : ReadOnlyArray[(
Symbol
, Value)]

vector, vector?, make-vector, vector-length

vector-ref, vector-set!

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io