From 78ca6b2cb3358e39e729507b50c7eaefbbaaf978 Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Mon, 21 Feb 2022 20:02:27 +0100 Subject: [PATCH] Squashed 'lispBM/lispBM/' changes from f6ae1498..d820e066 d820e066 renamed the array extensions f80d5936 some additions to documentation 4c499d52 version git-subtree-dir: lispBM/lispBM git-subtree-split: d820e066e98d90ec94b91f16f43b809d10bbd1f3 --- doc/lbm.dox | 2 + doc/lbmref.dox | 86 ++++++++++++++++++++++++++++++ include/lbm_version.h | 5 +- include/symrepr.h | 5 +- src/eval_cps.c | 2 + src/extensions/array_extensions.c | 30 +++++------ src/symrepr.c | 5 +- tests/test_array_extensions_0.lisp | 40 +++++++------- tests/test_array_extensions_1.lisp | 42 +++++++-------- tests/test_array_extensions_2.lisp | 16 +++--- tests/test_array_extensions_3.lisp | 16 +++--- tests/test_array_extensions_4.lisp | 16 +++--- tests/test_array_extensions_5.lisp | 2 +- 13 files changed, 181 insertions(+), 86 deletions(-) diff --git a/doc/lbm.dox b/doc/lbm.dox index 8bef28c6..a659d45b 100644 --- a/doc/lbm.dox +++ b/doc/lbm.dox @@ -3,6 +3,8 @@ \section sec_intro Introduction +WORK IN PROGRESS + LispBM is a lisp-like language implemented by a non-lisper. The inspiration for LispBM came from watching the SICP course on youtube and a tiny amount of experimenting with EMACS diff --git a/doc/lbmref.dox b/doc/lbmref.dox index 3dae04e1..9fe9e178 100644 --- a/doc/lbmref.dox +++ b/doc/lbmref.dox @@ -1066,6 +1066,92 @@ Example where a process waits for an i28 \endcode +--- + +\section sec_macros Macros + +lispBM macros are created using the macro keyword. A macro +is quite similar to lambda in lispBM except that +arguments are passed in unevaluated. Together with the code-splicing +capabilities given by quasiquotation, this +provides a powerful code-generation tool. + +A macro application is run through the interpreted two times. Once to +evaluate the body of the macro on the unevaluated arguments. The result of +this first application should be a program. The resulting program then goes +through the interpreter again to compute final values. + +Given this repeated evaluation, macros is not a performance boost in lispbm. +It is really a feature to invent new programming abstractions in cases where +it is ok to pay a little for the overhead for benefits in expressivity. + +

macro

