Removed MalType::Bool

mplemented instead MalType::T as opposed to Maltype::Nil
This commit is contained in:
teo3300
2025-06-13 18:30:20 +09:00
parent e97a348e80
commit 9af7ada706
11 changed files with 50 additions and 43 deletions

View File

@ -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 '()))))

View File

@ -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> {

View File

@ -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

View File

@ -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)

View File

@ -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")))

View File

@ -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 {

View File

@ -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))

View File

@ -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))

View File

@ -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)

View File

@ -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*

View File

@ -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)))