From 4105a02e10f2756175650e42eeb4b61fb662b9a2 Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Sun, 2 Oct 2022 08:36:11 +0200 Subject: [PATCH] Squashed 'lispBM/lispBM/' changes from 337ecc93..ebfa4c83 ebfa4c83 bugfix related to allowing parsing of underscore symbols, read_error specifically 926121ae bugfix related to allocation of arrays 603a58ea added spawn-trap and exit-ok and exit-error functions. All tests pass git-subtree-dir: lispBM/lispBM git-subtree-split: ebfa4c8393c071ce1babdf873d3adef17968b217 --- doc/lbmref.md | 36 ++++++++++++++- include/eval_cps.h | 12 +++-- include/lbm_defines.h | 34 +++++++++----- include/lbm_version.h | 5 ++- src/eval_cps.c | 100 +++++++++++++++++++++++++++++++++--------- src/heap.c | 3 +- src/symrepr.c | 58 +++++++++++++----------- src/tokpar.c | 12 ++--- 8 files changed, 189 insertions(+), 71 deletions(-) diff --git a/doc/lbmref.md b/doc/lbmref.md index 0bb67748..7c98f49c 100644 --- a/doc/lbmref.md +++ b/doc/lbmref.md @@ -1296,6 +1296,24 @@ that the runtime system should allocate to run the task in: `(spawn stack-size c --- +### spawn-trap + +Use `spawn-trap` to spawn a child process and enable trapping of exit conditions for that +child. The form of a `spawn-trap` expression is `(spawn-trap closure arg1 .. argN)`. +If the child process is terminated because of an error, a message is sent to the parent +process of the form `(exit-error tid err-val)`. If the child process terminates successfully +a message of the form `(exit-ok tid value)` is sent to the parent. + +Example: +```lisp +(spawn-trap my-thread) + +(recv ((exit-error (? tid) (? e)) ...) + ((exit-ok (? tid) (? v)) ...)) +``` + +--- + ### wait Use `wait` to wait for a spawned process to finish. @@ -1321,7 +1339,7 @@ is number indicating at least how many microseconds the process should sleep. `atomic` can be used to execute a LispBM expression without allowing the runtime system to switch task during the time that takes. -An example that atomically perfoms operations a,b and c. +An example that atomically perfoms operations a,b and c. ```lisp (atomic @@ -1330,7 +1348,23 @@ An example that atomically perfoms operations a,b and c. b c)) ``` +--- +### exit-ok + +The `exit-ok` function terminates the thread in a "successful" way and returnes a result +specified by the programmer. The form of an `exit-ok` expression is `(exit-ok value)`. +If the process that calls `exit-ok` was created using `spawn-trap` a message of the form +`(exit-ok tid value)` is be sent to the parent of this process. + +--- + +### exit-error + +The `exit-error` function terminates the thread with an error specified by the programmer. +The form of an `exit-error` expression is `(exit-error err_val)`. If the process that +calls `exit-error` was created using `spawn-trap` a message of the form +`(exit-error tid err_val)` is sent to the parent of this process. --- diff --git a/include/eval_cps.h b/include/eval_cps.h index f88507e2..266ed781 100644 --- a/include/eval_cps.h +++ b/include/eval_cps.h @@ -34,6 +34,9 @@ extern "C" { #define EVAL_CPS_DEFAULT_MAILBOX_SIZE 10 +#define EVAL_CPS_CONTEXT_FLAG_NOTHING (uint32_t)0x0 +#define EVAL_CPS_CONTEXT_FLAG_TRAP (uint32_t)0x1 + /** The eval_context_t struct represents a lispbm process. * */ @@ -41,18 +44,19 @@ typedef struct eval_context_s{ lbm_value program; lbm_value curr_exp; lbm_value curr_env; - lbm_value *mailbox; /* Message passing mailbox */ - lbm_uint mailbox_size; - lbm_uint num_mail; /* Number of messages in mailbox */ + lbm_value *mailbox; /* Message passing mailbox */ + uint32_t mailbox_size; + uint32_t num_mail; /* Number of messages in mailbox */ + uint32_t flags; lbm_value r; char *error_reason; bool done; bool app_cont; lbm_stack_t K; - /* Process control */ lbm_uint timestamp; lbm_uint sleep_us; lbm_cid id; + lbm_cid parent; /* List structure */ struct eval_context_s *prev; struct eval_context_s *next; diff --git a/include/lbm_defines.h b/include/lbm_defines.h index 17268550..4c8fb666 100644 --- a/include/lbm_defines.h +++ b/include/lbm_defines.h @@ -111,6 +111,9 @@ #define SYM_CALLCC 0x11 #define SYM_CONT 0x12 #define SYM_SETVAR 0x13 +#define SYM_EXIT_OK 0x14 +#define SYM_EXIT_ERROR 0x15 + // 0x20 - 0x2F are errors #define SYM_RERROR 0x20 /* READ ERROR */ @@ -168,18 +171,19 @@ #define SYM_TYPE_CHANNEL 0x5E //Relevant for the tokenizer -#define SYM_OPENPAR 0x70 -#define SYM_CLOSEPAR 0x71 -#define SYM_BACKQUOTE 0x72 -#define SYM_COMMA 0x73 -#define SYM_COMMAAT 0x74 -#define SYM_TOKENIZER_DONE 0x75 -#define SYM_DOT 0x76 -#define SYM_QUOTE_IT 0x77 -#define SYM_COLON 0x78 -#define SYM_TOKENIZER_WAIT 0x79 -#define SYM_OPENBRACK 0x80 -#define SYM_CLOSEBRACK 0x81 +#define SYM_OPENPAR 0x70 +#define SYM_CLOSEPAR 0x71 +#define SYM_BACKQUOTE 0x72 +#define SYM_COMMA 0x73 +#define SYM_COMMAAT 0x74 +#define SYM_TOKENIZER_DONE 0x75 +#define SYM_DOT 0x76 +#define SYM_QUOTE_IT 0x77 +#define SYM_COLON 0x78 +#define SYM_TOKENIZER_WAIT 0x79 +#define SYM_OPENBRACK 0x80 +#define SYM_CLOSEBRACK 0x81 +#define SYM_TOKENIZER_RERROR 0x82 // Fundamental Operations #define FUNDAMENTALS_START 0x100 @@ -208,6 +212,7 @@ #define SYM_ATOMIC 0x116 #define SYM_SELF 0x117 #define SYM_SET_MAILBOX_SIZE 0x118 +#define SYM_SPAWN_TRAP 0x119 #define SYM_CONS 0x120 #define SYM_CAR 0x121 @@ -305,10 +310,14 @@ #define ENC_SYM_MACRO ((SYM_MACRO << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_MACRO_EXPAND ((SYM_MACRO_EXPAND << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_SETVAR ((SYM_SETVAR << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) +#define ENC_SYM_EXIT_OK ((SYM_EXIT_OK << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) +#define ENC_SYM_EXIT_ERROR ((SYM_EXIT_ERROR << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) + #define ENC_SYM_SPAWN ((SYM_SPAWN << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_YIELD ((SYM_YIELD << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_WAIT ((SYM_WAIT << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_SEND ((SYM_SEND << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) +#define ENC_SYM_SPAWN_TRAP ((SYM_SPAWN_TRAP << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_CONS ((SYM_CONS << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_CAR ((SYM_CAR << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) @@ -321,6 +330,7 @@ #define ENC_SYM_COMMAAT ((SYM_COMMAAT << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_CLOSEPAR ((SYM_CLOSEPAR << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_TOKENIZER_DONE ((SYM_TOKENIZER_DONE << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) +#define ENC_SYM_TOKENIZER_RERROR ((SYM_TOKENIZER_RERROR << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_TYPE_LIST ((SYM_TYPE_LIST << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) #define ENC_SYM_TYPE_ARRAY ((SYM_TYPE_ARRAY << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL) diff --git a/include/lbm_version.h b/include/lbm_version.h index 5a9bf59b..7233525f 100644 --- a/include/lbm_version.h +++ b/include/lbm_version.h @@ -32,7 +32,10 @@ extern "C" { #define LBM_PATCH_VERSION 0 /*! \page changelog Changelog -Sep 25: version 0.7.0 +Oct 1: Version 0.7.0 + - Added spawn-trap inspired by Erlang (but simplified). + +Sep 25: Version 0.7.0 - Removed namespaces (they were too restricted). - Mailboxes are now stored in arrays of default size 10 mails. Mailbox size can be changed using set-mailbox-size. diff --git a/src/eval_cps.c b/src/eval_cps.c index 6d08f039..6f487e09 100644 --- a/src/eval_cps.c +++ b/src/eval_cps.c @@ -513,8 +513,7 @@ static void finish_ctx(void) { if (lbm_memory_ptr_inside((lbm_uint*)ctx_running->error_reason)) { lbm_memory_free((lbm_uint*)ctx_running->error_reason); } - - lbm_memory_free((lbm_uint*) ctx_running->mailbox); + lbm_memory_free((lbm_uint*)ctx_running->mailbox); lbm_memory_free((lbm_uint*)ctx_running); ctx_running = NULL; } @@ -562,15 +561,49 @@ int lbm_set_error_reason(char *error_str) { return r; } -static void error_ctx(lbm_value err_val) { - print_error_message(err_val, 0, 0); +// Not possible to CONS_WITH_GC ins error_ctx_base (potential loop) +static void error_ctx_base(lbm_value err_val, unsigned int row, unsigned int column) { ctx_running->r = err_val; + + if (ctx_running->flags & EVAL_CPS_CONTEXT_FLAG_TRAP) { + if (lbm_heap_num_free() < 3) { + gc(); + } + + if (lbm_heap_num_free() >= 3) { + lbm_value msg = lbm_cons(err_val, ENC_SYM_NIL); + msg = lbm_cons(lbm_enc_i(ctx_running->id), msg); + msg = lbm_cons(ENC_SYM_EXIT_ERROR, msg); + if (lbm_is_symbol_merror(msg)) { + // If this happens something is pretty seriously wrong. + print_error_message(err_val, row, column); + } else { + lbm_find_receiver_and_send(ctx_running->parent, msg); + } + } + } else { + print_error_message(err_val, row, column); + } finish_ctx(); } +static void error_ctx(lbm_value err_val) { + error_ctx_base(err_val, 0, 0); +} + static void read_error_ctx(unsigned int row, unsigned int column) { - print_error_message(ENC_SYM_RERROR, row, column); - ctx_running->r = ENC_SYM_RERROR; + error_ctx_base(ENC_SYM_RERROR, row, column); +} + +// successfully finish a context +static void ok_ctx(void) { + if (ctx_running->flags & EVAL_CPS_CONTEXT_FLAG_TRAP) { + lbm_value msg; + CONS_WITH_GC(msg, ctx_running->r, ENC_SYM_NIL, ENC_SYM_NIL); + CONS_WITH_GC(msg, lbm_enc_i(ctx_running->id), msg, msg); + CONS_WITH_GC(msg, ENC_SYM_EXIT_OK, msg, msg); + lbm_find_receiver_and_send(ctx_running->parent, msg); + } finish_ctx(); } @@ -649,7 +682,7 @@ static void yield_ctx(lbm_uint sleep_us) { ctx_running = NULL; } -lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, lbm_uint stack_size) { +static lbm_cid lbm_create_ctx_parent(lbm_value program, lbm_value env, lbm_uint stack_size, lbm_cid parent, uint32_t context_flags) { if (lbm_type_of(program) != LBM_TYPE_CONS) return -1; @@ -696,6 +729,7 @@ lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, lbm_uint stack_size) { ctx->error_reason = NULL; ctx->mailbox = mailbox; ctx->mailbox_size = EVAL_CPS_DEFAULT_MAILBOX_SIZE; + ctx->flags = context_flags; ctx->num_mail = 0; ctx->done = false; ctx->app_cont = false; @@ -705,6 +739,7 @@ lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, lbm_uint stack_size) { ctx->next = NULL; ctx->id = cid; + ctx->parent = parent; if (!lbm_push(&ctx->K, DONE)) { lbm_memory_free((lbm_uint*)ctx->mailbox); @@ -718,6 +753,15 @@ lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, lbm_uint stack_size) { return ctx->id; } +lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, lbm_uint stack_size) { + // Creates a parentless context. + return lbm_create_ctx_parent(program, + env, + stack_size, + -1, + EVAL_CPS_CONTEXT_FLAG_NOTHING); +} + bool lbm_mailbox_change_size(eval_context_t *ctx, lbm_uint new_size) { lbm_value *mailbox = NULL; @@ -769,7 +813,7 @@ static void advance_ctx(void) { } else { ctx_running->done = true; - finish_ctx(); + ok_ctx(); } } @@ -1661,7 +1705,7 @@ static inline void apply_read_program(lbm_value *args, lbm_uint nargs, eval_cont } } -static inline void apply_spawn(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) { +static inline void apply_spawn(lbm_value *args, lbm_uint nargs, eval_context_t *ctx, uint32_t context_flags) { lbm_uint stack_size = EVAL_CPS_DEFAULT_STACK_SIZE; lbm_uint closure_pos = 1; @@ -1707,9 +1751,11 @@ static inline void apply_spawn(lbm_value *args, lbm_uint nargs, eval_context_t * CONS_WITH_GC(program, exp, program, clo_env); - lbm_cid cid = lbm_create_ctx(program, - clo_env, - stack_size); + lbm_cid cid = lbm_create_ctx_parent(program, + clo_env, + stack_size, + lbm_get_current_cid(), + context_flags); ctx->r = lbm_enc_i(cid); ctx->app_cont = true; } @@ -1780,6 +1826,23 @@ static inline void apply_send(lbm_value *args, lbm_uint nargs, eval_context_t *c ctx->app_cont = true; } +static inline void apply_ok(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) { + lbm_value ok_val = ENC_SYM_TRUE; + if (nargs >= 1) { + ok_val = args[1]; + } + ctx->r = ok_val; + ok_ctx(); +} + +static inline void apply_error(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) { + lbm_value err_val = ENC_SYM_EERROR; + if (nargs >= 1) { + err_val = args[1]; + } + error_ctx(err_val); +} + static inline void apply_fundamental(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) { lbm_value res; WITH_GC(res, lbm_fundamental(&args[1], nargs, args[0]), ENC_SYM_NIL, ENC_SYM_NIL); @@ -1863,18 +1926,20 @@ static inline void cont_application(eval_context_t *ctx) { } else if (lbm_type_of(fun) == LBM_TYPE_SYMBOL) { /* eval_cps specific operations */ - //lbm_uint dfun = lbm_dec_sym(fun); switch(fun) { case ENC_SYM_SETVAR: apply_setvar(fun_args, lbm_dec_u(count), ctx); break; case ENC_SYM_READ: /* fall through */ case ENC_SYM_READ_PROGRAM: apply_read_program(fun_args, lbm_dec_u(count), ctx); break; - case ENC_SYM_SPAWN: apply_spawn(fun_args, lbm_dec_u(count), ctx); break; + case ENC_SYM_SPAWN: apply_spawn(fun_args, lbm_dec_u(count), ctx, EVAL_CPS_CONTEXT_FLAG_NOTHING); break; + case ENC_SYM_SPAWN_TRAP: apply_spawn(fun_args, lbm_dec_u(count), ctx, EVAL_CPS_CONTEXT_FLAG_TRAP); break; case ENC_SYM_YIELD: apply_yield(fun_args, lbm_dec_u(count), ctx); break; case ENC_SYM_WAIT: apply_wait(fun_args, lbm_dec_u(count), ctx); break; case ENC_SYM_EVAL: apply_eval(fun_args, lbm_dec_u(count), ctx); break; case ENC_SYM_EVAL_PROGRAM: apply_eval_program(fun_args, lbm_dec_u(count), ctx); break; case ENC_SYM_SEND: apply_send(fun_args, lbm_dec_u(count), ctx); break; + case ENC_SYM_EXIT_OK: apply_ok(fun_args, lbm_dec_u(count), ctx); break; + case ENC_SYM_EXIT_ERROR: apply_error(fun_args, lbm_dec_u(count), ctx); break; default: if (lbm_is_fundamental(fun)) { // If it is not a eval_cps specific function, it may be a fundamental operation @@ -2184,16 +2249,12 @@ static void read_process_token(eval_context_t *ctx, lbm_value stream, lbm_value if (lbm_type_of(tok) == LBM_TYPE_SYMBOL) { switch (lbm_dec_sym(tok)) { - case SYM_RERROR: + case SYM_TOKENIZER_RERROR: lbm_channel_reader_close(str); lbm_set_error_reason((char*)parse_error_token); read_error_ctx(lbm_channel_row(str), lbm_channel_column(str)); done_reading(ctx->id); return; - case SYM_MERROR: - error_ctx(ENC_SYM_MERROR); - done_reading(ctx->id); - return; case SYM_TOKENIZER_WAIT: printf("wait\n"); CHECK_STACK(lbm_push_2(&ctx->K, stream, READ_NEXT_TOKEN)); @@ -2217,7 +2278,6 @@ static void read_process_token(eval_context_t *ctx, lbm_value stream, lbm_value In case 2, we should find the READ_DONE at sp - 5. */ - if (ctx->K.data[ctx->K.sp-1] == READ_DONE && lbm_dec_u(ctx->K.data[ctx->K.sp-3]) == 0) { /* successfully finished reading an expression (CASE 3) */ diff --git a/src/heap.c b/src/heap.c index 6a984154..32c9e46c 100644 --- a/src/heap.c +++ b/src/heap.c @@ -513,6 +513,7 @@ int lbm_gc_sweep_phase(void) { case SYM_CHANNEL_TYPE:{ lbm_char_channel_t *chan = (lbm_char_channel_t*)heap[i].car; if (lbm_memory_ptr_inside((lbm_uint*)chan)) { + lbm_memory_free((lbm_uint*)chan->state); lbm_memory_free((lbm_uint*)chan); } } break; @@ -759,13 +760,13 @@ int lbm_heap_allocate_array(lbm_value *res, lbm_uint size, lbm_type type){ } array->data = (lbm_uint*)lbm_memory_allocate(allocate_size); - memset(array->data, 0, allocate_size * sizeof(lbm_uint)); if (array->data == NULL) { lbm_memory_free((lbm_uint*)array); *res = ENC_SYM_MERROR; return 0; } + memset(array->data, 0, allocate_size * sizeof(lbm_uint)); array->elt_type = type; array->size = size; diff --git a/src/symrepr.c b/src/symrepr.c index 1ce53f28..2bd6035c 100644 --- a/src/symrepr.c +++ b/src/symrepr.c @@ -57,7 +57,9 @@ special_sym const special_symbols[] = { {"call-cc" , SYM_CALLCC}, {"continuation" , SYM_CONT}, - {"setvar" , SYM_SETVAR}, + {"setvar" , SYM_SETVAR}, + {"exit-ok" , SYM_EXIT_OK}, + {"exit-error" , SYM_EXIT_ERROR}, {"gc" , SYM_PERFORM_GC}, // pattern matching @@ -72,7 +74,7 @@ special_sym const special_symbols[] = { {"?i64" , SYM_MATCH_I64}, {"?double" , SYM_MATCH_DOUBLE}, - // Special symbols with unparsable names + // Error symbols with parsable names {"no_match" , SYM_NO_MATCH}, {"read_error" , SYM_RERROR}, {"type_error" , SYM_TERROR}, @@ -81,33 +83,36 @@ special_sym const special_symbols[] = { {"fatal_error" , SYM_FATAL_ERROR}, {"out_of_stack" , SYM_STACK_ERROR}, {"division_by_zero" , SYM_DIVZERO}, - {"sym_array" , SYM_ARRAY_TYPE}, - {"sym_raw_i" , SYM_RAW_I_TYPE}, - {"sym_raw_u" , SYM_RAW_U_TYPE}, - {"sym_raw_f" , SYM_RAW_F_TYPE}, - {"sym_ind_i" , SYM_IND_I_TYPE}, - {"sym_ind_u" , SYM_IND_U_TYPE}, - {"sym_ind_f" , SYM_IND_F_TYPE}, - {"sym_channel" , SYM_CHANNEL_TYPE}, - {"sym_recovered" , SYM_RECOVERED}, - {"sym_bytecode" , SYM_BYTECODE_TYPE}, - {"sym_custom" , SYM_CUSTOM_TYPE}, - {"sym_nonsense" , SYM_NONSENSE}, {"variable_not_bound" , SYM_NOT_FOUND}, + // Special symbols with unparsable names + {"$array" , SYM_ARRAY_TYPE}, + {"$raw_i" , SYM_RAW_I_TYPE}, + {"$raw_u" , SYM_RAW_U_TYPE}, + {"$raw_f" , SYM_RAW_F_TYPE}, + {"$ind_i" , SYM_IND_I_TYPE}, + {"$ind_u" , SYM_IND_U_TYPE}, + {"$ind_f" , SYM_IND_F_TYPE}, + {"$channel" , SYM_CHANNEL_TYPE}, + {"$recovered" , SYM_RECOVERED}, + {"$bytecode" , SYM_BYTECODE_TYPE}, + {"$custom" , SYM_CUSTOM_TYPE}, + {"$nonsense" , SYM_NONSENSE}, + // tokenizer symbols with unparsable names - {"sym_openpar" , SYM_OPENPAR}, - {"sym_closepar" , SYM_CLOSEPAR}, - {"sym_backquote" , SYM_BACKQUOTE}, - {"sym_comma" , SYM_COMMA}, - {"sym_commaat" , SYM_COMMAAT}, - {"sym_dot" , SYM_DOT}, - {"sym_tok_done" , SYM_TOKENIZER_DONE}, - {"sym_quote_it" , SYM_QUOTE_IT}, - {"sym_colon" , SYM_COLON}, - {"sym_tok_wait" , SYM_TOKENIZER_WAIT}, - {"sym_openbrack" , SYM_OPENBRACK}, - {"sym_closebrack" , SYM_CLOSEBRACK}, + {"[openpar]" , SYM_OPENPAR}, + {"[closepar]" , SYM_CLOSEPAR}, + {"[backquote]" , SYM_BACKQUOTE}, + {"[comma]" , SYM_COMMA}, + {"[commaat]" , SYM_COMMAAT}, + {"[dot]" , SYM_DOT}, + {"[done]" , SYM_TOKENIZER_DONE}, + {"[quote_it]" , SYM_QUOTE_IT}, + {"[colon]" , SYM_COLON}, + {"[wait]" , SYM_TOKENIZER_WAIT}, + {"[openbrack]" , SYM_OPENBRACK}, + {"[closebrack]" , SYM_CLOSEBRACK}, + {"[rerror]" , SYM_TOKENIZER_RERROR}, // special symbols with parseable names {"type-list" , SYM_TYPE_LIST}, @@ -146,6 +151,7 @@ special_sym const special_symbols[] = { {"spawn" , SYM_SPAWN}, {"atomic" , SYM_ATOMIC}, {"self" , SYM_SELF}, + {"spawn-trap" , SYM_SPAWN_TRAP}, {"set-mailbox-size" , SYM_SET_MAILBOX_SIZE}, {"eq" , SYM_EQ}, {"car" , SYM_CAR}, diff --git a/src/tokpar.c b/src/tokpar.c index 2f729a89..503a2156 100644 --- a/src/tokpar.c +++ b/src/tokpar.c @@ -189,7 +189,7 @@ bool symchar0(char c) { } bool symchar(char c) { - const char *allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-*/=<>!?"; + const char *allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-*/=<>!?_"; int i = 0; while (allowed[i] != 0) { @@ -556,7 +556,7 @@ lbm_value lbm_get_next_token(lbm_char_channel_t *chan, bool peek) { return lbm_enc_sym(SYM_TOKENIZER_DONE); } - lbm_value res = lbm_enc_sym(SYM_RERROR); + lbm_value res = lbm_enc_sym(SYM_TOKENIZER_RERROR); uint32_t match; n = tok_match_fixed_size_tokens(chan, fixed_size_tokens, @@ -654,7 +654,7 @@ lbm_value lbm_get_next_token(lbm_char_channel_t *chan, bool peek) { } else if (n == TOKENIZER_NEED_MORE) { return lbm_enc_sym(SYM_TOKENIZER_WAIT); } else if (n == TOKENIZER_STRING_ERROR) { - return lbm_enc_sym(SYM_RERROR); + return ENC_SYM_TOKENIZER_RERROR; } token_float f_val; @@ -701,7 +701,7 @@ lbm_value lbm_get_next_token(lbm_char_channel_t *chan, bool peek) { return lbm_enc_u64((uint64_t)(int_result.negative ? -int_result.value : int_result.value)); break; default: - return lbm_enc_sym(SYM_RERROR); + return ENC_SYM_TOKENIZER_RERROR; break; } } else if (n == TOKENIZER_NEED_MORE) { @@ -730,7 +730,7 @@ lbm_value lbm_get_next_token(lbm_char_channel_t *chan, bool peek) { if (r) { res = lbm_enc_sym(symbol_id); } else { - res = lbm_enc_sym(SYM_RERROR); + res = ENC_SYM_TOKENIZER_RERROR; } } return res; @@ -746,6 +746,6 @@ lbm_value lbm_get_next_token(lbm_char_channel_t *chan, bool peek) { return lbm_enc_sym(SYM_TOKENIZER_WAIT); } - return ENC_SYM_RERROR; + return ENC_SYM_TOKENIZER_RERROR; }