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
|
|
@ -18,9 +18,10 @@
|
|||
use crate::eval::eval;
|
||||
use crate::error::{Traceback, start_trace};
|
||||
use crate::segment::{Ctr, Seg};
|
||||
use crate::sym::{SymTable, Symbol};
|
||||
use crate::sym::{SymTable, Symbol, ValueType, Args};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub const IF_DOCSTRING: &str =
|
||||
const IF_DOCSTRING: &str =
|
||||
"accepts three bodies, a condition, an unevaluated consequence, and an alternative consequence.
|
||||
If the condition is evaluated to true, the first consequence is evaluated.
|
||||
If the condition is evaluated to false, the second consequence is evaluated.
|
||||
|
|
@ -29,8 +30,7 @@ Otherwise, an error is thrown.
|
|||
example: (if my-state-switch
|
||||
(do-my-thing)
|
||||
(else-an-other-thing))";
|
||||
|
||||
pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
let cond: bool;
|
||||
match *ast.car {
|
||||
Ctr::Seg(ref cond_form) => {
|
||||
|
|
@ -119,7 +119,7 @@ pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
}
|
||||
}
|
||||
|
||||
pub const LET_DOCSTRING: &str = "creates a stack of local variables for a sequence of operations.
|
||||
const LET_DOCSTRING: &str = "creates a stack of local variables for a sequence of operations.
|
||||
returns the result of the final operation.
|
||||
|
||||
example: (let ((step1 'hello')
|
||||
|
|
@ -132,8 +132,7 @@ In this example step1, step2, and step3 are created sequentially.
|
|||
Then, the echo form is evaluated, printing 'hello-world'.
|
||||
Finally, the some-func form is evaluated.
|
||||
Since the call to some-func is the final form, its value is returned.";
|
||||
|
||||
pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
let mut localsyms = syms.clone();
|
||||
let mut locals = vec![];
|
||||
let locals_form: &Seg;
|
||||
|
|
@ -250,15 +249,14 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
|||
Ok((*result).clone())
|
||||
}
|
||||
|
||||
pub const WHILE_DOCSTRING: &str = "traverses a list of N un-evaluated forms.
|
||||
const WHILE_DOCSTRING: &str = "traverses a list of N un-evaluated forms.
|
||||
the first form is expected to evaluate to a boolean. if it evaluates to false, while will stop and return. Otherwise, while will evaluate each form in a loop.
|
||||
|
||||
example: (while (check-my-state)
|
||||
(do-thing-1 args)
|
||||
(do-thing-2 args)
|
||||
(edit-state my-state))";
|
||||
|
||||
pub fn while_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn while_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
let eval_cond: &Seg;
|
||||
let outer_maybe: Seg;
|
||||
let eval_bodies_head: &Seg;
|
||||
|
|
@ -319,7 +317,7 @@ pub fn while_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback>
|
|||
Ok(*(result.unwrap()).clone())
|
||||
}
|
||||
|
||||
pub const CIRCUIT_DOCSTRING: &str = "traverses a list of N un-evaluated forms.
|
||||
const CIRCUIT_DOCSTRING: &str = "traverses a list of N un-evaluated forms.
|
||||
evaluates each one until it stops. Circuit will stop when a form errors during evaluation.
|
||||
Circuit will also stop when a form does not evaluate to a boolean, or evaluates to false.
|
||||
|
||||
|
|
@ -329,8 +327,7 @@ example: (circuit (eq? (do-operation) myresult)
|
|||
(do-another-operation))
|
||||
|
||||
in this example, do-another-operation will not be called";
|
||||
|
||||
pub fn circuit_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
fn circuit_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||
let mut cursor = 0;
|
||||
let mut err_trace = Traceback::new();
|
||||
let result = ast.circuit(&mut |form: &Ctr| -> bool {
|
||||
|
|
@ -383,3 +380,53 @@ pub fn circuit_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback
|
|||
Ok(Ctr::Bool(result))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_control_lib(syms: &mut SymTable) {
|
||||
syms.insert(
|
||||
"if".to_string(),
|
||||
Symbol {
|
||||
name: String::from("if"),
|
||||
args: Args::Lazy(3),
|
||||
conditional_branches: true,
|
||||
docs: IF_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(if_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"let".to_string(),
|
||||
Symbol {
|
||||
name: String::from("let"),
|
||||
args: Args::Infinite,
|
||||
conditional_branches: true,
|
||||
docs: LET_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(let_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"while".to_string(),
|
||||
Symbol {
|
||||
name: String::from("while"),
|
||||
args: Args::Infinite,
|
||||
conditional_branches: true,
|
||||
docs: WHILE_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(while_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"circuit".to_string(),
|
||||
Symbol {
|
||||
name: String::from("circuit"),
|
||||
args: Args::Infinite,
|
||||
conditional_branches: true,
|
||||
docs: CIRCUIT_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(circuit_callback)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue