Minor fixes

Signed-off-by: teo3300 <matteo.rogora@live.it>
This commit is contained in:
teo3300
2024-01-17 19:17:04 +09:00
parent 4c55c9219f
commit 4f7140009d
4 changed files with 23 additions and 25 deletions

View File

@ -72,6 +72,6 @@ pub fn ns_init() -> Env {
"env" => Fun(|a| match env::var(car(a)?.if_string()?) {
Ok(s) => Ok(Str(s)),
_ => Ok(Nil),
}, "Retrieve environment variable")
}, "Retrieve the specified environment variable, returns NIL if that variable does not exist")
)
}

View File

@ -1,4 +1,4 @@
use crate::env::{self, call_func, car_cdr, CallFunc, CallRet};
use crate::env::{self, call_func, car, car_cdr, CallFunc, CallRet};
use crate::env::{env_get, env_new, env_set};
use crate::env::{first_last, Env};
use crate::printer::prt;
@ -139,20 +139,20 @@ pub fn eval(ast: &MalType, env: Env) -> MalRet {
loop {
match &ast {
M::List(list) if list.is_empty() => return Ok(ast.clone()),
M::List(list) if !list.is_empty() => {
let (car, cdr) = car_cdr(list)?;
match car {
M::Sym(sym) if sym == "def!" => return def_bang_form(cdr, env.clone()), // Set for env
M::Sym(sym) if sym == "let*" => (ast, env) = let_star_form(cdr, env.clone())?,
M::Sym(sym) if sym == "do" => ast = do_form(cdr, env.clone())?,
M::Sym(sym) if sym == "if" => ast = if_form(cdr, env.clone())?,
M::Sym(sym) if sym == "fn*" => return fn_star_form(cdr, env.clone()),
M::Sym(sym) if sym == "help" => return help_form(cdr, env.clone()),
M::Sym(sym) if sym == "find" => return find_form(cdr, env.clone()),
M::List(list) => {
let (symbol, args) = car_cdr(list)?;
match symbol {
M::Sym(sym) if sym == "def!" => return def_bang_form(args, env.clone()), // Set for env
M::Sym(sym) if sym == "let*" => (ast, env) = let_star_form(args, env.clone())?,
M::Sym(sym) if sym == "do" => ast = do_form(args, env.clone())?,
M::Sym(sym) if sym == "if" => ast = if_form(args, env.clone())?,
M::Sym(sym) if sym == "fn*" => return fn_star_form(args, env.clone()),
M::Sym(sym) if sym == "help" => return help_form(args, env.clone()),
M::Sym(sym) if sym == "find" => return find_form(args, env.clone()),
// Oh God, what have I done
M::Sym(sym) if sym == "quote" => return Ok(car_cdr(cdr)?.0.clone()),
M::Sym(sym) if sym == "quote" => return Ok(car(args)?.clone()),
M::Sym(sym) if sym == "ok?" => {
return match eval(car_cdr(cdr)?.0, env.clone()) {
return match eval(car(args)?, env.clone()) {
Err(_) => Ok(M::Nil),
_ => Ok(M::Bool(true)),
}
@ -160,7 +160,7 @@ pub fn eval(ast: &MalType, env: Env) -> MalRet {
// Special form, sad
// Bruh, is basically double eval
M::Sym(sym) if sym == "eval" => {
ast = eval(env::car(cdr)?, env.clone())?;
ast = eval(env::car(args)?, env.clone())?;
// Climb to the outermost environment (The repl env)
env = outermost(&env);
}

View File

@ -54,7 +54,7 @@ pub fn read_file(filename: &str) -> Result<String, MalErr> {
pub fn load_file(filename: &str, env: &Env) -> MalRet {
eval_str(
format!(
"(eval (read-string (str \"(do\n\" (slurp \"{}\") \"\nnil)\")))",
"(eval (read-string (str \"(do \" (slurp \"{}\") \"\nnil)\")))",
filename
)
.as_str(),

View File

@ -97,20 +97,18 @@ impl Reader {
"nil" => Ok(Nil),
tk => {
if Regex::new(r"^-?[0-9]+$").unwrap().is_match(tk) {
Ok(Int(tk.parse::<isize>().unwrap()))
return Ok(Int(tk.parse::<isize>().unwrap()));
} else if tk.starts_with('\"') {
if tk.len() > 2 && tk.ends_with('\"') {
Ok(Str(unescape_str(tk)))
} else {
Err(MalErr::unrecoverable(
"End of line reached without closing string",
))
return Ok(Str(unescape_str(tk)));
}
return Err(MalErr::unrecoverable(
"End of line reached without closing string",
));
} else if tk.starts_with(':') {
Ok(Key(format!("ʞ{}", tk)))
} else {
Ok(Sym(tk.to_string()))
return Ok(Key(format!("ʞ{}", tk)));
}
return Ok(Sym(tk.to_string()));
}
}
}