///|
pub fn Primitive::name(self : Primitive) -> Symbol {
match self {
Normal(_, name~) => name
CallCC => Symbol::of("call/cc")
Apply => Symbol::of("apply")
}
}
///|
pub impl Show for Primitive with fn output(self, logger) {
logger
..write_string("#')
}
///|
pub impl Show for Closure with fn output(self, logger) {
match self.name {
None => logger.write_string("#")
Some(name) =>
logger..write_string("#')
}
}
// +---------------------------+
// | Value |
// +---------------------------+
///|
pub impl Default for Value with fn default() {
Value::symbol("done")
}
///|
pub fn Value::eq(self : Value, other : Value) -> Bool {
match (self, other) {
(Nil | True | False | Pair(_) | Int(_) | Double(_) | String(_), _) =>
physical_equal(self, other)
(Symbol(a), Symbol(b)) => Symbol::equal(a, b)
(Vector(a), Vector(b)) => physical_equal(a, b)
(Primitive(a), Primitive(b)) => physical_equal(a, b)
(Closure(a), Closure(b)) => physical_equal(a, b)
_ => false
}
}
///|
pub impl Eq for Value with fn equal(self, other) {
match (self, other) {
(Nil, Nil) | (True, True) | (False, False) => true
(Int(a), Int(b)) => Int::equal(a, b)
(Double(a), Double(b)) => Double::equal(a, b)
(Symbol(a), Symbol(b)) => Symbol::equal(a, b)
(String(a), String(b)) => String::equal(a, b)
(Primitive(a), Primitive(b)) => physical_equal(a, b)
(Closure(a), Closure(b)) => physical_equal(a, b)
(Pair(_), Pair(_)) | (Vector(_), Vector(_)) => recur_equal(self, other)
_ => false
}
}
///|
fn recur_equal(a : Value, b : Value) -> Bool {
// Todo: According to R7RS, equal must terminate
match (a, b) {
(Pair(la, ra), Pair(lb, rb)) => Value::equal(la, lb) && Value::equal(ra, rb)
(Vector(a), Vector(b)) => FixedArray::equal(a, b)
_ => panic()
}
}
///|
pub impl Show for Value with fn output(self, logger) {
match self {
Nil => logger.write_string("()")
Pair(l, r) => {
logger..write_char('(').write_object(l)
for r = r {
match r {
Nil => break logger.write_char(')')
Pair(l, r) => {
logger..write_char(' ').write_object(l)
continue r
}
v =>
break logger..write_string(" . ")..write_object(v).write_char(')')
}
}
}
Int(i) => logger.write_object(i)
Double(d) => logger.write_object(d)
True => logger.write_string("#t")
False => logger.write_string("#f")
Symbol(s) => logger.write_object(s)
String(s) => logger.write_object(s)
Primitive(prim) => logger.write_object(prim)
Closure(closure) => logger.write_object(closure)
Continuation(_) => logger.write_string("#")
Vector(a) => logger.write_iter(a.iter(), prefix="#(", sep=" ", suffix=")")
}
}
///|
pub impl Debug for Value with fn to_repr(self) {
Repr::opaque_("Value", Repr::literal(self.to_string()))
}
///|
pub fn Value::symbol(s : String) -> Value {
Value::Symbol(Symbol::of(s))
}
///|
pub fn Value::bool(b : Bool) -> Value {
match b {
true => True
false => False
}
}
///|
pub fn Value::list(vs : FixedArray[Value]) -> Value {
vs.rev_fold(init=Nil, (acc, x) => Pair(x, acc))
}
///|
pub fn Value::list_tail_and_length(self : Value) -> (Value, Int) {
for p = self, len = 0; p is Pair(_, r); {
continue r, len + 1
} nobreak {
(p, len)
}
}
///|
pub fn Value::unsafe_to_fixedarray(
self : Value,
length : Int,
) -> FixedArray[Value] {
let res = FixedArray::make(length, Value::default())
for i = 0, p = self; p is Pair(l, r); {
res[i] = l
continue i + 1, r
}
res
}