Fixing some atom functions

This commit is contained in:
teo3300
2024-05-29 08:51:38 +09:00
parent eb894dfffc
commit 1f20079571
7 changed files with 37 additions and 9 deletions

View File

@ -46,9 +46,11 @@
(= (count l) 0)))
(def! assert-eq (fn* [a b]
"returns an error if arguments are not equals, NIL otherwise"
(assert (= a b))))
(def! assert-fail (fn* [x]
"returns NIL if evaluation of argument fails, error otherwise"
(assert (not (ok? (eval x))))))
;; Since thread safety is not required, I will leave it like this,
@ -58,13 +60,16 @@
;; File-interaction functions
(def! load-file (fn* [f]
"open a mal file and evaluate its content"
(eval (read-string (str "(do " (slurp f) "\nnil)")))))
(def! conf-reload (fn* []
"reload mal config file"
(load-file (str MAL_HOME "/" "config.mal"))))
;; Shorthand
(def! quit (fn* []
"Quit the program with status '0'"
(exit 0)))
;; variables
@ -132,5 +137,3 @@
"; (help <symbol>) : print information about a symbol\n"
";\n"
"; enjoy ^.^\n"))
(println BANNER)

View File

@ -34,11 +34,22 @@ macro_rules! env_init {
}
use crate::parse_tools::read_file;
use crate::printer::pr_str;
use crate::printer::{pr_str, prt};
use crate::reader::{read_str, Reader};
use crate::types::MalType::{Atom, Fun, Int, List, Nil, Str};
use crate::types::{mal_assert, mal_equals, reset_bang, MalErr};
macro_rules! if_atom {
($val:expr) => {{
match $val {
Atom(a) => Ok(a.borrow().clone()),
_ => Err(MalErr::unrecoverable(
format!("{:?} is not an atom", prt($val)).as_str(),
)),
}
}};
}
pub fn ns_init() -> Env {
env_init!(None,
// That's it, you are all going to be simpler functions
@ -66,9 +77,9 @@ pub fn ns_init() -> Env {
"assert" => Fun(mal_assert, "Return an error if assertion fails"),
"read-string" => Fun(|a| read_str(Reader::new().push(car(a)?.if_string()?)).map_err(MalErr::severe), "Tokenize and read the first argument"),
"slurp" => Fun(|a| Ok(Str(read_file(car(a)?.if_string()?)?)), "Read a file and return the content as a string"),
"atom" => Fun(|a| Ok(Atom(Rc::new(RefCell::new(car(a)?.clone())))), "Return an atom pointing to the given arg"),
"deref" => Fun(|a| match car(a)? { Atom(a) => Ok(a.borrow().clone()), _ => todo!("Cacca suprema") }, "Return the content of the atom argumet"),
"reset!" => Fun(reset_bang, "Set the value of the first argument to the second argument"),
"atom" => Fun(|a| Ok(Atom(Rc::new(RefCell::new(car(a).unwrap_or_default().clone())))), "Return an atom pointing to the given arg"),
"deref" => Fun(|a| if_atom!(car(a)?), "Return the content of the atom argumet"),
"reset!" => Fun(reset_bang, "Change the value of the Atom (frist argument) to the second argument"),
"env" => Fun(|a| match env::var(car(a)?.if_string()?) {
Ok(s) => Ok(Str(s.into())),
_ => Ok(Nil),

View File

@ -103,7 +103,7 @@ pub fn call_func(func: &MalType, args: &[MalType]) -> CallRet {
eval(x, inner_env.clone())?;
}
Ok(CallFunc::MalFun(
list.last().unwrap_or(&Nil).clone(),
list.last().unwrap_or_default().clone(),
inner_env,
))
}

View File

@ -12,7 +12,7 @@ mod step6_file;
mod types;
use core::ns_init;
use parse_tools::{interactive, load_file, load_home_file, set_home_path};
use parse_tools::{interactive, load_file, load_home_file, print_banner, set_home_path};
fn main() {
// Initialize ns environment
@ -33,5 +33,7 @@ fn main() {
}
});
print_banner(&reply_env);
interactive(reply_env);
}

View File

@ -22,6 +22,10 @@ pub fn set_home_path(env: &Env) {
.unwrap();
}
pub fn print_banner(env: &Env) {
let _ = eval_str("(prn BANNER)", env);
}
fn get_home_path(env: &Env) -> Result<String, MalErr> {
Ok(eval_str("MAL_HOME", env)?.if_string()?.to_string())
}
@ -92,7 +96,7 @@ pub fn interactive(env: Env) {
// // Read line to compose program input
// let mut line = String::new();
// io::stdin().read_line(&mut line).unwrap();
let line = rl.readline("; user> ");
let line = rl.readline("; mal> ");
match line {
Ok(line) => {

View File

@ -4,6 +4,8 @@
// input, thus this can be referenced by the previous step without the need
// to allocate more memory
// FIXME: (?) multiple sentences per line, only last is kept
use crate::env::Env;
use crate::eval::eval;
use crate::printer::pr_str;

View File

@ -29,6 +29,12 @@ pub enum MalType {
Nil,
}
impl Default for &MalType {
fn default() -> Self {
&MalType::Nil
}
}
impl MalType {
pub fn if_number(&self) -> Result<isize, MalErr> {
match self {