diff --git a/core/core.mal b/core/core.mal index 8abd1ef..c654c78 100644 --- a/core/core.mal +++ b/core/core.mal @@ -19,13 +19,22 @@ ; Arithmetic (def! abs (fn* [a] - (if (< a 0) - (- 0 a) - a))) + (if (> a 0) + a + (- 0 a)))) (def! mod (fn* [a b] (- a (* (/ a b) b)))) +(def! > (fn* [a b] + (< b a))) + +(def! >= (fn* [a b] + (not (< a b)))) + +(def! <= (fn* [a b] + (>= b a))) + ; Other functions in core.rs (def! list? (fn* [a] (= (type a) :list))) @@ -49,3 +58,6 @@ ;; Shorthand (def! quit (fn* [] (exit 0))) + +;; variables +(def! MAL_HISTORY (str MAL_HOME "/" ".mal-history")) diff --git a/src/eval.rs b/src/eval.rs index 40b039c..c3b4d7d 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -7,6 +7,16 @@ use crate::types::{MalArgs, MalErr, MalMap, MalRet, MalType}; use std::borrow::Borrow; use std::rc::Rc; +macro_rules! forms { + ($($name:ident : $value:expr),*) => { + $( + const $name: &'static str = $value; + )* + }; +} + +forms!(NAME_DEF : "def!"); + /// Resolve the first element of the list as the function name and call it /// with the other elements as arguments fn eval_func(list: &MalType) -> CallRet { @@ -162,7 +172,7 @@ pub fn eval(ast: &MalType, env: Env) -> MalRet { if let M::Sym(sym) = symbol { match sym.borrow() { // I don't like to borrow tho - "def!" => return def_bang_form(args, env.clone()), // Set for env + NAME_DEF => return def_bang_form(args, env.clone()), // Set for env "let*" => {(ast, env) = let_star_form(args, env.clone())?; continue;}, "do" => {ast = do_form(args, env.clone())?; continue;}, "if" => {ast = if_form(args, env.clone())?; continue;}, diff --git a/src/mal_tests/mod.rs b/src/mal_tests/mod.rs index 1e511b1..29decb8 100644 --- a/src/mal_tests/mod.rs +++ b/src/mal_tests/mod.rs @@ -17,7 +17,7 @@ mod functional { } #[test] - fn assert_fail() { + fn assert() { test!("assert") } diff --git a/src/parse_tools.rs b/src/parse_tools.rs index 6c6f8a4..87058a9 100644 --- a/src/parse_tools.rs +++ b/src/parse_tools.rs @@ -70,6 +70,7 @@ pub fn interactive(env: Env) { const HISTORY: &str = ".mal-history"; let home = get_home_path(&env).unwrap(); let history = home + "/" + HISTORY; + eval_str(format!("(def! MAL_HISTORY \"{}\")", history).as_str(), &env).unwrap(); // Using "Editor" instead of the standard I/O because I hate myself but not this much // TODO: remove unwrap and switch to a better error handling diff --git a/tests/assert.mal b/tests/assert.mal index 4b6686c..6f73a0c 100644 --- a/tests/assert.mal +++ b/tests/assert.mal @@ -2,7 +2,7 @@ (assert (ok? 1)) (assert-eq nil (ok? (1))) (assert-eq true (ok? 1)) -(ok? (assert true)) -(not (ok? (assert nil))) +(assert (ok? (assert true))) +(assert (not (ok? (assert nil)))) (assert (not (ok? (assert-fail '1)))) -(assert (ok? (assert-fail '(1)))) \ No newline at end of file +(assert-fail '(1))