From cb919480b6f13a5aeb1beb479303a127b2da7890 Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Tue, 15 Feb 2022 09:29:40 +0100 Subject: [PATCH] Squashed 'lispBM/lispBM/' changes from 0c09634e..1c2be895 1c2be895 extensions lookup is in an array and extensions occupy a specific range of symbol values git-subtree-dir: lispBM/lispBM git-subtree-split: 1c2be8958f937edf8a5fed394f88f55ca9eab382 --- chibios-examples/repl-ChibiOS/main.c | 8 +++-- chibios-examples/xmas_dac/main.c | 9 ++++-- include/extensions.h | 7 +++-- include/lbm_version.h | 15 +++------ include/lispbm.h | 5 ++- include/symrepr.h | 11 +++++++ repl-cps/repl.c | 8 +++-- src/eval_cps.c | 2 +- src/extensions.c | 46 +++++++++++++++------------- src/lispbm.c | 5 +-- src/symrepr.c | 35 ++++++++++++++++++--- src/tokpar.c | 2 +- tests/test_lisp_code_cps.c | 10 ++++++ 13 files changed, 113 insertions(+), 50 deletions(-) diff --git a/chibios-examples/repl-ChibiOS/main.c b/chibios-examples/repl-ChibiOS/main.c index f6178c98..847cb172 100644 --- a/chibios-examples/repl-ChibiOS/main.c +++ b/chibios-examples/repl-ChibiOS/main.c @@ -32,9 +32,11 @@ #define GC_STACK_SIZE 256 #define PRINT_STACK_SIZE 256 #define HEAP_SIZE 2048 +#define EXTENSION_STORAGE_SIZE 256 uint32_t gc_stack_storage[GC_STACK_SIZE]; uint32_t print_stack_storage[PRINT_STACK_SIZE]; +extension_fptr extension_storage[EXTENSION_STORAGE_SIZE]; static lbm_cons_t heap[HEAP_SIZE] __attribute__ ((aligned (8))); @@ -195,7 +197,8 @@ int main(void) { gc_stack_storage, GC_STACK_SIZE, memory_array, LBM_MEMORY_SIZE_8K, bitmap_array, LBM_MEMORY_BITMAP_SIZE_8K, - print_stack_storage, PRINT_STACK_SIZE)) { + print_stack_storage, PRINT_STACK_SIZE, + extension_storage, EXTENSION_STORAGE_SIZE)) { chprintf(chp,"LispBM Init failed.\r\n"); return 0; } @@ -307,7 +310,8 @@ int main(void) { gc_stack_storage, GC_STACK_SIZE, memory_array, LBM_MEMORY_SIZE_8K, bitmap_array, LBM_MEMORY_BITMAP_SIZE_8K, - print_stack_storage, PRINT_STACK_SIZE); + print_stack_storage, PRINT_STACK_SIZE, + extension_storage, EXTENSION_STORAGE_SIZE); lbm_add_extension("print", ext_print); diff --git a/chibios-examples/xmas_dac/main.c b/chibios-examples/xmas_dac/main.c index 3e119f01..ce61f685 100644 --- a/chibios-examples/xmas_dac/main.c +++ b/chibios-examples/xmas_dac/main.c @@ -32,11 +32,13 @@ #define EVAL_CPS_STACK_SIZE 256 #define GC_STACK_SIZE 256 #define PRINT_STACK_SIZE 256 +#define EXTENSION_STORAGE_SIZE 256 #define HEAP_SIZE 8192 -uint32_t gc_stack_storage[256]; -uint32_t print_stack_storage[256]; +uint32_t gc_stack_storage[GC_STACK_SIZE]; +uint32_t print_stack_storage[PRINT_STACK_SIZE]; +extension_fptr extension_storage[EXTENSION_STORAGE_SIZE]; lbm_cons_t heap[HEAP_SIZE] __attribute__ ((aligned (8))); @@ -324,7 +326,8 @@ int main(void) { gc_stack_storage, GC_STACK_SIZE, memory_array, LBM_MEMORY_SIZE_8K, bitmap_array, LBM_MEMORY_BITMAP_SIZE_8K, - print_stack_storage, PRINT_STACK_SIZE)) { + print_stack_storage, PRINT_STACK_SIZE, + extension_storage, EXTENSION_STORAGE_SIZE)) { chprintf(chp,"Initializing LispBM failed\r\n"); return 0; } diff --git a/include/extensions.h b/include/extensions.h index 6cde14cf..6b63ca47 100644 --- a/include/extensions.h +++ b/include/extensions.h @@ -32,9 +32,12 @@ typedef lbm_value (*extension_fptr)(lbm_value*,lbm_uint); /** Initialize the extensions subsystem. - * \return 1 + * + * \param extension_storage Pointer to array of extension_fptr. + * \param extension_storage_size Size of function pointer array. + * \return 1 on success and 0 for failure */ -extern int lbm_extensions_init(void); +extern int lbm_extensions_init(extension_fptr *extension_storage, int extension_storage_size); /** Look up an extension associated with a key symbol. * * \param sym Symbol bound to the extension to look for. diff --git a/include/lbm_version.h b/include/lbm_version.h index c1177d3c..8898eeb0 100644 --- a/include/lbm_version.h +++ b/include/lbm_version.h @@ -20,27 +20,22 @@ #ifndef LBM_VERSION_H_ #define LBM_VERSION_H_ -/* Approach to versions. - * Major version changes when there are interface breaking changes. - * Minor Backwards compatible additions. - * Patch Backwards compatible bug fixes or tweaks. - */ - /** LBM major version */ #define LBM_MAJOR_VERSION 0 /** LBM minor version */ -#define LBM_MINOR_VERSION 2 +#define LBM_MINOR_VERSION 3 /** LBM patch revision */ #define LBM_PATCH_VERSION 0 - - /* Change log */ +/* Feb 14 2022: version 0.3.0 + Extensions are stored in an array and occupy a range of dedicated symbol values. + /* Feb 14 2022: version 0.2.0 Added GEQ >= and LEQ <= comparisons. -/* Feb 13 2022: version 0.1.1 +/* Feb 13 2022: version 0.1.1 Bug fix in handling of environments in progn. */ /* Feb 11 2022: First state to be given a numbered version (0.1.0) */ diff --git a/include/lispbm.h b/include/lispbm.h index 551daed2..6ae9ca72 100644 --- a/include/lispbm.h +++ b/include/lispbm.h @@ -50,12 +50,15 @@ * \param bitmap_size Size of the memory meta-data array. * \param print_stack_storage Pointer to uint32_t array to use as print_value stack. * \param print_stack_size Size in number of uint32_t values of the print stack. + * \param extension_storage Pointer to array of extension_fptr. + * \param extension_storage_size Size of extension array. * \return 1 on success and 0 on failure. */ extern int lbm_init(lbm_cons_t *heap_storage, uint32_t heap_size, uint32_t *gc_stack_storage, uint32_t gc_stack_size, uint32_t *memory, uint32_t memory_size, uint32_t *memory_bitmap, uint32_t bitmap_size, - uint32_t *print_stack_storage, uint32_t print_stack_size); + uint32_t *print_stack_storage, uint32_t print_stack_size, + extension_fptr *extension_storage, int extension_storage_size ); #endif diff --git a/include/symrepr.h b/include/symrepr.h index 29a41f2d..2263564c 100644 --- a/include/symrepr.h +++ b/include/symrepr.h @@ -166,6 +166,9 @@ #define FUNDAMENTALS_END 0x200 #define MAX_SPECIAL_SYMBOLS 4096 // 12bits (highest id allowed is 0xFFFF) +#define MAX_EXTENSION_SYMBOLS 4096 // 12bits 0x10000 - 0x1FFFF + +#define MAX_SYMBOL_VALUE 0x0FFFFFFF /** Initialize the symbol table. * @@ -186,6 +189,14 @@ extern int lbm_add_symbol(char *name, lbm_uint *id); * \return 1 for success and 0 for failure. */ extern int lbm_add_symbol_const(char *name, lbm_uint *id); +/** Add an extension symbol to the symbol table. + * The name is assumed to be statically allocated. + * + * \param name Statically allocated name string. + * \param id Resulting id is returned through this argument. + * \return 1 for success and 0 for failure. + */ +extern int lbm_add_extension_symbol_const(char *name, lbm_uint* id); /** Look up an id from the symbol table given a name. * * \param name Name string to look up. diff --git a/repl-cps/repl.c b/repl-cps/repl.c index a0d33bdc..34393a13 100644 --- a/repl-cps/repl.c +++ b/repl-cps/repl.c @@ -30,9 +30,11 @@ #define EVAL_CPS_STACK_SIZE 256 #define GC_STACK_SIZE 256 #define PRINT_STACK_SIZE 256 +#define EXTENSION_STORAGE_SIZE 256 uint32_t gc_stack_storage[GC_STACK_SIZE]; uint32_t print_stack_storage[PRINT_STACK_SIZE]; +extension_fptr extension_storage[EXTENSION_STORAGE_SIZE]; static volatile bool allow_print = true; @@ -339,7 +341,8 @@ int main(int argc, char **argv) { gc_stack_storage, GC_STACK_SIZE, memory, LBM_MEMORY_SIZE_8K, bitmap, LBM_MEMORY_BITMAP_SIZE_8K, - print_stack_storage, PRINT_STACK_SIZE); + print_stack_storage, PRINT_STACK_SIZE, + extension_storage, EXTENSION_STORAGE_SIZE); lbm_set_ctx_done_callback(done_callback); lbm_set_timestamp_us_callback(timestamp_callback); @@ -461,7 +464,8 @@ int main(int argc, char **argv) { gc_stack_storage, GC_STACK_SIZE, memory, LBM_MEMORY_SIZE_8K, bitmap, LBM_MEMORY_BITMAP_SIZE_8K, - print_stack_storage, PRINT_STACK_SIZE); + print_stack_storage, PRINT_STACK_SIZE, + extension_storage, EXTENSION_STORAGE_SIZE); lbm_add_extension("print", ext_print); } else if (strncmp(str, ":prelude", 8) == 0) { diff --git a/src/eval_cps.c b/src/eval_cps.c index 9ef49d47..be30fbe2 100644 --- a/src/eval_cps.c +++ b/src/eval_cps.c @@ -1323,7 +1323,7 @@ static inline void cont_application(eval_context_t *ctx) { } break; } else { - // It may be an extension + // It may be an extension extension_fptr f = lbm_get_extension(lbm_dec_sym(fun)); if (f == NULL) { error_ctx(lbm_enc_sym(SYM_EERROR)); diff --git a/src/extensions.c b/src/extensions.c index c19d90c6..0f68417e 100644 --- a/src/extensions.c +++ b/src/extensions.c @@ -24,48 +24,50 @@ #include "extensions.h" +static int ext_offset = MAX_SPECIAL_SYMBOLS; +static int ext_max = -1; +static extension_fptr *extension_table = NULL; + #define SYM 0 #define FPTR 1 #define NEXT 2 -/* typedef struct s_extension_function{ */ -/* VALUE sym; */ -/* extension_fptr ext_fun; */ -/* struct s_extension_function* next; */ -/* } extension_function_t; */ - uint32_t* extensions = NULL; -int lbm_extensions_init(void) { - extensions = NULL; +int lbm_extensions_init(extension_fptr *extension_storage, int extension_storage_size) { + if (extension_storage == NULL) return 0; + + extension_table = extension_storage; + + ext_max = extension_storage_size; + return 1; } extension_fptr lbm_get_extension(lbm_uint sym) { - uint32_t *t = extensions; - while (t != NULL) { - if (t[SYM] == sym) { - return (extension_fptr)t[FPTR]; - } - t = (uint32_t*)t[NEXT]; + int ext_next = (int)sym - ext_offset; + + if (ext_next < 0 || ext_next > ext_max) { + return NULL; } - return NULL; + + return extension_table[ext_next]; } bool lbm_add_extension(char *sym_str, extension_fptr ext) { lbm_value symbol; - int res = lbm_add_symbol_const(sym_str, &symbol); + int res = lbm_add_extension_symbol_const(sym_str, &symbol); if (!res) return false; - uint32_t *m = lbm_memory_allocate(3); /* 3 words */ + int ext_next = (int)symbol - ext_offset; - if (!m) return false; + if (ext_next < 0 || ext_next > ext_max) { + return false; + } + + extension_table[ext_next] = ext; - m[SYM] = symbol; - m[FPTR] = (uint32_t) ext; - m[NEXT] = (uint32_t) extensions; - extensions = m; return true; } diff --git a/src/lispbm.c b/src/lispbm.c index 778aeb83..ed003249 100644 --- a/src/lispbm.c +++ b/src/lispbm.c @@ -21,7 +21,8 @@ int lbm_init(lbm_cons_t *heap_storage, uint32_t heap_size, uint32_t *gc_stack_storage, uint32_t gc_stack_size, uint32_t *memory, uint32_t memory_size, uint32_t *memory_bitmap, uint32_t bitmap_size, - uint32_t *print_stack_storage, uint32_t print_stack_size) { + uint32_t *print_stack_storage, uint32_t print_stack_size, + extension_fptr *extension_storage, int extension_storage_size ) { if (lbm_print_init(print_stack_storage, print_stack_size) == 0) return 0; @@ -42,7 +43,7 @@ int lbm_init(lbm_cons_t *heap_storage, uint32_t heap_size, if (lbm_eval_init() == 0) return 0; - if (lbm_extensions_init() == 0) + if (lbm_extensions_init(extension_storage, extension_storage_size) == 0) return 0; return 1; diff --git a/src/symrepr.c b/src/symrepr.c index bcca4b3b..8a66f53b 100644 --- a/src/symrepr.c +++ b/src/symrepr.c @@ -163,13 +163,15 @@ special_sym const special_symbols[NUM_SPECIAL_SYMBOLS] = { {"is-fundamental" , SYM_IS_FUNDAMENTAL} }; +#define RUNTIME_SYMBOLS_START (MAX_SPECIAL_SYMBOLS + MAX_EXTENSION_SYMBOLS) static uint32_t *symlist = NULL; -static lbm_uint next_symbol_id = 0; +static lbm_uint next_symbol_id = RUNTIME_SYMBOLS_START; +static lbm_uint next_extension_symbol_id = MAX_SPECIAL_SYMBOLS; int lbm_symrepr_init(void) { symlist = NULL; - next_symbol_id = 0; + next_symbol_id = RUNTIME_SYMBOLS_START; return 1; } @@ -255,7 +257,7 @@ int lbm_add_symbol(char *name, lbm_uint* id) { m[NEXT] = (uint32_t) symlist; symlist = m; } - m[ID] = MAX_SPECIAL_SYMBOLS + next_symbol_id++; + m[ID] = next_symbol_id++; *id = m[ID]; return 1; } @@ -278,11 +280,36 @@ int lbm_add_symbol_const(char *name, lbm_uint* id) { m[NEXT] = (uint32_t) symlist; symlist = m; } - m[ID] = MAX_SPECIAL_SYMBOLS + next_symbol_id++; + m[ID] = next_symbol_id++; *id = m[ID]; return 1; } +int lbm_add_extension_symbol_const(char *name, lbm_uint* id) { + if (strlen(name) == 0) return 0; // failure if empty symbol + if (next_extension_symbol_id >= RUNTIME_SYMBOLS_START) return 0; + + uint32_t *m = lbm_memory_allocate(3); + + if (m == NULL) { + return 0; + } + + m[NAME] = (uint32_t)name; + + if (symlist == NULL) { + m[NEXT] = (uint32_t) NULL; + symlist = m; + } else { + m[NEXT] = (uint32_t) symlist; + symlist = m; + } + m[ID] = next_extension_symbol_id++; + *id = m[ID]; + return 1; +} + + unsigned int lbm_get_symbol_table_size(void) { unsigned int n = 0; diff --git a/src/tokpar.c b/src/tokpar.c index 962bd90c..e95711e1 100644 --- a/src/tokpar.c +++ b/src/tokpar.c @@ -440,7 +440,7 @@ int tok_F(lbm_tokenizer_char_stream_t *str, lbm_float *res) { for (i = 0; i < m; i ++) { fbuf[i] = get(str); } - + fbuf[i] = 0; *res = (float)strtod(fbuf, NULL); return (int)n; diff --git a/tests/test_lisp_code_cps.c b/tests/test_lisp_code_cps.c index 7ff18595..99350d19 100644 --- a/tests/test_lisp_code_cps.c +++ b/tests/test_lisp_code_cps.c @@ -30,9 +30,11 @@ #define EVAL_CPS_STACK_SIZE 256 #define GC_STACK_SIZE 256 #define PRINT_STACK_SIZE 256 +#define EXTENSION_STORAGE_SIZE 256 uint32_t gc_stack_storage[GC_STACK_SIZE]; uint32_t print_stack_storage[PRINT_STACK_SIZE]; +extension_fptr *extension_storage[EXTENSION_STORAGE_SIZE]; /* Tokenizer state for strings */ static lbm_tokenizer_string_state_t string_tok_state; @@ -216,6 +218,14 @@ int main(int argc, char **argv) { return 0; } + res = lbm_extensions_init(extension_storage, EXTENSION_STORAGE_SIZE); + if (res) + printf("Extensions initialized.\n"); + else { + printf("Error initializing extensions.\n"); + return 0; + } + res = lbm_add_extension("ext-even", ext_even); if (res) printf("Extension added.\n");