mirror of https://github.com/rusefi/bldc.git
Merge commit '38a42ba20326836b12798ba3b5ea718deea50977'
This commit is contained in:
commit
6e8dc4d7aa
|
@ -2,9 +2,9 @@
|
|||
|
||||
## About Symbols
|
||||
|
||||
Symbols are very important and fundamental to LispBM and also perhaps
|
||||
Symbols are very important and central to LispBM and also perhaps
|
||||
a bit different from identifiers/names used in languages such as C, so
|
||||
a short intro could be good here.
|
||||
a short intro on symbols could be good here.
|
||||
|
||||
A symbol can be thought of as a name and can be used to give names
|
||||
to functions or values (variables). A symbol can also be treated and
|
||||
|
@ -37,20 +37,20 @@ should not be able to redefine and trying to redefine them leads to an error.
|
|||
Symbols that start with `ext-` are special and reserved for use together
|
||||
with extensions that are loaded and bound at runtime.
|
||||
|
||||
Examples of symbols used as data are `nil` and `t`. `nil` is used the
|
||||
represent nothing, the empty list or other similar things and `t`
|
||||
Examples of symbols used as data are `nil` and `t`. `nil` representds
|
||||
"nothing", the empty list or other similar things and `t`
|
||||
represents true. But any symbol can be used as data by quoting it
|
||||
`'`, see <a href="#quotes-and-quasiquotation"> Quotes and
|
||||
Quasiquotation </a>.
|
||||
|
||||
### Valid symbol names
|
||||
|
||||
A symbol is string of characters following the rules:
|
||||
A symbol is a string of characters following the rules:
|
||||
1. The first character is a one of 'a' - 'z' or 'A' - 'Z' or '+-*/=<>#!'.
|
||||
2. The rest of the characters are in 'a' - 'z' or 'A' - 'Z' or '0' - '9' or '+-*/=<>!?_'.
|
||||
3. At most 256 characters long.
|
||||
|
||||
Note that lower-case and upper-case alphabetical letters are considers identical
|
||||
Note that lower-case and upper-case alphabetical letters are considered identical
|
||||
so the symbol `apa` is the same symbol as `APA`.
|
||||
|
||||
examples of valid symbols
|
||||
|
@ -386,7 +386,7 @@ the argument.
|
|||
### nil
|
||||
|
||||
Represents the empty list. The nil value is also considered to be false by
|
||||
conditionals
|
||||
conditionals.
|
||||
|
||||
The example below creates a one element list by allocating a cons cell and putting a value (1) in the <a href="#car"> car </a> field
|
||||
and nil in the <a href="#cdr"> cdr </a> field.
|
||||
|
@ -874,7 +874,6 @@ These two programs are thus equivalent:
|
|||
(define a 10)
|
||||
(define b 20)
|
||||
(+ a b))
|
||||
|
||||
```
|
||||
|
||||
And
|
||||
|
@ -951,7 +950,7 @@ The code above evaluates to 11.
|
|||
|
||||
<a name="read-program"> <h3>read-program</h3> </a>
|
||||
|
||||
Parses a string containing multiple sequenced expressed. The resulting list of
|
||||
Parses a string containing multiple sequenced expressions. The resulting list of
|
||||
expressions can be evaluated as a program using <a href="#eval-program">eval-program</a>.
|
||||
The form of a read-program expression is `(read-program string)`.
|
||||
|
||||
|
@ -1170,7 +1169,7 @@ Example that combines to lists.
|
|||
|
||||
### ix
|
||||
|
||||
Index into a list using the `ix`. the form of an `ix` expression
|
||||
Index into a list using the `ix` function. The form of an `ix` expression
|
||||
is `(ix list-expr index-expr)`. Indexing starts from 0 and if you index out of bounds the result is nil.
|
||||
|
||||
Example that evaluates to 2.
|
||||
|
@ -1365,9 +1364,9 @@ alist. The form of a `setassoc` expression is `(setassoc alist-expr key-expr val
|
|||
### bufcreate
|
||||
|
||||
Create an array of bytes. The
|
||||
form of an `bufcreate` expression is `(bufcreate size-expr)`
|
||||
form of a `bufcreate` expression is `(bufcreate size-expr)`
|
||||
|
||||
Example that creates a 10 element buffer caled data:
|
||||
Example that creates a 10 element buffer called data:
|
||||
|
||||
```clj
|
||||
(define data (bufcreate 10))
|
||||
|
@ -1672,19 +1671,21 @@ An example that atomically perfoms operations a,b and 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
|
||||
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.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -199,102 +199,117 @@
|
|||
#define SYM_LOOP 0x115
|
||||
#define SPECIAL_FORMS_END 0x115
|
||||
|
||||
// Fundamental built in operations that take their
|
||||
// arguments on stack. Fundamentals do not handle
|
||||
// their own GC and they are not allowed to create
|
||||
// continuations.
|
||||
#define SYM_ADD 0x20000
|
||||
#define SYM_SUB 0x20001
|
||||
#define SYM_MUL 0x20002
|
||||
#define SYM_DIV 0x20003
|
||||
#define SYM_MOD 0x20004
|
||||
#define SYM_EQ 0x20005
|
||||
#define SYM_NOT_EQ 0x20006
|
||||
#define SYM_NUMEQ 0x20007
|
||||
#define SYM_NUM_NOT_EQ 0x20008
|
||||
#define SYM_LT 0x20009
|
||||
#define SYM_GT 0x2000A
|
||||
#define SYM_LEQ 0x2000B
|
||||
#define SYM_GEQ 0x2000C
|
||||
#define SYM_NOT 0x2000D
|
||||
#define SYM_PERFORM_GC 0x2000E
|
||||
#define SYM_SELF 0x2000F
|
||||
#define SYM_SET_MAILBOX_SIZE 0x20010
|
||||
#define SYM_CONS 0x20011
|
||||
#define SYM_CAR 0x20012
|
||||
#define SYM_CDR 0x20013
|
||||
#define SYM_LIST 0x20014
|
||||
#define SYM_APPEND 0x20015
|
||||
#define SYM_UNDEFINE 0x20016
|
||||
#define SYM_ARRAY_CREATE 0x20017
|
||||
#define SYM_SYMBOL_TO_STRING 0x20018
|
||||
#define SYM_STRING_TO_SYMBOL 0x20019
|
||||
#define SYM_SYMBOL_TO_UINT 0x2001A
|
||||
#define SYM_UINT_TO_SYMBOL 0x2001B
|
||||
#define SYM_SET_CAR 0x2001C
|
||||
#define SYM_SET_CDR 0x2001D
|
||||
#define SYM_SET_IX 0x2001E
|
||||
#define SYM_ASSOC 0x2001F
|
||||
#define SYM_ACONS 0x20020
|
||||
#define SYM_SET_ASSOC 0x20021
|
||||
#define SYM_COSSA 0x20022
|
||||
#define SYM_IX 0x20023
|
||||
#define SYM_TO_I 0x20024
|
||||
#define SYM_TO_I32 0x20025
|
||||
#define SYM_TO_U 0x20026
|
||||
#define SYM_TO_U32 0x20027
|
||||
#define SYM_TO_FLOAT 0x20028
|
||||
#define SYM_TO_I64 0x20029
|
||||
#define SYM_TO_U64 0x2002A
|
||||
#define SYM_TO_DOUBLE 0x2002B
|
||||
#define SYM_TO_BYTE 0x2002C
|
||||
#define SYM_SHL 0x2002D
|
||||
#define SYM_SHR 0x2002E
|
||||
#define SYM_BITWISE_AND 0x2002F
|
||||
#define SYM_BITWISE_OR 0x20030
|
||||
#define SYM_BITWISE_XOR 0x20031
|
||||
#define SYM_BITWISE_NOT 0x20032
|
||||
#define SYM_CUSTOM_DESTRUCT 0x20033
|
||||
#define SYM_TYPE_OF 0x20034
|
||||
#define SYM_LIST_LENGTH 0x20035
|
||||
#define SYM_RANGE 0x20036
|
||||
#define SYM_REG_EVENT_HANDLER 0x20037
|
||||
#define SYM_TAKE 0x20038
|
||||
#define SYM_DROP 0x20039
|
||||
|
||||
// Apply funs:
|
||||
// Get their arguments in evaluated form.
|
||||
// Get their arguments in evaluated form on the stack.
|
||||
// Consecutive value symbols for lookup-application
|
||||
#define APPLY_FUNS_START 0x150
|
||||
#define SYM_SETVAR 0x150
|
||||
#define SYM_READ 0x151
|
||||
#define SYM_READ_PROGRAM 0x152
|
||||
#define SYM_READ_AND_EVAL_PROGRAM 0x153
|
||||
#define SYM_SPAWN 0x154
|
||||
#define SYM_SPAWN_TRAP 0x155
|
||||
#define SYM_YIELD 0x156
|
||||
#define SYM_WAIT 0x157
|
||||
#define SYM_EVAL 0x158
|
||||
#define SYM_EVAL_PROGRAM 0x159
|
||||
#define SYM_SEND 0x15A
|
||||
#define SYM_EXIT_OK 0x15B
|
||||
#define SYM_EXIT_ERROR 0x15C
|
||||
#define SYM_MAP 0x15D
|
||||
#define SYM_REVERSE 0x15E
|
||||
#define SYM_FLATTEN 0x15F
|
||||
#define SYM_UNFLATTEN 0x160
|
||||
#define SYM_KILL 0x161
|
||||
#define SYM_SLEEP 0x162
|
||||
#define SYM_MERGE 0x163
|
||||
#define SYM_SORT 0x164
|
||||
#define APPLY_FUNS_END 0x164
|
||||
// apply funs handle their own GC needs and can
|
||||
// create continuations.
|
||||
#define SYM_SETVAR 0x30000
|
||||
#define SYM_READ 0x30001
|
||||
#define SYM_READ_PROGRAM 0x30002
|
||||
#define SYM_READ_AND_EVAL_PROGRAM 0x30003
|
||||
#define SYM_SPAWN 0x30004
|
||||
#define SYM_SPAWN_TRAP 0x30005
|
||||
#define SYM_YIELD 0x30006
|
||||
#define SYM_WAIT 0x30007
|
||||
#define SYM_EVAL 0x30008
|
||||
#define SYM_EVAL_PROGRAM 0x30009
|
||||
#define SYM_SEND 0x3000A
|
||||
#define SYM_EXIT_OK 0x3000B
|
||||
#define SYM_EXIT_ERROR 0x3000C
|
||||
#define SYM_MAP 0x3000D
|
||||
#define SYM_REVERSE 0x3000E
|
||||
#define SYM_FLATTEN 0x3000F
|
||||
#define SYM_UNFLATTEN 0x30010
|
||||
#define SYM_KILL 0x30011
|
||||
#define SYM_SLEEP 0x30012
|
||||
#define SYM_MERGE 0x30013
|
||||
#define SYM_SORT 0x30014
|
||||
|
||||
#define FUNDAMENTALS_START 0x20E
|
||||
#define SYM_ADD 0x20E
|
||||
#define SYM_SUB 0x20F
|
||||
#define SYM_MUL 0x210
|
||||
#define SYM_DIV 0x211
|
||||
#define SYM_MOD 0x212
|
||||
#define SYM_EQ 0x213
|
||||
#define SYM_NOT_EQ 0x214
|
||||
#define SYM_NUMEQ 0x215
|
||||
#define SYM_NUM_NOT_EQ 0x216
|
||||
#define SYM_LT 0x217
|
||||
#define SYM_GT 0x218
|
||||
#define SYM_LEQ 0x219
|
||||
#define SYM_GEQ 0x21A
|
||||
#define SYM_NOT 0x21B
|
||||
#define SYM_PERFORM_GC 0x21C
|
||||
#define SYM_SELF 0x21D
|
||||
#define SYM_SET_MAILBOX_SIZE 0x21E
|
||||
#define SYM_CONS 0x21F
|
||||
#define SYM_CAR 0x220
|
||||
#define SYM_CDR 0x221
|
||||
#define SYM_LIST 0x222
|
||||
#define SYM_APPEND 0x223
|
||||
#define SYM_UNDEFINE 0x224
|
||||
#define SYM_ARRAY_CREATE 0x225
|
||||
#define SYM_SYMBOL_TO_STRING 0x226
|
||||
#define SYM_STRING_TO_SYMBOL 0x227
|
||||
#define SYM_SYMBOL_TO_UINT 0x228
|
||||
#define SYM_UINT_TO_SYMBOL 0x229
|
||||
#define SYM_SET_CAR 0x22A
|
||||
#define SYM_SET_CDR 0x22B
|
||||
#define SYM_SET_IX 0x22C
|
||||
#define SYM_ASSOC 0x22D
|
||||
#define SYM_ACONS 0x22E
|
||||
#define SYM_SET_ASSOC 0x22F
|
||||
#define SYM_COSSA 0x230
|
||||
#define SYM_IX 0x231
|
||||
#define SYM_TO_I 0x232
|
||||
#define SYM_TO_I32 0x233
|
||||
#define SYM_TO_U 0x234
|
||||
#define SYM_TO_U32 0x235
|
||||
#define SYM_TO_FLOAT 0x236
|
||||
#define SYM_TO_I64 0x237
|
||||
#define SYM_TO_U64 0x238
|
||||
#define SYM_TO_DOUBLE 0x239
|
||||
#define SYM_TO_BYTE 0x23A
|
||||
#define SYM_SHL 0x23B
|
||||
#define SYM_SHR 0x23C
|
||||
#define SYM_BITWISE_AND 0x23D
|
||||
#define SYM_BITWISE_OR 0x23E
|
||||
#define SYM_BITWISE_XOR 0x23F
|
||||
#define SYM_BITWISE_NOT 0x240
|
||||
#define SYM_CUSTOM_DESTRUCT 0x241 /* run the destructor of a custom type */
|
||||
#define SYM_TYPE_OF 0x242
|
||||
#define SYM_LIST_LENGTH 0x243
|
||||
#define SYM_RANGE 0x244
|
||||
#define SYM_REG_EVENT_HANDLER 0x245
|
||||
#define SYM_TAKE 0x246
|
||||
#define SYM_DROP 0x247
|
||||
#define FUNDAMENTALS_END 0x249
|
||||
|
||||
#define SPECIAL_SYMBOLS_START 0
|
||||
#define SPECIAL_SYMBOLS_END 0xFFFF
|
||||
#define EXTENSION_SYMBOLS_START 0x10000
|
||||
#define EXTENSION_SYMBOLS_END 0x1FFFF
|
||||
#define VARIABLE_SYMBOLS_START 0x20000
|
||||
#define VARIABLE_SYMBOLS_END 0x2FFFF
|
||||
#define RUNTIME_SYMBOLS_START 0x30000
|
||||
#define MAX_SYMBOL_VALUE 0x0FFFFFFF
|
||||
#define SYMBOL_KIND(X) ((X) >> 16)
|
||||
#define SYMBOL_KIND_SPECIAL 0
|
||||
#define SYMBOL_KIND_EXTENSION 1
|
||||
#define SYMBOL_KIND_FUNDAMENTAL 2
|
||||
#define SYMBOL_KIND_APPFUN 3
|
||||
|
||||
#define SYMBOL_IX(X) ((X) & 0xFFFF)
|
||||
|
||||
#define SPECIAL_SYMBOLS_START 0
|
||||
#define SPECIAL_SYMBOLS_END 0xFFFF
|
||||
#define EXTENSION_SYMBOLS_START 0x10000
|
||||
#define EXTENSION_SYMBOLS_END 0x1FFFF
|
||||
#define FUNDAMENTAL_SYMBOLS_START 0x20000
|
||||
#define FUNDAMENTAL_SYMBOLS_END 0x2FFFF
|
||||
#define APPFUN_SYMBOLS_START 0x30000
|
||||
#define APPFUN_SYMBOLS_END 0x3FFFF
|
||||
#define RUNTIME_SYMBOLS_START 0x40000
|
||||
#define MAX_SYMBOL_VALUE 0x0FFFFFFF
|
||||
|
||||
// This leaves 268173312 runtime symbols available.
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
Encoded Symbols
|
||||
|
|
|
@ -72,20 +72,6 @@ int lbm_add_symbol_flash(char *name, lbm_uint* id);
|
|||
\return 1 for success and 0 for failure.
|
||||
*/
|
||||
int lbm_str_to_symbol(char *name, lbm_uint *sym_id);
|
||||
/** Add a variable-symbol to the symbol table. The symbol name string is copied to arrays and symbols memory.
|
||||
*
|
||||
* \param name String representation of the symbol.
|
||||
* \param id Resulting id is returned through this argument.
|
||||
* \return 1 for success and 0 for failure.
|
||||
*/
|
||||
int lbm_add_variable_symbol(char *name, lbm_uint* id);
|
||||
/** Add a variable-symbol to the symbol table. The symbol name is
|
||||
* considered to be a statically allocated constant.
|
||||
* \param name String representation of the symbol.
|
||||
* \param id Resulting id is returned through this argument.
|
||||
* \return 1 for success and 0 for failure.
|
||||
*/
|
||||
int lbm_add_variable_symbol_const(char *name, lbm_uint* id);
|
||||
/** Add a symbol to the symbol table. The name is assumed to be a statically allocated string.
|
||||
*
|
||||
* \param name Statically allocated name string.
|
||||
|
@ -113,8 +99,6 @@ int lbm_get_symbol_by_name(char *name, lbm_uint *id);
|
|||
*/
|
||||
const char* lbm_get_name_by_symbol(lbm_uint id);
|
||||
|
||||
lbm_uint lbm_get_num_variables(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* \return The total amount of lbm_memory space occupied by the symbol table in bytes.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Copyright 2018, 2020 - 2024 Joel Svensson svenssonjoel@yahoo.se
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -122,6 +122,24 @@ const char* lbm_error_str_variable_not_bound = "Variable not bound.";
|
|||
|
||||
static lbm_value lbm_error_suspect;
|
||||
static bool lbm_error_has_suspect = false;
|
||||
#ifdef LBM_ALWAYS_GC
|
||||
|
||||
#define WITH_GC(y, x) \
|
||||
gc(); \
|
||||
(y) = (x); \
|
||||
if (lbm_is_symbol_merror((y))) { \
|
||||
error_ctx(ENC_SYM_MERROR); \
|
||||
}
|
||||
|
||||
#define WITH_GC_RMBR_1(y, x, r) \
|
||||
lbm_gc_mark_phase(r); \
|
||||
gc(); \
|
||||
(y) = (x); \
|
||||
if (lbm_is_symbol_merror((y))) { \
|
||||
error_ctx(ENC_SYM_MERROR); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define WITH_GC(y, x) \
|
||||
(y) = (x); \
|
||||
|
@ -145,6 +163,8 @@ static bool lbm_error_has_suspect = false;
|
|||
/* continue executing statements below */ \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
eval_context_t *first;
|
||||
eval_context_t *last;
|
||||
|
@ -377,6 +397,17 @@ eval_context_t *lbm_get_current_context(void) {
|
|||
/* Utilities used locally in this file */
|
||||
|
||||
static lbm_value cons_with_gc(lbm_value head, lbm_value tail, lbm_value remember) {
|
||||
#ifdef LBM_ALWAYS_GC
|
||||
lbm_value roots[3] = {head, tail, remember};
|
||||
lbm_gc_mark_roots(roots, 3);
|
||||
gc();
|
||||
lbm_value res = lbm_heap_allocate_cell(LBM_TYPE_CONS, head, tail);
|
||||
res = lbm_heap_allocate_cell(LBM_TYPE_CONS, head, tail);
|
||||
if (lbm_is_symbol_merror(res)) {
|
||||
error_ctx(ENC_SYM_MERROR);
|
||||
}
|
||||
return res;
|
||||
#else
|
||||
lbm_value res = lbm_heap_allocate_cell(LBM_TYPE_CONS, head, tail);
|
||||
if (lbm_is_symbol_merror(res)) {
|
||||
lbm_value roots[3] = {head, tail, remember};
|
||||
|
@ -388,6 +419,7 @@ static lbm_value cons_with_gc(lbm_value head, lbm_value tail, lbm_value remember
|
|||
}
|
||||
}
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
static lbm_uint *get_stack_ptr(eval_context_t *ctx, unsigned int n) {
|
||||
|
@ -455,8 +487,10 @@ static void stack_push(lbm_stack_t *s, lbm_uint val) {
|
|||
|
||||
static void stack_push_2(lbm_stack_t *s, lbm_uint v1, lbm_uint v2) {
|
||||
if (s->sp + 1 < s->size) {
|
||||
s->data[s->sp++] = v1;
|
||||
s->data[s->sp++] = v2;
|
||||
lbm_uint *t = &s->data[s->sp];
|
||||
t[0] = v1;
|
||||
t[1] = v2;
|
||||
s->sp += 2;
|
||||
if (s->sp > s->max_sp) s->max_sp = s->sp;
|
||||
return;
|
||||
}
|
||||
|
@ -465,9 +499,11 @@ static void stack_push_2(lbm_stack_t *s, lbm_uint v1, lbm_uint v2) {
|
|||
|
||||
static void stack_push_3(lbm_stack_t *s, lbm_uint v1, lbm_uint v2, lbm_uint v3) {
|
||||
if (s->sp + 2 < s->size) {
|
||||
s->data[s->sp++] = v1;
|
||||
s->data[s->sp++] = v2;
|
||||
s->data[s->sp++] = v3;
|
||||
lbm_uint *t = &s->data[s->sp];
|
||||
t[0] = v1;
|
||||
t[1] = v2;
|
||||
t[2] = v3;
|
||||
s->sp += 3;
|
||||
if (s->sp > s->max_sp) s->max_sp = s->sp;
|
||||
return;
|
||||
}
|
||||
|
@ -476,10 +512,12 @@ static void stack_push_3(lbm_stack_t *s, lbm_uint v1, lbm_uint v2, lbm_uint v3)
|
|||
|
||||
static void stack_push_4(lbm_stack_t *s, lbm_uint v1, lbm_uint v2, lbm_uint v3, lbm_uint v4) {
|
||||
if (s->sp + 3 < s->size) {
|
||||
s->data[s->sp++] = v1;
|
||||
s->data[s->sp++] = v2;
|
||||
s->data[s->sp++] = v3;
|
||||
s->data[s->sp++] = v4;
|
||||
lbm_uint *t = &s->data[s->sp];
|
||||
t[0] = v1;
|
||||
t[1] = v2;
|
||||
t[2] = v3;
|
||||
t[3] = v4;
|
||||
s->sp += 4;
|
||||
if (s->sp > s->max_sp) s->max_sp = s->sp;
|
||||
return;
|
||||
}
|
||||
|
@ -571,24 +609,34 @@ static lbm_value get_cddr(lbm_value a) {
|
|||
|
||||
static lbm_value allocate_closure(lbm_value params, lbm_value body, lbm_value env) {
|
||||
|
||||
#ifdef LBM_ALWAYS_GC
|
||||
gc();
|
||||
if (lbm_heap_num_free() < 4) {
|
||||
error_ctx(ENC_SYM_MERROR);
|
||||
}
|
||||
#else
|
||||
if (lbm_heap_num_free() < 4) {
|
||||
gc();
|
||||
if (lbm_heap_num_free() < 4) {
|
||||
error_ctx(ENC_SYM_MERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// The freelist will always contain just plain heap-cells.
|
||||
// So dec_ptr is sufficient.
|
||||
lbm_value res = lbm_heap_state.freelist;
|
||||
if (lbm_type_of(res) == LBM_TYPE_CONS) {
|
||||
lbm_cons_t *cell = lbm_ref_cell(res);
|
||||
cell->car = ENC_SYM_CLOSURE;
|
||||
cell = lbm_ref_cell(cell->cdr);
|
||||
cell->car = params;
|
||||
cell = lbm_ref_cell(cell->cdr);
|
||||
cell->car = body;
|
||||
cell = lbm_ref_cell(cell->cdr);
|
||||
cell->car = env;
|
||||
lbm_heap_state.freelist = cell->cdr;
|
||||
cell->cdr = ENC_SYM_NIL;
|
||||
lbm_cons_t *heap = lbm_heap_state.heap;
|
||||
lbm_uint ix = lbm_dec_ptr(res);
|
||||
heap[ix].car = ENC_SYM_CLOSURE;
|
||||
ix = lbm_dec_ptr(heap[ix].cdr);
|
||||
heap[ix].car = params;
|
||||
ix = lbm_dec_ptr(heap[ix].cdr);
|
||||
heap[ix].car = body;
|
||||
ix = lbm_dec_ptr(heap[ix].cdr);
|
||||
heap[ix].car = env;
|
||||
lbm_heap_state.freelist = heap[ix].cdr;
|
||||
heap[ix].cdr = ENC_SYM_NIL;
|
||||
lbm_heap_state.num_alloc+=4;
|
||||
} else {
|
||||
error_ctx(ENC_SYM_FATAL_ERROR);
|
||||
|
@ -625,7 +673,7 @@ static void call_fundamental(lbm_uint fundamental, lbm_value *args, lbm_uint arg
|
|||
res = fundamental_table[fundamental](args, arg_count, ctx);
|
||||
}
|
||||
if (lbm_is_error(res)) {
|
||||
error_at_ctx(res, lbm_enc_sym(fundamental+FUNDAMENTALS_START));
|
||||
error_at_ctx(res, lbm_enc_sym(EXTENSION_SYMBOLS_START | fundamental));
|
||||
}
|
||||
}
|
||||
lbm_stack_drop(&ctx->K, arg_count+1);
|
||||
|
@ -1536,25 +1584,20 @@ int lbm_perform_gc(void) {
|
|||
static void eval_symbol(eval_context_t *ctx) {
|
||||
lbm_uint s = lbm_dec_sym(ctx->curr_exp);
|
||||
if (s >= RUNTIME_SYMBOLS_START) {
|
||||
lbm_value res;
|
||||
lbm_value res = ENC_SYM_NIL;
|
||||
if (lbm_env_lookup_b(&res, ctx->curr_exp, ctx->curr_env) ||
|
||||
lbm_global_env_lookup(&res, ctx->curr_exp)) {
|
||||
ctx->r = res;
|
||||
ctx->app_cont = true;
|
||||
return;
|
||||
}
|
||||
} else if (s <= EXTENSION_SYMBOLS_END) {
|
||||
//special symbols and extensions can be handled the same way.
|
||||
ctx->r = ctx->curr_exp;
|
||||
ctx->app_cont = true;
|
||||
return;
|
||||
}
|
||||
// Dynamic load attempt
|
||||
const char *sym_str = lbm_get_name_by_symbol(s);
|
||||
const char *code_str = NULL;
|
||||
if (!dynamic_load_callback(sym_str, &code_str)) {
|
||||
error_at_ctx(ENC_SYM_NOT_FOUND, ctx->curr_exp);
|
||||
} else {
|
||||
// Dynamic load attempt
|
||||
// Only symbols of kind RUNTIME can be dynamically loaded.
|
||||
const char *sym_str = lbm_get_name_by_symbol(s);
|
||||
const char *code_str = NULL;
|
||||
if (!dynamic_load_callback(sym_str, &code_str)) {
|
||||
error_at_ctx(ENC_SYM_NOT_FOUND, ctx->curr_exp);
|
||||
}
|
||||
stack_push_3(&ctx->K, ctx->curr_exp, ctx->curr_env, RESUME);
|
||||
|
||||
lbm_value chan;
|
||||
|
@ -1575,6 +1618,10 @@ static void eval_symbol(eval_context_t *ctx) {
|
|||
loader), loader);
|
||||
ctx->curr_exp = evaluator;
|
||||
ctx->curr_env = ENC_SYM_NIL; // dynamics should be evaluable in empty local env
|
||||
} else {
|
||||
//special symbols and extensions can be handled the same way.
|
||||
ctx->r = ctx->curr_exp;
|
||||
ctx->app_cont = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2701,19 +2748,11 @@ static void application(eval_context_t *ctx, lbm_value *fun_args, lbm_uint arg_c
|
|||
lbm_value fun = fun_args[0];
|
||||
|
||||
lbm_uint fun_val = lbm_dec_sym(fun);
|
||||
lbm_uint apply_val = fun_val - APPLY_FUNS_START;
|
||||
lbm_uint fund_val = fun_val - FUNDAMENTALS_START;
|
||||
lbm_uint fun_kind = SYMBOL_KIND(fun_val);
|
||||
|
||||
if (apply_val <= (APPLY_FUNS_END - APPLY_FUNS_START)) {
|
||||
fun_table[apply_val](&fun_args[1], arg_count, ctx);
|
||||
} else if (fund_val <= (FUNDAMENTALS_END - FUNDAMENTALS_START)) {
|
||||
call_fundamental(fund_val, &fun_args[1], arg_count, ctx);
|
||||
} else {
|
||||
// It may be an extension
|
||||
extension_fptr f = lbm_get_extension(fun_val);
|
||||
if (f == NULL) {
|
||||
error_at_ctx(ENC_SYM_EERROR,fun);
|
||||
}
|
||||
switch (fun_kind) {
|
||||
case SYMBOL_KIND_EXTENSION: {
|
||||
extension_fptr f = extension_table[SYMBOL_IX(fun_val)].fptr;
|
||||
|
||||
lbm_value ext_res;
|
||||
WITH_GC(ext_res, f(&fun_args[1], arg_count));
|
||||
|
@ -2735,6 +2774,16 @@ static void application(eval_context_t *ctx, lbm_value *fun_args, lbm_uint arg_c
|
|||
ctx->app_cont = true;
|
||||
ctx->r = ext_res;
|
||||
}
|
||||
} break;
|
||||
case SYMBOL_KIND_FUNDAMENTAL:
|
||||
call_fundamental(SYMBOL_IX(fun_val), &fun_args[1], arg_count, ctx);
|
||||
break;
|
||||
case SYMBOL_KIND_APPFUN:
|
||||
fun_table[SYMBOL_IX(fun_val)](&fun_args[1], arg_count, ctx);
|
||||
break;
|
||||
default:
|
||||
error_ctx(ENC_SYM_FATAL_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2756,20 +2805,20 @@ static void cont_closure_application_args(eval_context_t *ctx) {
|
|||
error_ctx(ENC_SYM_MERROR);
|
||||
}
|
||||
}
|
||||
lbm_cons_t* heap = lbm_heap_state.heap;
|
||||
lbm_value cell0 = lbm_heap_state.freelist;
|
||||
lbm_cons_t *cell0_r = lbm_ref_cell(cell0);
|
||||
lbm_value cell1 = cell0_r->cdr;
|
||||
lbm_cons_t *cell1_r = lbm_ref_cell(cell1);
|
||||
lbm_heap_state.freelist = cell1_r->cdr;
|
||||
lbm_uint cell0_ix = lbm_dec_ptr(cell0);
|
||||
lbm_value cell1 = heap[cell0_ix].cdr;
|
||||
lbm_uint cell1_ix = lbm_dec_ptr(cell1);
|
||||
lbm_heap_state.freelist = heap[cell1_ix].cdr;
|
||||
lbm_heap_state.num_alloc += 2;
|
||||
|
||||
cell0_r->car = car_params;
|
||||
cell0_r->cdr = ctx->r;
|
||||
cell1_r->car = cell0;
|
||||
cell1_r->cdr = clo_env;
|
||||
heap[cell0_ix].car = car_params;
|
||||
heap[cell0_ix].cdr = ctx->r;
|
||||
heap[cell1_ix].car = cell0;
|
||||
heap[cell1_ix].cdr = clo_env;
|
||||
clo_env = cell1;
|
||||
|
||||
// TODO: We are NOT going to implement a lazy sweep.
|
||||
bool a_nil = args == ENC_SYM_NIL;
|
||||
bool p_nil = cdr_params == ENC_SYM_NIL;
|
||||
|
||||
|
@ -2910,12 +2959,12 @@ static void cont_if(eval_context_t *ctx) {
|
|||
|
||||
static void cont_match(eval_context_t *ctx) {
|
||||
lbm_value e = ctx->r;
|
||||
lbm_value patterns;
|
||||
lbm_value new_env;
|
||||
lbm_value orig_env;
|
||||
bool do_gc = false;
|
||||
lbm_pop_2(&ctx->K, &orig_env, &patterns); // restore enclosing environment
|
||||
new_env = orig_env;
|
||||
|
||||
lbm_uint *sptr = get_stack_ptr(ctx, 2);
|
||||
lbm_value patterns = (lbm_value)sptr[0];
|
||||
lbm_value orig_env = (lbm_value)sptr[1]; // restore enclosing environment.
|
||||
lbm_value new_env = orig_env;
|
||||
|
||||
if (lbm_is_symbol_nil(patterns)) {
|
||||
// no more patterns
|
||||
|
@ -2937,8 +2986,6 @@ static void cont_match(eval_context_t *ctx) {
|
|||
|
||||
bool is_match = match(pattern, e, &new_env, &do_gc);
|
||||
if (do_gc) {
|
||||
lbm_uint roots[3] = {orig_env, patterns, e};
|
||||
lbm_gc_mark_roots(roots, 3);
|
||||
gc();
|
||||
do_gc = false;
|
||||
new_env = orig_env;
|
||||
|
@ -2949,23 +2996,26 @@ static void cont_match(eval_context_t *ctx) {
|
|||
}
|
||||
if (is_match) {
|
||||
if (check_guard) {
|
||||
lbm_value *sptr = stack_reserve(ctx,7);
|
||||
lbm_value *rptr = stack_reserve(ctx,5);
|
||||
sptr[0] = get_cdr(patterns);
|
||||
sptr[1] = ctx->curr_env;
|
||||
sptr[2] = MATCH;
|
||||
sptr[3] = new_env;
|
||||
sptr[4] = body;
|
||||
sptr[5] = e;
|
||||
sptr[6] = MATCH_GUARD;
|
||||
rptr[0] = MATCH;
|
||||
rptr[1] = new_env;
|
||||
rptr[2] = body;
|
||||
rptr[3] = e;
|
||||
rptr[4] = MATCH_GUARD;
|
||||
ctx->curr_env = new_env;
|
||||
ctx->curr_exp = n1; // The guard
|
||||
} else {
|
||||
lbm_stack_drop(&ctx->K, 2);
|
||||
ctx->curr_env = new_env;
|
||||
ctx->curr_exp = body;
|
||||
}
|
||||
} else {
|
||||
// set up for checking of next pattern
|
||||
stack_push_3(&ctx->K, get_cdr(patterns),orig_env, MATCH);
|
||||
sptr[0] = get_cdr(patterns);
|
||||
sptr[1] = orig_env;
|
||||
stack_push(&ctx->K, MATCH);
|
||||
// leave r unaltered
|
||||
ctx->app_cont = true;
|
||||
}
|
||||
|
@ -3116,12 +3166,11 @@ static void cont_merge_rest(eval_context_t *ctx) {
|
|||
lbm_value cmp_env = sptr[6];
|
||||
// Environment should be preallocated already at this point
|
||||
// and the operations below should never need GC.
|
||||
// maybe rewrite this as a more efficient update and
|
||||
// a fatal error if that is not possible.
|
||||
lbm_value new_env0;
|
||||
lbm_value new_env;
|
||||
WITH_GC(new_env0, lbm_env_set(cmp_env, par1, lbm_car(a)));
|
||||
WITH_GC_RMBR_1(new_env, lbm_env_set(new_env0, par2, lbm_car(b)), new_env0);
|
||||
lbm_value new_env0 = lbm_env_set(cmp_env, par1, lbm_car(a));
|
||||
lbm_value new_env = lbm_env_set(new_env0, par2, lbm_car(b));
|
||||
if (lbm_is_symbol(new_env0) || lbm_is_symbol(new_env)) {
|
||||
error_ctx(ENC_SYM_FATAL_ERROR);
|
||||
}
|
||||
cmp_env = new_env;
|
||||
|
||||
stack_push(&ctx->K, MERGE_REST);
|
||||
|
@ -3233,12 +3282,11 @@ static void cont_merge_layer(eval_context_t *ctx) {
|
|||
lbm_value par2 = sptr[3];
|
||||
// Environment should be preallocated already at this point
|
||||
// and the operations below should never need GC.
|
||||
// maybe rewrite this as a more efficient update and
|
||||
// a fatal error if that is not possible.
|
||||
lbm_value new_env0;
|
||||
lbm_value new_env;
|
||||
WITH_GC(new_env0, lbm_env_set(cmp_env, par1, lbm_car(a)));
|
||||
WITH_GC_RMBR_1(new_env, lbm_env_set(new_env0, par2, lbm_car(b)), new_env0);
|
||||
lbm_value new_env0 = lbm_env_set(cmp_env, par1, lbm_car(a));
|
||||
lbm_value new_env = lbm_env_set(cmp_env, par2, lbm_car(b));
|
||||
if (lbm_is_symbol(new_env0) || lbm_is_symbol(new_env)) {
|
||||
error_ctx(ENC_SYM_FATAL_ERROR);
|
||||
}
|
||||
cmp_env = new_env;
|
||||
|
||||
lbm_uint *merge_cont = stack_reserve(ctx, 11);
|
||||
|
@ -3576,7 +3624,7 @@ static void cont_read_next_token(eval_context_t *ctx) {
|
|||
if (!lbm_lookup_extension_id(ext_name, &ext_id)) {
|
||||
error_ctx(ENC_SYM_FATAL_ERROR);
|
||||
}
|
||||
symbol_id = ext_id + EXTENSION_SYMBOLS_START;
|
||||
symbol_id = ext_id;
|
||||
} else {
|
||||
error_ctx(ENC_SYM_MERROR);
|
||||
}
|
||||
|
@ -4289,7 +4337,7 @@ lbm_value append(lbm_value front, lbm_value back) {
|
|||
|
||||
lbm_value t0, t1;
|
||||
|
||||
t0 = cons_with_gc(back, ENC_SYM_NIL, ENC_SYM_NIL);
|
||||
t0 = cons_with_gc(back, ENC_SYM_NIL, front);
|
||||
t1 = cons_with_gc(front, t0, ENC_SYM_NIL);
|
||||
return cons_with_gc(ENC_SYM_APPEND, t1, ENC_SYM_NIL);
|
||||
}
|
||||
|
@ -4376,9 +4424,7 @@ static void cont_qq_expand_list(eval_context_t* ctx) {
|
|||
if (lbm_type_of(car_val) == LBM_TYPE_SYMBOL &&
|
||||
lbm_dec_sym(car_val) == SYM_COMMA) {
|
||||
lbm_value tl = cons_with_gc(get_car(cdr_val), ENC_SYM_NIL, ENC_SYM_NIL);
|
||||
//WITH_GC(tl, lbm_cons(get_car(cdr_val), ENC_SYM_NIL));
|
||||
lbm_value tmp = cons_with_gc(ENC_SYM_LIST, tl, ENC_SYM_NIL);
|
||||
//WITH_GC_RMBR_1(tmp, lbm_cons(ENC_SYM_LIST, tl), tl);
|
||||
ctx->r = append(ctx->r, tmp);
|
||||
ctx->app_cont = true;
|
||||
return;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "extensions.h"
|
||||
|
||||
static lbm_uint ext_offset = EXTENSION_SYMBOLS_START;
|
||||
static lbm_uint ext_max = 0;
|
||||
static lbm_uint ext_num = 0;
|
||||
static lbm_uint next_extension_ix = 0;
|
||||
|
@ -64,7 +63,7 @@ lbm_uint lbm_get_num_extensions(void) {
|
|||
}
|
||||
|
||||
extension_fptr lbm_get_extension(lbm_uint sym) {
|
||||
lbm_uint ext_next = sym - ext_offset;
|
||||
lbm_uint ext_next = sym - EXTENSION_SYMBOLS_START;
|
||||
if (ext_next >= ext_max) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -72,7 +71,7 @@ extension_fptr lbm_get_extension(lbm_uint sym) {
|
|||
}
|
||||
|
||||
bool lbm_clr_extension(lbm_uint sym_id) {
|
||||
lbm_uint ext_id = sym_id - ext_offset;
|
||||
lbm_uint ext_id = sym_id - EXTENSION_SYMBOLS_START;
|
||||
if (ext_id >= ext_max) {
|
||||
return false;
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ bool lbm_lookup_extension_id(char *sym_str, lbm_uint *ix) {
|
|||
for (lbm_uint i = 0; i < ext_max; i ++) {
|
||||
if(extension_table[i].name) {
|
||||
if (strcmp(extension_table[i].name, sym_str) == 0) {
|
||||
*ix = i;
|
||||
*ix = i + EXTENSION_SYMBOLS_START;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -100,9 +99,9 @@ bool lbm_add_extension(char *sym_str, extension_fptr ext) {
|
|||
if (lbm_get_symbol_by_name(sym_str, &symbol)) {
|
||||
if (lbm_is_extension(lbm_enc_sym(symbol))) {
|
||||
// update the extension entry.
|
||||
if (strcmp(extension_table[symbol - ext_offset].name, sym_str) == 0) {
|
||||
if (strcmp(extension_table[symbol - EXTENSION_SYMBOLS_START].name, sym_str) == 0) {
|
||||
// Do not replace name ptr.
|
||||
extension_table[symbol - ext_offset].fptr = ext;
|
||||
extension_table[symbol - EXTENSION_SYMBOLS_START].fptr = ext;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,19 +528,19 @@ lbm_value lbm_heap_allocate_cell(lbm_type ptr_type, lbm_value car, lbm_value cdr
|
|||
res = lbm_heap_state.freelist;
|
||||
|
||||
if (lbm_type_of(res) == LBM_TYPE_CONS) {
|
||||
lbm_cons_t *rc = lbm_ref_cell(res);
|
||||
lbm_heap_state.freelist = rc->cdr;
|
||||
lbm_uint heap_ix = lbm_dec_ptr(res);
|
||||
//lbm_cons_t *rc = lbm_ref_cell(res);
|
||||
lbm_heap_state.freelist = lbm_heap_state.heap[heap_ix].cdr;
|
||||
|
||||
lbm_heap_state.num_alloc++;
|
||||
|
||||
rc->car = car;
|
||||
rc->cdr = cdr;
|
||||
|
||||
lbm_heap_state.heap[heap_ix].car = car;
|
||||
lbm_heap_state.heap[heap_ix].cdr = cdr;
|
||||
res = lbm_set_ptr_type(res, ptr_type);
|
||||
return res;
|
||||
}
|
||||
else if ((lbm_type_of(lbm_heap_state.freelist) == LBM_TYPE_SYMBOL) &&
|
||||
(lbm_dec_sym(lbm_heap_state.freelist) == SYM_NIL)) {
|
||||
else if ((lbm_type_of(res) == LBM_TYPE_SYMBOL) &&
|
||||
(lbm_dec_sym(res) == SYM_NIL)) {
|
||||
// all is as it should be (but no free cells)
|
||||
return ENC_SYM_MERROR;
|
||||
}
|
||||
|
@ -691,6 +691,7 @@ void lbm_gc_mark_phase(lbm_value root) {
|
|||
}
|
||||
|
||||
#else
|
||||
extern eval_context_t *ctx_running;
|
||||
void lbm_gc_mark_phase(lbm_value root) {
|
||||
|
||||
lbm_stack_t *s = &lbm_heap_state.gc_stack;
|
||||
|
@ -867,7 +868,6 @@ int lbm_gc_sweep_phase(void) {
|
|||
lbm_heap_state.gc_recovered ++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1152,6 @@ int lbm_heap_allocate_array(lbm_value *res, lbm_uint size){
|
|||
|
||||
// Convert a C array into an lbm_array.
|
||||
// if the array is in LBM_MEMORY, the lifetime will be managed by the GC.
|
||||
// TODO: Use lbm_malloc for header data
|
||||
int lbm_lift_array(lbm_value *value, char *data, lbm_uint num_elt) {
|
||||
|
||||
lbm_array_header_t *array = NULL;
|
||||
|
@ -1165,13 +1164,15 @@ int lbm_lift_array(lbm_value *value, char *data, lbm_uint num_elt) {
|
|||
|
||||
array = (lbm_array_header_t*)lbm_malloc(sizeof(lbm_array_header_t));
|
||||
|
||||
if (array == NULL) return 0;
|
||||
if (array == NULL) {
|
||||
*value = ENC_SYM_MERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
array->data = (lbm_uint*)data;
|
||||
array->size = num_elt;
|
||||
|
||||
lbm_set_car(cell, (lbm_uint)array);
|
||||
//lbm_set_cdr(cell, lbm_enc_sym(SYM_ARRAY_TYPE));
|
||||
|
||||
cell = lbm_set_ptr_type(cell, LBM_TYPE_ARRAY);
|
||||
*value = cell;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2018, 2021 2022 Joel Svensson svenssonjoel@yahoo.se
|
||||
Copyright 2018, 2021, 2022, 2024 Joel Svensson svenssonjoel@yahoo.se
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -227,7 +227,6 @@ special_sym const special_symbols[] = {
|
|||
|
||||
static lbm_uint *symlist = NULL;
|
||||
static lbm_uint next_symbol_id = RUNTIME_SYMBOLS_START;
|
||||
static lbm_uint next_variable_symbol_id = VARIABLE_SYMBOLS_START;
|
||||
static lbm_uint symbol_table_size_list = 0;
|
||||
static lbm_uint symbol_table_size_list_flash = 0;
|
||||
static lbm_uint symbol_table_size_strings = 0;
|
||||
|
@ -239,7 +238,6 @@ lbm_value symbol_y = ENC_SYM_NIL;
|
|||
int lbm_symrepr_init(void) {
|
||||
symlist = NULL;
|
||||
next_symbol_id = RUNTIME_SYMBOLS_START;
|
||||
next_variable_symbol_id = VARIABLE_SYMBOLS_START;
|
||||
symbol_table_size_list = 0;
|
||||
symbol_table_size_list_flash = 0;
|
||||
symbol_table_size_strings = 0;
|
||||
|
@ -277,21 +275,28 @@ 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 < SPECIAL_SYMBOLS_END) {
|
||||
lbm_uint sym_kind = SYMBOL_KIND(id);
|
||||
switch (sym_kind) {
|
||||
case SYMBOL_KIND_SPECIAL: /* fall through */
|
||||
case SYMBOL_KIND_FUNDAMENTAL:
|
||||
case SYMBOL_KIND_APPFUN:
|
||||
for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) {
|
||||
if (id == special_symbols[i].id) {
|
||||
return (special_symbols[i].name);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
} else if (id - EXTENSION_SYMBOLS_START < EXTENSION_SYMBOLS_END) {
|
||||
break;
|
||||
case SYMBOL_KIND_EXTENSION: {
|
||||
unsigned int ext_id = id - EXTENSION_SYMBOLS_START;
|
||||
if (ext_id < lbm_get_max_extensions()) {
|
||||
return extension_table[ext_id].name;
|
||||
return extension_table[ext_id].name;
|
||||
}
|
||||
return NULL;
|
||||
} break;
|
||||
default:
|
||||
return lookup_symrepr_name_memory(id);
|
||||
}
|
||||
return lookup_symrepr_name_memory(id);
|
||||
}
|
||||
|
||||
lbm_uint *lbm_get_symbol_list_entry_by_name(char *name) {
|
||||
|
@ -465,10 +470,6 @@ lbm_uint lbm_get_symbol_table_size_names_flash(void) {
|
|||
return symbol_table_size_strings_flash * sizeof(lbm_uint);
|
||||
}
|
||||
|
||||
lbm_uint lbm_get_num_variables(void) {
|
||||
return next_variable_symbol_id - VARIABLE_SYMBOLS_START;
|
||||
}
|
||||
|
||||
bool lbm_symbol_in_flash(char *str) {
|
||||
return !lbm_memory_ptr_inside((lbm_uint*)str);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ OBJ = obj
|
|||
SOURCES = $(wildcard *.c)
|
||||
EXECS = $(patsubst %.c, %.exe, $(SOURCES))
|
||||
|
||||
gc: CCFLAGS += -m32 -DLBM_ALWAYS_GC
|
||||
gc: $(EXECS)
|
||||
mv test_lisp_code_cps.exe test_lisp_code_cps
|
||||
|
||||
|
||||
all: CCFLAGS += -m32
|
||||
all: $(EXECS)
|
||||
mv test_lisp_code_cps.exe test_lisp_code_cps
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "BUILDING"
|
||||
|
||||
make clean
|
||||
make gc
|
||||
|
||||
echo "PERFORMING TESTS:"
|
||||
|
||||
expected_fails=("test_lisp_code_cps -t 360 -h 1024 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -s -h 1024 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -h 512 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -s -h 512 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -i -h 1024 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -i -s -h 1024 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -i -h 512 test_take_iota_0.lisp"
|
||||
"test_lisp_code_cps -t 360 -i -s -h 512 test_take_iota_0.lisp"
|
||||
)
|
||||
|
||||
|
||||
success_count=0
|
||||
fail_count=0
|
||||
failing_tests=()
|
||||
result=0
|
||||
|
||||
for exe in *.exe; do
|
||||
|
||||
if [ "$exe" = "test_gensym.exe" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
./$exe
|
||||
|
||||
result=$?
|
||||
|
||||
echo "------------------------------------------------------------"
|
||||
if [ $result -eq 1 ]
|
||||
then
|
||||
success_count=$((success_count+1))
|
||||
echo $exe SUCCESS
|
||||
else
|
||||
|
||||
fail_count=$((fail_count+1))
|
||||
echo $exe FAILED
|
||||
fi
|
||||
echo "------------------------------------------------------------"
|
||||
done
|
||||
|
||||
test_config=("-t 360 -h 32768"
|
||||
"-t 360 -i -h 32768"
|
||||
"-t 360 -s -h 32768"
|
||||
"-t 360 -i -s -h 32768"
|
||||
"-t 360 -h 16384"
|
||||
"-t 360 -i -h 16384"
|
||||
"-t 360 -s -h 16384"
|
||||
"-t 360 -i -s -h 16384"
|
||||
"-t 360 -h 8192"
|
||||
"-t 360 -i -h 8192"
|
||||
"-t 360 -s -h 8192"
|
||||
"-t 360 -i -s -h 8192"
|
||||
"-t 360 -h 4096"
|
||||
"-t 360 -i -h 4096"
|
||||
"-t 360 -s -h 4096"
|
||||
"-t 360 -i -s -h 4096"
|
||||
"-t 360 -h 2048"
|
||||
"-t 360 -i -h 2048"
|
||||
"-t 360 -s -h 2048"
|
||||
"-t 360 -i -s -h 2048"
|
||||
"-t 360 -h 1024"
|
||||
"-t 360 -i -h 1024"
|
||||
"-t 360 -s -h 1024"
|
||||
"-t 360 -i -s -h 1024"
|
||||
"-t 360 -h 512"
|
||||
"-t 360 -i -h 512"
|
||||
"-t 360 -s -h 512"
|
||||
"-t 360 -i -s -h 512")
|
||||
|
||||
#"test_lisp_code_cps_nc"
|
||||
for prg in "test_lisp_code_cps" ; do
|
||||
for arg in "${test_config[@]}"; do
|
||||
for lisp in *.lisp; do
|
||||
|
||||
./$prg $arg $lisp
|
||||
|
||||
result=$?
|
||||
|
||||
echo "------------------------------------------------------------"
|
||||
#echo $arg
|
||||
if [ $result -eq 1 ]
|
||||
then
|
||||
success_count=$((success_count+1))
|
||||
echo $lisp SUCCESS
|
||||
else
|
||||
|
||||
#!/bin/bash
|
||||
# foo=('foo bar' 'foo baz' 'bar baz')
|
||||
# bar=$(printf ",%s" "${foo[@]}")
|
||||
# bar=${bar:1}
|
||||
|
||||
# echo $bar
|
||||
str=$(printf "%s " "$prg $arg $lisp")
|
||||
#echo $str
|
||||
|
||||
failing_tests+=("$prg $arg $lisp")
|
||||
fail_count=$((fail_count+1))
|
||||
#echo $failing_tests
|
||||
|
||||
echo $lisp FAILED
|
||||
fi
|
||||
echo "------------------------------------------------------------"
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
# echo -e $failing_tests
|
||||
|
||||
expected_count=0
|
||||
|
||||
for (( i = 0; i < ${#failing_tests[@]}; i++ ))
|
||||
do
|
||||
expected=false
|
||||
for (( j = 0; j < ${#expected_fails[@]}; j++))
|
||||
do
|
||||
|
||||
if [[ "${failing_tests[$i]}" == "${expected_fails[$j]}" ]] ;
|
||||
then
|
||||
expected=true
|
||||
fi
|
||||
done
|
||||
if $expected ; then
|
||||
expected_count=$((expected_count+1))
|
||||
echo "(OK - expected to fail)" ${failing_tests[$i]}
|
||||
else
|
||||
echo "(FAILURE)" ${failing_tests[$i]}
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo Tests passed: $success_count
|
||||
echo Tests failed: $fail_count
|
||||
echo Expected fails: $expected_count
|
||||
echo Actual fails: $((fail_count - expected_count))
|
||||
|
||||
if [ $((fail_count - expected_count)) -gt 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
|
@ -49,6 +49,7 @@
|
|||
lbm_extension_t extensions[EXTENSION_STORAGE_SIZE];
|
||||
lbm_uint constants_memory[CONSTANT_MEMORY_SIZE];
|
||||
|
||||
static uint32_t timeout = 10;
|
||||
|
||||
void const_heap_init(void) {
|
||||
for (int i = 0; i < CONSTANT_MEMORY_SIZE; i ++) {
|
||||
|
@ -338,6 +339,7 @@ LBM_EXTENSION(ext_check, args, argn) {
|
|||
}
|
||||
|
||||
int res = lbm_print_value(output, 128, t);
|
||||
printf("Checking result value: %s\n", output);
|
||||
|
||||
if (checks == 2) {
|
||||
experiment_done = true;
|
||||
|
@ -401,8 +403,11 @@ int main(int argc, char **argv) {
|
|||
int c;
|
||||
opterr = 1;
|
||||
|
||||
while (( c = getopt(argc, argv, "igsch:")) != -1) {
|
||||
while (( c = getopt(argc, argv, "igsch:t:")) != -1) {
|
||||
switch (c) {
|
||||
case 't':
|
||||
timeout = (uint32_t)atoi((char *)optarg);
|
||||
break;
|
||||
case 'h':
|
||||
heap_size = (unsigned int)atoi((char *)optarg);
|
||||
break;
|
||||
|
@ -752,15 +757,19 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
printf("Program loaded\n");
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
bool timed_out = false;
|
||||
while (!experiment_done) {
|
||||
if (i == 10000) break;
|
||||
if (i >= timeout * 1000) {
|
||||
timed_out = true;
|
||||
break;
|
||||
}
|
||||
sleep_callback(1000);
|
||||
i ++;
|
||||
}
|
||||
|
||||
if (i == 10000) {
|
||||
printf ("experiment failed due to taking longer than 10 seconds\n");
|
||||
if (timed_out) {
|
||||
printf ("experiment failed due to taking longer than %u seconds\n", timeout);
|
||||
experiment_success = false;
|
||||
return FAIL;
|
||||
}
|
||||
|
@ -778,6 +787,7 @@ int main(int argc, char **argv) {
|
|||
free(heap_storage);
|
||||
|
||||
printf("Experiment done: ");
|
||||
printf("Check was executed %u times\n", checks);
|
||||
if (experiment_success) {
|
||||
printf("SUCCESS\n");
|
||||
return 1;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
(defun larger ( x ) {
|
||||
(gc)
|
||||
(> x 10)
|
||||
})
|
||||
|
||||
(defun smaller ( x ) {
|
||||
(gc)
|
||||
(< x 10)
|
||||
})
|
||||
|
||||
(defun f (x)
|
||||
(match x
|
||||
( ((? x) . ((? y) . _)) (smaller x) (list y 'smaller))
|
||||
( ((? x) . ((? y) . _)) (larger x) (list y 'larger))
|
||||
( _ 'whatever)))
|
||||
|
||||
(check (and (eq (f '(0 1 2 3)) '(1 smaller))
|
||||
(eq (f '(11 9 8 7)) '(9 larger))))
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
(defun larger ( x ) {
|
||||
(gc)
|
||||
(> x 10)
|
||||
})
|
||||
|
||||
(defun smaller ( x ) {
|
||||
(gc)
|
||||
(< x 10)
|
||||
})
|
||||
|
||||
(defun f (x)
|
||||
(atomic
|
||||
(var z "apa")
|
||||
(match x
|
||||
( ((? x) . ((? y) . _)) (smaller z) (list y 'smaller))
|
||||
( ((? x) . ((? y) . _)) (larger z) (list y 'larger))
|
||||
( _ 'whatever))))
|
||||
|
||||
(check (and (eq (f '(0 1 2 3)) 'whatever)
|
||||
(eq (f '(11 9 8 7)) 'whatever)))
|
Loading…
Reference in New Issue