mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 09:15:32 +01:00
EPrintlns and libs
- Moving all repl prints to stderr - Adding small functions to module string
This commit is contained in:
@ -71,6 +71,10 @@
|
||||
"open a mal file and evaluate its content"
|
||||
(eval (read-string (str "(do " (slurp f) "\nnil)")))))
|
||||
|
||||
(def! module (fn* [f]
|
||||
"load a file from the library path"
|
||||
(load-file (str MAL_HOME "/libs/" f ".mal"))))
|
||||
|
||||
(def! conf-reload (fn* []
|
||||
"reload mal config file"
|
||||
(load-file (str MAL_HOME "/" "config.mal"))))
|
||||
@ -139,8 +143,8 @@
|
||||
(def! BANNER
|
||||
(str
|
||||
"; rust-mal: a toy lisp interpreter written in rust\n"
|
||||
"; $ mal [filename ...] : load specified modules at start\n"
|
||||
"; (load-file <name>) : load specified module while mal is running\n"
|
||||
"; $ mal [filename ...] : load specified files at start\n"
|
||||
"; (load-file <name>) : load specified file while mal is running\n"
|
||||
"; (find [pattern...]) : list symbols matching all patterns\n"
|
||||
"; (help <symbol>) : print information about a symbol\n"
|
||||
";\n"
|
||||
@ -186,3 +190,5 @@
|
||||
c
|
||||
(collect-r (f c (car l)) (cdr l)))))
|
||||
(collect-r i l)))
|
||||
|
||||
(conf-reload)
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
(def! char (fn* [l]
|
||||
(car (boom l))))
|
||||
|
||||
(def! #n (char "\n"))
|
||||
(def! #s (char " "))
|
||||
(def! #t (char "\t"))
|
||||
|
||||
(def! char? (fn* [a]
|
||||
(= (type a) :char)))
|
||||
|
||||
(def! string? (fn* [a]
|
||||
(= (type a) :string)))
|
||||
|
||||
(def! strlen (fn* [s] (count (boom s))))
|
||||
|
||||
(def! strc (fn* [l]
|
||||
(def! strc-r (fn* [l s]
|
||||
(if (empty? l)
|
||||
@ -38,3 +44,5 @@
|
||||
|
||||
(def! chsub (fn* [s c1 c2]
|
||||
(strc (map-if (fn* [x] (= x c1)) (fn* [x] c2) (boom s)))))
|
||||
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ pub fn ns_init() -> Env {
|
||||
"car" => Fun(|a| mal_car(car(a)?), "Returns the first element of the list, NIL if its empty"),
|
||||
"cdr" => Fun(|a| mal_cdr(car(a)?), "Returns all the list but the first element"),
|
||||
// A tribute to PHP's explode (PHP, a language I never used)
|
||||
"boom" => Fun(mal_boom, "Split a string into a list of string\n; BE CAREFUL WHEN USING"),
|
||||
"boom" => Fun(mal_boom, "Split a string into a list of characters\n; BE CAREFUL WHEN USING"),
|
||||
"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).unwrap_or_default().clone())))), "Return an atom pointing to the given arg"),
|
||||
|
||||
@ -129,7 +129,7 @@ pub fn help_form(list: &[MalType], env: Env) -> MalRet {
|
||||
let (sym, _) = car_cdr(list)?;
|
||||
let sym_str = sym.if_symbol()?;
|
||||
match eval(sym, env.clone())? {
|
||||
M::Fun(_, desc) => println!("{}\t[builtin]: {}\n", sym_str, desc),
|
||||
M::Fun(_, desc) => eprintln!("{}\t[builtin]: {}\n", sym_str, desc),
|
||||
M::MalFun { params, ast, .. } => print_malfun(sym_str, params, ast),
|
||||
_ => eprintln!("{}\t[symbol]: {}\n", sym_str, prt(&env_get(&env, sym_str)?)),
|
||||
}
|
||||
|
||||
@ -24,12 +24,15 @@ fn main() {
|
||||
load_home_file("core.mal", &reply_env, true);
|
||||
// Load config files ($MAL_HOME/config.mal, or default $HOME/.config/mal/config.mal)
|
||||
// [warn: false] since this file is optional
|
||||
load_home_file("config.mal", &reply_env, false);
|
||||
// replaced by (ok? '(reload-config)) at the end of core.mal
|
||||
// - I used this to overwrite BANNER to prevent it from displaying
|
||||
// based on conf
|
||||
//load_home_file("config.mal", &reply_env, false);
|
||||
|
||||
// load all files passed as arguments
|
||||
args().collect::<Vec<String>>()[1..].iter().for_each(|f| {
|
||||
if let Err(e) = load_file(f, &reply_env) {
|
||||
println!("{}", e.message())
|
||||
eprintln!("{}", e.message())
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -15,6 +15,8 @@ mod functional {
|
||||
));
|
||||
}};
|
||||
}
|
||||
// TODO: modify to accept more parameters for test/libraries
|
||||
// TODO: text 'boom' from within rust
|
||||
|
||||
#[test]
|
||||
fn assert() {
|
||||
|
||||
@ -109,16 +109,19 @@ pub fn interactive(env: Env) {
|
||||
|
||||
// Perform rep on whole available input
|
||||
match rep(&parser, &env) {
|
||||
Ok(output) => output.iter().for_each(|el| println!("; [{}]> {}", num, el)),
|
||||
Ok(output) => output.iter().for_each(|el| {
|
||||
eprintln!("; [{}]> {}", num, el);
|
||||
num += 1;
|
||||
}),
|
||||
Err(error) => {
|
||||
if error.is_recoverable() {
|
||||
// && line != "\n" {
|
||||
continue;
|
||||
}
|
||||
eprintln!("; [{}]> Error @ {}", num, error.message());
|
||||
num += 1
|
||||
}
|
||||
}
|
||||
num += 1;
|
||||
break;
|
||||
}
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
|
||||
@ -98,14 +98,16 @@ impl Reader {
|
||||
tk => {
|
||||
if Regex::new(r"^-?[0-9]+$").unwrap().is_match(tk) {
|
||||
return Ok(Int(tk.parse::<isize>().unwrap()));
|
||||
} else if tk.starts_with('\"') {
|
||||
}
|
||||
if tk.starts_with('\"') {
|
||||
if tk.len() > 1 && tk.ends_with('\"') {
|
||||
return Ok(Str(unescape_str(tk).into()));
|
||||
}
|
||||
return Err(MalErr::unrecoverable(
|
||||
"End of line reached without closing string",
|
||||
));
|
||||
} else if tk.starts_with(':') {
|
||||
}
|
||||
if tk.starts_with(':') {
|
||||
return Ok(Key(format!("ʞ{}", tk).into()));
|
||||
}
|
||||
Ok(Sym(tk.into()))
|
||||
|
||||
@ -220,6 +220,8 @@ pub fn escape_str(s: &str) -> String {
|
||||
String::from(s)
|
||||
.replace('\\', "\\\\")
|
||||
.replace('\n', "\\n")
|
||||
.replace('\u{000D}', "\\r")
|
||||
.replace('\t', "\\t")
|
||||
.replace('\"', "\\\"")
|
||||
)
|
||||
}
|
||||
@ -228,6 +230,8 @@ pub fn unescape_str(s: &str) -> String {
|
||||
String::from(&s[1..s.len() - 1])
|
||||
.replace("\\\\", "\\")
|
||||
.replace("\\n", "\n")
|
||||
.replace("\\r", "\r")
|
||||
.replace("\\t", "\t")
|
||||
.replace("\\\"", "\"")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user