mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 09:15:32 +01:00
Moving some functios
- Some functions moved from core.rs to core.mal - Separating MAL_HOME setting from core/config loading Signed-off-by: teo3300 <matteo.rogora@live.it>
This commit is contained in:
@ -53,13 +53,12 @@ pub fn ns_init() -> Env {
|
||||
"println" => Fun(|a| {a.iter().for_each(|a| print!("{} ", pr_str(a, false))); println!(); Ok(Nil) }, "Print readably all the arguments"),
|
||||
"list" => Fun(|a| Ok(List(MalArgs::new(a.to_vec()))), "Return the arguments as a list"),
|
||||
"list?" => Fun(|a| Ok(Bool(a.iter().all(|el| matches!(el, List(_))))), "Return true if the first argument is a list, false otherwise"),
|
||||
"empty?" => Fun(|a| Ok(Bool(car(a)?.if_list()?.is_empty())), "Return true if the first parameter is an empty list, false otherwise, returns an error if the element is not a list"),
|
||||
// "empty?" => implemented through "count" in core.mal
|
||||
"count" => Fun(|a| Ok(Int(car(a)?.if_list()?.len() as isize)), "Return the number of elements in the first argument"),
|
||||
"and" => Fun(|a| Ok(Bool(a.iter().all(|a| !matches!(a, Nil | Bool(false))))), "Returns false if at least one of the arguments is 'false' or 'nil', true otherwise"),
|
||||
"or" => Fun(|a| Ok(Bool(a.iter().any(|a| !matches!(a, Nil | Bool(false))))), "Returns false if all the arguments are 'false' or 'nil', true otherwise"),
|
||||
"xor" => Fun(|a| Ok(Bool(a.iter().filter(|a| !matches!(a, Nil | Bool(false))).count() == 1)), "Returns true if one of the arguments is different from 'nil' or 'false', false otherwise"),
|
||||
// "not" defined inside mal itself
|
||||
// "not" => Fun(|a| Ok(Bool(matches!(car(a)?, Nil | Bool(false)))), "Negate the first argument"),
|
||||
// "not" => implemented throught "if" in core.mal
|
||||
"=" => Fun(mal_comp, "Return true if the first two parameters are the same type and content, in case of lists propagate to all elements"),
|
||||
"assert" => Fun(mal_assert, "Return an error if assertion fails"),
|
||||
"assert-eq" => Fun(mal_assert_eq, "Return an error if arguments are not the same"),
|
||||
|
||||
@ -12,12 +12,15 @@ mod step6_file;
|
||||
mod types;
|
||||
|
||||
use core::ns_init;
|
||||
use parse_tools::{interactive, load_conf, load_core, load_file};
|
||||
use parse_tools::{interactive, load_conf, load_core, load_file, set_home_path};
|
||||
|
||||
fn main() {
|
||||
// Initialize ns environment
|
||||
let reply_env = ns_init();
|
||||
|
||||
// Set the "MAL_HOME" symbol to the specified directory or the default one
|
||||
set_home_path(&reply_env);
|
||||
// load "$MAL_HOME/core.mal"
|
||||
load_core(&reply_env);
|
||||
|
||||
// Load config files ($MAL_HOME/config.mal, or default $HOME/.config/mal/config.mal)
|
||||
|
||||
@ -5,8 +5,9 @@ mod functional {
|
||||
($file:expr) => {{
|
||||
use crate::core::ns_init;
|
||||
use crate::load_file;
|
||||
use crate::parse_tools::load_core;
|
||||
use crate::parse_tools::{load_core, set_home_path};
|
||||
let env = ns_init();
|
||||
set_home_path(&env);
|
||||
load_core(&env);
|
||||
assert!(matches!(
|
||||
load_file(format!("tests/{}.mal", $file).as_str(), &env),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::env::Env;
|
||||
use crate::env::{env_get, Env};
|
||||
use crate::eval::eval;
|
||||
use crate::reader::{read_str, Reader};
|
||||
use crate::step6_file::rep;
|
||||
@ -10,33 +10,33 @@ use std::io::{BufRead, BufReader, Read};
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
|
||||
pub fn load_core(env: &Env) {
|
||||
eval_str("(def! not (fn* [x] (if x nil true)))", env).unwrap();
|
||||
eval_str(
|
||||
"(def! load-file (fn* [f] (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
|
||||
env,
|
||||
)
|
||||
.unwrap();
|
||||
eval_str(
|
||||
"(def! conf-reload (fn* [] (load-file (str MAL_HOME \"/\" \"config.mal\"))))",
|
||||
env,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn eval_str(line: &str, env: &Env) -> MalRet {
|
||||
eval(&read_str(Reader::new().push(line))?, env.clone())
|
||||
}
|
||||
|
||||
pub fn load_conf(work_env: &Env) {
|
||||
const CONFIG: &str = "config.mal";
|
||||
pub fn set_home_path(env: &Env) {
|
||||
let home = match env::var("MAL_HOME") {
|
||||
Ok(s) => s,
|
||||
Err(_) => env::var("HOME").unwrap() + "/.config/mal",
|
||||
};
|
||||
|
||||
// Add config path to mal
|
||||
eval_str(format!("(def! MAL_HOME \"{home}\")").as_str(), work_env).unwrap();
|
||||
let config = home + "/" + CONFIG;
|
||||
eval_str(format!("(def! MAL_HOME \"{home}\")").as_str(), env).unwrap();
|
||||
}
|
||||
|
||||
fn get_home_path(env: &Env) -> Result<String, MalErr> {
|
||||
Ok(env_get(env, "MAL_HOME")?.if_string()?.to_string())
|
||||
}
|
||||
|
||||
pub fn load_core(env: &Env) {
|
||||
let mut home_path = get_home_path(env).unwrap();
|
||||
home_path.push_str("/core.mal");
|
||||
load_file(&home_path, env).unwrap();
|
||||
}
|
||||
|
||||
pub fn load_conf(work_env: &Env) {
|
||||
const CONFIG: &str = "config.mal";
|
||||
let config = get_home_path(work_env).unwrap() + "/" + CONFIG;
|
||||
|
||||
if Path::new(&config).exists() {
|
||||
if let Err(e) = load_file(&config, work_env) {
|
||||
@ -127,7 +127,7 @@ pub fn interactive(env: Env) {
|
||||
// TODO: remove unwrap and switch to a better error handling
|
||||
let mut rl = DefaultEditor::new().unwrap();
|
||||
if rl.load_history(HISTORY_PATH).is_err() {
|
||||
eprintln!("Failed to load history");
|
||||
eprintln!("; Failed to load history");
|
||||
}
|
||||
|
||||
let mut num = 0;
|
||||
@ -169,12 +169,12 @@ pub fn interactive(env: Env) {
|
||||
}
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
parser.clear();
|
||||
eprintln!("; ... Interrupted");
|
||||
// eprintln!("; ... Interrupted");
|
||||
continue;
|
||||
}
|
||||
Err(ReadlineError::Eof) => exit(0),
|
||||
Err(err) => {
|
||||
eprint!("Error reading lnie: {:?}", err);
|
||||
eprint!("; Error reading lnie: {:?}", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,5 +66,6 @@ pub fn print_malfun(sym: &str, params: Rc<MalType>, ast: Rc<MalType>) {
|
||||
.if_list()
|
||||
.unwrap_or(&[])
|
||||
.iter()
|
||||
.for_each(|el| println!("; {}\n", pr_str(el, true)));
|
||||
.for_each(|el| println!("; {}", pr_str(el, true)));
|
||||
println!();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user