diff --git a/src/append.rs b/src/append.rs index 415cf05..8819713 100644 --- a/src/append.rs +++ b/src/append.rs @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -/* + use crate::func::{FTable, Function, Args, Operation}; use crate::vars::{VTable}; use crate::segment::{Ctr, Ast, circuit, list_idx, list_append, new_ast}; @@ -27,7 +27,7 @@ pub fn get_append() -> Function { loose_syms: false, eval_lazy: false, args: Args::Lazy(-1), - function: Operation::Internal( + function: Operation::Internal(Box::new( |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { let ptr = list_idx(a.clone(), 0); match ptr { @@ -63,6 +63,6 @@ pub fn get_append() -> Function { } } } - ) + )) }; -}*/ +} diff --git a/src/config.rs b/src/config.rs index 1a0a67e..0b45ba2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,7 +16,7 @@ */ use crate::vars::{VTable, define}; -use crate::func::{FTable, Args, Function, Operation, InternalOperation, func_declare}; +use crate::func::{FTable, Args, Function, Operation, func_declare}; use crate::segment::{Ast, Ctr}; use crate::lex::lex; use crate::eval::eval; @@ -25,13 +25,11 @@ use std::rc::Rc; use std::cell::RefCell; use std::fs; -/* -fn get_prompt_default() -> InternalOperation { - |_: Ast, _: Rc>, _: Rc>| -> Ctr { - print!("λ "); - return Ctr::None; - } -}*/ + +fn prompt_default_callback(_: Ast, _: Rc>, _: Rc>) -> Ctr { + print!("λ "); + return Ctr::None; +} pub fn configure(filename: String, vars: Rc>, mut funcs: Rc>) { define(vars.clone(), String::from("CFG_RELISH_POSIX"), Rc::new(Ctr::String(String::from("0")))); @@ -42,14 +40,14 @@ pub fn configure(filename: String, vars: Rc>, mut funcs: Rc println!("{}", s) } - /* + func_declare(funcs.clone(), Rc::new(RefCell::new(Function{ name: String::from("CFG_RELISH_PROMPT"), loose_syms: false, eval_lazy: false, args: Args::Lazy(0), - function: Operation::Internal(get_prompt_default()) - })));*/ + function: Operation::Internal(Box::new(prompt_default_callback)) + }))); match fs::read_to_string(filename) { Err(s) => { diff --git a/src/func.rs b/src/func.rs index 7e6ac27..07b3b5a 100644 --- a/src/func.rs +++ b/src/func.rs @@ -26,7 +26,7 @@ use crate::eval::eval; pub type FTable = HashMap>>; // Standardized function signature for stdlib functions -pub type InternalOperation = impl Fn(Ast, Rc>, Rc>) -> Ctr; +//pub type InternalOperation = impl Fn(Ast, Rc>, Rc>) -> Ctr; pub struct ExternalOperation { // Un-evaluated abstract syntax tree // TODO: Intermediate evaluation to simplify branches with no argument in them @@ -41,7 +41,7 @@ pub struct ExternalOperation { * or a syntax tree to eval with the arguments */ pub enum Operation { - Internal(InternalOperation), + Internal(Box>, Rc>)->Ctr>), External(ExternalOperation) } @@ -160,9 +160,10 @@ pub fn func_call( } match &called_func.function { - Operation::Internal(f) => Ok((f)(n_args, vars, funcs)), + Operation::Internal(f) => { + return Ok(f(n_args, vars, funcs)) + }, Operation::External(f) => { - for n in 0..f.arg_syms.len() { let iter_arg = list_idx(n_args.clone(), n as u128); diff --git a/src/lib.rs b/src/lib.rs index 8afda30..633a639 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -#![feature(type_alias_impl_trait)] mod segment; mod lex; @@ -31,16 +30,15 @@ pub mod ast { pub use crate::segment::{Seg, Ctr, ast_to_string, Type, Ast, new_ast}; pub use crate::lex::lex; pub use crate::func::{Function, Operation, FTable, Args, - InternalOperation, ExternalOperation, - func_declare, func_call}; + ExternalOperation, func_declare, func_call}; pub use crate::vars::{VTable, define}; pub use crate::eval::eval; } pub mod stdlib { pub use crate::stl::{get_stdlib}; -// pub use crate::str::{get_echo, get_concat}; -// pub use crate::append::{get_append}; + pub use crate::str::{get_echo, get_concat}; + pub use crate::append::{get_append}; pub use crate::vars::{get_export}; } diff --git a/src/stl.rs b/src/stl.rs index 64450eb..b03eb9d 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -16,8 +16,8 @@ */ use crate::segment::{Ctr}; -//use crate::str::{get_echo, get_concat}; -//use crate::append::get_append; +use crate::str::{get_echo, get_concat}; +use crate::append::get_append; use crate::func::{FTable, func_declare}; use crate::vars::{VTable, get_export}; use std::rc::Rc; @@ -25,7 +25,7 @@ use std::cell::RefCell; pub fn get_stdlib(conf: Rc>) -> Result>, String> { let ft = Rc::new(RefCell::new(FTable::new())); - /* if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_echo()))) { + if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_echo()))) { return Err(s) } if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_append()))) { @@ -33,7 +33,7 @@ pub fn get_stdlib(conf: Rc>) -> Result>, Stri } if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_concat()))) { return Err(s) - }*/ + } let mut cfg_env = true; match conf.borrow().get(&String::from("CFG_RELISH_ENV")) { diff --git a/src/str.rs b/src/str.rs index 19eb6bf..06aab18 100644 --- a/src/str.rs +++ b/src/str.rs @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -/* + use crate::func::{FTable, Function, Args, Operation}; use crate::vars::{VTable}; use crate::segment::{Ctr, Ast, circuit, ast_as_string}; @@ -29,7 +29,7 @@ pub fn get_echo() -> Function { loose_syms: false, eval_lazy: false, args: Args::Lazy(-1), - function: Operation::Internal( + function: Operation::Internal(Box::new( |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { let mut string = String::from(""); if !circuit(a, &mut |arg: &Ctr| { @@ -50,7 +50,7 @@ pub fn get_echo() -> Function { } return Ctr::None; } - ) + )) }; } @@ -60,7 +60,7 @@ pub fn get_concat() -> Function { loose_syms: false, eval_lazy: false, args: Args::Lazy(-1), - function: Operation::Internal( + function: Operation::Internal(Box::new( |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { let mut string = String::from(""); if !circuit(a, &mut |arg: &Ctr| { @@ -80,7 +80,6 @@ pub fn get_concat() -> Function { } return Ctr::String(string); } - ) + )) }; } -*/ diff --git a/src/vars.rs b/src/vars.rs index cc5d8dd..441d139 100644 --- a/src/vars.rs +++ b/src/vars.rs @@ -21,7 +21,7 @@ use std::collections::HashMap; use std::env; use crate::segment::{Ctr, Ast, ast_to_string}; use crate::eval::eval; -use crate::func::{Function, Operation, InternalOperation, Args, FTable}; +use crate::func::{Function, Operation, Args, FTable}; /* Mapping between a string token and a tree of Segments * The string token can be found in any Ctr::Symbol value * it is expected that the trees stored are already evaluated @@ -40,63 +40,76 @@ pub fn define( } pub fn get_export(env_cfg: bool) -> Function { - return Function{ - name: String::from("export"), - loose_syms: true, - eval_lazy: true, - args: Args::Lazy(2), - function: Operation::Internal(get_export_callback(env_cfg)), - }; + // This is the most hilarious way to work around the lifetime of env_cfg + // TODO: figure out the RUSTEY way of doing this + if env_cfg { + return Function{ + name: String::from("export"), + loose_syms: true, + eval_lazy: true, + args: Args::Lazy(2), + function: Operation::Internal(Box::new(|a: Ast, b: Rc>, c: Rc>| -> Ctr { + export_callback(true, a, b, c) + })), + }; + } else { + return Function{ + name: String::from("export"), + loose_syms: true, + eval_lazy: true, + args: Args::Lazy(2), + function: Operation::Internal(Box::new(|a: Ast, b: Rc>, c: Rc>| -> Ctr { + export_callback(false, a, b, c) + })), + }; + } } -fn get_export_callback(env_cfg: bool) -> InternalOperation { - InternalOperation(|a: Ast, b: Rc>, c: Rc>| -> Ctr { - let inner = a.borrow_mut(); - match &inner.car { - Ctr::Symbol(identifier) => { - match &inner.cdr { - Ctr::Seg(tree) => { - match eval(tree.clone(), b.clone(), c.clone(), false) { - Ok(seg) => { - match seg { - Ctr::Seg(val) => { - let val_tmp = val.borrow().clone(); - define(b, identifier.to_string(), Rc::new(val_tmp.car)); - if env_cfg { - match val_tmp.car { - Ctr::Symbol(s) => env::set_var(identifier, s), - Ctr::String(s) => env::set_var(identifier, s), - Ctr::Integer(i) => env::set_var(identifier, format!("{}", i)), - Ctr::Float(f) => env::set_var(identifier, format!("{}", f)), - Ctr::Bool(b) => env::set_var(identifier, format!("{}", b)), - Ctr::Seg(c) => env::set_var(identifier, ast_to_string(c)), - Ctr::None => () - } +fn export_callback(env_cfg: bool, a: Ast, b: Rc>, c: Rc>) -> Ctr{ + let inner = a.borrow_mut(); + match &inner.car { + Ctr::Symbol(identifier) => { + match &inner.cdr { + Ctr::Seg(tree) => { + match eval(tree.clone(), b.clone(), c.clone(), false) { + Ok(seg) => { + match seg { + Ctr::Seg(val) => { + define(b, identifier.to_string(), Rc::new(val.borrow().clone().car)); + if env_cfg { + match val.borrow().clone().car { + Ctr::Symbol(s) => env::set_var(identifier, s), + Ctr::String(s) => env::set_var(identifier, s), + Ctr::Integer(i) => env::set_var(identifier, format!("{}", i)), + Ctr::Float(f) => env::set_var(identifier, format!("{}", f)), + Ctr::Bool(b) => env::set_var(identifier, format!("{}", b)), + Ctr::Seg(c) => env::set_var(identifier, ast_to_string(c)), + Ctr::None => () } - }, + } + }, - _ => eprintln!("impossible args to export") - } - }, + _ => eprintln!("impossible args to export") + } + }, - Err(e) => eprintln!("couldnt eval symbol: {}", e) - } - }, + Err(e) => eprintln!("couldnt eval symbol: {}", e) + } + }, - Ctr::None => { - (*b).borrow_mut().remove(identifier); - if env_cfg { - // TODO: unset variable - } - }, + Ctr::None => { + (*b).borrow_mut().remove(identifier); + if env_cfg { + // TODO: unset variable + } + }, - _ => eprintln!("args not in standard form") - } - }, + _ => eprintln!("args not in standard form") + } + }, - _ => eprintln!("first argument to export must be a symbol") - } + _ => eprintln!("first argument to export must be a symbol") + } - return Ctr::None; - }) + return Ctr::None; } diff --git a/tests/test_func.rs b/tests/test_func.rs index 6868fe4..4a522ca 100644 --- a/tests/test_func.rs +++ b/tests/test_func.rs @@ -12,7 +12,7 @@ mod func_tests { loose_syms: false, eval_lazy: false, args: Args::Strict(vec![Type::Bool]), - function: Operation::Internal( + function: Operation::Internal(Box::new( |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { let inner = a.borrow(); let mut is_bool = false; @@ -22,7 +22,7 @@ mod func_tests { Ctr::Bool(is_bool) } - ) + )) }; let ft = Rc::new(RefCell::new(FTable::new())); let vt = Rc::new(RefCell::new(VTable::new())); @@ -174,7 +174,7 @@ mod func_tests { loose_syms: false, eval_lazy: false, args: Args::Strict(vec![Type::Bool]), - function: Operation::Internal( + function: Operation::Internal(Box::new( |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { let inner = a.borrow(); if let Ctr::Bool(b) = &inner.car { @@ -187,7 +187,7 @@ mod func_tests { Ctr::None } } - ) + )) }; match lex("((test_inner true))".to_string()) {