diff options
| author | Mistivia <i@mistivia.com> | 2025-07-15 14:36:26 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-07-16 16:53:44 +0800 |
| commit | c90c10293399c17744237735f80edaad24e009fc (patch) | |
| tree | b2155290fdcd5211c0142e1ed1cc558d0eac6dd3 | |
| parent | 4fdde0172948dfd875f58779b91cfa8e517acedf (diff) | |
add vector tests
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | Readme.md | 8 | ||||
| -rw-r--r-- | docs/builtins.md | 22 | ||||
| -rw-r--r-- | docs/primitives.md | 169 | ||||
| -rw-r--r-- | src/main.c | 6 | ||||
| -rw-r--r-- | tests/vector.lisp | 12 |
6 files changed, 19 insertions, 203 deletions
@@ -21,6 +21,8 @@ tests_bin=$(tests:.c=.bin) all: bamboo-lisp +staticlib: libbamboo-lisp.a + web: web-bamboo-lisp.js web-bamboo-lisp.js: $(src) @@ -37,6 +39,9 @@ src/prelude.c: src/prelude.lisp bamboo-lisp: $(obj) src/main.o 3rdparty/algds/build/lib/libalgds.a gcc $(cflags) -o $@ $^ $(ldflags) +libbamboo-lisp.a: $(obj) + ar cr $@ $^ + 3rdparty/algds/build/lib/libalgds.a: cd 3rdparty/algds && \ make profile=$(mode) @@ -62,13 +62,9 @@ You can use `load` to load a lisp script into the interpreter: (load "my-script.lisp") ``` -## Documents (WIP) +## Examples -- [Primitives](https://github.com/mistivia/bamboo-lisp/blob/master/docs/primitives.md) - -## Example - -See `tests/` for more examples. +See `tests/` for more examples. The tests alse serve as documented. ### 1. Y Combinator diff --git a/docs/builtins.md b/docs/builtins.md deleted file mode 100644 index 0399247..0000000 --- a/docs/builtins.md +++ /dev/null @@ -1,22 +0,0 @@ -# Built-in Functions - -## Type Predicate - -## Control Flow - -## List - -## Boolean - -## Character - -## String - -## Symbol - -## Number & Math - -## Bitwise Operation - -## Debug - diff --git a/docs/primitives.md b/docs/primitives.md deleted file mode 100644 index 749b6c0..0000000 --- a/docs/primitives.md +++ /dev/null @@ -1,169 +0,0 @@ -# Primitives - -**(assert *expression*)** - -Evaluates *expression*. If *expression* evaluates to a non-false, -non-control-flow value, `assert` returns `#t`. Otherwise, it signals an error -indicating that the assertion failed, including the string representation of -the original *expression*. - -```lisp -(assert (= 1 1)) -;; -> #t - -(assert (> 1 2)) -;; -> Error -``` - ---- - -**(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. - -```lisp -(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) (concat "Caught exception: " e))) -;; -> "Caught exception: Alas!" - -(try - (+ 1 2) - (lambda (e) (concat "Caught exception: " e))) -;; -> 3 - -(try - (+ 1 2) - 'not-a-function) -;; -> Error: try: syntax error, catch is not a function. -``` - ---- - -**(load *filename*)** - -Evaluates the Lisp expressions contained in the file specified by `filename`. The `filename` argument must be a string. This primitive can only be called from the top-level environment. - -```lisp -(load "my-program.lisp") -;; -> <Result of the last expression in my-program.lisp> -``` - ---- - -**(return *expression*)** - -Evaluates `expression` and returns its value from the current **function**. If `expression` is omitted, `return` evaluates to **nil**. It's important to note that `return` only exits functions and does not break out of `let` blocks or other control structures. - -```lisp -(defun my-func (x) - (if (> x 10) - (return "Value too large!") - (+ x 5))) -;; -> my-func - -(my-func 5) -;; -> 10 - -(my-func 12) -;; -> "Value too large!" -``` - ---- - -**(break)** - -This primitive immediately exits the innermost enclosing loop or iteration construct. It's analogous to the `break` statement in C. The `break` primitive takes no arguments. - -```lisp -(defun count-to-five () - (let ((i 0)) - (while #t - (setq i (+ i 1)) - (when (> i 5) - (break)) - (print i)))) -;; -> count-to-five - -(count-to-five) -;; 1 -;; 2 -;; 3 -;; 4 -;; 5 -;; -> () -``` - ---- - -**(eval *expression*)** - -Evaluates *expression* and returns its result. This primitive is typically used to evaluate code that is constructed or obtained at runtime. - -```lisp -(eval '(+ 1 2)) -;; -> 3 - -(eval '(* 3 4)) -;; -> 12 - -(defvar my-expression '(+ 10 20)) -(eval my-expression) -;; -> 30 -``` - ---- - -**(unwind-protect *protected-form* *cleanup-form* \&rest *more-cleanup-forms*)** - -Evaluates *protected-form*. After *protected-form* is evaluated, whether it completes normally or exits via a non-local exit (like an error or a `return`), each *cleanup-form* is evaluated sequentially. The return value of `unwind-protect` is the result of *protected-form*. This primitive is crucial for ensuring that cleanup actions (like closing files or releasing resources) always occur. - -```lisp -(unwind-protect - (progn (print "Doing something...") - (/ 10 2)) - (print "Cleaning up!")) -;; "Doing something..." -;; "Cleaning up!" -;; -> 5 - -(unwind-protect - (progn (print "About to error...") - (error "error!")) - (print "Still cleaning up!")) -;; "About to error..." -;; "Still cleaning up!" -;; -> Error -``` - @@ -31,12 +31,6 @@ int main(int argc, char **argv) { interp.stacktrace = interp.nil; mainret = -1; goto end; } - if (Interp_ref(&interp, ret)->type == kBreakSignal - || Interp_ref(&interp, ret)->type == kContinueSignal - || Interp_ref(&interp, ret)->type == kReturnSignal) { - fprintf(stderr, "Error: unexpected control flow signal.\n"); - mainret = -1; goto end; - } } #ifdef WITHREADLINE Parser_set_readline(interp.parser); diff --git a/tests/vector.lisp b/tests/vector.lisp index 9146168..d4f7231 100644 --- a/tests/vector.lisp +++ b/tests/vector.lisp @@ -18,3 +18,15 @@ (assert (equal? (vector-ref v 1) 99)) (assert (equal? (vector-ref v 2) "123")) (assert (equal? (vector-ref v 3) 1.2)) + +(vector-remove v 2) + +(assert (equal? (vector-ref v 2) 1.2)) +(assert (equal? (vector-ref v 1) 99)) + +(defvar x 2) +(vector-append v x) + +(vector-set v 3 3) +(assert (= x 2)) +(assert (= 3 (vector-ref v 3))) |
