This MR finishes up all remaining Pre V1 goals
* add a posix exit() builtin * improve separation of concerns regarding standard library structure
This commit is contained in:
parent
b3c0b80ee6
commit
3bbea6bea0
9 changed files with 753 additions and 752 deletions
177
src/stl/decl.rs
177
src/stl/decl.rs
|
|
@ -19,12 +19,12 @@ use crate::eval::eval;
|
|||
use crate::error::{Traceback, start_trace};
|
||||
use crate::segment::{Ctr, Seg, Type};
|
||||
use crate::stdlib::{CONSOLE_XDIM_VNAME, RELISH_DEFAULT_CONS_WIDTH};
|
||||
use crate::sym::{SymTable, Symbol, UserFn, ValueType};
|
||||
use crate::sym::{SymTable, Symbol, UserFn, ValueType, Args};
|
||||
use std::env;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub const QUOTE_DOCSTRING: &str = "takes a single unevaluated tree and returns it as it is: unevaluated.";
|
||||
|
||||
pub fn quote_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
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> {
|
||||
if ast.len() > 1 {
|
||||
Err(start_trace(("quote", "do not quote more than one thing at a time").into()))
|
||||
} else {
|
||||
|
|
@ -32,12 +32,11 @@ pub fn quote_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback>
|
|||
}
|
||||
}
|
||||
|
||||
pub const EVAL_DOCSTRING: &str = "takes an unevaluated argument and evaluates it.
|
||||
const EVAL_DOCSTRING: &str = "takes an unevaluated argument and evaluates it.
|
||||
Specifically, does one pass of the tree simplification algorithm.
|
||||
If you have a variable referencing another variable you will get the
|
||||
referenced variable.";
|
||||
|
||||
pub fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if ast.len() > 1 {
|
||||
Err(start_trace(
|
||||
("eval", "do not eval more than one thing at a time")
|
||||
|
|
@ -96,9 +95,8 @@ pub fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
}
|
||||
}
|
||||
|
||||
pub const HELP_DOCSTRING: &str = "prints help text for a given symbol. Expects only one argument.";
|
||||
|
||||
pub fn help_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
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> {
|
||||
if ast.len() != 1 {
|
||||
return Err(start_trace(("help", "expected one input").into()));
|
||||
}
|
||||
|
|
@ -129,10 +127,9 @@ CURRENT VALUE AND/OR BODY:
|
|||
Ok(Ctr::None)
|
||||
}
|
||||
|
||||
pub const ISSET_DOCSTRING: &str = "accepts a single argument: a symbol.
|
||||
const ISSET_DOCSTRING: &str = "accepts a single argument: a symbol.
|
||||
returns true or false according to whether or not the symbol is found in the symbol table.";
|
||||
|
||||
pub fn isset_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn isset_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if ast.len() != 1 {
|
||||
Err(start_trace(("set?", "expcted one input").into()))
|
||||
} else {
|
||||
|
|
@ -148,10 +145,9 @@ pub fn isset_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback>
|
|||
}
|
||||
}
|
||||
|
||||
pub const ENV_DOCSTRING: &str = "takes no arguments
|
||||
const ENV_DOCSTRING: &str = "takes no arguments
|
||||
prints out all available symbols and their associated values";
|
||||
|
||||
pub fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
// get width of current output
|
||||
let xdim: i128;
|
||||
if let Ctr::Integer(dim) = *syms
|
||||
|
|
@ -226,7 +222,7 @@ pub fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
Ok(Ctr::None)
|
||||
}
|
||||
|
||||
pub const LAMBDA_DOCSTRING: &str = "Takes two arguments of any type.
|
||||
const LAMBDA_DOCSTRING: &str = "Takes two arguments of any type.
|
||||
No args are evaluated when lambda is called.
|
||||
Lambda makes sure the first argument is a list of symbols (or 'arguments') to the lambda function.
|
||||
The next arg is stored in a tree to evaluate on demand.
|
||||
|
|
@ -236,8 +232,7 @@ This can then be evaluated like so:
|
|||
((lambda (x y) (add x y)) 1 2)
|
||||
which is functionally equivalent to:
|
||||
(add 1 2)";
|
||||
|
||||
pub fn lambda_callback(
|
||||
fn lambda_callback(
|
||||
ast: &Seg,
|
||||
_syms: &mut SymTable
|
||||
) -> Result<Ctr, Traceback> {
|
||||
|
|
@ -274,13 +269,12 @@ pub fn lambda_callback(
|
|||
}
|
||||
}
|
||||
|
||||
pub const GETDOC_DOCSTRING: &str = "accepts an unevaluated symbol, returns the doc string.
|
||||
const GETDOC_DOCSTRING: &str = "accepts an unevaluated symbol, returns the doc string.
|
||||
Returns an error if symbol is undefined.
|
||||
|
||||
Note: make sure to quote the input like this:
|
||||
(get-doc (quote symbol-name))";
|
||||
|
||||
pub fn getdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn getdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if let Ctr::Symbol(ref symbol) = *ast.car {
|
||||
if let Some(sym) = syms.get(symbol) {
|
||||
Ok(Ctr::String(sym.docs.clone()))
|
||||
|
|
@ -292,13 +286,12 @@ pub fn getdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback>
|
|||
}
|
||||
}
|
||||
|
||||
pub const SETDOC_DOCSTRING: &str = "accepts a symbol and a doc string.
|
||||
const SETDOC_DOCSTRING: &str = "accepts a symbol and a doc string.
|
||||
Returns an error if symbol is undefined, otherwise sets the symbols docstring to the argument.
|
||||
|
||||
Note: make sure to quote the input like this:
|
||||
(set-doc (quote symbol-name) my-new-docs)";
|
||||
|
||||
pub fn setdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn setdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
if ast.len() != 2 {
|
||||
Err(start_trace(
|
||||
("set-doc", "expected two inputs")
|
||||
|
|
@ -336,7 +329,7 @@ pub fn setdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback>
|
|||
}
|
||||
}
|
||||
|
||||
pub const STORE_DOCSTRING: &str = "allows user to define functions and variables.
|
||||
const STORE_DOCSTRING: &str = "allows user to define functions and variables.
|
||||
A call may take one of three forms:
|
||||
1. variable declaration:
|
||||
Takes a name, doc string, and a value.
|
||||
|
|
@ -351,9 +344,7 @@ pub const STORE_DOCSTRING: &str = "allows user to define functions and variables
|
|||
|
||||
Additionally, passing a tree as a name will trigger def to evaluate the tree and try to derive
|
||||
a value from it. If it does not return a ";
|
||||
|
||||
|
||||
pub fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<Ctr, Traceback> {
|
||||
fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<Ctr, Traceback> {
|
||||
let is_var = ast.len() == 3;
|
||||
let name: String;
|
||||
let docs: String;
|
||||
|
|
@ -509,3 +500,131 @@ pub fn store_callback(ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result<C
|
|||
.into()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_decl_lib_static(syms: &mut SymTable) {
|
||||
syms.insert(
|
||||
"help".to_string(),
|
||||
Symbol {
|
||||
name: String::from("help"),
|
||||
args: Args::Strict(vec![Type::Symbol]),
|
||||
conditional_branches: true,
|
||||
docs: HELP_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(help_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"set?".to_string(),
|
||||
Symbol {
|
||||
name: String::from("set?"),
|
||||
args: Args::Strict(vec![Type::Symbol]),
|
||||
conditional_branches: true,
|
||||
docs: ISSET_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(isset_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"env".to_string(),
|
||||
Symbol {
|
||||
name: String::from("env"),
|
||||
args: Args::None,
|
||||
conditional_branches: false,
|
||||
docs: ENV_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(env_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"quote".to_string(),
|
||||
Symbol {
|
||||
name: String::from("quote"),
|
||||
args: Args::Lazy(1),
|
||||
conditional_branches: true,
|
||||
docs: QUOTE_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(quote_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"q".to_string(),
|
||||
Symbol {
|
||||
name: String::from("quote"),
|
||||
args: Args::Lazy(1),
|
||||
conditional_branches: true,
|
||||
docs: QUOTE_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(quote_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"eval".to_string(),
|
||||
Symbol {
|
||||
name: String::from("eval"),
|
||||
args: Args::Lazy(1),
|
||||
conditional_branches: true,
|
||||
docs: EVAL_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(eval_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"lambda".to_string(),
|
||||
Symbol {
|
||||
name: String::from("lambda"),
|
||||
args: Args::Lazy(2),
|
||||
conditional_branches: true,
|
||||
docs: LAMBDA_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(lambda_callback)),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"get-doc".to_string(),
|
||||
Symbol {
|
||||
name: String::from("get-doc"),
|
||||
args: Args::Strict(vec![Type::Symbol]),
|
||||
conditional_branches: false,
|
||||
docs: GETDOC_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(getdoc_callback)),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"set-doc".to_string(),
|
||||
Symbol {
|
||||
name: String::from("get-doc"),
|
||||
args: Args::Strict(vec![Type::Symbol, Type::String]),
|
||||
conditional_branches: false,
|
||||
docs: SETDOC_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(setdoc_callback)),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
pub fn add_decl_lib_dynamic(syms: &mut SymTable, env: bool) {
|
||||
syms.insert(
|
||||
"def".to_string(),
|
||||
Symbol {
|
||||
name: String::from("define"),
|
||||
args: Args::Infinite,
|
||||
conditional_branches: true,
|
||||
docs: STORE_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(
|
||||
move |ast: &Seg, syms: &mut SymTable| -> Result<Ctr, Traceback> {
|
||||
store_callback(ast, syms, env)
|
||||
},
|
||||
)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue