mark core as nostd

* implement custom hashmap to back symtable
* pass in print and read callbacks to keep stdlib pure
* use core / alloc versions of Box, Rc, Vec, etc
* replace pow func with libm

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2024-07-26 22:16:21 -07:00
parent 0c2aad2cb6
commit d6a0e68460
26 changed files with 493 additions and 288 deletions

View file

@ -5,6 +5,7 @@ authors = ["Ava <ava@sunnypup.io>"]
edition = "2021" edition = "2021"
[dependencies] [dependencies]
libm = "0.2.8"
# this one provides a global constant lookup table for simple # this one provides a global constant lookup table for simple
# string escaping in the lexer # string escaping in the lexer
phf = { version = "0.11", default-features = false, features = ["macros"] } phf = { version = "0.11", default-features = false, features = ["macros"] }
@ -14,4 +15,4 @@ name = "flesh"
# only turn this on if you set POSIX_LOAD_NAME at build time # only turn this on if you set POSIX_LOAD_NAME at build time
[features] [features]
implicit-load = [] implicit-load = []

View file

@ -15,7 +15,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use std::fmt; use alloc::vec::Vec;
use alloc::string::String;
use core::fmt;
use core::convert;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TraceItem { pub struct TraceItem {
@ -32,7 +35,7 @@ pub fn start_trace(item: TraceItem) -> Traceback {
impl Traceback { impl Traceback {
pub fn new() -> Traceback { pub fn new() -> Traceback {
Traceback(vec![]) Traceback(Vec::new())
} }
pub fn with_trace(mut self, item: TraceItem) -> Traceback { pub fn with_trace(mut self, item: TraceItem) -> Traceback {
@ -56,13 +59,13 @@ impl fmt::Display for Traceback {
} }
impl std::convert::From<Traceback> for String { impl convert::From<Traceback> for String {
fn from(arg: Traceback) -> Self { fn from(arg: Traceback) -> Self {
format!("{}", arg) format!("{}", arg)
} }
} }
impl std::convert::From<(&String, &str)> for TraceItem { impl convert::From<(&String, &str)> for TraceItem {
fn from(value: (&String, &str)) -> Self { fn from(value: (&String, &str)) -> Self {
TraceItem { TraceItem {
caller: value.0.clone(), caller: value.0.clone(),
@ -71,7 +74,7 @@ impl std::convert::From<(&String, &str)> for TraceItem {
} }
} }
impl std::convert::From<(&String, String)> for TraceItem { impl convert::From<(&String, String)> for TraceItem {
fn from(value: (&String, String)) -> Self { fn from(value: (&String, String)) -> Self {
TraceItem { TraceItem {
caller: value.0.clone(), caller: value.0.clone(),
@ -80,7 +83,7 @@ impl std::convert::From<(&String, String)> for TraceItem {
} }
} }
impl std::convert::From<(&str, String)> for TraceItem { impl convert::From<(&str, String)> for TraceItem {
fn from(value: (&str, String)) -> Self { fn from(value: (&str, String)) -> Self {
TraceItem { TraceItem {
caller: String::from(value.0), caller: String::from(value.0),
@ -89,7 +92,7 @@ impl std::convert::From<(&str, String)> for TraceItem {
} }
} }
impl std::convert::From<(&str, &str)> for TraceItem { impl convert::From<(&str, &str)> for TraceItem {
fn from(value: (&str, &str)) -> Self { fn from(value: (&str, &str)) -> Self {
TraceItem { TraceItem {
caller: String::from(value.0), caller: String::from(value.0),

View file

@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use alloc::boxed::Box;
use crate::segment::{Ctr, Seg}; use crate::segment::{Ctr, Seg};
use crate::sym::{SymTable, call_lambda}; use crate::sym::{SymTable, call_lambda};
use crate::error::Traceback; use crate::error::Traceback;

159
core/src/hashmap.rs Normal file
View file

@ -0,0 +1,159 @@
/* Flesh: Flexible Shell
* Copyright (C) 2021 Ava Affine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use alloc::slice;
use alloc::vec::Vec;
use alloc::boxed::Box;
use alloc::string::String;
/* Use a prime number so that the modulus operation
* provides better avalanche effect
*/
const INDEXED_BUCKETS: u8 = 199;
/* This only has to work to make quasi unique indexes from
* variable names. Any given program will not have so many
* symbols that this becomes a bottleneck in runtime.
*
* Priorities:
* - SPEED in embedded code
* - avalanche effect
*
* Not a priority: minimal collisions
*
* Just to make sure this is not misused I keep it private
*/
#[inline]
fn string_hash(input: &String) -> u8 {
input
.chars()
.map(|c| c.to_digit(10)
.or_else(|| Some(0))
.unwrap())
.reduce(|acc, i| (acc + i) % INDEXED_BUCKETS as u32)
.or_else(|| Some(0))
.unwrap() as u8
}
#[derive(Clone)]
pub struct Bucket<T: Clone>(Vec<(String, T)>);
#[derive(Clone)]
pub struct QuickMap<T: Clone>(Box<[Bucket<T>; INDEXED_BUCKETS as usize]>);
impl<'a, T: Clone> QuickMap<T> {
const ARRAY_REPEAT_VALUE: Bucket<T> = Bucket(vec![]);
pub fn new() -> QuickMap<T> {
QuickMap(Box::new([QuickMap::ARRAY_REPEAT_VALUE; INDEXED_BUCKETS as usize]))
}
pub fn get(&self, arg: &String) -> Option<&T> {
let idx = string_hash(&arg);
for kv in self.0[idx as usize].0.iter() {
if &kv.0 == arg {
return Some(&kv.1);
}
}
return None;
}
pub fn remove(&mut self, arg: &String) -> Option<T> {
let idx = string_hash(&arg);
let len = self.0[idx as usize].0.len();
for i in 0..len {
if &self
.0[idx as usize]
.0[i as usize]
.0 == arg {
return Some(self.0[idx as usize].0.swap_remove(i).1);
}
}
return None;
}
pub fn contains_key(&self, arg: &String) -> bool {
let idx = string_hash(arg);
for kv in self.0[idx as usize].0.iter() {
if &kv.0 == arg {
return true;
}
}
return false;
}
pub fn insert(&mut self, k: String, v: T) -> Option<T> {
let idx = string_hash(&k);
for kv in self.0[idx as usize].0.iter_mut() {
if kv.0 == k {
let tmp = kv.1.clone();
kv.1 = v;
return Some(tmp);
}
}
self.0[idx as usize].0.push((k, v));
return None
}
pub fn iter(&'a self) -> QuickMapIter<'a, T> {
QuickMapIter::<'a, T>{
buckets: &self.0,
bucket_cursor: 0,
vec_iter: self.0[0].0.iter(),
}
}
}
#[derive(Clone)]
pub struct QuickMapIter<'a, T: Clone> {
buckets: &'a [Bucket<T>; INDEXED_BUCKETS as usize],
bucket_cursor: usize,
vec_iter: slice::Iter<'a, (String, T)>,
}
impl<'a, T: Clone> Iterator for QuickMapIter<'a, T> {
type Item = &'a (String, T);
fn next(&mut self) -> Option<Self::Item> {
self.vec_iter
.next()
.or_else(|| {
self.bucket_cursor += 1;
if self.bucket_cursor == INDEXED_BUCKETS as usize{
None
} else {
self.vec_iter = self.buckets[self.bucket_cursor].0.iter();
self.next()
}
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_and_fetch_simple() {
let mut q = QuickMap::<u8>::new();
q.insert(String::from("test"), 1);
assert_eq!(*q.get(&String::from("test")).unwrap(), 1);
}
}

View file

@ -15,6 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use alloc::boxed::Box;
use alloc::string::{String, ToString};
use crate::segment::{Ctr, Seg}; use crate::segment::{Ctr, Seg};
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use phf::{Map, phf_map}; use phf::{Map, phf_map};
@ -67,7 +69,7 @@ fn process(document: &String) -> Result<Box<Seg>, String> {
let mut is_str = false; let mut is_str = false;
let mut ign = false; let mut ign = false;
let mut token = String::new(); let mut token = String::new();
let mut delim_stack = Vec::new(); let mut delim_stack = vec![];
let mut ref_stack = vec![]; let mut ref_stack = vec![];
let mut cursor = 0; let mut cursor = 0;
@ -130,7 +132,6 @@ fn process(document: &String) -> Result<Box<Seg>, String> {
match c { match c {
// add a new Seg reference to the stack // add a new Seg reference to the stack
'(' if !is_str && token.is_empty() => { '(' if !is_str && token.is_empty() => {
let mut s = Seg::new();
ref_stack.push(Seg::new()); ref_stack.push(Seg::new());
delim_stack.push(')'); delim_stack.push(')');
} }

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//#![no_std] #![cfg_attr(not(test), no_std)]
mod eval; mod eval;
mod lex; mod lex;
@ -24,6 +24,9 @@ mod stl;
mod sym; mod sym;
mod error; mod error;
#[macro_use]
extern crate alloc;
pub mod ast { pub mod ast {
pub use crate::eval::eval; pub use crate::eval::eval;
pub use crate::lex::lex; pub use crate::lex::lex;

View file

@ -15,9 +15,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use crate::sym::UserFn; use crate::sym::UserFn;
use std::fmt; use alloc::fmt;
use std::marker::PhantomData; use alloc::string::{String, ToString};
use std::ops::{Add, Div, Index, Mul, Sub}; use alloc::boxed::Box;
use core::convert;
use core::marker::PhantomData;
use core::ops::{Add, Div, Index, Mul, Sub};
// Container // Container
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -409,7 +412,7 @@ impl fmt::Display for Type {
} }
} }
impl std::convert::From<String> for Type { impl convert::From<String> for Type {
fn from(value: String) -> Self { fn from(value: String) -> Self {
match value.as_str() { match value.as_str() {
"symbol" => Type::Symbol, "symbol" => Type::Symbol,

View file

@ -16,6 +16,7 @@
*/ */
use crate::sym::SymTable; use crate::sym::SymTable;
use alloc::string::String;
pub mod append; pub mod append;
pub mod boolean; pub mod boolean;
@ -29,10 +30,10 @@ pub const CFG_FILE_VNAME: &str = "FLESH_CFG_FILE";
/// static_stdlib /// static_stdlib
/// inserts all stdlib functions that can be inserted without /// inserts all stdlib functions that can be inserted without
/// any kind of further configuration data into a symtable /// any kind of further configuration data into a symtable
pub fn static_stdlib(syms: &mut SymTable) { pub fn static_stdlib(syms: &mut SymTable, print: fn(&String), read: fn() -> String) {
append::add_list_lib(syms); append::add_list_lib(syms);
strings::add_string_lib(syms); strings::add_string_lib(syms, print, read);
decl::add_decl_lib_static(syms); decl::add_decl_lib_static(syms, print);
control::add_control_lib(syms); control::add_control_lib(syms);
boolean::add_bool_lib(syms); boolean::add_bool_lib(syms);
math::add_math_lib(syms); math::add_math_lib(syms);

View file

@ -18,7 +18,10 @@
use crate::segment::{Ctr, Seg, Type}; use crate::segment::{Ctr, Seg, Type};
use crate::sym::{SymTable, Symbol, Args, ValueType}; use crate::sym::{SymTable, Symbol, Args, ValueType};
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use std::rc::Rc; use alloc::rc::Rc;
use alloc::boxed::Box;
use alloc::string::{String, ToString};
const CONS_DOCSTRING: &str = "traverses any number of arguments collecting them into a list. const CONS_DOCSTRING: &str = "traverses any number of arguments collecting them into a list.
If the first argument is a list, all other arguments are added sequentially to the end of the list contained in the first argument."; If the first argument is a list, all other arguments are added sequentially to the end of the list contained in the first argument.";

View file

@ -18,7 +18,9 @@
use crate::segment::{Ctr, Seg, Type}; use crate::segment::{Ctr, Seg, Type};
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use crate::sym::{SymTable, ValueType, Args, Symbol}; use crate::sym::{SymTable, ValueType, Args, Symbol};
use std::rc::Rc; use alloc::rc::Rc;
use alloc::boxed::Box;
use alloc::string::{String, ToString};
const AND_DOCSTRING: &str = const AND_DOCSTRING: &str =
"traverses a list of N arguments, all of which are expected to be boolean. "traverses a list of N arguments, all of which are expected to be boolean.

View file

@ -19,8 +19,9 @@ use crate::eval::eval;
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use crate::segment::{Ctr, Seg, Type}; use crate::segment::{Ctr, Seg, Type};
use crate::sym::{SymTable, Symbol, ValueType, Args}; use crate::sym::{SymTable, Symbol, ValueType, Args};
use std::rc::Rc; use alloc::rc::Rc;
use std::process; use alloc::boxed::Box;
use alloc::string::{String, ToString};
const IF_DOCSTRING: &str = const IF_DOCSTRING: &str =
"accepts three bodies, a condition, an unevaluated consequence, and an alternative consequence. "accepts three bodies, a condition, an unevaluated consequence, and an alternative consequence.
@ -397,33 +398,7 @@ fn assert_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
} }
} }
const EXIT_DOCSTRING: &str = "Takes on input: an integer used as an exit code.
Entire REPL process quits with exit code.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
if let Ctr::Integer(i) = *ast.car {
if i > 2 ^ 32 {
panic!("argument to exit too large!")
} else {
process::exit(i as i32);
}
} else {
panic!("impossible argument to exit")
}
}
pub fn add_control_lib(syms: &mut SymTable) { pub fn add_control_lib(syms: &mut SymTable) {
syms.insert(
"exit".to_string(),
Symbol {
name: String::from("exit"),
args: Args::Strict(vec![Type::Integer]),
conditional_branches: false,
docs: EXIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(exit_callback)),
..Default::default()
},
);
syms.insert( syms.insert(
"assert".to_string(), "assert".to_string(),
Symbol { Symbol {

View file

@ -19,7 +19,9 @@ use crate::eval::eval;
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use crate::segment::{Ctr, Seg, Type}; use crate::segment::{Ctr, Seg, Type};
use crate::sym::{SymTable, Symbol, UserFn, ValueType, Args}; use crate::sym::{SymTable, Symbol, UserFn, ValueType, Args};
use std::rc::Rc; use alloc::rc::Rc;
use alloc::boxed::Box;
use alloc::string::{String, ToString};
const QUOTE_DOCSTRING: &str = "takes a single unevaluated tree and returns it as it is: unevaluated."; const QUOTE_DOCSTRING: &str = "takes a single unevaluated tree and returns it as it is: unevaluated.";
fn quote_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> { fn quote_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
@ -84,7 +86,7 @@ fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
} }
const HELP_DOCSTRING: &str = "prints help text for a given symbol. Expects only one argument."; const HELP_DOCSTRING: &str = "prints help text for a given symbol. Expects only one argument.";
fn help_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> { fn help_callback(ast: &Seg, syms: &mut SymTable, print: fn(&String)) -> Result<Ctr, Traceback> {
if ast.len() != 1 { if ast.len() != 1 {
return Err(start_trace(("help", "expected one input").into())); return Err(start_trace(("help", "expected one input").into()));
} }
@ -96,7 +98,7 @@ fn help_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
} else { } else {
args_str = sym.args.to_string(); args_str = sym.args.to_string();
} }
println!( print(&format!(
"NAME: {0}\n "NAME: {0}\n
ARGS: {1}\n ARGS: {1}\n
DOCUMENTATION:\n DOCUMENTATION:\n
@ -104,7 +106,7 @@ DOCUMENTATION:\n
CURRENT VALUE AND/OR BODY: CURRENT VALUE AND/OR BODY:
{3}", {3}",
sym.name, args_str, sym.docs, sym.value sym.name, args_str, sym.docs, sym.value
); ));
} else { } else {
return Err(start_trace(("help", format!("{symbol} is undefined")).into())); return Err(start_trace(("help", format!("{symbol} is undefined")).into()));
} }
@ -129,7 +131,7 @@ fn isset_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
const ENV_DOCSTRING: &str = "takes no arguments const ENV_DOCSTRING: &str = "takes no arguments
prints out all available symbols and their associated values"; prints out all available symbols and their associated values";
fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> { fn env_callback(_ast: &Seg, syms: &mut SymTable, print: fn(&String)) -> Result<Ctr, Traceback> {
let mut functions = vec![]; let mut functions = vec![];
let mut variables = vec![]; let mut variables = vec![];
for (name, val) in syms.iter() { for (name, val) in syms.iter() {
@ -146,13 +148,13 @@ fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
} }
} }
println!("VARIABLES:"); print(&String::from("VARIABLES:"));
for var in variables { for var in variables {
println!("{}", var) print(&var)
} }
println!("\nFUNCTIONS:"); print(&String::from("\nFUNCTIONS:"));
for func in functions { for func in functions {
println!("{}", func); print(&func);
} }
Ok(Ctr::None) Ok(Ctr::None)
} }
@ -414,7 +416,8 @@ pub fn store_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback>
} }
} }
pub fn add_decl_lib_static(syms: &mut SymTable) { pub fn add_decl_lib_static(syms: &mut SymTable, print: fn(&String)) {
let help_print = print.clone();
syms.insert( syms.insert(
"help".to_string(), "help".to_string(),
Symbol { Symbol {
@ -422,7 +425,11 @@ pub fn add_decl_lib_static(syms: &mut SymTable) {
args: Args::Strict(vec![Type::Symbol]), args: Args::Strict(vec![Type::Symbol]),
conditional_branches: true, conditional_branches: true,
docs: HELP_DOCSTRING.to_string(), docs: HELP_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(help_callback)), value: ValueType::Internal(Rc::new(
move |ast: &Seg, syms: &mut SymTable| -> Result<Ctr, Traceback> {
help_callback(ast, syms, help_print)
}
)),
..Default::default() ..Default::default()
}, },
); );
@ -511,6 +518,7 @@ pub fn add_decl_lib_static(syms: &mut SymTable) {
} }
); );
let env_print = print.clone();
syms.insert( syms.insert(
"env".to_string(), "env".to_string(),
Symbol { Symbol {
@ -518,7 +526,11 @@ pub fn add_decl_lib_static(syms: &mut SymTable) {
args: Args::None, args: Args::None,
conditional_branches: false, conditional_branches: false,
docs: ENV_DOCSTRING.to_string(), docs: ENV_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(env_callback)), value: ValueType::Internal(Rc::new(
move |ast: &Seg, syms: &mut SymTable| -> Result<Ctr, Traceback> {
env_callback(ast, syms, env_print)
}
)),
..Default::default() ..Default::default()
}, },
); );

View file

@ -18,7 +18,12 @@
use crate::segment::{Ctr, Seg}; use crate::segment::{Ctr, Seg};
use crate::sym::{SymTable, ValueType, Symbol, Args}; use crate::sym::{SymTable, ValueType, Symbol, Args};
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use std::rc::Rc;
use libm::pow;
use alloc::rc::Rc;
use alloc::boxed::Box;
use alloc::string::{String, ToString};
fn isnumeric(arg: &Ctr) -> bool { fn isnumeric(arg: &Ctr) -> bool {
matches!(arg, Ctr::Integer(_) | Ctr::Float(_)) matches!(arg, Ctr::Integer(_) | Ctr::Float(_))
@ -189,12 +194,7 @@ fn floatcast_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> {
const EXP_DOCSTRING: &str = "Takes two args, both expected to be numeric. const EXP_DOCSTRING: &str = "Takes two args, both expected to be numeric.
Returns the first arg to the power of the second arg. Returns the first arg to the power of the second arg.
Does not handle overflow or underflow. Does not handle overflow or underflow.";
PANIC CASES:
- arg1 is a float and arg2 is greater than an int32
- an integer exceeding the size of a float64 is raised to a float power
- an integer is rased to the power of another integer exceeding the max size of an unsigned 32bit integer";
fn exp_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> { fn exp_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> {
let first = *ast.car.clone(); let first = *ast.car.clone();
if !isnumeric(&first) { if !isnumeric(&first) {
@ -218,15 +218,15 @@ fn exp_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> {
match first { match first {
Ctr::Float(lf) => match second { Ctr::Float(lf) => match second {
Ctr::Float(rf) => Ok(Ctr::Float(f64::powf(lf, rf))), Ctr::Float(rf) => Ok(Ctr::Float(pow(lf, rf))),
Ctr::Integer(ri) => Ok(Ctr::Float(f64::powi(lf, ri as i32))), Ctr::Integer(ri) => Ok(Ctr::Float(pow(lf as f64, ri as f64))),
_ => Err(start_trace( _ => Err(start_trace(
("exp", "not implemented for these input types") ("exp", "not implemented for these input types")
.into())), .into())),
}, },
Ctr::Integer(li) => match second { Ctr::Integer(li) => match second {
Ctr::Float(rf) => Ok(Ctr::Float(f64::powf(li as f64, rf))), Ctr::Float(rf) => Ok(Ctr::Float(pow(li as f64, rf))),
Ctr::Integer(ri) => Ok(Ctr::Integer(li.pow(ri as u32))), Ctr::Integer(ri) => Ok(Ctr::Float(pow(li as f64, ri as f64))),
_ => Err(start_trace( _ => Err(start_trace(
("exp", "not implemented for these input types") ("exp", "not implemented for these input types")
.into())), .into())),

View file

@ -18,18 +18,19 @@
use crate::segment::{Ctr, Seg, Type}; use crate::segment::{Ctr, Seg, Type};
use crate::sym::{SymTable, Symbol, ValueType, Args}; use crate::sym::{SymTable, Symbol, ValueType, Args};
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use std::io::Write; use alloc::rc::Rc;
use std::io; use alloc::boxed::Box;
use std::rc::Rc; use alloc::string::{String, ToString};
const ECHO_DOCSTRING: &str = const ECHO_DOCSTRING: &str =
"traverses any number of arguments. Prints their evaluated values on a new line for each."; "traverses any number of arguments. Prints their evaluated values on a new line for each.";
fn echo_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> { fn echo_callback(ast: &Seg, _syms: &mut SymTable, print_callback: fn(&String)) -> Result<Ctr, Traceback> {
ast.circuit(&mut |arg: &Ctr| match arg { ast.circuit(&mut |arg: &Ctr| match arg {
Ctr::String(s) => print!("{}", s) == (), Ctr::String(s) => print_callback(s) == (),
_ => print!("{}", arg) == (), _ => print_callback(&arg.to_string()) == (),
}); });
println!(); print_callback(&String::from("\n"));
Ok(Ctr::None) Ok(Ctr::None)
} }
@ -239,13 +240,15 @@ fn split_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
const INPUT_DOCSTRING: &str = "Takes one argument (string) and prints it. const INPUT_DOCSTRING: &str = "Takes one argument (string) and prints it.
Then prompts for user input. Then prompts for user input.
User input is returned as a string"; User input is returned as a string";
fn input_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> { fn input_callback(
ast: &Seg,
_syms: &mut SymTable,
print_callback: fn(&String),
read_callback: fn() -> String,
) -> Result<Ctr, Traceback> {
if let Ctr::String(ref s) = *ast.car { if let Ctr::String(ref s) = *ast.car {
print!("{}", s); print_callback(s);
let _= io::stdout().flush(); Ok(Ctr::String(read_callback()))
let mut input = String::new();
io::stdin().read_line(&mut input).expect("couldnt read user input");
Ok(Ctr::String(input.trim().to_string()))
} else { } else {
Err(start_trace( Err(start_trace(
("input", "expected a string input to prompt user with") ("input", "expected a string input to prompt user with")
@ -253,7 +256,8 @@ fn input_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
} }
} }
pub fn add_string_lib(syms: &mut SymTable) { pub fn add_string_lib(syms: &mut SymTable, print: fn(&String), read: fn() -> String) {
let echo_print = print.clone();
syms.insert( syms.insert(
"echo".to_string(), "echo".to_string(),
Symbol { Symbol {
@ -261,7 +265,11 @@ pub fn add_string_lib(syms: &mut SymTable) {
args: Args::Infinite, args: Args::Infinite,
conditional_branches: false, conditional_branches: false,
docs: ECHO_DOCSTRING.to_string(), docs: ECHO_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(echo_callback)), value: ValueType::Internal(Rc::new(
move |ast: &Seg, syms: &mut SymTable| -> Result<Ctr, Traceback> {
echo_callback(ast, syms, echo_print)
}
)),
..Default::default() ..Default::default()
}, },
); );
@ -344,6 +352,8 @@ pub fn add_string_lib(syms: &mut SymTable) {
}, },
); );
let input_print = print.clone();
let input_read = read.clone();
syms.insert( syms.insert(
"input".to_string(), "input".to_string(),
Symbol { Symbol {
@ -351,7 +361,11 @@ pub fn add_string_lib(syms: &mut SymTable) {
args: Args::Strict(vec![Type::String]), args: Args::Strict(vec![Type::String]),
conditional_branches: false, conditional_branches: false,
docs: INPUT_DOCSTRING.to_string(), docs: INPUT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(input_callback)), value: ValueType::Internal(Rc::new(
move |ast: &Seg, syms: &mut SymTable| -> Result<Ctr, Traceback> {
input_callback(ast, syms, input_print, input_read)
}
)),
..Default::default() ..Default::default()
} }
); );

View file

@ -15,15 +15,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#[path = "hashmap.rs"]
mod hashmap;
use hashmap::{QuickMap, QuickMapIter};
use crate::eval::eval; use crate::eval::eval;
use crate::error::{Traceback, start_trace}; use crate::error::{Traceback, start_trace};
use crate::segment::{Ctr, Seg, Type}; use crate::segment::{Ctr, Seg, Type};
use std::collections::HashMap; use alloc::fmt;
use std::fmt; use alloc::rc::Rc;
use std::rc::Rc; use alloc::vec::Vec;
use alloc::boxed::Box;
use alloc::string::{String, ToString};
#[derive(Clone)] #[derive(Clone)]
pub struct SymTable(HashMap<String, Symbol>, usize); pub struct SymTable(QuickMap<Symbol>, usize);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UserFn { pub struct UserFn {
@ -76,7 +82,7 @@ pub struct Symbol {
impl SymTable { impl SymTable {
pub fn new() -> SymTable { pub fn new() -> SymTable {
SymTable(HashMap::<String, Symbol>::new(), 0) SymTable(QuickMap::<Symbol>::new(), 0)
} }
pub fn get(&self, arg: &String) -> Option<&Symbol> { pub fn get(&self, arg: &String) -> Option<&Symbol> {
@ -97,33 +103,30 @@ impl SymTable {
self.0.remove(arg) self.0.remove(arg)
} }
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, String, Symbol> { pub fn iter(&self) -> QuickMapIter<'_, Symbol>{
self.0.iter() self.0.iter()
} }
pub fn keys(&self) -> std::collections::hash_map::Keys<String, Symbol> {
self.0.keys()
}
pub fn update(&mut self, other: &mut SymTable) { pub fn update(&mut self, other: &mut SymTable) {
/* updates self with all syms in other that match the following cases: /* updates self with all syms in other that match the following cases:
* * sym is not in self * * sym is not in self
* * sym has a newer generation than the entry in self * * sym has a newer generation than the entry in self
*
* TODO: Write a method for QuickMap for update in place
* so that none of these need to be reallocated
*/ */
let tmp = self.1; let tmp = self.1;
for i in other.iter() { for i in other.iter() {
self.0.entry(i.0.to_string()) let s = self.0
.and_modify(|inner: &mut Symbol| { .remove(&i.0)
if tmp < i.1.__generation { .map_or(
inner.__generation = i.1.__generation; i.1.clone(),
inner.value = i.1.value.clone(); |existing| if tmp < i.1.__generation {
inner.args = i.1.args.clone(); i.1.clone()
inner.docs = i.1.docs.clone(); } else {
inner.conditional_branches = i.1.conditional_branches; existing
inner.name = i.1.name.clone(); });
} self.0.insert(i.0.to_string(), s);
})
.or_insert(i.1.clone());
} }
} }

View file

@ -102,7 +102,7 @@ mod eval_tests {
let rh_doc = "(apply (lambda (x) (car x)) (1 2 3))"; let rh_doc = "(apply (lambda (x) (car x)) (1 2 3))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&comparator.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&comparator.to_string()).unwrap(), &mut syms).unwrap();
assert_eq!( assert_eq!(

View file

@ -7,7 +7,7 @@ mod append_lib_tests {
let document = "(cons () 1)"; let document = "(cons () 1)";
let result = "(1)"; let result = "(1)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -22,7 +22,7 @@ mod append_lib_tests {
let result = "(1 \"two\" 3.4)"; let result = "(1 \"two\" 3.4)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -37,7 +37,7 @@ mod append_lib_tests {
let result = "(1 2 3)"; let result = "(1 2 3)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -52,7 +52,7 @@ mod append_lib_tests {
let result = "(<nil>)"; let result = "(<nil>)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -67,7 +67,7 @@ mod append_lib_tests {
let result = "(\"test\" 1 2 3)"; let result = "(\"test\" 1 2 3)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -82,7 +82,7 @@ mod append_lib_tests {
let result = "0"; let result = "0";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -97,7 +97,7 @@ mod append_lib_tests {
let result = "3"; let result = "3";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -111,7 +111,7 @@ mod append_lib_tests {
let document = "(car ())"; let document = "(car ())";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.err() .err()
@ -130,7 +130,7 @@ mod append_lib_tests {
let result = "1"; let result = "1";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -144,7 +144,7 @@ mod append_lib_tests {
let document = "(cdr ())"; let document = "(cdr ())";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -164,7 +164,7 @@ mod append_lib_tests {
let result = "3"; let result = "3";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -183,7 +183,7 @@ mod append_lib_tests {
let result2 = "(2 3)"; let result2 = "(2 3)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
let ch1 = lex(&check1.to_string()).unwrap(); let ch1 = lex(&check1.to_string()).unwrap();
@ -209,7 +209,7 @@ mod append_lib_tests {
let result2 = "(<nil>)"; let result2 = "(<nil>)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
let ch1 = lex(&check1.to_string()).unwrap(); let ch1 = lex(&check1.to_string()).unwrap();
@ -235,7 +235,7 @@ mod append_lib_tests {
let result2 = "(1 2)"; let result2 = "(1 2)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
let ch1 = lex(&check1.to_string()).unwrap(); let ch1 = lex(&check1.to_string()).unwrap();
@ -261,7 +261,7 @@ mod append_lib_tests {
let result2 = "(<nil>)"; let result2 = "(<nil>)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
let ch1 = lex(&check1.to_string()).unwrap(); let ch1 = lex(&check1.to_string()).unwrap();
@ -284,7 +284,7 @@ mod append_lib_tests {
let result = "(3 2 1 \"test\")"; let result = "(3 2 1 \"test\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -300,7 +300,7 @@ mod append_lib_tests {
let result = "(\"test\")"; let result = "(\"test\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -316,7 +316,7 @@ mod append_lib_tests {
let result = "(<nil>)"; let result = "(<nil>)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -332,7 +332,7 @@ mod append_lib_tests {
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -348,7 +348,7 @@ mod append_lib_tests {
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)

View file

@ -7,7 +7,7 @@ mod bool_lib_tests {
let document = "(and true true true true true)"; let document = "(and true true true true true)";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -21,7 +21,7 @@ mod bool_lib_tests {
let document = "(and true true false true true)"; let document = "(and true true false true true)";
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -35,7 +35,7 @@ mod bool_lib_tests {
let document = "(and false false false false false)"; let document = "(and false false false false false)";
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -49,7 +49,7 @@ mod bool_lib_tests {
let document = "(or true true true true true)"; let document = "(or true true true true true)";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -63,7 +63,7 @@ mod bool_lib_tests {
let document = "(or true true false true true)"; let document = "(or true true false true true)";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -77,7 +77,7 @@ mod bool_lib_tests {
let document = "(or false false false false false)"; let document = "(or false false false false false)";
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -91,7 +91,7 @@ mod bool_lib_tests {
let document = "(not true)"; let document = "(not true)";
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -107,7 +107,7 @@ mod bool_lib_tests {
let check = "(tester)"; let check = "(tester)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -145,7 +145,7 @@ mod bool_lib_tests {
let check = "(tester)"; let check = "(tester)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -177,7 +177,7 @@ mod bool_lib_tests {
let check = "(tester \"1\")"; let check = "(tester \"1\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -206,7 +206,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(b) assert!(b)
@ -221,7 +221,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)
@ -236,7 +236,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)
@ -251,7 +251,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)
@ -266,7 +266,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(b) assert!(b)
@ -281,7 +281,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(b) assert!(b)
@ -296,7 +296,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)
@ -311,7 +311,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(b) assert!(b)
@ -326,7 +326,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)
@ -341,7 +341,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(b) assert!(b)
@ -356,7 +356,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)
@ -371,7 +371,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(b) assert!(b)
@ -386,7 +386,7 @@ mod bool_lib_tests {
let test = lex(&document.to_string()).unwrap(); let test = lex(&document.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() {
assert!(!b) assert!(!b)

View file

@ -6,7 +6,7 @@ mod control_lib_tests {
fn test_assert_t() { fn test_assert_t() {
let document = "(assert true)"; let document = "(assert true)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
} }
@ -14,7 +14,7 @@ mod control_lib_tests {
fn test_assert_f() { fn test_assert_f() {
let document = "(assert false)"; let document = "(assert false)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert!(eval(&lex(&document.to_string()).unwrap(), &mut syms).is_err()) assert!(eval(&lex(&document.to_string()).unwrap(), &mut syms).is_err())
} }
@ -23,7 +23,7 @@ mod control_lib_tests {
let document = "(if true 1 2)"; let document = "(if true 1 2)";
let result = 1; let result = 1;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -37,7 +37,7 @@ mod control_lib_tests {
let document = "(if false 1 2)"; let document = "(if false 1 2)";
let result = 2; let result = 2;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -51,7 +51,7 @@ mod control_lib_tests {
let document = "(if true (cons () 1) 2)"; let document = "(if true (cons () 1) 2)";
let result = "(1)"; let result = "(1)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -68,7 +68,7 @@ mod control_lib_tests {
temp)"; temp)";
let result = "(\"1\" \"2\")"; let result = "(\"1\" \"2\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -86,7 +86,7 @@ mod control_lib_tests {
let document2 = "global"; let document2 = "global";
let result = "(\"hello world\")"; let result = "(\"hello world\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&document1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&document1.to_string()).unwrap(), &mut syms).unwrap();
assert_eq!( assert_eq!(
*eval(&lex(&document2.to_string()).unwrap(), &mut syms) *eval(&lex(&document2.to_string()).unwrap(), &mut syms)
@ -101,7 +101,7 @@ mod control_lib_tests {
let document = "(let ((temp \"1\")) temp (cons () temp \"2\"))"; let document = "(let ((temp \"1\")) temp (cons () temp \"2\"))";
let result = "(\"1\" \"2\")"; let result = "(\"1\" \"2\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -120,7 +120,7 @@ mod control_lib_tests {
let result = "(\"1\" \"2\" \"3\")"; let result = "(\"1\" \"2\" \"3\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -148,7 +148,7 @@ mod control_lib_tests {
let check_tree = lex(&test_check.to_string()).unwrap(); let check_tree = lex(&test_check.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&switch_tree, &mut syms).unwrap(); eval(&switch_tree, &mut syms).unwrap();
eval(&while_tree, &mut syms).unwrap(); eval(&while_tree, &mut syms).unwrap();
@ -174,7 +174,7 @@ mod control_lib_tests {
let check_tree = lex(&test_check.to_string()).unwrap(); let check_tree = lex(&test_check.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&switch_tree, &mut syms).unwrap(); eval(&switch_tree, &mut syms).unwrap();
eval(&while_tree, &mut syms).unwrap(); eval(&while_tree, &mut syms).unwrap();
@ -200,7 +200,7 @@ mod control_lib_tests {
let check_tree = lex(&test_check.to_string()).unwrap(); let check_tree = lex(&test_check.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&another_tree, &mut syms).unwrap(); eval(&another_tree, &mut syms).unwrap();
eval(&switch_tree, &mut syms).unwrap(); eval(&switch_tree, &mut syms).unwrap();
@ -217,7 +217,7 @@ mod control_lib_tests {
let test_tree = lex(&test.to_string()).unwrap(); let test_tree = lex(&test.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&doc_tree, &mut syms).unwrap(); eval(&doc_tree, &mut syms).unwrap();
let res = eval(&test_tree, &mut syms); let res = eval(&test_tree, &mut syms);
@ -234,7 +234,7 @@ mod control_lib_tests {
let test_tree = lex(&test.to_string()).unwrap(); let test_tree = lex(&test.to_string()).unwrap();
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&doc_tree, &mut syms).unwrap(); eval(&doc_tree, &mut syms).unwrap();
assert_eq!( assert_eq!(

View file

@ -9,7 +9,7 @@ mod decl_lib_tests {
let result = "(1)"; let result = "(1)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -23,7 +23,7 @@ mod decl_lib_tests {
let result = "((1))"; let result = "((1))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -37,7 +37,7 @@ mod decl_lib_tests {
let result = "1"; let result = "1";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -52,7 +52,7 @@ mod decl_lib_tests {
let result = "(\"2\")"; let result = "(\"2\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -68,7 +68,7 @@ mod decl_lib_tests {
let doc3 = "(test)"; let doc3 = "(test)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -95,7 +95,7 @@ mod decl_lib_tests {
let res2 = "(\"2\")"; let res2 = "(\"2\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -117,7 +117,7 @@ mod decl_lib_tests {
(eq? test \"one\")))"; (eq? test \"one\")))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -135,7 +135,7 @@ mod decl_lib_tests {
let result = "1"; let result = "1";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap();
let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap();
@ -148,7 +148,7 @@ mod decl_lib_tests {
let doc2 = "(set? test)"; let doc2 = "(set? test)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let def_tree = lex(&doc1.to_string()).unwrap(); let def_tree = lex(&doc1.to_string()).unwrap();
let set_tree = lex(&doc2.to_string()).unwrap(); let set_tree = lex(&doc2.to_string()).unwrap();
@ -162,7 +162,7 @@ mod decl_lib_tests {
fn test_isset_false() { fn test_isset_false() {
let doc = "(set? test)"; let doc = "(set? test)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let set_tree = lex(&doc.to_string()).unwrap(); let set_tree = lex(&doc.to_string()).unwrap();
if let Ctr::Bool(b) = *eval(&set_tree, &mut syms).unwrap() { if let Ctr::Bool(b) = *eval(&set_tree, &mut syms).unwrap() {
assert!(!b); assert!(!b);
@ -175,7 +175,7 @@ mod decl_lib_tests {
let doc2 = "(env)"; let doc2 = "(env)";
let doc3 = "t"; let doc3 = "t";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let set_tree = lex(&doc1.to_string()).unwrap(); let set_tree = lex(&doc1.to_string()).unwrap();
let env_tree = lex(&doc2.to_string()).unwrap(); let env_tree = lex(&doc2.to_string()).unwrap();
let tst_tree = lex(&doc3.to_string()).unwrap(); let tst_tree = lex(&doc3.to_string()).unwrap();
@ -189,7 +189,7 @@ mod decl_lib_tests {
let document = "(quote (add 1 2))"; let document = "(quote (add 1 2))";
let result = "(add 1 2)"; let result = "(add 1 2)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -205,7 +205,7 @@ mod decl_lib_tests {
(eval stored-tree)))"; (eval stored-tree)))";
let result = "3"; let result = "3";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -219,7 +219,7 @@ mod decl_lib_tests {
let document = "(eval (1 2 3))"; let document = "(eval (1 2 3))";
let result = "(1 2 3)"; let result = "(1 2 3)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -232,7 +232,7 @@ mod decl_lib_tests {
fn test_lambda_str_equivalency_list() { fn test_lambda_str_equivalency_list() {
let document = "(lambda (x y) (add x y))"; let document = "(lambda (x y) (add x y))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -245,7 +245,7 @@ mod decl_lib_tests {
fn test_lambda_str_equivalency_no_args() { fn test_lambda_str_equivalency_no_args() {
let document = "(lambda () (add 1 2))"; let document = "(lambda () (add 1 2))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -258,7 +258,7 @@ mod decl_lib_tests {
fn test_lambda_inline_call() { fn test_lambda_inline_call() {
let document = "((lambda (x y) (add x y)) 1 2)"; let document = "((lambda (x y) (add x y)) 1 2)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let it = *eval( let it = *eval(
&lex(&document.to_string()).unwrap(), &lex(&document.to_string()).unwrap(),
&mut syms).unwrap(); &mut syms).unwrap();
@ -274,7 +274,7 @@ mod decl_lib_tests {
let document = "(let ((adder (lambda (x y) (add x y)))) let document = "(let ((adder (lambda (x y) (add x y))))
(adder 1 2))"; (adder 1 2))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let it = *eval( let it = *eval(
&lex(&document.to_string()).unwrap(), &lex(&document.to_string()).unwrap(),
&mut syms).unwrap(); &mut syms).unwrap();
@ -291,7 +291,7 @@ mod decl_lib_tests {
(def adder \"my adder\" (lambda (x y) (add x y))) (def adder \"my adder\" (lambda (x y) (add x y)))
(adder 1 2))"; (adder 1 2))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let it = *eval( let it = *eval(
&lex(&document.to_string()).unwrap(), &lex(&document.to_string()).unwrap(),
&mut syms).unwrap(); &mut syms).unwrap();
@ -309,7 +309,7 @@ mod decl_lib_tests {
(def adder \"my adder\" (lambda (x) (add x 1))) (def adder \"my adder\" (lambda (x) (add x 1)))
(appl adder 2))"; (appl adder 2))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let it = *eval( let it = *eval(
&lex(&document.to_string()).unwrap(), &lex(&document.to_string()).unwrap(),
&mut syms).unwrap(); &mut syms).unwrap();
@ -326,7 +326,7 @@ mod decl_lib_tests {
let highly_inadvisable = "(set-doc (q help) \"help\")"; let highly_inadvisable = "(set-doc (q help) \"help\")";
let document = "(get-doc (q help))"; let document = "(get-doc (q help))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let _ = *eval( let _ = *eval(
&lex(&highly_inadvisable.to_string()).unwrap(), &lex(&highly_inadvisable.to_string()).unwrap(),
&mut syms).unwrap(); &mut syms).unwrap();
@ -344,7 +344,7 @@ mod decl_lib_tests {
fn test_eval_quote() { fn test_eval_quote() {
let doc = "(eval (quote (add 1 1)))"; let doc = "(eval (quote (add 1 1)))";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&doc.to_string()).unwrap(), &mut syms).unwrap().to_string(), *eval(&lex(&doc.to_string()).unwrap(), &mut syms).unwrap().to_string(),
2.to_string() 2.to_string()

View file

@ -1,6 +1,7 @@
mod math_lib_tests { mod math_lib_tests {
use flesh::ast::{eval, lex, Ctr, SymTable}; use flesh::ast::{eval, lex, Ctr, SymTable};
use flesh::stdlib::static_stdlib; use flesh::stdlib::static_stdlib;
use libm::pow;
#[test] #[test]
fn test_add_chain() { fn test_add_chain() {
@ -8,7 +9,7 @@ mod math_lib_tests {
let result = "10"; let result = "10";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -23,7 +24,7 @@ mod math_lib_tests {
let result = "10.2"; let result = "10.2";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -38,7 +39,7 @@ mod math_lib_tests {
let result = "24"; let result = "24";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -53,7 +54,7 @@ mod math_lib_tests {
let result = "-8.2"; let result = "-8.2";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -68,7 +69,7 @@ mod math_lib_tests {
let result = "2"; let result = "2";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -83,7 +84,7 @@ mod math_lib_tests {
let result = "10"; let result = "10";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -98,7 +99,7 @@ mod math_lib_tests {
let result = "10"; let result = "10";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -113,7 +114,7 @@ mod math_lib_tests {
let result = "10"; let result = "10";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -128,7 +129,7 @@ mod math_lib_tests {
let result = "10.3"; let result = "10.3";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -140,10 +141,10 @@ mod math_lib_tests {
#[test] #[test]
fn test_ii_exp() { fn test_ii_exp() {
let document = "(exp 7 20)"; let document = "(exp 7 20)";
let result = 7i128.pow(20); let result = pow(7 as f64, 20 as f64);
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -158,7 +159,7 @@ mod math_lib_tests {
let result = f64::powf(1f64, 10.2); let result = f64::powf(1f64, 10.2);
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -169,26 +170,26 @@ mod math_lib_tests {
#[test] #[test]
fn test_fi_exp() { fn test_fi_exp() {
let document = "(exp 1.2 5)"; let document = "(exp 10.2 1)";
let result = f64::powf(1.2, 5f64); let result = pow(10.2 as f64, 1 as f64);
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
.to_string(), .to_string(),
format!("{:.5}", result), result.to_string(),
); );
} }
#[test] #[test]
fn test_ff_exp() { fn test_ff_exp() {
let document = "(exp 1.3 1.5)"; let document = "(exp 1.4 1.5)";
let result = f64::powf(1.3, 1.5); let result = pow(1.4, 1.5);
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -206,7 +207,7 @@ mod math_lib_tests {
let result2 = "1"; let result2 = "1";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
assert_eq!( assert_eq!(
*eval(&lex(&check1.to_string()).unwrap(), &mut syms) *eval(&lex(&check1.to_string()).unwrap(), &mut syms)
@ -229,7 +230,7 @@ mod math_lib_tests {
let result1 = "2"; let result1 = "2";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
assert_eq!( assert_eq!(
*eval(&lex(&check1.to_string()).unwrap(), &mut syms) *eval(&lex(&check1.to_string()).unwrap(), &mut syms)
@ -245,7 +246,7 @@ mod math_lib_tests {
let check1 = "(car test)"; let check1 = "(car test)";
let result1 = "3"; let result1 = "3";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
assert_eq!( assert_eq!(
*eval(&lex(&check1.to_string()).unwrap(), &mut syms) *eval(&lex(&check1.to_string()).unwrap(), &mut syms)
@ -262,7 +263,7 @@ mod math_lib_tests {
let result1 = "2"; let result1 = "2";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap(); let _ = *eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
assert_eq!( assert_eq!(
*eval(&lex(&check1.to_string()).unwrap(), &mut syms) *eval(&lex(&check1.to_string()).unwrap(), &mut syms)
@ -278,7 +279,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -293,7 +294,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -308,7 +309,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -323,7 +324,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -338,7 +339,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -353,7 +354,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -368,7 +369,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -383,7 +384,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -398,7 +399,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -413,7 +414,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -428,7 +429,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -443,7 +444,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -458,7 +459,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -473,7 +474,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -488,7 +489,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -503,7 +504,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -518,7 +519,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -533,7 +534,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -548,7 +549,7 @@ mod math_lib_tests {
let result = false; let result = false;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -563,7 +564,7 @@ mod math_lib_tests {
let result = true; let result = true;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -579,7 +580,7 @@ mod math_lib_tests {
let check = "(tester)"; let check = "(tester)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -617,7 +618,7 @@ mod math_lib_tests {
let check = "(tester)"; let check = "(tester)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -649,7 +650,7 @@ mod math_lib_tests {
let check = "(tester \"1\")"; let check = "(tester \"1\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -679,7 +680,7 @@ mod math_lib_tests {
let check = "(tester)"; let check = "(tester)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -717,7 +718,7 @@ mod math_lib_tests {
let check = "(tester)"; let check = "(tester)";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();
@ -749,7 +750,7 @@ mod math_lib_tests {
let check = "(tester \"1\")"; let check = "(tester \"1\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_tree = lex(&document.to_string()).unwrap(); let doc_tree = lex(&document.to_string()).unwrap();
let change_tree = lex(&change.to_string()).unwrap(); let change_tree = lex(&change.to_string()).unwrap();

View file

@ -7,7 +7,7 @@ mod str_lib_tests {
let document = "(concat \"test\")"; let document = "(concat \"test\")";
let result = "\"test\""; let result = "\"test\"";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -21,7 +21,7 @@ mod str_lib_tests {
let document = "(concat \"test\" 1 2 3)"; let document = "(concat \"test\" 1 2 3)";
let result = "\"test123\""; let result = "\"test123\"";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -35,7 +35,7 @@ mod str_lib_tests {
let document = "(concat)"; let document = "(concat)";
let result = "\"\""; let result = "\"\"";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -49,7 +49,7 @@ mod str_lib_tests {
let document = "(strlen \"test\")"; let document = "(strlen \"test\")";
let result = 4; let result = 4;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -63,7 +63,7 @@ mod str_lib_tests {
let document = "(strlen 1000)"; let document = "(strlen 1000)";
let result = 4; let result = 4;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -77,7 +77,7 @@ mod str_lib_tests {
let document = "(strlen 10.2)"; let document = "(strlen 10.2)";
let result = 4; let result = 4;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -91,7 +91,7 @@ mod str_lib_tests {
let document = "(strlen (1 2 3))"; let document = "(strlen (1 2 3))";
let result = 7; let result = 7;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -105,7 +105,7 @@ mod str_lib_tests {
let document = "(strlen true)"; let document = "(strlen true)";
let result = 4; let result = 4;
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -119,7 +119,7 @@ mod str_lib_tests {
let document = "(string 4)"; let document = "(string 4)";
let result = "\"4\""; let result = "\"4\"";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -133,7 +133,7 @@ mod str_lib_tests {
let document = "(string (1 2 3))"; let document = "(string (1 2 3))";
let result = "\"(1 2 3)\""; let result = "\"(1 2 3)\"";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -147,7 +147,7 @@ mod str_lib_tests {
let document = "(substr? \"bigger\" \"ger\")"; let document = "(substr? \"bigger\" \"ger\")";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -161,7 +161,7 @@ mod str_lib_tests {
let document = "(substr? \"smaller\" \"ger\")"; let document = "(substr? \"smaller\" \"ger\")";
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -175,7 +175,7 @@ mod str_lib_tests {
let document = "(split \"one.two.three\" \".\")"; let document = "(split \"one.two.three\" \".\")";
let result = "(\"one\" \"two\" \"three\")"; let result = "(\"one\" \"two\" \"three\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -189,7 +189,7 @@ mod str_lib_tests {
let document = "(split \"one:d:two:d:three\" \":d:\")"; let document = "(split \"one:d:two:d:three\" \":d:\")";
let result = "(\"one\" \"two\" \"three\")"; let result = "(\"one\" \"two\" \"three\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -203,7 +203,7 @@ mod str_lib_tests {
let document = "(split \"one.two.three\" \"-\")"; let document = "(split \"one.two.three\" \"-\")";
let result = "(\"one.two.three\")"; let result = "(\"one.two.three\")";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -217,7 +217,7 @@ mod str_lib_tests {
let document = "(substr \"test\" 0 4)"; let document = "(substr \"test\" 0 4)";
let result = "\"test\""; let result = "\"test\"";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
.unwrap() .unwrap()
@ -231,7 +231,7 @@ mod str_lib_tests {
let document = "(substr \"test\" -1 3)"; let document = "(substr \"test\" -1 3)";
let result = "start index cannot be negative"; let result = "start index cannot be negative";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms); let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms);
if let Err(e) = doc_res { if let Err(e) = doc_res {
assert_eq!( assert_eq!(
@ -248,7 +248,7 @@ mod str_lib_tests {
let document = "(substr \"test\" 1 -3)"; let document = "(substr \"test\" 1 -3)";
let result = "end index cannot be negative"; let result = "end index cannot be negative";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms); let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms);
if let Err(e) = doc_res { if let Err(e) = doc_res {
assert_eq!( assert_eq!(
@ -265,7 +265,7 @@ mod str_lib_tests {
let document = "(substr \"test\" 5 3)"; let document = "(substr \"test\" 5 3)";
let result = "start index larger than source string"; let result = "start index larger than source string";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms); let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms);
if let Err(e) = doc_res { if let Err(e) = doc_res {
assert_eq!( assert_eq!(
@ -282,7 +282,7 @@ mod str_lib_tests {
let document = "(substr \"test\" 1 5)"; let document = "(substr \"test\" 1 5)";
let result = "end index larger than source string"; let result = "end index larger than source string";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms); let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms);
if let Err(e) = doc_res { if let Err(e) = doc_res {
assert_eq!( assert_eq!(
@ -299,7 +299,7 @@ mod str_lib_tests {
let document = "(substr \"test\" 3 2)"; let document = "(substr \"test\" 3 2)";
let result = "end index must be larger than start index"; let result = "end index must be larger than start index";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms); let doc_res= eval(&lex(&document.to_string()).unwrap(), &mut syms);
if let Err(e) = doc_res { if let Err(e) = doc_res {
assert_eq!( assert_eq!(

View file

@ -184,7 +184,7 @@ mod tests {
let document = "(exists? \"/tmp\")"; let document = "(exists? \"/tmp\")";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms); static_stdlib_overwrites(&mut syms);
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -199,7 +199,7 @@ mod tests {
let document = "(exists? \"cargo.timtam\")"; let document = "(exists? \"cargo.timtam\")";
let result = "false"; let result = "false";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms); static_stdlib_overwrites(&mut syms);
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -219,7 +219,7 @@ mod tests {
(eq? (read-file t) s))"; (eq? (read-file t) s))";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms); static_stdlib_overwrites(&mut syms);
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)
@ -240,7 +240,7 @@ mod tests {
(concat s s)))"; (concat s s)))";
let result = "true"; let result = "true";
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
static_stdlib_overwrites(&mut syms); static_stdlib_overwrites(&mut syms);
assert_eq!( assert_eq!(
*eval(&lex(&document.to_string()).unwrap(), &mut syms) *eval(&lex(&document.to_string()).unwrap(), &mut syms)

View file

@ -466,11 +466,9 @@ fn make_prompt(syms: &mut SymTable) -> CustomPrompt {
} }
fn make_completer(syms: &mut SymTable) -> CustomCompleter { fn make_completer(syms: &mut SymTable) -> CustomCompleter {
let mut toks = vec![]; CustomCompleter(syms.iter()
for i in syms.keys(){ .map(|i| i.0.clone())
toks.push(i.clone()); .collect())
}
CustomCompleter(toks)
} }
fn get_token_to_complete(line: &str, pos: usize) -> (String, bool, usize) { fn get_token_to_complete(line: &str, pos: usize) -> (String, bool, usize) {

View file

@ -23,7 +23,7 @@ use {
}, },
crate::run, crate::run,
libc::{ libc::{
sigaddset, sigemptyset, sigprocmask, exit, sigaddset, sigemptyset, sigprocmask,
SIGINT, SIGCHLD, SIGTTOU, SIGTTIN, SIGQUIT, SIGTSTP, SIGINT, SIGCHLD, SIGTTOU, SIGTTIN, SIGQUIT, SIGTSTP,
SIG_BLOCK, SIG_UNBLOCK SIG_BLOCK, SIG_UNBLOCK
}, },
@ -43,6 +43,7 @@ use {
os::unix::process::CommandExt, os::unix::process::CommandExt,
mem, mem,
thread, thread,
process,
time::Duration, time::Duration,
}, },
nix::{ nix::{
@ -619,19 +620,6 @@ fn q_callback(_ast: &Seg, _syms: &SymTable, state: &mut ShellState) -> Result<Ct
Ok(Ctr::Integer(state.last_exit_code.into())) Ok(Ctr::Integer(state.last_exit_code.into()))
} }
const EXIT_DOCSTRING: &str = "Takes on integer input. calls libc exit() with given argument.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
let mut ret = -1;
if let Ctr::Integer(i) = *ast.car {
ret = i;
} else {
eprintln!("WARNING: input was not an integer. Exiting -1.")
}
unsafe {
exit(ret as i32);
}
}
const BG_DOCSTRING: &str = "Calls a binary off disk with given arguments. const BG_DOCSTRING: &str = "Calls a binary off disk with given arguments.
Arguments may be of any type except lambda. If a symbol is not defined it will be passed as a string. Arguments may be of any type except lambda. If a symbol is not defined it will be passed as a string.
first argument (command name) will be found on path (or an error returned). first argument (command name) will be found on path (or an error returned).
@ -780,7 +768,34 @@ fn cd_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
} }
} }
const EXIT_DOCSTRING: &str = "Takes on input: an integer used as an exit code.
Entire REPL process quits with exit code.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
if let Ctr::Integer(i) = *ast.car {
if i > 2 ^ 32 {
panic!("argument to exit too large!")
} else {
process::exit(i as i32);
}
} else {
panic!("impossible argument to exit")
}
}
pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>>) { pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>>) {
syms.insert(
"exit".to_string(),
Symbol {
name: String::from("exit"),
args: Args::Strict(vec![Type::Integer]),
conditional_branches: false,
docs: EXIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(exit_callback)),
..Default::default()
},
);
let pid = unistd::getpid(); let pid = unistd::getpid();
let pgid_res = unistd::getpgid(Some(pid)); let pgid_res = unistd::getpgid(Some(pid));
let sid_res = unistd::getsid(Some(pid)); let sid_res = unistd::getsid(Some(pid));
@ -986,7 +1001,7 @@ mod tests {
let result = vec!["binary"]; let result = vec!["binary"];
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) { if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!( assert_eq!(
@ -1004,7 +1019,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true"]; let result = vec!["binary", "--flag=1", "122", "yeet", "true"];
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) { if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!( assert_eq!(
@ -1022,7 +1037,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true", "syms"]; let result = vec!["binary", "--flag=1", "122", "yeet", "true", "syms"];
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) { if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!( assert_eq!(
@ -1041,7 +1056,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true", "1"]; let result = vec!["binary", "--flag=1", "122", "yeet", "true", "1"];
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
eval(&lex(&decl.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&decl.to_string()).unwrap(), &mut syms).unwrap();
@ -1061,7 +1076,7 @@ mod tests {
let result = vec!["binary", "--flag=1", "122", "yeet", "true", "3"]; let result = vec!["binary", "--flag=1", "122", "yeet", "true", "3"];
let mut syms = SymTable::new(); let mut syms = SymTable::new();
static_stdlib(&mut syms); static_stdlib(&mut syms, |_: &String| (), || String::new());
if let Ok(ref s) = lex(&document.to_string()) { if let Ok(ref s) = lex(&document.to_string()) {
assert_eq!( assert_eq!(

View file

@ -25,6 +25,7 @@ use crate::run::{run_callback, RUN_DOCSTRING};
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use std::env::vars; use std::env::vars;
use std::io;
#[cfg(feature = "posix")] #[cfg(feature = "posix")]
use crate::posix; use crate::posix;
@ -63,7 +64,16 @@ fn prompt_delimiter_default_callback(_: &Seg, _: &mut SymTable) -> Result<Ctr, T
/// inserts all stdlib functions that can be inserted without /// inserts all stdlib functions that can be inserted without
/// any kind of further configuration data into a symtable /// any kind of further configuration data into a symtable
pub fn static_stdlib_overwrites(syms: &mut SymTable) { pub fn static_stdlib_overwrites(syms: &mut SymTable) {
static_stdlib(syms); static_stdlib(
syms,
|arg: &String| print!("{}", arg),
|| -> String {
let _= io::stdout();
let mut input = String::new();
io::stdin().read_line(&mut input).expect("couldnt read user input");
input.trim().to_string()
},
);
window::add_window_lib_funcs(syms); window::add_window_lib_funcs(syms);
file::add_file_lib(syms); file::add_file_lib(syms);