diff --git a/lispBM/lispBM/benchmarks/bench_chibi/Makefile b/lispBM/lispBM/benchmarks/bench_chibi/Makefile
index 9652aabb..69604a3d 100644
--- a/lispBM/lispBM/benchmarks/bench_chibi/Makefile
+++ b/lispBM/lispBM/benchmarks/bench_chibi/Makefile
@@ -128,7 +128,7 @@ LBMSRC = ../../src/compression.c \
../../src/extensions.c \
../../src/fundamental.c \
../../src/heap.c \
- ../../src/lispbm_memory.c \
+ ../../src/lbm_memory.c \
../../src/prelude.c \
../../src/print.c \
../../src/qq_expand.c \
diff --git a/lispBM/lispBM/chibios-examples/repl-ChibiOS/Makefile b/lispBM/lispBM/chibios-examples/repl-ChibiOS/Makefile
index 9652aabb..20fe3027 100644
--- a/lispBM/lispBM/chibios-examples/repl-ChibiOS/Makefile
+++ b/lispBM/lispBM/chibios-examples/repl-ChibiOS/Makefile
@@ -128,7 +128,7 @@ LBMSRC = ../../src/compression.c \
../../src/extensions.c \
../../src/fundamental.c \
../../src/heap.c \
- ../../src/lispbm_memory.c \
+ ../../src/lbm_memory.c \
../../src/prelude.c \
../../src/print.c \
../../src/qq_expand.c \
@@ -137,6 +137,7 @@ LBMSRC = ../../src/compression.c \
../../src/symrepr.c \
../../src/tokpar.c \
../../src/lispbm.c \
+ ../../src/lbm_c_interop.c \
../../platform/chibios/src/platform_mutex.c
CSRC = $(ALLCSRC) \
diff --git a/lispBM/lispBM/chibios-examples/xmas_dac/Makefile b/lispBM/lispBM/chibios-examples/xmas_dac/Makefile
index fd336a56..a9ebbc03 100644
--- a/lispBM/lispBM/chibios-examples/xmas_dac/Makefile
+++ b/lispBM/lispBM/chibios-examples/xmas_dac/Makefile
@@ -128,7 +128,7 @@ LBMSRC = ../../src/env.c \
../../src/extensions.c \
../../src/fundamental.c \
../../src/heap.c \
- ../../src/lispbm_memory.c \
+ ../../src/lbm_memory.c \
../../src/prelude.c \
../../src/print.c \
../../src/qq_expand.c \
@@ -137,6 +137,7 @@ LBMSRC = ../../src/env.c \
../../src/symrepr.c \
../../src/tokpar.c \
../../src/lispbm.c \
+ ../../src/lbm_c_interop.c \
../../platform/chibios/src/platform_mutex.c
CSRC = $(ALLCSRC) \
diff --git a/lispBM/lispBM/doc/lbmref.dox b/lispBM/lispBM/doc/lbmref.dox
index 36949f6b..eb7b402c 100644
--- a/lispBM/lispBM/doc/lbmref.dox
+++ b/lispBM/lispBM/doc/lbmref.dox
@@ -397,11 +397,56 @@ The expression above evaluates to 3 with the side effect that the global environ
has been extended with the binding (apa 1)
.
+---
+
+\section sec_lists Lists
+
+ car
+
+---
+
+ cdr
+
+---
+
+ cons
+
+---
+
+ list
+
+---
+
+ append
+
+---
+
+ ix
+
+---
+
+ set-car
+
+---
+
+ set-cdr
+
+
+
+\section sec_arrays Arrays
+
+
+ array-read
+
+---
+
+ array-write
+
---
\section sec_pattern Pattern-matching
- match
+ match
Pattern-matching is expressed using match. The form of a match expression is
(match expr (pat1 expr1) ... (patN exprN))
. Pattern-matching compares
@@ -451,7 +496,7 @@ An example that evaluates to 19.
(match '(orange 17)
((green (? n)) (+ n 1))
((orange (? n)) (+ n 2))
- ((blue (?n)) (+ n 3)))
+ ((blue (? n)) (+ n 3)))
\endcode
---
@@ -543,40 +588,6 @@ An example that evaluates to 19.
---
- car
-
----
-
- cdr
-
----
-
- cons
-
----
-
- list
-
----
-
- append
-
-
----
-
- array-read
-
-
----
-
- array-write
-
----
-
- array-create
-
----
-
type-of
---
@@ -597,14 +608,6 @@ An example that evaluates to 19.
---
- set-car
-
----
-
- set-cdr
-
----
-
is-fundamental
---
@@ -711,4 +714,55 @@ An example that evaluates to 19.
sym_nonsense
---
-*/
\ No newline at end of file
+
+\section sec_low_level Low level operations
+
+ encode-i32
+
+---
+
+ encode-u32
+
+---
+
+ encode-float
+
+---
+
+ decode
+
+---
+
+
+*/
+
+
+
+
+
+ array-create
+
+---
+
+
+\section sec_streams Streams
+
+ stream-get
+
+---
+
+ stream-more
+
+---
+
+ stream-peek
+
+---
+
+ stream-drop
+
+---
+
+ stream-put
+
+---
diff --git a/lispBM/lispBM/include/compression.h b/lispBM/lispBM/include/compression.h
index 495d0c9e..9d5bd8d0 100644
--- a/lispBM/lispBM/include/compression.h
+++ b/lispBM/lispBM/include/compression.h
@@ -21,7 +21,8 @@
#include
#include
-#include "lispbm_types.h"
+
+#include "lbm_types.h"
typedef struct {
uint32_t compressed_bits;
diff --git a/lispBM/lispBM/include/env.h b/lispBM/lispBM/include/env.h
index 46ed06fe..884254b7 100644
--- a/lispBM/lispBM/include/env.h
+++ b/lispBM/lispBM/include/env.h
@@ -19,7 +19,7 @@
#ifndef ENV_H_
#define ENV_H_
-#include "lispbm_types.h"
+#include "lbm_types.h"
//environment interface
/** Initialize the global environment. This sets the global environment to NIL
diff --git a/lispBM/lispBM/include/eval_cps.h b/lispBM/lispBM/include/eval_cps.h
index 95195f13..aa50aa22 100644
--- a/lispBM/lispBM/include/eval_cps.h
+++ b/lispBM/lispBM/include/eval_cps.h
@@ -18,8 +18,8 @@
#ifndef EVAL_CPS_H_
#define EVAL_CPS_H_
+#include "lbm_types.h"
#include "stack.h"
-#include "lispbm_types.h"
#define EVAL_CPS_STATE_INIT 0
#define EVAL_CPS_STATE_PAUSED 1
@@ -111,6 +111,11 @@ extern void lbm_run_eval(void);
* return value EVAL_CPS_STATE_PAUSED.
*/
extern void lbm_pause_eval(void);
+/** Pause the evaluator and perform GC if needed.
+ *
+ * \param num_free Perform GC if there are less than this many elements free on the heap.
+ */
+extern void lbm_pause_eval_with_gc(uint32_t num_free);
/** Perform a single step of evaluation.
* The evaluator should be in EVAL_CPS_STATE_PAUSED before running this function.
* After taking one step of evaluation, the evaluator will return to being in the
@@ -131,6 +136,15 @@ extern void lbm_kill_eval(void);
*/
extern uint32_t lbm_get_eval_state(void);
+/** Create a context and enqueue it as runnable.
+ *
+ * \param program The program to evaluate in the context.
+ * \param env An initial environment.
+ * \param stack_size Stack size for the context.
+ * \return
+ */
+extern lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, uint32_t stack_size);
+
/* statistics interface */
/** Iterate over all ready contexts and apply function on each context.
*
@@ -176,54 +190,19 @@ extern void lbm_set_timestamp_us_callback(uint32_t (*fptr)(void));
*/
extern void lbm_set_ctx_done_callback(void (*fptr)(eval_context_t *));
-/* loading of programs interface */
-/** Load and schedule a program for execution.
+/** Create a token stream for parsing for code
*
- * \param tokenizer The tokenizer to read the program from.
- * \return A context id on success or 0 on failure.
+ * \param str character stream to convert into a token stream.
+ * \return token stream.
*/
-extern lbm_cid lbm_load_and_eval_program(lbm_tokenizer_char_stream_t *tokenizer);
-/** Load and schedule an expression for execution.
- *
- * \param tokenizer The tokenizer to read the expression from.
- * \return A context id on success or 0 on failure.
- */
-extern lbm_cid lbm_load_and_eval_expression(lbm_tokenizer_char_stream_t *tokenizer);
-/** Load a program and bind it to a symbol in the environment.
- *
- * \param tokenizer The tokenizer to read the program from.
- * \param symbol A string with the name you want the binding to have in the environment.
- * \return A context id on success or 0 on failure.
- */
-extern lbm_cid lbm_load_and_define_program(lbm_tokenizer_char_stream_t *tokenizer, char *symbol);
-/** Load an expression and bind it to a symbol in the environment.
- *
- * \param tokenizer The tokenizer to read the expression from.
- * \param symbol A string with the name you want the binding to have in the environment.
- * \return A context id on success or 0 on failure.
- */
-extern lbm_cid lbm_load_and_define_expression(lbm_tokenizer_char_stream_t *tokenizer, char *symbol);
+extern lbm_value lbm_create_token_stream(lbm_tokenizer_char_stream_t *str);
-/* Evaluating a definition in a new context */
-/** Create a context for a bound expression and schedule it for execution
+/** deliver a message
*
- * \param symbol The name of the binding to schedule for execution.
- * \return A context if on success or 0 on failure.
+ * \param cid Process to deliver to.
+ * \param msg Message to deliver
+ * \return lbm_enc_sym(SYM_NIL) on failure and lbm_enc_sym(SYM_TRUE) on success.
*/
-extern lbm_cid lbm_eval_defined_expression(char *symbol);
-/** Create a context for a bound program and schedule it for execution
- *
- * \param symbol The name of the binding to schedule for execution.
- * \return A context if on success or 0 on failure.
- */
-extern lbm_cid lbm_eval_defined_program(char *symbol);
+lbm_value lbm_find_receiver_and_send(lbm_cid cid, lbm_value msg);
-/* send message from c to LBM process */
-/** Send a message to a process running in the evaluator.
- *
- * \param cid Context id of the process to send a message to.
- * \param msg lbm_value that will be sent to the process.
- * \return 1 on success or 0 on failure.
- */
-extern int lbm_send_message(lbm_cid cid, lbm_value msg);
#endif
diff --git a/lispBM/lispBM/include/extensions.h b/lispBM/lispBM/include/extensions.h
index 453be276..6cde14cf 100644
--- a/lispBM/lispBM/include/extensions.h
+++ b/lispBM/lispBM/include/extensions.h
@@ -22,7 +22,7 @@
#include "symrepr.h"
#include "heap.h"
-#include "lispbm_types.h"
+#include "lbm_types.h"
/** Type representing an extension function.
* \param Pointer to array of lbm_values.
diff --git a/lispBM/lispBM/include/heap.h b/lispBM/lispBM/include/heap.h
index 62808888..cfa56447 100644
--- a/lispBM/lispBM/include/heap.h
+++ b/lispBM/lispBM/include/heap.h
@@ -20,7 +20,8 @@
#define HEAP_H_
#include
-#include "lispbm_types.h"
+
+#include "lbm_types.h"
#include "symrepr.h"
#include "streams.h"
@@ -205,11 +206,12 @@ Aux bits could be used for storing vector size. Up to 30bits should be available
#define LBM_VAL_MASK 0xFFFFFFF0u
#define LBM_VAL_TYPE_MASK 0x0000000Cu
- // gc ptr
+ // gc ptr
#define LBM_VAL_TYPE_SYMBOL 0x00000000u // 00 0 0
+/// Character or byte.
#define LBM_VAL_TYPE_CHAR 0x00000004u // 01 0 0
-#define LBM_VAL_TYPE_U 0x00000008u // 11 0 0
-#define LBM_VAL_TYPE_I 0x0000000Cu // 10 0 0
+#define LBM_VAL_TYPE_U 0x00000008u // 10 0 0
+#define LBM_VAL_TYPE_I 0x0000000Cu // 11 0 0
/** Struct representing a heap cons-cell.
*
@@ -247,8 +249,9 @@ typedef struct {
* The header portion of an array stored in array and symbol memory.
*/
typedef struct {
- lbm_type elt_type; // Type of elements: VAL_TYPE_FLOAT, U, I or CHAR
- uint32_t size; // Number of elements
+ lbm_type elt_type; /// Type of elements: VAL_TYPE_FLOAT, U, I or CHAR
+ uint32_t size; /// Number of elements
+ uint32_t *data; /// pointer to lbm_memory array or C array.
} lbm_array_header_t;
/** Initialize heap storage.
@@ -557,11 +560,17 @@ static inline bool lbm_is_number(lbm_value x) {
lbm_uint t = lbm_type_of(x);
return ((t == LBM_VAL_TYPE_I) ||
(t == LBM_VAL_TYPE_U) ||
+ (t == LBM_VAL_TYPE_CHAR) ||
(t == LBM_PTR_TYPE_BOXED_I) ||
(t == LBM_PTR_TYPE_BOXED_U) ||
(t == LBM_PTR_TYPE_BOXED_F));
}
+static inline bool lbm_is_char(lbm_value x) {
+ lbm_uint t = lbm_type_of(x);
+ return (t == LBM_VAL_TYPE_CHAR);
+}
+
static inline bool lbm_is_special(lbm_value symrep) {
return ((lbm_type_of(symrep) == LBM_VAL_TYPE_SYMBOL) &&
(lbm_dec_sym(symrep) < MAX_SPECIAL_SYMBOLS));
diff --git a/lispBM/lispBM/include/lbm_c_interop.h b/lispBM/lispBM/include/lbm_c_interop.h
new file mode 100644
index 00000000..397dfc5c
--- /dev/null
+++ b/lispBM/lispBM/include/lbm_c_interop.h
@@ -0,0 +1,93 @@
+/*
+ Copyright 2018, 2020, 2021, 2022 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+/** \file lbm_c_interop.h */
+
+#ifndef LBM_C_INTEROP_H_
+#define LBM_C_INTEROP_H_
+
+#include "env.h"
+#include "symrepr.h"
+#include "eval_cps.h"
+#include "heap.h"
+#include "streams.h"
+#include "tokpar.h"
+#include "lbm_memory.h"
+#include "heap.h"
+#include "lbm_types.h"
+
+
+/** Load and schedule a program for execution.
+ *
+ * \param tokenizer The tokenizer to read the program from.
+ * \return A context id on success or 0 on failure.
+ */
+extern lbm_cid lbm_load_and_eval_program(lbm_tokenizer_char_stream_t *tokenizer);
+/** Load and schedule an expression for execution.
+ *
+ * \param tokenizer The tokenizer to read the expression from.
+ * \return A context id on success or 0 on failure.
+ */
+extern lbm_cid lbm_load_and_eval_expression(lbm_tokenizer_char_stream_t *tokenizer);
+/** Load a program and bind it to a symbol in the environment.
+ *
+ * \param tokenizer The tokenizer to read the program from.
+ * \param symbol A string with the name you want the binding to have in the environment.
+ * \return A context id on success or 0 on failure.
+ */
+extern lbm_cid lbm_load_and_define_program(lbm_tokenizer_char_stream_t *tokenizer, char *symbol);
+/** Load an expression and bind it to a symbol in the environment.
+ *
+ * \param tokenizer The tokenizer to read the expression from.
+ * \param symbol A string with the name you want the binding to have in the environment.
+ * \return A context id on success or 0 on failure.
+ */
+extern lbm_cid lbm_load_and_define_expression(lbm_tokenizer_char_stream_t *tokenizer, char *symbol);
+
+/* Evaluating a definition in a new context */
+/** Create a context for a bound expression and schedule it for execution
+ *
+ * \param symbol The name of the binding to schedule for execution.
+ * \return A context if on success or 0 on failure.
+ */
+extern lbm_cid lbm_eval_defined_expression(char *symbol);
+/** Create a context for a bound program and schedule it for execution
+ *
+ * \param symbol The name of the binding to schedule for execution.
+ * \return A context if on success or 0 on failure.
+ */
+extern lbm_cid lbm_eval_defined_program(char *symbol);
+
+/** Send a message to a process running in the evaluator.
+ *
+ * \param cid Context id of the process to send a message to.
+ * \param msg lbm_value that will be sent to the process.
+ * \return 1 on success or 0 on failure.
+ */
+extern int lbm_send_message(lbm_cid cid, lbm_value msg);
+
+/** Add a definition to the global environment
+ *
+ * \param symbol Name to bind the data to.
+ * \param value The data.
+ * \return 1 on success and 0 on failure.
+ */
+extern int lbm_define(char *symbol, lbm_value value);
+
+
+
+#endif
diff --git a/lispBM/lispBM/include/lispbm_memory.h b/lispBM/lispBM/include/lbm_memory.h
similarity index 96%
rename from lispBM/lispBM/include/lispbm_memory.h
rename to lispBM/lispBM/include/lbm_memory.h
index b9d994de..c4938340 100644
--- a/lispBM/lispBM/include/lispbm_memory.h
+++ b/lispBM/lispBM/include/lbm_memory.h
@@ -1,4 +1,4 @@
-/** \file lispbm_memory.h */
+/** \file lbm_memory.h */
/*
Copyright 2020, 2022 Joel Svensson svenssonjoel@yahoo.se
@@ -133,4 +133,11 @@ extern uint32_t *lbm_memory_allocate(uint32_t num_words);
*/
extern int lbm_memory_free(uint32_t *ptr);
+/** Check if a pointer points into the lbm_memory
+ *
+ * \param ptr
+ * \return 1 for yes and 0 for no.
+ */
+extern int lbm_memory_ptr_inside(uint32_t *ptr);
+
#endif
diff --git a/lispBM/lispBM/include/lispbm_types.h b/lispBM/lispBM/include/lbm_types.h
similarity index 98%
rename from lispBM/lispBM/include/lispbm_types.h
rename to lispBM/lispBM/include/lbm_types.h
index 540b8019..a45574b9 100644
--- a/lispBM/lispBM/include/lispbm_types.h
+++ b/lispBM/lispBM/include/lbm_types.h
@@ -1,4 +1,4 @@
-/** \file lispbm_types.h */
+/** \file lbm_types.h */
/*
Copyright 2019 Joel Svensson svenssonjoel@yahoo.se
diff --git a/lispBM/lispBM/include/lispbm.h b/lispBM/lispBM/include/lispbm.h
index 5ffa390e..15fbfa01 100644
--- a/lispBM/lispBM/include/lispbm.h
+++ b/lispBM/lispBM/include/lispbm.h
@@ -27,10 +27,11 @@
#include "print.h"
#include "tokpar.h"
#include "prelude.h"
-#include "lispbm_types.h"
-#include "lispbm_memory.h"
#include "env.h"
#include "compression.h"
+#include "lbm_memory.h"
+#include "lbm_types.h"
+#include "lbm_c_interop.h"
/** Initialize lispBM. This function initials all subsystems by calling:
* - \ref lbm_memory_init
diff --git a/lispBM/lispBM/include/prelude.h b/lispBM/lispBM/include/prelude.h
index 0a1a91b9..5e063226 100644
--- a/lispBM/lispBM/include/prelude.h
+++ b/lispBM/lispBM/include/prelude.h
@@ -19,7 +19,7 @@
#ifndef _PRELUDE_H_
#define _PRELUDE_H_
-#include "lispbm_types.h"
+#include "lbm_types.h"
/** Creates the tokenizer state needed to load the prelude library into the heap.
*
diff --git a/lispBM/lispBM/include/print.h b/lispBM/lispBM/include/print.h
index d8930dd7..f979dfca 100644
--- a/lispBM/lispBM/include/print.h
+++ b/lispBM/lispBM/include/print.h
@@ -21,7 +21,8 @@
#define PRINT_H_
#include
-#include "lispbm_types.h"
+
+#include "lbm_types.h"
/** Print an lbm_value into a buffer provided by the user.
* If printing fails, the buffer may contain an error message.
diff --git a/lispBM/lispBM/include/stack.h b/lispBM/lispBM/include/stack.h
index 26f74b55..847046a5 100644
--- a/lispBM/lispBM/include/stack.h
+++ b/lispBM/lispBM/include/stack.h
@@ -24,7 +24,7 @@
#include
#include
-#include "lispbm_types.h"
+#include "lbm_types.h"
typedef struct {
lbm_uint* data;
diff --git a/lispBM/lispBM/include/streams.h b/lispBM/lispBM/include/streams.h
index 9ae35903..7ddd04eb 100644
--- a/lispBM/lispBM/include/streams.h
+++ b/lispBM/lispBM/include/streams.h
@@ -24,7 +24,7 @@
#ifndef STREAMS_H_
#define STREAMS_H_
-#include "lispbm_types.h"
+#include "lbm_types.h"
typedef struct lbm_stream_s{
void *state; /* stream implementation dependent state */
diff --git a/lispBM/lispBM/include/symrepr.h b/lispBM/lispBM/include/symrepr.h
index c9cf62ad..47500793 100644
--- a/lispBM/lispBM/include/symrepr.h
+++ b/lispBM/lispBM/include/symrepr.h
@@ -31,7 +31,7 @@
#include
#include
-#include "lispbm_types.h"
+#include "lbm_types.h"
// Default and fixed symbol ids
#define SYM_NIL 0x0
@@ -125,7 +125,7 @@
#define SYM_ARRAY_READ 0x130
#define SYM_ARRAY_WRITE 0x131
-#define SYM_ARRAY_CREATE 0x132
+//#define SYM_ARRAY_CREATE 0x132
#define SYM_SYMBOL_TO_STRING 0x140
#define SYM_STRING_TO_SYMBOL 0x141
@@ -136,6 +136,18 @@
#define SYM_IS_FUNDAMENTAL 0x150
+#define SYM_IX 0x151
+#define SYM_ENCODE_I32 0x152
+#define SYM_ENCODE_U32 0x153
+#define SYM_ENCODE_FLOAT 0x154
+#define SYM_DECODE 0x155
+
+//#define SYM_STREAM_GET 0x160
+//#define SYM_STREAM_MORE 0x161
+//#define SYM_STREAM_PEEK 0x162
+//#define SYM_STREAM_DROP 0x163
+//#define SYM_STREAM_PUT 0x164
+
#define SYM_TYPE_OF 0x200
#define FUNDAMENTALS_END 0x200
diff --git a/lispBM/lispBM/include/tokpar.h b/lispBM/lispBM/include/tokpar.h
index 79e1a8fd..7cc74985 100644
--- a/lispBM/lispBM/include/tokpar.h
+++ b/lispBM/lispBM/include/tokpar.h
@@ -19,7 +19,7 @@
#ifndef TOKPAR_H_
#define TOKPAR_H_
-#include "lispbm_types.h"
+#include "lbm_types.h"
/**
* State struct for the string tokenizer.
diff --git a/lispBM/lispBM/lispbm.mk b/lispBM/lispBM/lispbm.mk
index aae01067..434dfd9f 100644
--- a/lispBM/lispBM/lispbm.mk
+++ b/lispBM/lispBM/lispbm.mk
@@ -3,7 +3,7 @@ first_rule: all
LISPBM_SRC = $(LISPBM)/src/env.c \
$(LISPBM)/src/fundamental.c \
$(LISPBM)/src/heap.c \
- $(LISPBM)/src/lispbm_memory.c \
+ $(LISPBM)/src/lbm_memory.c \
$(LISPBM)/src/print.c \
$(LISPBM)/src/qq_expand.c \
$(LISPBM)/src/stack.c \
@@ -14,7 +14,8 @@ LISPBM_SRC = $(LISPBM)/src/env.c \
$(LISPBM)/src/extensions.c \
$(LISPBM)/src/lispbm.c \
$(LISPBM)/src/eval_cps.c \
- $(LISPBM)/src/streams.c
+ $(LISPBM)/src/streams.c \
+ $(LISPBM)/src/lbm_c_interop.c
LISPBM_INC = -I$(LISPBM)/include \
-I$(LISPBM)/src
diff --git a/lispBM/lispBM/src/compression.c b/lispBM/lispBM/src/compression.c
index 543169b0..2c9735d4 100644
--- a/lispBM/lispBM/src/compression.c
+++ b/lispBM/lispBM/src/compression.c
@@ -17,12 +17,12 @@
#include
#include
+#include
#include
#include
#include
#include "compression.h"
-#include "lispbm_types.h"
#include "tokpar.h"
#define KEY 0
diff --git a/lispBM/lispBM/src/env.c b/lispBM/lispBM/src/env.c
index 6e47df79..0f44498c 100644
--- a/lispBM/lispBM/src/env.c
+++ b/lispBM/lispBM/src/env.c
@@ -15,12 +15,12 @@
along with this program. If not, see .
*/
+#include
#include
#include "symrepr.h"
#include "heap.h"
#include "print.h"
-#include "lispbm_types.h"
lbm_value env_global;
diff --git a/lispBM/lispBM/src/eval_cps.c b/lispBM/lispBM/src/eval_cps.c
index a88b3d00..f8a086d5 100644
--- a/lispBM/lispBM/src/eval_cps.c
+++ b/lispBM/lispBM/src/eval_cps.c
@@ -15,6 +15,8 @@
along with this program. If not, see .
*/
+#include
+#include
#include "symrepr.h"
#include "heap.h"
#include "env.h"
@@ -22,10 +24,8 @@
#include "stack.h"
#include "fundamental.h"
#include "extensions.h"
-#include "lispbm_types.h"
#include "exp_kind.h"
#include "streams.h"
-#include "lispbm_memory.h"
#include "tokpar.h"
#include "qq_expand.h"
@@ -113,6 +113,7 @@ static lbm_value cons_with_gc(lbm_value head, lbm_value tail, lbm_value remember
static uint32_t eval_cps_run_state = EVAL_CPS_STATE_INIT;
volatile uint32_t eval_cps_next_state = EVAL_CPS_STATE_INIT;
+volatile uint32_t eval_cps_next_state_arg = 0;
/*
On ChibiOs the CH_CFG_ST_FREQUENCY setting in chconf.h sets the
@@ -195,7 +196,7 @@ static lbm_value token_stream_put(lbm_stream_t *str, lbm_value v){
return lbm_enc_sym(SYM_NIL);
}
-lbm_value eval_cps_create_token_stream(lbm_tokenizer_char_stream_t *str) {
+lbm_value lbm_create_token_stream(lbm_tokenizer_char_stream_t *str) {
lbm_stream_t *stream;
@@ -244,8 +245,8 @@ lbm_value token_stream_from_string_value(lbm_value s) {
}
lbm_create_char_stream_from_string(tok_stream_state,
- tok_stream,
- str);
+ tok_stream,
+ str);
stream->state = (void*)tok_stream;
stream->more = token_stream_more;
@@ -488,7 +489,7 @@ static void yield_ctx(uint32_t sleep_us) {
ctx_running = NULL;
}
-static lbm_cid create_ctx(lbm_value program, lbm_value env, uint32_t stack_size) {
+lbm_cid lbm_create_ctx(lbm_value program, lbm_value env, uint32_t stack_size) {
if (next_ctx_id == 0) return 0; // overflow of CIDs
@@ -546,7 +547,7 @@ static void advance_ctx(void) {
}
}
-static lbm_value find_receiver_and_send(lbm_cid cid, lbm_value msg) {
+lbm_value lbm_find_receiver_and_send(lbm_cid cid, lbm_value msg) {
eval_context_t *found = NULL;
found = lookup_ctx(&blocked, cid);
@@ -818,7 +819,7 @@ static inline void eval_symbol(eval_context_t *ctx) {
if (lbm_is_special(ctx->curr_exp) ||
(lbm_get_extension(lbm_dec_sym(ctx->curr_exp)) != NULL)) {
- // Special symbols and extension symbols evaluate to themself
+ // Special symbols and extension symbols evaluate to themselves
value = ctx->curr_exp;
} else {
// If not special, check if there is a binding in the environments
@@ -1008,7 +1009,7 @@ static inline void eval_match(eval_context_t *ctx) {
rest == NIL) {
/* Someone wrote the program (match) */
ctx->app_cont = true;
- ctx->r = lbm_enc_sym(SYM_NIL); /* make up new specific symbol? */
+ ctx->r = lbm_enc_sym(SYM_NIL);
return;
} else {
CHECK_STACK(lbm_push_u32_2(&ctx->K, lbm_cdr(rest), lbm_enc_u(MATCH)));
@@ -1064,12 +1065,6 @@ static inline void eval_receive(eval_context_t *ctx) {
ctx_running = NULL;
ctx->r = lbm_enc_sym(SYM_NO_MATCH);
}
-
- /* Match messages on mailbox against the patterns */
- /* FATAL_ON_FAIL(ctx->done, push_u32_4(&ctx->K, ctx->curr_exp, car(cdr(pats)), cdr(msgs), enc_u(MATCH_MANY))); */
- /* FATAL_ON_FAIL(ctx->done, push_u32_2(&ctx->K, car(cdr(pats)), enc_u(MATCH))); */
- /* ctx->r = car(msgs); */
- /* ctx->app_cont = true; */
}
}
return;
@@ -1135,7 +1130,7 @@ static inline void cont_spawn_all(eval_context_t *ctx) {
lbm_value cid_list;
WITH_GC(cid_list, lbm_cons(cid_val, ctx->r), rest, env);
- lbm_cid cid = create_ctx(lbm_car(rest),
+ lbm_cid cid = lbm_create_ctx(lbm_car(rest),
env,
EVAL_CPS_DEFAULT_STACK_SIZE);
if (!cid) {
@@ -1299,7 +1294,7 @@ static inline void cont_application(eval_context_t *ctx) {
lbm_cid cid = (lbm_cid)lbm_dec_u(fun_args[1]);
lbm_value msg = fun_args[2];
- WITH_GC(status, find_receiver_and_send(cid, msg), NIL, NIL);
+ WITH_GC(status, lbm_find_receiver_and_send(cid, msg), NIL, NIL);
}
}
/* return the status */
@@ -1889,10 +1884,17 @@ static void evaluation_step(void){
return;
}
-void lbm_pause_eval(void) {
+void lbm_pause_eval(void ) {
+ eval_cps_next_state_arg = 0;
eval_cps_next_state = EVAL_CPS_STATE_PAUSED;
}
+void lbm_pause_eval_with_gc(uint32_t num_free) {
+ eval_cps_next_state_arg = num_free;
+ eval_cps_next_state = EVAL_CPS_STATE_PAUSED;
+}
+
+
void lbm_step_eval(void) {
eval_cps_next_state = EVAL_CPS_STATE_STEP;
}
@@ -1917,6 +1919,7 @@ void lbm_run_eval(void){
while (eval_running) {
+ uint32_t prev_state = eval_cps_run_state;
eval_cps_run_state = eval_cps_next_state;
switch (eval_cps_run_state) {
@@ -1927,6 +1930,12 @@ void lbm_run_eval(void){
eval_cps_next_state = EVAL_CPS_STATE_PAUSED;
break;
case EVAL_CPS_STATE_PAUSED:
+ if (prev_state != EVAL_CPS_STATE_PAUSED) {
+ if (lbm_heap_num_free() < eval_cps_next_state_arg) {
+ gc(NIL, NIL);
+ }
+ eval_cps_next_state_arg = 0;
+ }
eval_cps_next_state = EVAL_CPS_STATE_PAUSED;
usleep_callback(EVAL_CPS_MIN_SLEEP);
continue; /* jump back to start of eval_running loop */
@@ -1977,11 +1986,11 @@ lbm_value evaluate_non_concurrent(void) {
}
lbm_cid lbm_eval_program(lbm_value lisp) {
- return create_ctx(lisp, NIL, 256);
+ return lbm_create_ctx(lisp, NIL, 256);
}
lbm_cid lbm_eval_program_ext(lbm_value lisp, unsigned int stack_size) {
- return create_ctx(lisp, NIL, stack_size);
+ return lbm_create_ctx(lisp, NIL, stack_size);
}
int lbm_eval_init() {
@@ -2014,172 +2023,3 @@ int lbm_eval_init() {
return res;
}
-/****************************************************/
-/* Interface for loading and running programs and */
-/* expressions */
-
-static lbm_cid eval_cps_load_and_eval(lbm_tokenizer_char_stream_t *tokenizer, bool program) {
-
- lbm_stream_t *stream = NULL;
-
- stream = (lbm_stream_t*)lbm_memory_allocate(sizeof(lbm_stream_t) / 4);
- if (stream == NULL) {
- return 0; // No valid CID is 0
- }
-
- stream->state = (void*)tokenizer;
- stream->more = token_stream_more;
- stream->get = token_stream_get;
- stream->peek = token_stream_peek;
- stream->drop = token_stream_drop;
- stream->put = token_stream_put;
-
- lbm_value lisp_stream = lbm_stream_create(stream);
-
- if (lbm_type_of(lisp_stream) == LBM_VAL_TYPE_SYMBOL) {
- lbm_memory_free((uint32_t*)stream);
- return 0;
- }
-
- /* LISP ZONE */
-
- lbm_value launcher = lbm_cons(lisp_stream, NIL);
- launcher = lbm_cons(lbm_enc_sym(program ? SYM_READ_PROGRAM : SYM_READ), launcher);
- lbm_value evaluator = lbm_cons(launcher, NIL);
- evaluator = lbm_cons(lbm_enc_sym(program ? SYM_EVAL_PROGRAM : SYM_EVAL), evaluator);
- lbm_value start_prg = lbm_cons(evaluator, NIL);
-
- /* LISP ZONE ENDS */
-
- if (lbm_type_of(launcher) != LBM_PTR_TYPE_CONS ||
- lbm_type_of(evaluator) != LBM_PTR_TYPE_CONS ||
- lbm_type_of(start_prg) != LBM_PTR_TYPE_CONS ) {
- lbm_memory_free((uint32_t*)stream);
- return 0;
- }
- return create_ctx(start_prg, NIL, 256);
-}
-
-lbm_cid lbm_load_and_eval_expression(lbm_tokenizer_char_stream_t *tokenizer) {
- return eval_cps_load_and_eval(tokenizer, false);
-}
-
-static lbm_cid eval_cps_load_and_define(lbm_tokenizer_char_stream_t *tokenizer, char *symbol, bool program) {
-
- lbm_stream_t *stream = NULL;
-
- stream = (lbm_stream_t*)lbm_memory_allocate(sizeof(lbm_stream_t) / 4);
- if (stream == NULL) {
- return 0; // No valid CID is 0
- }
-
- stream->state = (void*)tokenizer;
- stream->more = token_stream_more;
- stream->get = token_stream_get;
- stream->peek = token_stream_peek;
- stream->drop = token_stream_drop;
- stream->put = token_stream_put;
-
- lbm_value lisp_stream = lbm_stream_create(stream);
-
- if (lbm_type_of(lisp_stream) == LBM_VAL_TYPE_SYMBOL) {
- lbm_memory_free((uint32_t*)stream);
- return 0;
- }
-
- lbm_uint sym_id;
-
- if (!lbm_get_symbol_by_name(symbol, &sym_id)) {
- if (!lbm_add_symbol(symbol, &sym_id)) {
- lbm_memory_free((uint32_t*)stream);
- return 0;
- }
- }
-
- /* LISP ZONE */
-
- lbm_value launcher = lbm_cons(lisp_stream, NIL);
- launcher = lbm_cons(lbm_enc_sym(program ? SYM_READ_PROGRAM : SYM_READ), launcher);
- lbm_value binding = lbm_cons(launcher, NIL);
- binding = lbm_cons(lbm_enc_sym(sym_id), binding);
- lbm_value definer = lbm_cons(lbm_enc_sym(SYM_DEFINE), binding);
- definer = lbm_cons(definer, NIL);
- /* LISP ZONE ENDS */
-
- if (lbm_type_of(launcher) != LBM_PTR_TYPE_CONS ||
- lbm_type_of(binding) != LBM_PTR_TYPE_CONS ||
- lbm_type_of(definer) != LBM_PTR_TYPE_CONS ) {
- lbm_memory_free((uint32_t*)stream);
- return 0;
- }
- return create_ctx(definer, NIL, 256);
-}
-
-
-lbm_cid lbm_load_and_define_program(lbm_tokenizer_char_stream_t *tokenizer, char *symbol) {
- return eval_cps_load_and_define(tokenizer, symbol, true);
-}
-
-lbm_cid lbm_load_and_define_expression(lbm_tokenizer_char_stream_t *tokenizer, char *symbol) {
- return eval_cps_load_and_define(tokenizer, symbol, false);
-}
-
-lbm_cid lbm_load_and_eval_program(lbm_tokenizer_char_stream_t *tokenizer) {
- return eval_cps_load_and_eval(tokenizer, true);
-}
-
-static lbm_cid lbm_eval_defined(char *symbol, bool program) {
-
- lbm_uint sym_id;
-
- if(!lbm_get_symbol_by_name(symbol, &sym_id)) {
- // The symbol does not exist, so it cannot be defined
- return 0;
- }
-
- lbm_value binding = lbm_env_lookup(lbm_enc_sym(sym_id), *lbm_get_env_ptr());
-
- if (lbm_type_of(binding) == LBM_VAL_TYPE_SYMBOL &&
- lbm_dec_sym(binding) == SYM_NOT_FOUND) {
- return 0;
- }
-
- /* LISP ZONE */
-
- lbm_value launcher = lbm_cons(lbm_enc_sym(sym_id), NIL);
- lbm_value evaluator = launcher;
- evaluator = lbm_cons(lbm_enc_sym(program ? SYM_EVAL_PROGRAM : SYM_EVAL), evaluator);
- lbm_value start_prg = lbm_cons(evaluator, NIL);
-
- /* LISP ZONE ENDS */
-
- if (lbm_type_of(launcher) != LBM_PTR_TYPE_CONS ||
- lbm_type_of(evaluator) != LBM_PTR_TYPE_CONS ||
- lbm_type_of(start_prg) != LBM_PTR_TYPE_CONS ) {
- return 0;
- }
- return create_ctx(start_prg, NIL, 256);
-}
-
-lbm_cid lbm_eval_defined_expression(char *symbol) {
- return lbm_eval_defined(symbol, false);
-}
-
-lbm_cid lbm_eval_defined_program(char *symbol) {
- return lbm_eval_defined(symbol, true);
-}
-
-int lbm_send_message(lbm_cid cid, lbm_value msg) {
- int res = 0;
-
- if (lbm_get_eval_state() == EVAL_CPS_STATE_PAUSED) {
-
- lbm_value v = find_receiver_and_send(cid, msg);
-
- if (lbm_type_of(v) == LBM_VAL_TYPE_SYMBOL &&
- lbm_dec_sym(v) == SYM_TRUE) {
- res = 1;
- }
- }
- return res;
-}
diff --git a/lispBM/lispBM/src/extensions.c b/lispBM/lispBM/src/extensions.c
index aadd4e11..c19d90c6 100644
--- a/lispBM/lispBM/src/extensions.c
+++ b/lispBM/lispBM/src/extensions.c
@@ -16,12 +16,12 @@
along with this program. If not, see .
*/
+#include
#include
#include
#include
#include
-#include "lispbm_memory.h"
#include "extensions.h"
#define SYM 0
diff --git a/lispBM/lispBM/src/fundamental.c b/lispBM/lispBM/src/fundamental.c
index 508ca857..01aad411 100644
--- a/lispBM/lispBM/src/fundamental.c
+++ b/lispBM/lispBM/src/fundamental.c
@@ -16,12 +16,12 @@
along with this program. If not, see .
*/
+#include
#include "symrepr.h"
#include "stack.h"
#include "heap.h"
#include "eval_cps.h"
#include "print.h"
-
#include
#include
@@ -167,17 +167,17 @@ static bool array_equality(lbm_value a, lbm_value b) {
switch(a_->elt_type) {
case LBM_VAL_TYPE_U:
case LBM_PTR_TYPE_BOXED_U:
- if (memcmp((char*)a_+8, (char*)b_+8, a_->size * sizeof(lbm_uint)) == 0) return true;
+ if (memcmp((char*)a_->data, (char*)b_->data, a_->size * sizeof(lbm_uint)) == 0) return true;
break;
case LBM_VAL_TYPE_I:
case LBM_PTR_TYPE_BOXED_I:
- if (memcmp((char*)a_+8, (char*)b_+8, a_->size * sizeof(lbm_int)) == 0) return true;
+ if (memcmp((char*)a_->data, (char*)b_->data, a_->size * sizeof(lbm_int)) == 0) return true;
break;
case LBM_VAL_TYPE_CHAR:
- if (memcmp((char*)a_+8, (char*)b_+8, a_->size) == 0) return true;
+ if (memcmp((char*)a_->data, (char*)b_->data, a_->size) == 0) return true;
break;
case LBM_PTR_TYPE_BOXED_F:
- if (memcmp((char*)a_+8, (char*)b_+8, a_->size * sizeof(lbm_float)) == 0) return true;
+ if (memcmp((char*)a_->data, (char*)b_->data, a_->size * sizeof(lbm_float)) == 0) return true;
break;
default:
break;
@@ -270,83 +270,89 @@ static int compare(lbm_uint a, lbm_uint b) {
void array_read(lbm_value *args, lbm_uint nargs, lbm_uint *result) {
(void) nargs;
+ if (nargs < 2) return;
// Args are: array, index
lbm_value arr = args[0];
lbm_value index = args[1];
+ lbm_value index_end = index;
+ lbm_value acc = lbm_enc_sym(SYM_NIL);
+ lbm_value curr = lbm_enc_sym(SYM_EERROR);
+ bool read_many = false;
+
+ if (nargs > 2) {
+ index_end = args[2];
+ read_many = true;
+ }
// Get array index
lbm_uint ix;
- lbm_int tmp;
+ lbm_uint ix_end;
- *result = lbm_enc_sym(SYM_EERROR);
- switch (lbm_type_of(index)) {
- case LBM_VAL_TYPE_U:
- ix = lbm_dec_u(index);
- break;
- case LBM_VAL_TYPE_I:
- tmp = (lbm_int)lbm_dec_i(index);
- if (tmp < 0) {
- *result = lbm_enc_sym(SYM_EERROR);
- return;
- }
- ix = (lbm_uint)tmp;
- break;
- case LBM_PTR_TYPE_BOXED_U:
- ix = lbm_dec_U(index);
- break;
- case LBM_PTR_TYPE_BOXED_I:
- tmp = lbm_dec_I(index);
- if (tmp < 0) {
- *result = lbm_enc_sym(SYM_EERROR);
- return;
- }
- ix = (lbm_uint) tmp;
- break;
- default:
- *result = lbm_enc_sym(SYM_NIL);
+ if (lbm_is_number(index) && lbm_is_number(index_end)) {
+ ix = lbm_dec_as_u(index);
+ ix_end = lbm_dec_as_u(index_end);
+ } else {
return;
}
+ if (ix > ix_end) {
+ lbm_uint tmp = ix;
+ ix = ix_end;
+ ix_end = tmp;
+ }
+
if (lbm_type_of(arr) == LBM_PTR_TYPE_ARRAY) {
lbm_array_header_t *array = (lbm_array_header_t*)lbm_car(arr);
+ uint32_t* data = array->data;
- if (ix >= array->size){
- *result = lbm_enc_sym(SYM_NIL);
- return;
- }
+ printf("ix: %d, ix_end: %d\n", ix, ix_end);
+ for (lbm_int i = (lbm_int)ix_end; i >= (lbm_int)ix; i--) {
+ printf("%d\n", i);
+ if ((lbm_uint)i >= array->size){
+ printf("hmm %d %d\n", i, array->size);
+ *result = lbm_enc_sym(SYM_NIL);
+ return;
+ }
- switch(array->elt_type) {
- case LBM_VAL_TYPE_CHAR:
- *result = lbm_enc_char((lbm_uint) ((char*)array+8)[ix]);
- break;
- case LBM_VAL_TYPE_U:
- *result = lbm_enc_u(((lbm_uint*)array + 2)[ix]);
- break;
- case LBM_VAL_TYPE_I:
- *result = lbm_enc_i(((lbm_int*)array + 2)[ix]);
- break;
- case LBM_PTR_TYPE_BOXED_U:
- *result = lbm_cons(((lbm_uint*)array + 2)[ix], lbm_enc_sym(SYM_BOXED_U_TYPE));
- if (lbm_type_of(*result) == LBM_VAL_TYPE_SYMBOL) return;
- *result = lbm_set_ptr_type(*result, LBM_PTR_TYPE_BOXED_U);
- break;
- case LBM_PTR_TYPE_BOXED_I:
- *result = lbm_cons(((lbm_uint*)array + 2)[ix], lbm_enc_sym(SYM_BOXED_I_TYPE));
- if (lbm_type_of(*result) == LBM_VAL_TYPE_SYMBOL) return;
- *result = lbm_set_ptr_type(*result, LBM_PTR_TYPE_BOXED_I);
- break;
- case LBM_PTR_TYPE_BOXED_F:
- *result = lbm_cons(((lbm_uint*)array+2)[ix], lbm_enc_sym(SYM_BOXED_F_TYPE));
- if (lbm_type_of(*result) == LBM_VAL_TYPE_SYMBOL) return;
- *result = lbm_set_ptr_type(*result, LBM_PTR_TYPE_BOXED_F);
- break;
- default:
- *result = lbm_enc_sym(SYM_EERROR);
- return;
- }
- return;
+ switch(array->elt_type) {
+ case LBM_VAL_TYPE_CHAR:
+ curr = lbm_enc_char((lbm_uint) ((char*)data)[i]);
+ break;
+ case LBM_VAL_TYPE_U:
+ curr = lbm_enc_u(((lbm_uint*)data)[i]);
+ break;
+ case LBM_VAL_TYPE_I:
+ curr = lbm_enc_i(((lbm_int*)data)[i]);
+ break;
+ case LBM_PTR_TYPE_BOXED_U:
+ curr = lbm_cons(((lbm_uint*)data)[i], lbm_enc_sym(SYM_BOXED_U_TYPE));
+ if (lbm_type_of(curr) == LBM_VAL_TYPE_SYMBOL) return;
+ curr = lbm_set_ptr_type(curr, LBM_PTR_TYPE_BOXED_U);
+ break;
+ case LBM_PTR_TYPE_BOXED_I:
+ curr = lbm_cons(((lbm_uint*)data)[i], lbm_enc_sym(SYM_BOXED_I_TYPE));
+ if (lbm_type_of(curr) == LBM_VAL_TYPE_SYMBOL) return;
+ curr = lbm_set_ptr_type(curr, LBM_PTR_TYPE_BOXED_I);
+ break;
+ case LBM_PTR_TYPE_BOXED_F:
+ curr = lbm_cons(((lbm_uint*)data)[i], lbm_enc_sym(SYM_BOXED_F_TYPE));
+ if (lbm_type_of(*result) == LBM_VAL_TYPE_SYMBOL) return;
+ curr = lbm_set_ptr_type(curr, LBM_PTR_TYPE_BOXED_F);
+ break;
+ default:
+ curr = lbm_enc_sym(SYM_EERROR);
+ break;
+ }
+ if (read_many) {
+ acc = lbm_cons(curr, acc);
+ }
+ } /* for i */
+ }
+ if (read_many) {
+ *result = acc;
+ } else {
+ *result = curr;
}
- *result = lbm_enc_sym(SYM_EERROR);
}
void array_write(lbm_value *args, lbm_uint nargs, lbm_uint *result) {
@@ -355,38 +361,19 @@ void array_write(lbm_value *args, lbm_uint nargs, lbm_uint *result) {
lbm_value index = args[1];
lbm_value val = args[2];
lbm_uint ix;
- lbm_int tmp;
- switch (lbm_type_of(index)) {
- case LBM_VAL_TYPE_U:
- ix = lbm_dec_u(index);
- break;
- case LBM_VAL_TYPE_I:
- tmp = (lbm_int)lbm_dec_i(index);
- if (tmp < 0) {
- *result = lbm_enc_sym(SYM_EERROR);
- return;
- }
- ix = (lbm_uint) tmp;
- break;
- case LBM_PTR_TYPE_BOXED_U:
- ix = lbm_car(index);
- break;
- case LBM_PTR_TYPE_BOXED_I:
- tmp = (lbm_int)lbm_car(index);
- if (tmp < 0) {
- *result = lbm_enc_sym(SYM_EERROR);
- return;
- }
- ix = (lbm_uint) tmp;
- break;
- default:
- *result = lbm_enc_sym(SYM_NIL);
+
+ *result = lbm_enc_sym(SYM_EERROR);
+
+ if (lbm_is_number(index)) {
+ ix = lbm_dec_as_u(index);
+ } else {
return;
}
if (lbm_type_of(arr) == LBM_PTR_TYPE_ARRAY) {
lbm_array_header_t *array = (lbm_array_header_t*)lbm_car(arr);
+
if (lbm_type_of(val) != array->elt_type ||
ix >= array->size) {
*result = lbm_enc_sym(SYM_NIL);
@@ -395,65 +382,67 @@ void array_write(lbm_value *args, lbm_uint nargs, lbm_uint *result) {
switch(array->elt_type) {
case LBM_VAL_TYPE_CHAR: {
- char * data = (char *)array + 8;
+ char * data = (char *)array->data;
data[ix] = lbm_dec_char(val);
break;
}
case LBM_VAL_TYPE_U: {
- lbm_uint* data = (lbm_uint*)array + 2;
+ lbm_uint* data = (lbm_uint*)array->data;
data[ix] = lbm_dec_u(val);
break;
}
case LBM_VAL_TYPE_I: {
- lbm_int *data = (lbm_int*)array + 2;
+ lbm_int *data = (lbm_int*)array->data;
data[ix] = lbm_dec_i(val);
break;
}
case LBM_PTR_TYPE_BOXED_U: {
- lbm_uint *data = (lbm_uint*)array + 2;
+ lbm_uint *data = (lbm_uint*)array->data;
data[ix] = lbm_dec_U(val);
break;
}
case LBM_PTR_TYPE_BOXED_I: {
- lbm_int *data = (lbm_int*)array + 2;
+ lbm_int *data = (lbm_int*)array->data;
data[ix] = lbm_dec_I(val);
break;
}
case LBM_PTR_TYPE_BOXED_F: {
//uv = car(val);
//memcpy(&v, &uv, sizeof(FLOAT));
- lbm_uint *data = (lbm_uint*)array + 2;
+ lbm_uint *data = (lbm_uint*)array->data;
data[ix] = lbm_car(val);
break;
}
default:
- *result = lbm_enc_sym(SYM_EERROR);
- return;
+ // Maybe result should be something else than arr here.
+ break;
}
- *result = lbm_enc_sym(SYM_TRUE);
+ *result = arr;
return;
}
- *result = lbm_enc_sym(SYM_NIL);
}
-void array_create(lbm_value *args, lbm_uint nargs, lbm_uint *result) {
- (void) args;
- (void) nargs;
- (void) result;
-
-}
+//void array_create(lbm_value *args, lbm_uint nargs, lbm_uint *result) {
+// (void) args;
+// (void) nargs;
+// (void) result;
+//
+//}
-lbm_value index_list(lbm_value l, int n) {
- /* TODO: error checking */
+lbm_value index_list(lbm_value l, unsigned int n) {
lbm_value curr = l;
while ( lbm_type_of(curr) == LBM_PTR_TYPE_CONS &&
n > 0) {
curr = lbm_cdr(curr);
n --;
}
- return lbm_car(curr);
+ if (lbm_type_of(curr) == LBM_PTR_TYPE_CONS) {
+ return lbm_car(curr);
+ } else {
+ return lbm_enc_sym(SYM_NIL);
+ }
}
lbm_value lbm_fundamental(lbm_value* args, lbm_uint nargs, lbm_value op) {
@@ -462,6 +451,108 @@ lbm_value lbm_fundamental(lbm_value* args, lbm_uint nargs, lbm_value op) {
int cmp_res = -1;
switch (lbm_dec_sym(op)) {
+ case SYM_IX:
+ if (nargs == 2 && lbm_is_number(args[0])) {
+ result = index_list(args[1], lbm_dec_as_u(args[0]));
+ }
+ break;
+ case SYM_DECODE:
+ if (nargs == 1 && (lbm_is_number(args[0]) ||
+ lbm_is_char(args[0]))) {
+ switch (lbm_type_of(args[0])) {
+ case LBM_VAL_TYPE_CHAR:
+ /*fall through*/
+ case LBM_VAL_TYPE_I:
+ /* fall through */
+ case LBM_VAL_TYPE_U: {
+ lbm_uint v = lbm_dec_as_u(args[0]);
+ result = lbm_cons(lbm_enc_u(v & 0xFF), lbm_enc_sym(SYM_NIL));
+ result = lbm_cons(lbm_enc_u(v >> 8 & 0xFF), result);
+ result = lbm_cons(lbm_enc_u(v >> 16 & 0xFF), result);
+ result = lbm_cons(lbm_enc_u(v >> 24 & 0xF), result);
+ } break;
+ case LBM_PTR_TYPE_BOXED_F: {
+ lbm_float tmp = lbm_dec_F(args[0]);
+ lbm_uint v;
+ memcpy(&v, &tmp, sizeof(lbm_uint));
+ result = lbm_cons(lbm_enc_u(v & 0xFF), lbm_enc_sym(SYM_NIL));
+ result = lbm_cons(lbm_enc_u(v >> 8 & 0xFF), result);
+ result = lbm_cons(lbm_enc_u(v >> 16 & 0xFF), result);
+ result = lbm_cons(lbm_enc_u(v >> 24 & 0xFF), result);
+ } break;
+ case LBM_PTR_TYPE_BOXED_I:
+ /* fall through */
+ case LBM_PTR_TYPE_BOXED_U: {
+ lbm_uint v = lbm_dec_as_u(args[0]);
+ result = lbm_cons(lbm_enc_u(v & 0xFF), lbm_enc_sym(SYM_NIL));
+ result = lbm_cons(lbm_enc_u(v >> 8 & 0xFF), result);
+ result = lbm_cons(lbm_enc_u(v >> 16 & 0xFF), result);
+ result = lbm_cons(lbm_enc_u(v >> 24 & 0xFF), result);
+ } break;
+ } // close if
+ }break;
+ /// Encode a list of up to 4 bytes as an i32
+ case SYM_ENCODE_I32:
+ if (nargs == 1 && lbm_type_of(args[0]) == LBM_PTR_TYPE_CONS) {
+ lbm_value curr = args[0];
+ lbm_uint r = 0;
+ int n = 4;
+ while (lbm_type_of(curr) == LBM_PTR_TYPE_CONS && n > 0) {
+ if (n < 4) r = r << 8;
+ if (lbm_is_number(lbm_car(curr))) {
+ uint32_t v = lbm_dec_as_u(lbm_car(curr));
+ r |= v;
+ n --;
+ curr = lbm_cdr(curr);
+ } else {
+ break;
+ }
+ }
+ result = lbm_enc_I((lbm_int)r);
+ }
+ break;
+ /// Encode a list of up to 4 bytes as an U32
+ case SYM_ENCODE_U32:
+ if (nargs == 1 && lbm_type_of(args[0]) == LBM_PTR_TYPE_CONS) {
+ lbm_value curr = args[0];
+ lbm_uint r = 0;
+ int n = 4;
+ while (lbm_type_of(curr) == LBM_PTR_TYPE_CONS && n > 0) {
+ if (n < 4) r = r << 8;
+ if (lbm_is_number(lbm_car(curr))) {
+ uint32_t v = lbm_dec_as_u(lbm_car(curr));
+ r |= v;
+ n --;
+ curr = lbm_cdr(curr);
+ } else {
+ break;
+ }
+ }
+ result = lbm_enc_U(r);
+ }
+ break;
+ /// Encode a list of up to 4 bytes as an U32
+ case SYM_ENCODE_FLOAT:
+ if (nargs == 1 && lbm_type_of(args[0]) == LBM_PTR_TYPE_CONS) {
+ lbm_value curr = args[0];
+ lbm_uint r = 0;
+ lbm_float f;
+ int n = 4;
+ while (lbm_type_of(curr) == LBM_PTR_TYPE_CONS && n > 0) {
+ if (n < 4) r = r << 8;
+ if (lbm_is_number(lbm_car(curr))) {
+ uint32_t v = lbm_dec_as_u(lbm_car(curr));
+ r |= v;
+ n --;
+ curr = lbm_cdr(curr);
+ } else {
+ break;
+ }
+ }
+ memcpy(&f,&r, sizeof(lbm_uint));
+ result = lbm_enc_F(f);
+ }
+ break;
case SYM_IS_FUNDAMENTAL:
if (nargs < 1 ||
lbm_type_of(args[0]) != LBM_VAL_TYPE_SYMBOL)
@@ -583,7 +674,7 @@ lbm_value lbm_fundamental(lbm_value* args, lbm_uint nargs, lbm_value op) {
}
for (int i = n-1; i >= 0; i --) {
- result = lbm_cons(index_list(a,i), result);
+ result = lbm_cons(index_list(a,(unsigned int)i), result);
if (lbm_type_of(result) == LBM_VAL_TYPE_SYMBOL)
break;
}
@@ -723,10 +814,9 @@ lbm_value lbm_fundamental(lbm_value* args, lbm_uint nargs, lbm_value op) {
case SYM_ARRAY_WRITE:
array_write(args, nargs, &result);
break;
- case SYM_ARRAY_CREATE:
- array_create(args, nargs, &result);
- break;
-
+// case SYM_ARRAY_CREATE:
+// array_create(args, nargs, &result);
+// break;
case SYM_TYPE_OF:
if (nargs != 1) return lbm_enc_sym(SYM_NIL);
lbm_value val = args[0];
diff --git a/lispBM/lispBM/src/heap.c b/lispBM/lispBM/src/heap.c
index 0ce73a4f..8711be38 100644
--- a/lispBM/lispBM/src/heap.c
+++ b/lispBM/lispBM/src/heap.c
@@ -20,11 +20,11 @@
#include
#include
#include
+#include
#include "heap.h"
#include "symrepr.h"
#include "stack.h"
-#include "lispbm_memory.h"
#ifdef VISUALIZE_HEAP
#include "heap_vis.h"
#endif
@@ -41,7 +41,7 @@ char *lbm_dec_str(lbm_value val) {
lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(val);
if (array->elt_type == LBM_VAL_TYPE_CHAR) {
- res = (char *)array + 8;
+ res = (char *)array->data;
}
}
return res;
@@ -62,6 +62,8 @@ lbm_uint lbm_dec_as_u(lbm_value a) {
lbm_float f_tmp;
switch (lbm_type_of(a)) {
+ case LBM_VAL_TYPE_CHAR:
+ return (lbm_uint) lbm_dec_char(a);
case LBM_VAL_TYPE_I:
return (lbm_uint) lbm_dec_i(a);
case LBM_VAL_TYPE_U:
@@ -83,6 +85,8 @@ lbm_int lbm_dec_as_i(lbm_value a) {
lbm_float f_tmp;
switch (lbm_type_of(a)) {
+ case LBM_VAL_TYPE_CHAR:
+ return (lbm_int) lbm_dec_char(a);
case LBM_VAL_TYPE_I:
return lbm_dec_i(a);
case LBM_VAL_TYPE_U:
@@ -104,6 +108,8 @@ lbm_float lbm_dec_as_f(lbm_value a) {
lbm_float f_tmp;
switch (lbm_type_of(a)) {
+ case LBM_VAL_TYPE_CHAR:
+ return (lbm_float) lbm_dec_char(a);
case LBM_VAL_TYPE_I:
return (lbm_float) lbm_dec_i(a);
case LBM_VAL_TYPE_U:
@@ -429,8 +435,10 @@ int lbm_gc_sweep_phase(void) {
if (lbm_type_of(heap[i].cdr) == LBM_VAL_TYPE_SYMBOL &&
lbm_dec_sym(heap[i].cdr) == SYM_ARRAY_TYPE) {
lbm_array_header_t *arr = (lbm_array_header_t*)heap[i].car;
- lbm_memory_free((uint32_t *)arr);
- heap_state.gc_recovered_arrays++;
+ if (lbm_memory_ptr_inside((uint32_t*)arr)) {
+ lbm_memory_free((uint32_t *)arr);
+ heap_state.gc_recovered_arrays++;
+ }
}
// create pointer to use as new freelist
@@ -609,10 +617,12 @@ int lbm_heap_allocate_array(lbm_value *res, unsigned int size, lbm_type type){
allocate_size = size;
}
- array = (lbm_array_header_t*)lbm_memory_allocate(2 + allocate_size);
+ array = (lbm_array_header_t*)lbm_memory_allocate(sizeof(lbm_array_header_t) / 4);
if (array == NULL) return 0;
+ array->data = (uint32_t*)lbm_memory_allocate(allocate_size);
+
array->elt_type = type;
array->size = size;
diff --git a/lispBM/lispBM/src/lbm_c_interop.c b/lispBM/lispBM/src/lbm_c_interop.c
new file mode 100644
index 00000000..70af0946
--- /dev/null
+++ b/lispBM/lispBM/src/lbm_c_interop.c
@@ -0,0 +1,178 @@
+/*
+ Copyright 2022 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "lbm_c_interop.h"
+
+
+
+/****************************************************/
+/* Interface for loading and running programs and */
+/* expressions */
+
+lbm_cid eval_cps_load_and_eval(lbm_tokenizer_char_stream_t *tokenizer, bool program) {
+
+ lbm_value stream = lbm_create_token_stream(tokenizer);
+
+ if (lbm_type_of(stream) == LBM_VAL_TYPE_SYMBOL) {
+ // TODO: Check what should be done.
+ return 0;
+ }
+
+ /* LISP ZONE */
+
+ lbm_value launcher = lbm_cons(stream, lbm_enc_sym(SYM_NIL));
+ launcher = lbm_cons(lbm_enc_sym(program ? SYM_READ_PROGRAM : SYM_READ), launcher);
+ lbm_value evaluator = lbm_cons(launcher, lbm_enc_sym(SYM_NIL));
+ evaluator = lbm_cons(lbm_enc_sym(program ? SYM_EVAL_PROGRAM : SYM_EVAL), evaluator);
+ lbm_value start_prg = lbm_cons(evaluator, lbm_enc_sym(SYM_NIL));
+
+ /* LISP ZONE ENDS */
+
+ if (lbm_type_of(launcher) != LBM_PTR_TYPE_CONS ||
+ lbm_type_of(evaluator) != LBM_PTR_TYPE_CONS ||
+ lbm_type_of(start_prg) != LBM_PTR_TYPE_CONS ) {
+ lbm_memory_free((uint32_t*)stream);
+ return 0;
+ }
+ return lbm_create_ctx(start_prg, lbm_enc_sym(SYM_NIL), 256);
+}
+
+lbm_cid eval_cps_load_and_define(lbm_tokenizer_char_stream_t *tokenizer, char *symbol, bool program) {
+
+ lbm_value stream = lbm_create_token_stream(tokenizer);
+
+ if (lbm_type_of(stream) == LBM_VAL_TYPE_SYMBOL) {
+ return 0;
+ }
+
+ lbm_uint sym_id;
+
+ if (!lbm_get_symbol_by_name(symbol, &sym_id)) {
+ if (!lbm_add_symbol(symbol, &sym_id)) {
+ lbm_memory_free((uint32_t*)stream);
+ return 0;
+ }
+ }
+
+ /* LISP ZONE */
+
+ lbm_value launcher = lbm_cons(stream, lbm_enc_sym(SYM_NIL));
+ launcher = lbm_cons(lbm_enc_sym(program ? SYM_READ_PROGRAM : SYM_READ), launcher);
+ lbm_value binding = lbm_cons(launcher, lbm_enc_sym(SYM_NIL));
+ binding = lbm_cons(lbm_enc_sym(sym_id), binding);
+ lbm_value definer = lbm_cons(lbm_enc_sym(SYM_DEFINE), binding);
+ definer = lbm_cons(definer, lbm_enc_sym(SYM_NIL));
+ /* LISP ZONE ENDS */
+
+ if (lbm_type_of(launcher) != LBM_PTR_TYPE_CONS ||
+ lbm_type_of(binding) != LBM_PTR_TYPE_CONS ||
+ lbm_type_of(definer) != LBM_PTR_TYPE_CONS ) {
+ lbm_memory_free((uint32_t*)stream);
+ return 0;
+ }
+ return lbm_create_ctx(definer, lbm_enc_sym(SYM_NIL), 256);
+}
+
+lbm_cid lbm_eval_defined(char *symbol, bool program) {
+
+ lbm_uint sym_id;
+
+ if(!lbm_get_symbol_by_name(symbol, &sym_id)) {
+ // The symbol does not exist, so it cannot be defined
+ return 0;
+ }
+
+ lbm_value binding = lbm_env_lookup(lbm_enc_sym(sym_id), *lbm_get_env_ptr());
+
+ if (lbm_type_of(binding) == LBM_VAL_TYPE_SYMBOL &&
+ lbm_dec_sym(binding) == SYM_NOT_FOUND) {
+ return 0;
+ }
+
+ /* LISP ZONE */
+
+ lbm_value launcher = lbm_cons(lbm_enc_sym(sym_id), lbm_enc_sym(SYM_NIL));
+ lbm_value evaluator = launcher;
+ evaluator = lbm_cons(lbm_enc_sym(program ? SYM_EVAL_PROGRAM : SYM_EVAL), evaluator);
+ lbm_value start_prg = lbm_cons(evaluator, lbm_enc_sym(SYM_NIL));
+
+ /* LISP ZONE ENDS */
+
+ if (lbm_type_of(launcher) != LBM_PTR_TYPE_CONS ||
+ lbm_type_of(evaluator) != LBM_PTR_TYPE_CONS ||
+ lbm_type_of(start_prg) != LBM_PTR_TYPE_CONS ) {
+ return 0;
+ }
+ return lbm_create_ctx(start_prg, lbm_enc_sym(SYM_NIL), 256);
+}
+
+
+
+lbm_cid lbm_load_and_eval_expression(lbm_tokenizer_char_stream_t *tokenizer) {
+ return eval_cps_load_and_eval(tokenizer, false);
+}
+
+lbm_cid lbm_load_and_define_expression(lbm_tokenizer_char_stream_t *tokenizer, char *symbol) {
+ return eval_cps_load_and_define(tokenizer, symbol, false);
+}
+
+lbm_cid lbm_load_and_eval_program(lbm_tokenizer_char_stream_t *tokenizer) {
+ return eval_cps_load_and_eval(tokenizer, true);
+}
+
+lbm_cid lbm_load_and_define_program(lbm_tokenizer_char_stream_t *tokenizer, char *symbol) {
+ return eval_cps_load_and_define(tokenizer, symbol, true);
+}
+
+lbm_cid lbm_eval_defined_expression(char *symbol) {
+ return lbm_eval_defined(symbol, false);
+}
+
+lbm_cid lbm_eval_defined_program(char *symbol) {
+ return lbm_eval_defined(symbol, true);
+}
+
+int lbm_send_message(lbm_cid cid, lbm_value msg) {
+ int res = 0;
+
+ if (lbm_get_eval_state() == EVAL_CPS_STATE_PAUSED) {
+
+ lbm_value v = lbm_find_receiver_and_send(cid, msg);
+
+ if (lbm_type_of(v) == LBM_VAL_TYPE_SYMBOL &&
+ lbm_dec_sym(v) == SYM_TRUE) {
+ res = 1;
+ }
+ }
+ return res;
+}
+
+int lbm_define(char *symbol, lbm_value value) {
+ int res = 0;
+
+ lbm_uint sym_id;
+ if (lbm_get_eval_state() == EVAL_CPS_STATE_PAUSED) {
+
+ if (!lbm_get_symbol_by_name(symbol, &sym_id)) {
+ if (!lbm_add_symbol(symbol, &sym_id)) {
+ return 0;
+ }
+ }
+ lbm_env_set(lbm_get_env(), lbm_enc_sym(sym_id), value);
+ }
+ return res;
+}
diff --git a/lispBM/lispBM/src/lispbm_memory.c b/lispBM/lispBM/src/lbm_memory.c
similarity index 96%
rename from lispBM/lispBM/src/lispbm_memory.c
rename to lispBM/lispBM/src/lbm_memory.c
index 6211f5a1..7334ba94 100644
--- a/lispBM/lispBM/src/lispbm_memory.c
+++ b/lispBM/lispBM/src/lbm_memory.c
@@ -15,11 +15,11 @@
along with this program. If not, see .
*/
+#include
#include
#include
#include
-#include "lispbm_memory.h"
/* Status bit patterns */
#define FREE_OR_USED 0 //00b
@@ -227,3 +227,12 @@ int lbm_memory_free(uint32_t *ptr) {
return 0;
}
+
+int lbm_memory_ptr_inside(uint32_t *ptr) {
+ int r = 0;
+
+ if ((uint32_t)ptr >= (uint32_t)memory &&
+ (uint32_t)ptr < (uint32_t)memory + (memory_size * 4))
+ r = 1;
+ return r;
+}
diff --git a/lispBM/lispBM/src/print.c b/lispBM/lispBM/src/print.c
index 89d7811c..41b54d85 100644
--- a/lispBM/lispBM/src/print.c
+++ b/lispBM/lispBM/src/print.c
@@ -19,11 +19,11 @@
#include
#include
#include
+#include
#include "print.h"
#include "heap.h"
#include "symrepr.h"
-#include "lispbm_types.h"
#include "stack.h"
#define PRINT_STACK_SIZE 128 /* 1 KB */
@@ -246,7 +246,7 @@ int lbm_print_value(char *buf,unsigned int len, lbm_value t) {
lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(curr);
switch (array->elt_type){
case LBM_VAL_TYPE_CHAR:
- r = snprintf(buf + offset, len - offset, "\"%s\"", (char *)(array)+8);
+ r = snprintf(buf + offset, len - offset, "\"%s\"", (char *)array->data);
if ( r > 0) {
n = (unsigned int) r;
} else {
diff --git a/lispBM/lispBM/src/qq_expand.c b/lispBM/lispBM/src/qq_expand.c
index 9b091d46..f8bc2a2f 100644
--- a/lispBM/lispBM/src/qq_expand.c
+++ b/lispBM/lispBM/src/qq_expand.c
@@ -24,8 +24,8 @@
*/
+#include
#include "heap.h"
-#include "lispbm_types.h"
#include "symrepr.h"
#include "stack.h"
#include "qq_expand.h"
diff --git a/lispBM/lispBM/src/stack.c b/lispBM/lispBM/src/stack.c
index c51922e9..43bcdc8a 100644
--- a/lispBM/lispBM/src/stack.c
+++ b/lispBM/lispBM/src/stack.c
@@ -15,12 +15,12 @@
along with this program. If not, see .
*/
+#include
+#include
#include
#include "stack.h"
-#include "lispbm_types.h"
#include "print.h"
-#include "lispbm_memory.h"
int lbm_stack_allocate(lbm_stack_t *s, unsigned int stack_size) {
s->data = lbm_memory_allocate(stack_size);
diff --git a/lispBM/lispBM/src/symrepr.c b/lispBM/lispBM/src/symrepr.c
index 1d6d4f19..015c139c 100644
--- a/lispBM/lispBM/src/symrepr.c
+++ b/lispBM/lispBM/src/symrepr.c
@@ -20,11 +20,11 @@
#include
#include
#include
+#include
#include "symrepr.h"
-#include "lispbm_memory.h"
-#define NUM_SPECIAL_SYMBOLS 88
+#define NUM_SPECIAL_SYMBOLS 92
#define NAME 0
#define ID 1
@@ -124,7 +124,7 @@ special_sym const special_symbols[NUM_SPECIAL_SYMBOLS] = {
{"append" , SYM_APPEND},
{"array-read" , SYM_ARRAY_READ},
{"array-write" , SYM_ARRAY_WRITE},
- {"array-create" , SYM_ARRAY_CREATE},
+// {"array-create" , SYM_ARRAY_CREATE},
{"type-of" , SYM_TYPE_OF},
{"sym-to-str" , SYM_SYMBOL_TO_STRING},
{"str-to-sym" , SYM_STRING_TO_SYMBOL},
@@ -132,6 +132,23 @@ special_sym const special_symbols[NUM_SPECIAL_SYMBOLS] = {
{"u-to-sym" , SYM_UINT_TO_SYMBOL},
{"set-car" , SYM_SET_CAR},
{"set-cdr" , SYM_SET_CDR},
+
+ // Streams
+// {"stream-get" , SYM_STREAM_GET},
+// {"stream-more" , SYM_STREAM_MORE},
+// {"stream-peek" , SYM_STREAM_PEEK},
+// {"stream-drop" , SYM_STREAM_DROP},
+// {"stream-put" , SYM_STREAM_PUT},
+
+ // fast access in list
+ {"ix" , SYM_IX},
+
+ // Low-level
+ {"encode-i32" , SYM_ENCODE_I32},
+ {"encode-u32" , SYM_ENCODE_U32},
+ {"encode-float" , SYM_ENCODE_FLOAT},
+ {"decode" , SYM_DECODE},
+
{"is-fundamental" , SYM_IS_FUNDAMENTAL}
};
diff --git a/lispBM/lispBM/src/tokpar.c b/lispBM/lispBM/src/tokpar.c
index e9337f2d..42647445 100644
--- a/lispBM/lispBM/src/tokpar.c
+++ b/lispBM/lispBM/src/tokpar.c
@@ -18,16 +18,16 @@
#include
#include
#include
+#include
+#include
#include
#include
#include "tokpar.h"
#include "symrepr.h"
#include "heap.h"
-#include "lispbm_types.h"
#include "compression.h"
#include "qq_expand.h"
-#include "lispbm_memory.h"
#include "env.h"
#define NOTOKEN 0u
@@ -531,7 +531,7 @@ lbm_value lbm_get_next_token(lbm_tokenizer_char_stream_t *str) {
// TODO: Proper error checking here!
lbm_heap_allocate_array(&res, (unsigned int)(n-2)+1, LBM_VAL_TYPE_CHAR);
lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(res);
- char *data = (char *)arr + 8;
+ char *data = (char *)arr->data;
memset(data, 0, (unsigned int)((n-2)+1) * sizeof(char));
memcpy(data, sym_str, (unsigned int)(n - 2) * sizeof(char));
return res;
diff --git a/lispBM/lispBM/tests/test_decode_0.lisp b/lispBM/lispBM/tests/test_decode_0.lisp
new file mode 100644
index 00000000..8044b723
--- /dev/null
+++ b/lispBM/lispBM/tests/test_decode_0.lisp
@@ -0,0 +1,2 @@
+
+(= '(0u28 0u28 255u28 255u28) (decode (- 65536 1)))
diff --git a/lispBM/lispBM/tests/test_encode_0.lisp b/lispBM/lispBM/tests/test_encode_0.lisp
new file mode 100644
index 00000000..179b975f
--- /dev/null
+++ b/lispBM/lispBM/tests/test_encode_0.lisp
@@ -0,0 +1 @@
+(= 12345678i32 (encode-i32 (decode 12345678i32)))
diff --git a/lispBM/lispBM/tests/test_encode_1.lisp b/lispBM/lispBM/tests/test_encode_1.lisp
new file mode 100644
index 00000000..d03518dd
--- /dev/null
+++ b/lispBM/lispBM/tests/test_encode_1.lisp
@@ -0,0 +1 @@
+(= 3.14 (encode-float (decode 3.14)))
diff --git a/lispBM/lispBM/tests/test_encode_2.lisp b/lispBM/lispBM/tests/test_encode_2.lisp
new file mode 100644
index 00000000..218918f3
--- /dev/null
+++ b/lispBM/lispBM/tests/test_encode_2.lisp
@@ -0,0 +1 @@
+(= 999999u32 (encode-u32 (decode 999999u32)))
diff --git a/lispBM/lispBM/tests/test_ix_0.lisp b/lispBM/lispBM/tests/test_ix_0.lisp
new file mode 100644
index 00000000..8a210c62
--- /dev/null
+++ b/lispBM/lispBM/tests/test_ix_0.lisp
@@ -0,0 +1 @@
+(= 7 (ix 3 '(1 2 0 7 3 2 1)))
diff --git a/lispBM/lispBM/tests/test_ix_1.lisp b/lispBM/lispBM/tests/test_ix_1.lisp
new file mode 100644
index 00000000..f5cf7b93
--- /dev/null
+++ b/lispBM/lispBM/tests/test_ix_1.lisp
@@ -0,0 +1 @@
+(= nil (ix 100000 '(1 2)))
diff --git a/lispBM/lispBM/tests/test_ix_2.lisp b/lispBM/lispBM/tests/test_ix_2.lisp
new file mode 100644
index 00000000..99b45230
--- /dev/null
+++ b/lispBM/lispBM/tests/test_ix_2.lisp
@@ -0,0 +1,2 @@
+(= 45 (ix 45 (iota 100)))
+
diff --git a/lispBM/lispBM/tests/test_lisp_code_cps.c b/lispBM/lispBM/tests/test_lisp_code_cps.c
index 107c6263..a7a21a88 100644
--- a/lispBM/lispBM/tests/test_lisp_code_cps.c
+++ b/lispBM/lispBM/tests/test_lisp_code_cps.c
@@ -25,16 +25,7 @@
#include
#include
-#include "heap.h"
-#include "symrepr.h"
-#include "eval_cps.h"
-#include "print.h"
-#include "tokpar.h"
-#include "prelude.h"
-#include "compression.h"
-#include "lispbm_memory.h"
-#include "env.h"
-#include "extensions.h"
+#include "lispbm.h"
#define EVAL_CPS_STACK_SIZE 256
diff --git a/lispBM/lispBM/tests/test_match_2.lisp b/lispBM/lispBM/tests/test_match_2.lisp
index 17dc8a40..218bc30d 100644
--- a/lispBM/lispBM/tests/test_match_2.lisp
+++ b/lispBM/lispBM/tests/test_match_2.lisp
@@ -2,7 +2,7 @@
(define f (lambda (ls)
(match ls
( nil 0 )
- ( (?cons c) (+ (car c) (f (cdr c))))
+ ( ((? x) . (? xs)) (+ x (f xs)))
( _ 'error-not-a-list))))
(= (f '(1 2 3 4)) 10)
diff --git a/lispBM/lispBM/tests/test_read_0.lisp b/lispBM/lispBM/tests/test_read_0.lisp
new file mode 100644
index 00000000..d1e24629
--- /dev/null
+++ b/lispBM/lispBM/tests/test_read_0.lisp
@@ -0,0 +1 @@
+(= (read "1") 1)
\ No newline at end of file
diff --git a/lispBM/lispBM/tests/test_read_1.lisp b/lispBM/lispBM/tests/test_read_1.lisp
new file mode 100644
index 00000000..509b2926
--- /dev/null
+++ b/lispBM/lispBM/tests/test_read_1.lisp
@@ -0,0 +1 @@
+(= (eval (read "(+ 1 2)")) 3)
\ No newline at end of file
diff --git a/lispBM/lispBM/tests/test_read_2.lisp b/lispBM/lispBM/tests/test_read_2.lisp
new file mode 100644
index 00000000..f8677700
--- /dev/null
+++ b/lispBM/lispBM/tests/test_read_2.lisp
@@ -0,0 +1,4 @@
+
+(define prg "(define a 10) (+ a 10)")
+
+(= (eval-program (read-program prg)) 20)
\ No newline at end of file