mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 09:15:32 +01:00
Adding some info functions and tests
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use std::env;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::env::{any_zero, arithmetic_op, car, comparison_op, env_new, env_set, mal_exit, Env};
|
||||
|
||||
@ -34,7 +35,7 @@ macro_rules! env_init {
|
||||
use crate::parse_tools::read_file;
|
||||
use crate::printer::pr_str;
|
||||
use crate::reader::{read_str, Reader};
|
||||
use crate::types::MalType::{Fun, Int, List, Nil, Str};
|
||||
use crate::types::MalType::{Atom, Fun, Int, List, Nil, Str};
|
||||
use crate::types::{mal_assert, mal_equals, MalErr};
|
||||
|
||||
pub fn ns_init() -> Env {
|
||||
@ -62,6 +63,8 @@ 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(car(a)?.clone()))), "Return an atom pointing to the given arg"),
|
||||
"deref" => Fun(|a| Ok(car(a)?.if_atom()?.clone()), "Return the content of the atom argumet"),
|
||||
"env" => Fun(|a| match env::var(car(a)?.if_string()?) {
|
||||
Ok(s) => Ok(Str(s.into())),
|
||||
_ => Ok(Nil),
|
||||
|
||||
@ -21,6 +21,7 @@ forms!(NAME_DEF : "def!",
|
||||
NAME_FN : "fn*",
|
||||
NAME_FN_ALT : "λ",
|
||||
NAME_HELP : "help",
|
||||
NAME_HELP_ALT: "h",
|
||||
NAME_FIND : "find",
|
||||
NAME_QUOTE : "quote",
|
||||
NAME_OK : "ok?",
|
||||
@ -188,7 +189,7 @@ pub fn eval(ast: &MalType, env: Env) -> MalRet {
|
||||
NAME_FN | NAME_FN_ALT /* :) */ => {
|
||||
return fn_star_form(args, env.clone())
|
||||
}
|
||||
NAME_HELP => return help_form(args, env.clone()),
|
||||
NAME_HELP | NAME_HELP_ALT => return help_form(args, env.clone()),
|
||||
NAME_FIND => return find_form(args, env.clone()),
|
||||
// Oh God, what have I done
|
||||
NAME_QUOTE => return Ok(car(args)?.clone()),
|
||||
|
||||
@ -45,4 +45,14 @@ mod functional {
|
||||
fn forms() {
|
||||
test!("forms")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lists() {
|
||||
test!("lists")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atoms() {
|
||||
test!("atoms")
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,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("; user> ");
|
||||
|
||||
match line {
|
||||
Ok(line) => {
|
||||
@ -105,7 +105,7 @@ pub fn interactive(env: Env) {
|
||||
|
||||
// Perform rep on whole available input
|
||||
match rep(&parser, &env) {
|
||||
Ok(output) => output.iter().for_each(|el| eprintln!("[{}]> {}", num, el)),
|
||||
Ok(output) => output.iter().for_each(|el| println!("; [{}]> {}", num, el)),
|
||||
Err(error) => {
|
||||
if error.is_recoverable() {
|
||||
// && line != "\n" {
|
||||
|
||||
@ -53,6 +53,7 @@ pub fn pr_str(ast: &MalType, print_readably: bool) -> String {
|
||||
),
|
||||
M::Fun(..) => "#<builtin>".to_string(),
|
||||
M::MalFun { .. } => "#<function>".to_string(),
|
||||
M::Atom(sub) => format!("Atom({})", pr_str(sub, print_readably)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +62,7 @@ pub fn prt(ast: &MalType) -> String {
|
||||
}
|
||||
|
||||
pub fn print_malfun(sym: &str, params: Rc<MalType>, ast: Rc<MalType>) {
|
||||
println!("{}\t[function]: {}", sym, prt(¶ms));
|
||||
println!("; {}\t[function]: {}", sym, prt(¶ms));
|
||||
ast.as_ref()
|
||||
.if_list()
|
||||
.unwrap_or(&[])
|
||||
|
||||
13
src/types.rs
13
src/types.rs
@ -25,6 +25,7 @@ pub enum MalType {
|
||||
Str(MalStr),
|
||||
Int(isize),
|
||||
Bool(bool),
|
||||
Atom(Rc<MalType>),
|
||||
Nil,
|
||||
}
|
||||
|
||||
@ -74,6 +75,15 @@ impl MalType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn if_atom(&self) -> Result<&MalType, MalErr> {
|
||||
match self {
|
||||
Self::Atom(sym) => Ok(sym),
|
||||
_ => Err(MalErr::unrecoverable(
|
||||
format!("{:?} is not an atom", prt(self)).as_str(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn label_type(&self) -> MalType {
|
||||
Key(match self {
|
||||
M::Nil => "ʞ:nil",
|
||||
@ -83,9 +93,10 @@ impl MalType {
|
||||
M::Key(_) => "ʞ:key",
|
||||
M::Str(_) => "ʞ:string",
|
||||
M::Sym(_) => "ʞ:symbol",
|
||||
M::List(_) => "ʞ:ist",
|
||||
M::List(_) => "ʞ:list",
|
||||
M::Vector(_) => "ʞ:vector",
|
||||
M::Map(_) => "ʞ:map",
|
||||
M::Atom(_) => "ʞ:atom",
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user