add variable export function

This commit is contained in:
Aidan Hahn 2021-11-06 15:43:42 -07:00
parent 7ca42f18da
commit 0931fbdcf0
No known key found for this signature in database
GPG key ID: 327711E983899316
5 changed files with 102 additions and 6 deletions

View file

@ -38,4 +38,5 @@ 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};
} }

View file

@ -18,6 +18,7 @@
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::{get_export};
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
@ -32,6 +33,9 @@ pub fn get_stdlib() -> Result<Rc<RefCell<FTable>>, String> {
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)
} }
if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_export()))) {
return Err(s)
}
return Ok(ft) return Ok(ft)
} }

67
src/test_lib_vars.rs Normal file
View file

@ -0,0 +1,67 @@
mod str_lib_tests {
use relish::stdlib::{get_stdlib};
use relish::ast::{lex, eval, ast_to_string, VTable, FTable, Ctr};
use std::rc::Rc;
use std::cell::RefCell;
#[test]
fn test_variable_export_and_lookup() {
let doc1 = "(export test 1)";
let doc2 = "(echo test)";
let result = "1";
let vt = Rc::new(RefCell::new(VTable::new()));
let ft: Rc<RefCell<FTable>>;
match get_stdlib() {
Ok(f) => ft = f,
Err(s) => {
ft = Rc::new(RefCell::new(FTable::new()));
println!("Couldnt get stdlib: {}!", s);
assert!(false);
}
}
match lex(doc1.to_string()) {
Err(s) => {
println!("Couldnt lex {}: {}", doc1, s);
assert!(false);
},
Ok(tree) => {
match eval(tree, vt.clone(), ft.clone(), false) {
Err(s) => {
println!("Couldnt eval {}: {}", doc2, s);
assert!(false);
},
Ok(ctr) => {
Ctr::None => assert!(true),
_ => assert!(false)
}
}
}
}
match lex(doc2.to_string()) {
Err(s) => {
println!("Couldnt lex {}: {}", doc2, s);
assert!(false);
},
Ok(tree) => {
match eval(tree, vt.clone(), ft.clone(), false) {
Err(s) => {
println!("Couldnt eval {}: {}", doc2, s);
assert!(false);
},
Ok(ctr) => {
match ctr {
Ctr::String(s) => assert_eq!(s, result),
_ => assert!(false)
}
}
}
}
}
}
}

View file

@ -18,8 +18,8 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use crate::segment::{Ctr}; use crate::segment::{Ctr, Ast};
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
@ -36,3 +36,27 @@ pub fn define(
drop(rc_segment); drop(rc_segment);
} }
} }
pub fn get_export() -> Function {
return Function{
name: String::from("export"),
loose_syms: true,
eval_lazy: false,
args: Args::Lazy(2),
function: Operation::Internal(
|a: Ast, b: Rc<RefCell<VTable>>, _c: Rc<RefCell<FTable>>| -> Ctr {
let inner = a.borrow_mut();
match &inner.car {
Ctr::Symbol(identifier) => {
define(b, identifier.to_string(), Rc::new(inner.cdr.clone()));
return Ctr::None;
},
_ => {
eprintln!("first argument to export must be a symbol");
return Ctr::None;
}
}
}
)
};
}

View file

@ -1,11 +1,11 @@
mod str_lib_tests { mod str_lib_tests {
use relish::stdlib::{get_stdlib}; use relish::stdlib::{get_stdlib};
use relish::ast::{lex, eval, ast_to_string, VTable, FTable, Ctr}; use relish::ast::{lex, eval, VTable, FTable, Ctr};
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
#[test] #[test]
fn test_simple_echo() { fn test_simple_concat() {
let document = "(concat 'test')"; let document = "(concat 'test')";
let result = "test"; let result = "test";
let vt = Rc::new(RefCell::new(VTable::new())); let vt = Rc::new(RefCell::new(VTable::new()));
@ -49,7 +49,7 @@ mod str_lib_tests {
} }
#[test] #[test]
fn test_poly_echo() { fn test_poly_concat() {
let document = "(concat 'test' 1 2 3)"; let document = "(concat 'test' 1 2 3)";
let result = "test123"; let result = "test123";
let vt = Rc::new(RefCell::new(VTable::new())); let vt = Rc::new(RefCell::new(VTable::new()));
@ -93,7 +93,7 @@ mod str_lib_tests {
} }
#[test] #[test]
fn test_empty_echo() { fn test_empty_concat() {
let document = "(concat)"; let document = "(concat)";
let result = ""; let result = "";
let vt = Rc::new(RefCell::new(VTable::new())); let vt = Rc::new(RefCell::new(VTable::new()));