aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-06-30 20:50:08 +0800
committerMistivia <i@mistivia.com>2025-06-30 20:50:08 +0800
commit628c76ab4a242294ddf915872e733c317e3fe242 (patch)
treead883429a649e6bff769732ac1f54dcb1a26cfa7
parent9a4f460d6dd476767ea211c879f115e127ee2410 (diff)
add docs
-rw-r--r--Readme.md4
-rw-r--r--docs/builtins.md0
-rw-r--r--docs/primitives.md54
-rw-r--r--src/builtins.h122
4 files changed, 133 insertions, 47 deletions
diff --git a/Readme.md b/Readme.md
index df63a2c..63b83d9 100644
--- a/Readme.md
+++ b/Readme.md
@@ -108,3 +108,7 @@ See `tests/` for more examples.
;; ... (10 times)
```
+## Documents (WIP)
+
+- [Primitives](https://github.com/mistivia/bamboo-lisp/blob/master/docs/primitives.md)
+
diff --git a/docs/builtins.md b/docs/builtins.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/builtins.md
diff --git a/docs/primitives.md b/docs/primitives.md
new file mode 100644
index 0000000..f1c8850
--- /dev/null
+++ b/docs/primitives.md
@@ -0,0 +1,54 @@
+# Primitives
+
+**(assert-exception *form*)**
+
+Evaluates *form*. If *form* evaluates to an exception signal,
+`assert-exception` returns `#t`. Otherwise, it raises an error indicating that
+no exception was thrown by *form*. This primitive is useful for testing code
+that is expected to throw exceptions.
+
+```lisp
+(assert-exception (throw "This is an exception."))
+ ;; -> #t
+
+(assert-exception (+ 1 2))
+ ;; -> Error
+```
+
+---
+
+**(assert-error *form*)**
+
+Evaluates *form*. If *form* results in an **error signal**, `assert-error` returns `#t`. Otherwise, it throws an error indicating that *form* did not produce an error. This primitive is useful for writing tests that verify if specific code paths correctly raise errors.
+
+```llisp
+(assert-error (error "This is an error."))
+ -> #t
+
+(assert-error (+ 1 2))
+ -> Error
+```
+
+---
+
+**(try *expression* *catch-function*)**
+
+The `try` primitive evaluates the given ***expression***. If the evaluation of ***expression*** results in an **exception signal**, the ***catch-function*** is then invoked with the exception's return value as its sole argument. If ***expression*** evaluates without an exception, its result is returned directly, and the ***catch-function*** is not called. If the second argument, ***catch-function***, is not a valid function, `try` will signal a syntax error.
+
+```lisp
+(try
+ (throw "Alas!")
+ (lambda (e) (string-append "Caught exception: " e)))
+ -> "Caught exception: Alas!"
+
+(try
+ (+ 1 2)
+ (lambda (e) (string-append "Caught exception: " e)))
+ -> 3
+
+(try
+ (+ 1 2)
+ 'not-a-function)
+ -> Error: try: syntax error, catch is not a function.
+```
+
diff --git a/src/builtins.h b/src/builtins.h
index 9cac797..70f58fd 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -3,19 +3,23 @@
#include "interp.h"
+SExpRef builtin_logand(Interp *interp, SExpRef args);
SExpRef builtin_logior(Interp *interp, SExpRef args);
SExpRef builtin_logxor(Interp *interp, SExpRef args);
SExpRef builtin_lognot(Interp *interp, SExpRef args);
SExpRef builtin_lsh(Interp *interp, SExpRef args);
SExpRef builtin_ash(Interp *interp, SExpRef args);
+
+SExpRef builtin_numberp(Interp *interp, SExpRef args);
+SExpRef builtin_integerp(Interp *interp, SExpRef args);
SExpRef builtin_functionp(Interp *interp, SExpRef args);
-SExpRef builtin_setnth(Interp *interp, SExpRef args);
-SExpRef builtin_setnthcdr(Interp *interp, SExpRef args);
-SExpRef builtin_foldl(Interp *interp, SExpRef args);
-SExpRef builtin_append(Interp *interp, SExpRef args);
-SExpRef builtin_nconc(Interp *interp, SExpRef args);
-SExpRef builtin_logand(Interp *interp, SExpRef args);
SExpRef builtin_charp(Interp *interp, SExpRef args);
+SExpRef builtin_listp(Interp *interp, SExpRef args);
+SExpRef builtin_consp(Interp *interp, SExpRef args);
+SExpRef builtin_atomp(Interp *interp, SExpRef args);
+SExpRef builtin_nullp(Interp *interp, SExpRef args);
+SExpRef builtin_floatp(Interp *interp, SExpRef args);
+
SExpRef builtin_char_eq(Interp *interp, SExpRef args);
SExpRef builtin_char_gt(Interp *interp, SExpRef args);
SExpRef builtin_char_lt(Interp *interp, SExpRef args);
@@ -24,30 +28,10 @@ SExpRef builtin_char_le(Interp *interp, SExpRef args);
SExpRef builtin_char_neq(Interp *interp, SExpRef args);
SExpRef builtin_int2char(Interp *interp, SExpRef args);
SExpRef builtin_char2int(Interp *interp, SExpRef args);
-SExpRef builtin_alphabeticp(Interp *interp, SExpRef args);
SExpRef builtin_numericp(Interp *interp, SExpRef args);
+SExpRef builtin_alphabeticp(Interp *interp, SExpRef args);
SExpRef builtin_alphanump(Interp *interp, SExpRef args);
-SExpRef builtin_listp(Interp *interp, SExpRef args);
-SExpRef builtin_consp(Interp *interp, SExpRef args);
-SExpRef builtin_atomp(Interp *interp, SExpRef args);
-SExpRef builtin_nullp(Interp *interp, SExpRef args);
-SExpRef builtin_memberp(Interp *interp, SExpRef args);
-SExpRef builtin_numberp(Interp *interp, SExpRef args);
-SExpRef builtin_integerp(Interp *interp, SExpRef args);
-SExpRef builtin_floatp(Interp *interp, SExpRef args);
-SExpRef builtin_nreverse(Interp *interp, SExpRef args);
-SExpRef builtin_reverse(Interp *interp, SExpRef args);
-SExpRef builtin_last(Interp *interp, SExpRef args);
-SExpRef builtin_map(Interp *interp, SExpRef args);
-SExpRef builtin_filter(Interp *interp, SExpRef args);
-SExpRef builtin_remove(Interp *interp, SExpRef args);
-SExpRef builtin_count(Interp *interp, SExpRef args);
-SExpRef builtin_foreach(Interp *interp, SExpRef args);
-SExpRef builtin_set_car(Interp *interp, SExpRef args);
-SExpRef builtin_set_cdr(Interp *interp, SExpRef args);
-SExpRef builtin_length(Interp *interp, SExpRef args);
-SExpRef builtin_nth(Interp *interp, SExpRef args);
-SExpRef builtin_nthcdr(Interp *interp, SExpRef args);
+
SExpRef builtin_string(Interp *interp, SExpRef args);
SExpRef builtin_string_eq(Interp *interp, SExpRef args);
SExpRef builtin_string_gt(Interp *interp, SExpRef args);
@@ -57,12 +41,11 @@ SExpRef builtin_string_le(Interp *interp, SExpRef args);
SExpRef builtin_string_neq(Interp *interp, SExpRef args);
SExpRef builtin_split_string(Interp *interp, SExpRef args);
SExpRef builtin_strip_string(Interp *interp, SExpRef args);
-SExpRef builtin_symbol2string(Interp *interp, SExpRef args);
-SExpRef builtin_intern(Interp *interp, SExpRef args);
-SExpRef builtin_gensym(Interp *interp, SExpRef args);
-SExpRef builtin_sqrt(Interp *interp, SExpRef args);
-SExpRef builtin_cbrt(Interp *interp, SExpRef args);
-SExpRef builtin_float(Interp *interp, SExpRef args);
+SExpRef builtin_format(Interp *interp, SExpRef args);
+SExpRef builtin_concat(Interp *interp, SExpRef args);
+SExpRef builtin_print(Interp *interp, SExpRef args);
+SExpRef builtin_princ(Interp *interp, SExpRef args);
+
SExpRef builtin_abs(Interp *interp, SExpRef args);
SExpRef builtin_pow(Interp *interp, SExpRef args);
SExpRef builtin_floor(Interp *interp, SExpRef args);
@@ -81,18 +64,7 @@ SExpRef builtin_log2(Interp *interp, SExpRef args);
SExpRef builtin_exp(Interp *interp, SExpRef args);
SExpRef builtin_min(Interp *interp, SExpRef args);
SExpRef builtin_max(Interp *interp, SExpRef args);
-SExpRef builtin_equal(Interp *interp, SExpRef args);
-SExpRef builtin_eq(Interp *interp, SExpRef args);
-SExpRef builtin_format(Interp *interp, SExpRef args);
-SExpRef builtin_concat(Interp *interp, SExpRef args);
-SExpRef builtin_print(Interp *interp, SExpRef args);
-SExpRef builtin_exit(Interp *interp, SExpRef args);
-SExpRef builtin_error(Interp *interp, SExpRef args);
-SExpRef builtin_list(Interp *interp, SExpRef args);
-SExpRef builtin_car(Interp *interp, SExpRef args);
-SExpRef builtin_cdr(Interp *interp, SExpRef args);
-SExpRef builtin_cons(Interp *interp, SExpRef args);
-SExpRef builtin_not(Interp *interp, SExpRef args);
+
SExpRef builtin_add(Interp *interp, SExpRef args);
SExpRef builtin_sub(Interp *interp, SExpRef args);
SExpRef builtin_mul(Interp *interp, SExpRef args);
@@ -105,8 +77,64 @@ SExpRef builtin_gt(Interp *interp, SExpRef args);
SExpRef builtin_lt(Interp *interp, SExpRef args);
SExpRef builtin_ge(Interp *interp, SExpRef args);
SExpRef builtin_le(Interp *interp, SExpRef args);
-SExpRef builtin_princ(Interp *interp, SExpRef args);
+SExpRef builtin_sqrt(Interp *interp, SExpRef args);
+SExpRef builtin_cbrt(Interp *interp, SExpRef args);
+SExpRef builtin_float(Interp *interp, SExpRef args);
+SExpRef builtin_abs(Interp *interp, SExpRef args);
+SExpRef builtin_pow(Interp *interp, SExpRef args);
+SExpRef builtin_floor(Interp *interp, SExpRef args);
+SExpRef builtin_truncate(Interp *interp, SExpRef args);
+SExpRef builtin_ceiling(Interp *interp, SExpRef args);
+SExpRef builtin_round(Interp *interp, SExpRef args);
+SExpRef builtin_sin(Interp *interp, SExpRef args);
+SExpRef builtin_cos(Interp *interp, SExpRef args);
+SExpRef builtin_tan(Interp *interp, SExpRef args);
+SExpRef builtin_asin(Interp *interp, SExpRef args);
+SExpRef builtin_acos(Interp *interp, SExpRef args);
+SExpRef builtin_atan(Interp *interp, SExpRef args);
+SExpRef builtin_ln(Interp *interp, SExpRef args);
+SExpRef builtin_log10(Interp *interp, SExpRef args);
+SExpRef builtin_log2(Interp *interp, SExpRef args);
+SExpRef builtin_exp(Interp *interp, SExpRef args);
+SExpRef builtin_min(Interp *interp, SExpRef args);
+SExpRef builtin_max(Interp *interp, SExpRef args);
+
+SExpRef builtin_list(Interp *interp, SExpRef args);
+SExpRef builtin_setnth(Interp *interp, SExpRef args);
+SExpRef builtin_setnthcdr(Interp *interp, SExpRef args);
+SExpRef builtin_foldl(Interp *interp, SExpRef args);
+SExpRef builtin_append(Interp *interp, SExpRef args);
+SExpRef builtin_nconc(Interp *interp, SExpRef args);
+SExpRef builtin_memberp(Interp *interp, SExpRef args);
+SExpRef builtin_nreverse(Interp *interp, SExpRef args);
+SExpRef builtin_reverse(Interp *interp, SExpRef args);
+SExpRef builtin_last(Interp *interp, SExpRef args);
+SExpRef builtin_map(Interp *interp, SExpRef args);
+SExpRef builtin_filter(Interp *interp, SExpRef args);
+SExpRef builtin_remove(Interp *interp, SExpRef args);
+SExpRef builtin_count(Interp *interp, SExpRef args);
+SExpRef builtin_foreach(Interp *interp, SExpRef args);
+SExpRef builtin_set_car(Interp *interp, SExpRef args);
+SExpRef builtin_set_cdr(Interp *interp, SExpRef args);
+SExpRef builtin_length(Interp *interp, SExpRef args);
+SExpRef builtin_nth(Interp *interp, SExpRef args);
+SExpRef builtin_nthcdr(Interp *interp, SExpRef args);
+SExpRef builtin_car(Interp *interp, SExpRef args);
+SExpRef builtin_cdr(Interp *interp, SExpRef args);
+SExpRef builtin_cons(Interp *interp, SExpRef args);
+
+SExpRef builtin_symbol2string(Interp *interp, SExpRef args);
+SExpRef builtin_intern(Interp *interp, SExpRef args);
+SExpRef builtin_gensym(Interp *interp, SExpRef args);
+
+SExpRef builtin_not(Interp *interp, SExpRef args);
+SExpRef builtin_equal(Interp *interp, SExpRef args);
+SExpRef builtin_eq(Interp *interp, SExpRef args);
+
+SExpRef builtin_exit(Interp *interp, SExpRef args);
+SExpRef builtin_error(Interp *interp, SExpRef args);
SExpRef builtin_throw(Interp *interp, SExpRef args);
+
SExpRef builtin_gcstat(Interp *interp, SExpRef args);
SExpRef builtin_alwaysgc(Interp *interp, SExpRef args);