Assert, Exit builtins

* Builtins for assert and exit are added
* Tests for assert are added
* file operations from previous MR are added to documents
* assert and exit are added to documents
This commit is contained in:
Ava Apples Affine 2023-06-20 01:25:19 +00:00
parent 270cc32572
commit 2cd5016c1d
6 changed files with 119 additions and 34 deletions

View file

@ -156,12 +156,9 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
(See tag: v0.3.0)
** TODO v1.0 tasks
- islist type query
- assert function
- set library
- Can pass args to relish scripts (via interpreter)
- Can pass args to relish scripts (via command line)
- File operations
- (add this all to the readme)
- finish basic goals in the [[file:snippets/interactive-devel.rls][interactive development library]]
- Release CI
- Rename to Flesh

View file

@ -283,35 +283,35 @@ The following table is up to date as of Relish 0.3.0. For latest information try
- Call ~env~ from a fresh shell: ~(env)~
This will output all variables and functions defined
- Read the [[file:src/stl.rs][std library declaration code]]
| *Control Flow* | *Declaration* | *Shell* | *List* | *Math* | *Strings* | *Boolean* | *Userlib* | *Misc* |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| if | lambda | pipe | car | float | strlen | toggle | reduce | call |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| let | q / quote | load-to-string | len | sub | substr? | bool | prepend | help |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| circuit | def | load / l | cons | mul | echo | and | add-path | env |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| while | get-doc | load-with | cdr | inc | split | eq? | set | eval |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | set-doc | cd | reverse | dec | input | not | map | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | set? | fg | dq | div | concat | or | get-paths | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | pop | gte? | string | | cond | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | int | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | mod | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | exp | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | lt? | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | gt? | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | add | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------|
| | | | | lte? | | | | |
| *Control Flow* | *Declaration* | *Shell* | *List* | *Math* | *Strings* | *Boolean* | *Userlib* | *Misc* | *Files* |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| if | lambda | pipe | car | float | strlen | toggle | reduce | call | read-file |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| let | q / quote | load-to-string | len | sub | substr? | bool | prepend | help | append-file |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| circuit | def | load / l | cons | mul | echo | and | add-path | env | write-file |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| while | get-doc | load-with | cdr | inc | split | eq? | set | eval | exists? |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| assert | set-doc | cd | reverse | dec | input | not | map | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| exit | set? | fg | dq | div | concat | or | get-paths | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | pop | gte? | string | | cond | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | int | | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | mod | | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | exp | | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | lt? | | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | gt? | | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | add | | | | | |
|----------------+---------------+----------------+---------+--------+-----------+-----------+-----------+--------+-------------|
| | | | | lte? | | | | | |
To learn how to use a given function use the ~help~ command. See the Documentation section for more information.

View file

@ -27,7 +27,9 @@
(def failed
'prints if a test has failed'
(test)
(echo (concat "FAILED: " test)))
(let (())
(echo (concat "FAILED: " test))
(exit 1)))
(def test-cases 'all test cases'
(('set updates var'

View file

@ -18,6 +18,20 @@
;; USERLIB
;; This file contains useful features that are not shipped in the STL
;; TODO
;; dir-path
;; abs-path
;; rel-path
;; unique (make set)
;; set add
;; set del
;; superset
;; common-set
;; make-map
;; ins-mapping
;; del-mapping
;; get-mapping
;; mapped?
;; this would be way faster as code in stl
;; but stl already suffers scope creep

View file

@ -17,9 +17,10 @@
use crate::eval::eval;
use crate::error::{Traceback, start_trace};
use crate::segment::{Ctr, Seg};
use crate::segment::{Ctr, Seg, Type};
use crate::sym::{SymTable, Symbol, ValueType, Args};
use std::rc::Rc;
use std::process;
const IF_DOCSTRING: &str =
"accepts three bodies, a condition, an unevaluated consequence, and an alternative consequence.
@ -381,7 +382,60 @@ fn circuit_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
}
}
const ASSERT_DOCSTRING: &str = "Takes one input: a boolean (or form that evaluates to a boolean).
If input is false, a traceback is started and code throws an error.
Otherwise, if input is true, returns None.";
fn assert_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
if let Ctr::Bool(b) = *ast.car {
if b {
Ok(Ctr::None)
} else {
Err(start_trace(("assert", "assertion failed").into()))
}
} else {
Err(start_trace(("assert", "impossible arg").into()))
}
}
const EXIT_DOCSTRING: &str = "Takes on input: an integer used as an exit code.
Entire REPL process quits with exit code.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
if let Ctr::Integer(i) = *ast.car {
if i > 2 ^ 32 {
panic!("argument to exit too large!")
} else {
process::exit(i as i32);
}
} else {
panic!("impossible argument to exit")
}
}
pub fn add_control_lib(syms: &mut SymTable) {
syms.insert(
"exit".to_string(),
Symbol {
name: String::from("exit"),
args: Args::Strict(vec![Type::Integer]),
conditional_branches: false,
docs: EXIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(exit_callback)),
..Default::default()
},
);
syms.insert(
"assert".to_string(),
Symbol {
name: String::from("assert"),
args: Args::Strict(vec![Type::Bool]),
conditional_branches: false,
docs: ASSERT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(assert_callback)),
..Default::default()
},
);
syms.insert(
"if".to_string(),
Symbol {

View file

@ -2,6 +2,24 @@ mod control_lib_tests {
use relish::ast::{eval, lex, SymTable};
use relish::stdlib::{dynamic_stdlib, static_stdlib};
#[test]
fn test_assert_t() {
let document = "(assert true)";
let mut syms = SymTable::new();
static_stdlib(&mut syms);
dynamic_stdlib(&mut syms, None);
eval(&lex(&document.to_string()).unwrap(), &mut syms).unwrap();
}
#[test]
fn test_assert_f() {
let document = "(assert false)";
let mut syms = SymTable::new();
static_stdlib(&mut syms);
dynamic_stdlib(&mut syms, None);
assert!(eval(&lex(&document.to_string()).unwrap(), &mut syms).is_err())
}
#[test]
fn test_if_first_case_singlet() {
let document = "(if true 1 2)";