finally figure out how to hold closures
This commit is contained in:
parent
69f31db23b
commit
f805290a4b
8 changed files with 98 additions and 89 deletions
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* 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::func::{FTable, Function, Args, Operation};
|
use crate::func::{FTable, Function, Args, Operation};
|
||||||
use crate::vars::{VTable};
|
use crate::vars::{VTable};
|
||||||
use crate::segment::{Ctr, Ast, circuit, list_idx, list_append, new_ast};
|
use crate::segment::{Ctr, Ast, circuit, list_idx, list_append, new_ast};
|
||||||
|
|
@ -27,7 +27,7 @@ pub fn get_append() -> Function {
|
||||||
loose_syms: false,
|
loose_syms: false,
|
||||||
eval_lazy: false,
|
eval_lazy: false,
|
||||||
args: Args::Lazy(-1),
|
args: Args::Lazy(-1),
|
||||||
function: Operation::Internal(
|
function: Operation::Internal(Box::new(
|
||||||
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
||||||
let ptr = list_idx(a.clone(), 0);
|
let ptr = list_idx(a.clone(), 0);
|
||||||
match ptr {
|
match ptr {
|
||||||
|
|
@ -63,6 +63,6 @@ pub fn get_append() -> Function {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
}*/
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::vars::{VTable, define};
|
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::segment::{Ast, Ctr};
|
||||||
use crate::lex::lex;
|
use crate::lex::lex;
|
||||||
use crate::eval::eval;
|
use crate::eval::eval;
|
||||||
|
|
@ -25,13 +25,11 @@ use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
/*
|
|
||||||
fn get_prompt_default() -> InternalOperation {
|
fn prompt_default_callback(_: Ast, _: Rc<RefCell<VTable>>, _: Rc<RefCell<FTable>>) -> Ctr {
|
||||||
|_: Ast, _: Rc<RefCell<VTable>>, _: Rc<RefCell<FTable>>| -> Ctr {
|
print!("λ ");
|
||||||
print!("λ ");
|
return Ctr::None;
|
||||||
return Ctr::None;
|
}
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pub fn configure(filename: String, vars: Rc<RefCell<VTable>>, mut funcs: Rc<RefCell<FTable>>) {
|
pub fn configure(filename: String, vars: Rc<RefCell<VTable>>, mut funcs: Rc<RefCell<FTable>>) {
|
||||||
define(vars.clone(), String::from("CFG_RELISH_POSIX"), Rc::new(Ctr::String(String::from("0"))));
|
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<RefCell<VTable>>, mut funcs: Rc<RefC
|
||||||
Err(s) => println!("{}", s)
|
Err(s) => println!("{}", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func_declare(funcs.clone(), Rc::new(RefCell::new(Function{
|
func_declare(funcs.clone(), Rc::new(RefCell::new(Function{
|
||||||
name: String::from("CFG_RELISH_PROMPT"),
|
name: String::from("CFG_RELISH_PROMPT"),
|
||||||
loose_syms: false,
|
loose_syms: false,
|
||||||
eval_lazy: false,
|
eval_lazy: false,
|
||||||
args: Args::Lazy(0),
|
args: Args::Lazy(0),
|
||||||
function: Operation::Internal(get_prompt_default())
|
function: Operation::Internal(Box::new(prompt_default_callback))
|
||||||
})));*/
|
})));
|
||||||
|
|
||||||
match fs::read_to_string(filename) {
|
match fs::read_to_string(filename) {
|
||||||
Err(s) => {
|
Err(s) => {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ use crate::eval::eval;
|
||||||
pub type FTable = HashMap<String, Rc<RefCell<Function>>>;
|
pub type FTable = HashMap<String, Rc<RefCell<Function>>>;
|
||||||
|
|
||||||
// Standardized function signature for stdlib functions
|
// Standardized function signature for stdlib functions
|
||||||
pub type InternalOperation = impl Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>) -> Ctr;
|
//pub type InternalOperation = impl Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>) -> Ctr;
|
||||||
pub struct ExternalOperation {
|
pub struct ExternalOperation {
|
||||||
// Un-evaluated abstract syntax tree
|
// Un-evaluated abstract syntax tree
|
||||||
// TODO: Intermediate evaluation to simplify branches with no argument in them
|
// 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
|
* or a syntax tree to eval with the arguments
|
||||||
*/
|
*/
|
||||||
pub enum Operation {
|
pub enum Operation {
|
||||||
Internal(InternalOperation),
|
Internal(Box<dyn Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>)->Ctr>),
|
||||||
External(ExternalOperation)
|
External(ExternalOperation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,9 +160,10 @@ pub fn func_call(
|
||||||
}
|
}
|
||||||
|
|
||||||
match &called_func.function {
|
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) => {
|
Operation::External(f) => {
|
||||||
|
|
||||||
for n in 0..f.arg_syms.len() {
|
for n in 0..f.arg_syms.len() {
|
||||||
let iter_arg = list_idx(n_args.clone(), n as u128);
|
let iter_arg = list_idx(n_args.clone(), n as u128);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
|
||||||
|
|
||||||
mod segment;
|
mod segment;
|
||||||
mod lex;
|
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::segment::{Seg, Ctr, ast_to_string, Type, Ast, new_ast};
|
||||||
pub use crate::lex::lex;
|
pub use crate::lex::lex;
|
||||||
pub use crate::func::{Function, Operation, FTable, Args,
|
pub use crate::func::{Function, Operation, FTable, Args,
|
||||||
InternalOperation, ExternalOperation,
|
ExternalOperation, func_declare, func_call};
|
||||||
func_declare, func_call};
|
|
||||||
pub use crate::vars::{VTable, define};
|
pub use crate::vars::{VTable, define};
|
||||||
pub use crate::eval::eval;
|
pub use crate::eval::eval;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod stdlib {
|
pub mod stdlib {
|
||||||
pub use crate::stl::{get_stdlib};
|
pub use crate::stl::{get_stdlib};
|
||||||
// pub use crate::str::{get_echo, get_concat};
|
pub use crate::str::{get_echo, get_concat};
|
||||||
// pub use crate::append::{get_append};
|
pub use crate::append::{get_append};
|
||||||
pub use crate::vars::{get_export};
|
pub use crate::vars::{get_export};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::segment::{Ctr};
|
use crate::segment::{Ctr};
|
||||||
//use crate::str::{get_echo, get_concat};
|
use crate::str::{get_echo, get_concat};
|
||||||
//use crate::append::get_append;
|
use crate::append::get_append;
|
||||||
use crate::func::{FTable, func_declare};
|
use crate::func::{FTable, func_declare};
|
||||||
use crate::vars::{VTable, get_export};
|
use crate::vars::{VTable, get_export};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -25,7 +25,7 @@ use std::cell::RefCell;
|
||||||
|
|
||||||
pub fn get_stdlib(conf: Rc<RefCell<VTable>>) -> Result<Rc<RefCell<FTable>>, String> {
|
pub fn get_stdlib(conf: Rc<RefCell<VTable>>) -> Result<Rc<RefCell<FTable>>, String> {
|
||||||
let ft = Rc::new(RefCell::new(FTable::new()));
|
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)
|
return Err(s)
|
||||||
}
|
}
|
||||||
if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_append()))) {
|
if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_append()))) {
|
||||||
|
|
@ -33,7 +33,7 @@ pub fn get_stdlib(conf: Rc<RefCell<VTable>>) -> Result<Rc<RefCell<FTable>>, Stri
|
||||||
}
|
}
|
||||||
if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_concat()))) {
|
if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_concat()))) {
|
||||||
return Err(s)
|
return Err(s)
|
||||||
}*/
|
}
|
||||||
|
|
||||||
let mut cfg_env = true;
|
let mut cfg_env = true;
|
||||||
match conf.borrow().get(&String::from("CFG_RELISH_ENV")) {
|
match conf.borrow().get(&String::from("CFG_RELISH_ENV")) {
|
||||||
|
|
|
||||||
11
src/str.rs
11
src/str.rs
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* 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::func::{FTable, Function, Args, Operation};
|
use crate::func::{FTable, Function, Args, Operation};
|
||||||
use crate::vars::{VTable};
|
use crate::vars::{VTable};
|
||||||
use crate::segment::{Ctr, Ast, circuit, ast_as_string};
|
use crate::segment::{Ctr, Ast, circuit, ast_as_string};
|
||||||
|
|
@ -29,7 +29,7 @@ pub fn get_echo() -> Function {
|
||||||
loose_syms: false,
|
loose_syms: false,
|
||||||
eval_lazy: false,
|
eval_lazy: false,
|
||||||
args: Args::Lazy(-1),
|
args: Args::Lazy(-1),
|
||||||
function: Operation::Internal(
|
function: Operation::Internal(Box::new(
|
||||||
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
||||||
let mut string = String::from("");
|
let mut string = String::from("");
|
||||||
if !circuit(a, &mut |arg: &Ctr| {
|
if !circuit(a, &mut |arg: &Ctr| {
|
||||||
|
|
@ -50,7 +50,7 @@ pub fn get_echo() -> Function {
|
||||||
}
|
}
|
||||||
return Ctr::None;
|
return Ctr::None;
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ pub fn get_concat() -> Function {
|
||||||
loose_syms: false,
|
loose_syms: false,
|
||||||
eval_lazy: false,
|
eval_lazy: false,
|
||||||
args: Args::Lazy(-1),
|
args: Args::Lazy(-1),
|
||||||
function: Operation::Internal(
|
function: Operation::Internal(Box::new(
|
||||||
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
||||||
let mut string = String::from("");
|
let mut string = String::from("");
|
||||||
if !circuit(a, &mut |arg: &Ctr| {
|
if !circuit(a, &mut |arg: &Ctr| {
|
||||||
|
|
@ -80,7 +80,6 @@ pub fn get_concat() -> Function {
|
||||||
}
|
}
|
||||||
return Ctr::String(string);
|
return Ctr::String(string);
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
115
src/vars.rs
115
src/vars.rs
|
|
@ -21,7 +21,7 @@ use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use crate::segment::{Ctr, Ast, ast_to_string};
|
use crate::segment::{Ctr, Ast, ast_to_string};
|
||||||
use crate::eval::eval;
|
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
|
/* Mapping between a string token and a tree of Segments
|
||||||
* The string token can be found in any Ctr::Symbol value
|
* The string token can be found in any Ctr::Symbol value
|
||||||
* it is expected that the trees stored are already evaluated
|
* 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 {
|
pub fn get_export(env_cfg: bool) -> Function {
|
||||||
return Function{
|
// This is the most hilarious way to work around the lifetime of env_cfg
|
||||||
name: String::from("export"),
|
// TODO: figure out the RUSTEY way of doing this
|
||||||
loose_syms: true,
|
if env_cfg {
|
||||||
eval_lazy: true,
|
return Function{
|
||||||
args: Args::Lazy(2),
|
name: String::from("export"),
|
||||||
function: Operation::Internal(get_export_callback(env_cfg)),
|
loose_syms: true,
|
||||||
};
|
eval_lazy: true,
|
||||||
|
args: Args::Lazy(2),
|
||||||
|
function: Operation::Internal(Box::new(|a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> 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<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
|
||||||
|
export_callback(false, a, b, c)
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_export_callback(env_cfg: bool) -> InternalOperation {
|
fn export_callback(env_cfg: bool, a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>) -> Ctr{
|
||||||
InternalOperation(|a: Ast, b: Rc<RefCell<VTable>>, c: Rc<RefCell<FTable>>| -> Ctr {
|
let inner = a.borrow_mut();
|
||||||
let inner = a.borrow_mut();
|
match &inner.car {
|
||||||
match &inner.car {
|
Ctr::Symbol(identifier) => {
|
||||||
Ctr::Symbol(identifier) => {
|
match &inner.cdr {
|
||||||
match &inner.cdr {
|
Ctr::Seg(tree) => {
|
||||||
Ctr::Seg(tree) => {
|
match eval(tree.clone(), b.clone(), c.clone(), false) {
|
||||||
match eval(tree.clone(), b.clone(), c.clone(), false) {
|
Ok(seg) => {
|
||||||
Ok(seg) => {
|
match seg {
|
||||||
match seg {
|
Ctr::Seg(val) => {
|
||||||
Ctr::Seg(val) => {
|
define(b, identifier.to_string(), Rc::new(val.borrow().clone().car));
|
||||||
let val_tmp = val.borrow().clone();
|
if env_cfg {
|
||||||
define(b, identifier.to_string(), Rc::new(val_tmp.car));
|
match val.borrow().clone().car {
|
||||||
if env_cfg {
|
Ctr::Symbol(s) => env::set_var(identifier, s),
|
||||||
match val_tmp.car {
|
Ctr::String(s) => env::set_var(identifier, s),
|
||||||
Ctr::Symbol(s) => env::set_var(identifier, s),
|
Ctr::Integer(i) => env::set_var(identifier, format!("{}", i)),
|
||||||
Ctr::String(s) => env::set_var(identifier, s),
|
Ctr::Float(f) => env::set_var(identifier, format!("{}", f)),
|
||||||
Ctr::Integer(i) => env::set_var(identifier, format!("{}", i)),
|
Ctr::Bool(b) => env::set_var(identifier, format!("{}", b)),
|
||||||
Ctr::Float(f) => env::set_var(identifier, format!("{}", f)),
|
Ctr::Seg(c) => env::set_var(identifier, ast_to_string(c)),
|
||||||
Ctr::Bool(b) => env::set_var(identifier, format!("{}", b)),
|
Ctr::None => ()
|
||||||
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 => {
|
Ctr::None => {
|
||||||
(*b).borrow_mut().remove(identifier);
|
(*b).borrow_mut().remove(identifier);
|
||||||
if env_cfg {
|
if env_cfg {
|
||||||
// TODO: unset variable
|
// 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;
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ mod func_tests {
|
||||||
loose_syms: false,
|
loose_syms: false,
|
||||||
eval_lazy: false,
|
eval_lazy: false,
|
||||||
args: Args::Strict(vec![Type::Bool]),
|
args: Args::Strict(vec![Type::Bool]),
|
||||||
function: Operation::Internal(
|
function: Operation::Internal(Box::new(
|
||||||
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
||||||
let inner = a.borrow();
|
let inner = a.borrow();
|
||||||
let mut is_bool = false;
|
let mut is_bool = false;
|
||||||
|
|
@ -22,7 +22,7 @@ mod func_tests {
|
||||||
|
|
||||||
Ctr::Bool(is_bool)
|
Ctr::Bool(is_bool)
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
let ft = Rc::new(RefCell::new(FTable::new()));
|
let ft = Rc::new(RefCell::new(FTable::new()));
|
||||||
let vt = Rc::new(RefCell::new(VTable::new()));
|
let vt = Rc::new(RefCell::new(VTable::new()));
|
||||||
|
|
@ -174,7 +174,7 @@ mod func_tests {
|
||||||
loose_syms: false,
|
loose_syms: false,
|
||||||
eval_lazy: false,
|
eval_lazy: false,
|
||||||
args: Args::Strict(vec![Type::Bool]),
|
args: Args::Strict(vec![Type::Bool]),
|
||||||
function: Operation::Internal(
|
function: Operation::Internal(Box::new(
|
||||||
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
|a: Ast, _b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
|
||||||
let inner = a.borrow();
|
let inner = a.borrow();
|
||||||
if let Ctr::Bool(b) = &inner.car {
|
if let Ctr::Bool(b) = &inner.car {
|
||||||
|
|
@ -187,7 +187,7 @@ mod func_tests {
|
||||||
Ctr::None
|
Ctr::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
match lex("((test_inner true))".to_string()) {
|
match lex("((test_inner true))".to_string()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue