mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 01:05:32 +01:00
Removed MalType::Bool
mplemented instead MalType::T as opposed to Maltype::Nil
This commit is contained in:
@ -1,11 +1,15 @@
|
||||
;; Previously in core.rs
|
||||
; Logic
|
||||
|
||||
; Just to keep them if someone uses them
|
||||
(def! true t)
|
||||
(def! false nil)
|
||||
|
||||
; Identity function
|
||||
(def! I (fn* [x] x))
|
||||
|
||||
(def! not (fn* [x]
|
||||
(if x nil true)))
|
||||
(if x nil t)))
|
||||
|
||||
(def! and (fn* [a b]
|
||||
(if a
|
||||
@ -152,10 +156,10 @@
|
||||
|
||||
(def! reverse (fn* [x]
|
||||
"Reverses order of elements in the arg"
|
||||
(def! reverse-r (fn* [x t]
|
||||
(def! reverse-r (fn* [x e]
|
||||
(if (empty? x)
|
||||
t
|
||||
(reverse-r (cdr x) (cons (car x) t)))))
|
||||
e
|
||||
(reverse-r (cdr x) (cons (car x) e)))))
|
||||
(reverse-r x '())))
|
||||
|
||||
(def! map (fn* [f l]
|
||||
@ -171,8 +175,8 @@
|
||||
(def! filter-r (fn* [l p]
|
||||
(if (empty? l)
|
||||
p
|
||||
(if (f (def! t (car l)))
|
||||
(filter-r (cdr l) (cons t p))
|
||||
(if (f (def! e (car l)))
|
||||
(filter-r (cdr l) (cons e p))
|
||||
(filter-r (cdr l) p)))))
|
||||
(reverse (filter-r l '()))))
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ pub fn arithmetic_op(set: isize, f: fn(isize, isize) -> isize, args: &[MalType])
|
||||
}))
|
||||
}
|
||||
|
||||
use MalType::{Bool, Nil};
|
||||
use MalType::{Nil, T};
|
||||
pub fn comparison_op(f: fn(isize, isize) -> bool, args: &[MalType]) -> MalRet {
|
||||
if args.is_empty() {
|
||||
return Ok(Nil);
|
||||
@ -184,7 +184,7 @@ pub fn comparison_op(f: fn(isize, isize) -> bool, args: &[MalType]) -> MalRet {
|
||||
}
|
||||
left = right;
|
||||
}
|
||||
Ok(Bool(true))
|
||||
Ok(T)
|
||||
}
|
||||
|
||||
pub fn car(list: &[MalType]) -> Result<&MalType, MalErr> {
|
||||
|
||||
@ -104,7 +104,7 @@ fn if_form(list: &[MalType], env: Env) -> MalRet {
|
||||
}
|
||||
let (cond, branches) = car_cdr(list)?;
|
||||
Ok(match eval(cond, env.clone())? {
|
||||
M::Nil | M::Bool(false) => match branches.len() {
|
||||
M::Nil => match branches.len() {
|
||||
1 => M::Nil,
|
||||
_ => branches[1].clone(),
|
||||
},
|
||||
@ -195,7 +195,7 @@ pub fn eval(ast: &MalType, env: Env) -> MalRet {
|
||||
NAME_OK => {
|
||||
return match eval(car(args)?, env.clone()) {
|
||||
Err(_) => Ok(M::Nil),
|
||||
_ => Ok(M::Bool(true)),
|
||||
_ => Ok(M::T),
|
||||
}
|
||||
}
|
||||
// Special form, sad
|
||||
|
||||
@ -14,10 +14,10 @@ fn key_str(val: &str) -> MalType {
|
||||
pub fn pr_str(ast: &MalType, print_readably: bool) -> String {
|
||||
match ast {
|
||||
M::Nil => "NIL".to_string(),
|
||||
M::T => "t".to_string(),
|
||||
M::Sym(sym) => sym.to_string(),
|
||||
M::Key(sym) => sym[2..].to_string(),
|
||||
M::Int(val) => val.to_string(),
|
||||
M::Bool(val) => val.to_string(),
|
||||
M::Str(str) => {
|
||||
if print_readably {
|
||||
escape_str(str)
|
||||
|
||||
@ -92,8 +92,7 @@ impl Reader {
|
||||
fn read_atom(&self) -> MalRet {
|
||||
match &self.next()?[..] {
|
||||
")" | "]" | "}" => Err(MalErr::unrecoverable("Missing open parenthesis")),
|
||||
"false" => Ok(Bool(false)),
|
||||
"true" => Ok(Bool(true)),
|
||||
"t" => Ok(T),
|
||||
"nil" => Ok(Nil),
|
||||
tk => {
|
||||
if Regex::new(r"^-?[0-9]+$").unwrap().is_match(tk) {
|
||||
@ -269,10 +268,10 @@ mod tests {
|
||||
#[test]
|
||||
fn read_atom() {
|
||||
let r = Reader::new();
|
||||
r.push("nil 1 true a \"s\" :a ) ] }");
|
||||
r.push("nil 1 t a \"s\" :a ) ] }");
|
||||
assert!(matches!(r.read_atom(), Ok(x) if matches!(x, M::Nil)));
|
||||
assert!(matches!(r.read_atom(), Ok(x) if matches!(x, M::Int(1))));
|
||||
assert!(matches!(r.read_atom(), Ok(x) if matches!(x, M::Bool(true))));
|
||||
assert!(matches!(r.read_atom(), Ok(x) if matches!(x, M::T)));
|
||||
assert!(
|
||||
matches!(r.read_atom(), Ok(x) if matches!(x.clone(), M::Sym(v) if matches!(v.borrow(), "a")))
|
||||
);
|
||||
@ -314,7 +313,7 @@ mod tests {
|
||||
r.clear();
|
||||
|
||||
// Test map
|
||||
r.push("{\"i\" 1 \"s\" \"str\" \"t\" true \"n\" nil :s :sym}");
|
||||
r.push("{\"i\" 1 \"s\" \"str\" \"t\" t \"n\" nil :s :sym}");
|
||||
let t = match read_str(&r) {
|
||||
Ok(x) => match x {
|
||||
M::Map(x) => x,
|
||||
@ -329,7 +328,7 @@ mod tests {
|
||||
}
|
||||
};
|
||||
assert!(matches!(t.get("n"), Some(x) if matches!(&x, M::Nil)));
|
||||
assert!(matches!(t.get("t"), Some(x) if matches!(&x, M::Bool(v) if *v)));
|
||||
assert!(matches!(t.get("t"), Some(x) if matches!(&x, M::T)));
|
||||
assert!(matches!(t.get("i"), Some(x) if matches!(&x, M::Int(v) if *v == 1)));
|
||||
assert!(
|
||||
matches!(t.get("s"), Some(x) if matches!(&x, M::Str(v) if matches!(v.borrow(), "str")))
|
||||
|
||||
18
src/types.rs
18
src/types.rs
@ -25,9 +25,9 @@ pub enum MalType {
|
||||
Str(MalStr),
|
||||
Ch(char),
|
||||
Int(isize),
|
||||
Bool(bool),
|
||||
Atom(Rc<RefCell<MalType>>),
|
||||
Nil,
|
||||
T,
|
||||
}
|
||||
|
||||
impl Default for &MalType {
|
||||
@ -86,7 +86,7 @@ impl MalType {
|
||||
Key(("ʞ:".to_owned()
|
||||
+ match self {
|
||||
M::Nil => "nil",
|
||||
M::Bool(_) => "bool",
|
||||
M::T => "t",
|
||||
M::Int(_) => "int",
|
||||
M::Fun(_, _) | M::MalFun { .. } => "lambda",
|
||||
M::Key(_) => "key",
|
||||
@ -108,7 +108,7 @@ use crate::types::MalType as M;
|
||||
fn mal_compare(args: (&MalType, &MalType)) -> bool {
|
||||
match (args.0, args.1) {
|
||||
(M::Nil, M::Nil) => true,
|
||||
(M::Bool(a), M::Bool(b)) => a == b,
|
||||
(M::T, M::T) => true,
|
||||
(M::Int(a), M::Int(b)) => a == b,
|
||||
(M::Ch(a), M::Ch(b)) => a == b,
|
||||
(M::Key(a), M::Key(b)) | (M::Str(a), M::Str(b)) | (M::Sym(a), M::Sym(b)) => a == b,
|
||||
@ -120,13 +120,17 @@ fn mal_compare(args: (&MalType, &MalType)) -> bool {
|
||||
}
|
||||
|
||||
pub fn mal_equals(args: &[MalType]) -> MalRet {
|
||||
Ok(M::Bool(match args.len() {
|
||||
0 => true,
|
||||
Ok(match args.len() {
|
||||
0 => M::T,
|
||||
_ => {
|
||||
let (car, cdr) = car_cdr(args)?;
|
||||
cdr.iter().all(|x| mal_compare((car, x)))
|
||||
if cdr.iter().all(|x| mal_compare((car, x))) {
|
||||
M::T
|
||||
} else {
|
||||
M::Nil
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reset_bang(args: &[MalType]) -> MalRet {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
(assert true)
|
||||
(assert t)
|
||||
(assert (ok? 1))
|
||||
(assert-eq nil (ok? (1)))
|
||||
(assert-eq true (ok? 1))
|
||||
(assert (ok? (assert true)))
|
||||
(assert-eq t (ok? 1))
|
||||
(assert (ok? (assert t)))
|
||||
(assert (not (ok? (assert nil))))
|
||||
(assert (not (ok? (assert-fail '1))))
|
||||
(assert-fail '(1))
|
||||
|
||||
@ -8,13 +8,13 @@
|
||||
|
||||
; nil
|
||||
(assert (= nil nil))
|
||||
(assert (not (= nil true)))
|
||||
(assert (not (= nil t)))
|
||||
(assert (not (= nil 1)))
|
||||
|
||||
; bool
|
||||
(assert (= true true))
|
||||
(assert (not (= false true)))
|
||||
(assert (not (= true 1)))
|
||||
(assert (= t t))
|
||||
(assert (not (= nil t)))
|
||||
(assert (not (= t 1)))
|
||||
|
||||
; int
|
||||
(assert (= 1 1))
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
expected
|
||||
"got"
|
||||
(n-fib n)))
|
||||
(assert false))))) ; cause test panic
|
||||
(assert nil))))) ; cause test panic
|
||||
|
||||
(assert-fib 0 0)
|
||||
(assert-fib 1 1)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
; def!
|
||||
(assert (not (def! FALSE nil)))
|
||||
(assert (def! TRUE true))
|
||||
(assert (def! TRUE t))
|
||||
|
||||
(println :def)
|
||||
(def! value-0 0)
|
||||
@ -32,13 +32,13 @@
|
||||
(assert-eq (do) nil)
|
||||
|
||||
; if
|
||||
(assert (if true 1))
|
||||
(assert (not (if false 1)))
|
||||
(assert (not (if false nil)))
|
||||
(assert (if false nil 1))
|
||||
(assert (if true 1 nil))
|
||||
(assert-fail '(if true))
|
||||
(assert-fail '(if false))
|
||||
(assert (if t 1))
|
||||
(assert (not (if nil 1)))
|
||||
(assert (not (if nil nil)))
|
||||
(assert (if nil nil 1))
|
||||
(assert (if t 1 nil))
|
||||
(assert-fail '(if t))
|
||||
(assert-fail '(if nil))
|
||||
(assert-fail '(if))
|
||||
|
||||
; let*
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
; positive assert
|
||||
(assert true)
|
||||
(assert t)
|
||||
(assert ())
|
||||
(assert 1)
|
||||
|
||||
; not
|
||||
(assert (not false))
|
||||
(assert (not nil))
|
||||
(assert (not (not true)))
|
||||
(assert (not nil))
|
||||
(assert (not (not t)))
|
||||
|
||||
; or
|
||||
(assert (not (or nil nil)))
|
||||
|
||||
Reference in New Issue
Block a user