+ +The form of a macro expression is: (macro args body) + +\note +Some lisps provide a defun operation for defining functions +with a bit less typing. The example below defines a defun macro. +\code +(define defun (macro (name args body) + `(define ,name (lambda ,args ,body)))) +\endcode +With this macro the function inc that adds 1 to its argument +can be defined as: +\code +(defun inc (x) (+ x 1)) +\endcode + + +--- + +\section sec_cc Call With Current Continuation + +"Call with current continuation" is called call-cc in LBM. +Call with current continuation saves the "current continuation", which encodes what +the evaluator will do next, into an object in the language. This encoded +continuation object behaves as a function taking one argument. + +The call-cc should be given a function, f, as the single argument. This +function, f, should also take a single argument, the continuation. +At any point in the body of f the continuation can be applied to +a value, in essense replacing the entire call-cc with that value. + +\note +The example below creates a macro for a progn facility that +allows returning at an arbitrary point. +\code +(define do (macro (body) + `(call-cc (lambda (return) (progn ,@body))))) +\endcode +The example using do below makes use of print which is not a +built-in feature of lispBM. There are just to many different ways a programmer may +want to implement print on an microcontroller. Use the lispBM extensions +framework to implement your own version of print +\code +(do ((print 10) + (return 't) + (print 20))) +\endcode +In the example above only "10" will be printed. +Below is an example that conditionally returns. +\code +(define f (lambda (x) + (do ((print "hello world" \#newline) + (if (= x 1) + (return 't) + nil) + (print "Gizmo!" \#newline))))) +\endcode + + + +--- + + + + + \section sec_unparse Unparsable symbols diff --git a/include/lbm_version.h b/include/lbm_version.h index 5e04fa9b..24330871 100644 --- a/include/lbm_version.h +++ b/include/lbm_version.h @@ -25,10 +25,13 @@ /** LBM minor version */ #define LBM_MINOR_VERSION 4 /** LBM patch revision */ -#define LBM_PATCH_VERSION 0 +#define LBM_PATCH_VERSION 1 /* Change log */ +/* Feb 21 2022: Version (0.4.1) + - Bug fixes in gc related to arrays +*/ /* Feb 20 2022: Version (0.4.0) - Adds support for macros. diff --git a/include/symrepr.h b/include/symrepr.h index 7214cd1d..4d757beb 100644 --- a/include/symrepr.h +++ b/include/symrepr.h @@ -57,8 +57,9 @@ #define SYM_SEND 0x14 #define SYM_RECEIVE 0x15 #define SYM_MACRO 0x16 -#define SYM_CALLCC 0x17 -#define SYM_CONT 0x18 +#define SYM_MACRO_EXPAND 0x17 +#define SYM_CALLCC 0x18 +#define SYM_CONT 0x19 #define SYM_ARRAY_TYPE 0x20 #define SYM_BOXED_I_TYPE 0x21 diff --git a/src/eval_cps.c b/src/eval_cps.c index 58e023e0..02e14faf 100644 --- a/src/eval_cps.c +++ b/src/eval_cps.c @@ -951,6 +951,7 @@ static inline void eval_progn(eval_context_t *ctx) { lbm_value env = ctx->curr_env; if (lbm_type_of(exps) == LBM_VAL_TYPE_SYMBOL && exps == NIL) { + printf("the nil case\n"); ctx->r = NIL; ctx->app_cont = true; return; @@ -1173,6 +1174,7 @@ static inline void cont_progn_rest(eval_context_t *ctx) { lbm_value env; lbm_pop_u32_2(&ctx->K, &rest, &env); if (lbm_type_of(rest) == LBM_VAL_TYPE_SYMBOL && rest == NIL) { + printf("cont: rest is nil\n"); ctx->app_cont = true; return; } diff --git a/src/extensions/array_extensions.c b/src/extensions/array_extensions.c index 5b4413fb..7769b4c8 100644 --- a/src/extensions/array_extensions.c +++ b/src/extensions/array_extensions.c @@ -57,22 +57,22 @@ bool lbm_array_extensions_init(void) { } } bool res = true; - res = res && lbm_add_extension("unsafe-free", array_extension_unsafe_free_array); - res = res && lbm_add_extension("buffer-append-i8", array_extension_buffer_append_i8); - res = res && lbm_add_extension("buffer-append-i16", array_extension_buffer_append_i16); - res = res && lbm_add_extension("buffer-append-i32", array_extension_buffer_append_i32); - res = res && lbm_add_extension("buffer-append-u8", array_extension_buffer_append_u8); - res = res && lbm_add_extension("buffer-append-u16", array_extension_buffer_append_u16); - res = res && lbm_add_extension("buffer-append-u32", array_extension_buffer_append_u32); - res = res && lbm_add_extension("buffer-append-f32", array_extension_buffer_append_f32); + res = res && lbm_add_extension("free", array_extension_unsafe_free_array); + res = res && lbm_add_extension("bufset-i8", array_extension_buffer_append_i8); + res = res && lbm_add_extension("bufset-i16", array_extension_buffer_append_i16); + res = res && lbm_add_extension("bufset-i32", array_extension_buffer_append_i32); + res = res && lbm_add_extension("bufset-u8", array_extension_buffer_append_u8); + res = res && lbm_add_extension("bufset-u16", array_extension_buffer_append_u16); + res = res && lbm_add_extension("bufset-u32", array_extension_buffer_append_u32); + res = res && lbm_add_extension("bufset-f32", array_extension_buffer_append_f32); - res = res && lbm_add_extension("buffer-get-i8", array_extension_buffer_get_i8); - res = res && lbm_add_extension("buffer-get-i16", array_extension_buffer_get_i16); - res = res && lbm_add_extension("buffer-get-i32", array_extension_buffer_get_i32); - res = res && lbm_add_extension("buffer-get-u8", array_extension_buffer_get_u8); - res = res && lbm_add_extension("buffer-get-u16", array_extension_buffer_get_u16); - res = res && lbm_add_extension("buffer-get-u32", array_extension_buffer_get_u32); - res = res && lbm_add_extension("buffer-get-f32", array_extension_buffer_get_f32); + res = res && lbm_add_extension("bufget-i8", array_extension_buffer_get_i8); + res = res && lbm_add_extension("bufget-i16", array_extension_buffer_get_i16); + res = res && lbm_add_extension("bufget-i32", array_extension_buffer_get_i32); + res = res && lbm_add_extension("bufget-u8", array_extension_buffer_get_u8); + res = res && lbm_add_extension("bufget-u16", array_extension_buffer_get_u16); + res = res && lbm_add_extension("bufget-u32", array_extension_buffer_get_u32); + res = res && lbm_add_extension("bufget-f32", array_extension_buffer_get_f32); return res; } diff --git a/src/symrepr.c b/src/symrepr.c index dc931993..c600dd4b 100644 --- a/src/symrepr.c +++ b/src/symrepr.c @@ -24,7 +24,7 @@ #include "symrepr.h" -#define NUM_SPECIAL_SYMBOLS 109 +#define NUM_SPECIAL_SYMBOLS 110 #define NAME 0 #define ID 1 #define NEXT 2 @@ -53,6 +53,7 @@ special_sym const special_symbols[NUM_SPECIAL_SYMBOLS] = { {"send" , SYM_SEND}, {"recv" , SYM_RECEIVE}, {"macro" , SYM_MACRO}, + {"macro-expand" , SYM_MACRO_EXPAND}, {"call-cc" , SYM_CALLCC}, {"continuation" , SYM_CONT}, @@ -198,7 +199,7 @@ const char *lookup_symrepr_name_memory(lbm_uint id) { // Lookup symbol name given a symbol id const char *lbm_get_name_by_symbol(lbm_uint id) { - if (id < NUM_SPECIAL_SYMBOLS) { + if (id < SPECIAL_SYMBOLS_END) { for (int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { if (id == special_symbols[i].id) { return (special_symbols[i].name); diff --git a/tests/test_array_extensions_0.lisp b/tests/test_array_extensions_0.lisp index d00f94cb..55e2f664 100644 --- a/tests/test_array_extensions_0.lisp +++ b/tests/test_array_extensions_0.lisp @@ -1,23 +1,23 @@ (define arr (array-create type-byte 10)) -(buffer-append-i8 arr 70 0) -(buffer-append-i8 arr 69 1) -(buffer-append-i8 arr 68 2) -(buffer-append-i8 arr 67 3) -(buffer-append-i8 arr 66 4) -(buffer-append-i8 arr 65 5) -(buffer-append-i8 arr 64 6) -(buffer-append-i8 arr 63 7) -(buffer-append-i8 arr 62 8) -(buffer-append-i8 arr 61 9) +(bufset-i8 arr 70 0) +(bufset-i8 arr 69 1) +(bufset-i8 arr 68 2) +(bufset-i8 arr 67 3) +(bufset-i8 arr 66 4) +(bufset-i8 arr 65 5) +(bufset-i8 arr 64 6) +(bufset-i8 arr 63 7) +(bufset-i8 arr 62 8) +(bufset-i8 arr 61 9) -(and (= (buffer-get-i8 arr 0) 70) - (= (buffer-get-i8 arr 1) 69) - (= (buffer-get-i8 arr 2) 68) - (= (buffer-get-i8 arr 3) 67) - (= (buffer-get-i8 arr 4) 66) - (= (buffer-get-i8 arr 5) 65) - (= (buffer-get-i8 arr 6) 64) - (= (buffer-get-i8 arr 7) 63) - (= (buffer-get-i8 arr 8) 62) - (= (buffer-get-i8 arr 9) 61)) +(and (= (bufget-i8 arr 0) 70) + (= (bufget-i8 arr 1) 69) + (= (bufget-i8 arr 2) 68) + (= (bufget-i8 arr 3) 67) + (= (bufget-i8 arr 4) 66) + (= (bufget-i8 arr 5) 65) + (= (bufget-i8 arr 6) 64) + (= (bufget-i8 arr 7) 63) + (= (bufget-i8 arr 8) 62) + (= (bufget-i8 arr 9) 61)) diff --git a/tests/test_array_extensions_1.lisp b/tests/test_array_extensions_1.lisp index 573053e5..e9d975c8 100644 --- a/tests/test_array_extensions_1.lisp +++ b/tests/test_array_extensions_1.lisp @@ -1,24 +1,24 @@ (define arr (array-create type-byte 10)) -(buffer-append-u8 arr 70 0) -(buffer-append-u8 arr 69 1) -(buffer-append-u8 arr 68 2) -(buffer-append-u8 arr 67 3) -(buffer-append-u8 arr 66 4) -(buffer-append-u8 arr 65 5) -(buffer-append-u8 arr 64 6) -(buffer-append-u8 arr 63 7) -(buffer-append-u8 arr 62 8) -(buffer-append-u8 arr 61 9) +(bufset-u8 arr 70 0) +(bufset-u8 arr 69 1) +(bufset-u8 arr 68 2) +(bufset-u8 arr 67 3) +(bufset-u8 arr 66 4) +(bufset-u8 arr 65 5) +(bufset-u8 arr 64 6) +(bufset-u8 arr 63 7) +(bufset-u8 arr 62 8) +(bufset-u8 arr 61 9) -(= (buffer-get-u8 arr 0) 70u28) -(and (num-eq (buffer-get-u8 arr 0) 70) - (num-eq (buffer-get-u8 arr 1) 69) - (num-eq (buffer-get-u8 arr 2) 68) - (num-eq (buffer-get-u8 arr 3) 67) - (num-eq (buffer-get-u8 arr 4) 66) - (num-eq (buffer-get-u8 arr 5) 65) - (num-eq (buffer-get-u8 arr 6) 64) - (num-eq (buffer-get-u8 arr 7) 63) - (num-eq (buffer-get-u8 arr 8) 62) - (num-eq (buffer-get-u8 arr 9) 61)) +(= (bufget-u8 arr 0) 70u28) +(and (num-eq (bufget-u8 arr 0) 70) + (num-eq (bufget-u8 arr 1) 69) + (num-eq (bufget-u8 arr 2) 68) + (num-eq (bufget-u8 arr 3) 67) + (num-eq (bufget-u8 arr 4) 66) + (num-eq (bufget-u8 arr 5) 65) + (num-eq (bufget-u8 arr 6) 64) + (num-eq (bufget-u8 arr 7) 63) + (num-eq (bufget-u8 arr 8) 62) + (num-eq (bufget-u8 arr 9) 61)) diff --git a/tests/test_array_extensions_2.lisp b/tests/test_array_extensions_2.lisp index 6433cc8f..62b2ba3f 100644 --- a/tests/test_array_extensions_2.lisp +++ b/tests/test_array_extensions_2.lisp @@ -1,14 +1,14 @@ (define arr (array-create type-byte 16)) -(buffer-append-u32 arr 16777215 0) -(buffer-append-u32 arr 0xFFFFFFFF 4) -(buffer-append-u32 arr 10 8) -(buffer-append-u32 arr 0xDEADBEEF 12) +(bufset-u32 arr 16777215 0) +(bufset-u32 arr 0xFFFFFFFF 4) +(bufset-u32 arr 10 8) +(bufset-u32 arr 0xDEADBEEF 12) -(and (num-eq (buffer-get-u32 arr 0) 16777215) - (num-eq (buffer-get-u32 arr 4) 0xFFFFFFFF) - (num-eq (buffer-get-u32 arr 8) 10) - (num-eq (buffer-get-u32 arr 12) 0xDEADBEEF)) +(and (num-eq (bufget-u32 arr 0) 16777215) + (num-eq (bufget-u32 arr 4) 0xFFFFFFFF) + (num-eq (bufget-u32 arr 8) 10) + (num-eq (bufget-u32 arr 12) 0xDEADBEEF)) diff --git a/tests/test_array_extensions_3.lisp b/tests/test_array_extensions_3.lisp index 504cb335..719a420e 100644 --- a/tests/test_array_extensions_3.lisp +++ b/tests/test_array_extensions_3.lisp @@ -1,11 +1,11 @@ (define arr (array-create type-byte 16)) -(buffer-append-i32 arr 16777215 0) -(buffer-append-i32 arr 0xFFFFFFFF 4) -(buffer-append-i32 arr 10 8) -(buffer-append-i32 arr 0xDEADBEEF 12) +(bufset-i32 arr 16777215 0) +(bufset-i32 arr 0xFFFFFFFF 4) +(bufset-i32 arr 10 8) +(bufset-i32 arr 0xDEADBEEF 12) -(and (num-eq (buffer-get-i32 arr 0) 16777215) - (num-eq (buffer-get-i32 arr 4) 0xFFFFFFFF) - (num-eq (buffer-get-i32 arr 8) 10) - (num-eq (buffer-get-i32 arr 12) 0xDEADBEEF)) +(and (num-eq (bufget-i32 arr 0) 16777215) + (num-eq (bufget-i32 arr 4) 0xFFFFFFFF) + (num-eq (bufget-i32 arr 8) 10) + (num-eq (bufget-i32 arr 12) 0xDEADBEEF)) diff --git a/tests/test_array_extensions_4.lisp b/tests/test_array_extensions_4.lisp index f5d4b6a9..e29e3a39 100644 --- a/tests/test_array_extensions_4.lisp +++ b/tests/test_array_extensions_4.lisp @@ -1,11 +1,11 @@ (define arr (array-create type-byte 16)) -(buffer-append-f32 arr 3.14 0) -(buffer-append-f32 arr 666.666 4) -(buffer-append-f32 arr 100 8) -(buffer-append-f32 arr 42 12) +(bufset-f32 arr 3.14 0) +(bufset-f32 arr 666.666 4) +(bufset-f32 arr 100 8) +(bufset-f32 arr 42 12) -(and (num-eq (buffer-get-f32 arr 0) 3.14) - (num-eq (buffer-get-f32 arr 4) 666.666) - (num-eq (buffer-get-f32 arr 8) 100) - (num-eq (buffer-get-f32 arr 12) 42)) +(and (num-eq (bufget-f32 arr 0) 3.14) + (num-eq (bufget-f32 arr 4) 666.666) + (num-eq (bufget-f32 arr 8) 100) + (num-eq (bufget-f32 arr 12) 42)) diff --git a/tests/test_array_extensions_5.lisp b/tests/test_array_extensions_5.lisp index 70120941..ee26a783 100644 --- a/tests/test_array_extensions_5.lisp +++ b/tests/test_array_extensions_5.lisp @@ -1,7 +1,7 @@ (define arr (array-create type-byte 16)) -(unsafe-free arr) +(free arr) (and (= (car arr) nil) (= (cdr arr) nil))