mirror of https://github.com/rusefi/bldc.git
Merge commit 'dccfe151354c45e77946b6b41a09d97b521c14e4'
This commit is contained in:
commit
3f2d79394c
|
@ -1,7 +1,14 @@
|
|||
# lispBM (LBM)
|
||||
|
||||
A concurrent lisp-like language with message-passing and
|
||||
pattern-matching implemented in C for 32 bit and 64 bit platforms.
|
||||
LispBM is a lisp or scheme like programming language for
|
||||
microcontrollers. LispBM also borrows a couple of ideas from Erlang
|
||||
when it comes to concurrency, message passing, pattern matching and
|
||||
process monitoring. The LispBM runtime system can be compiled for
|
||||
either 32 or 64 bit platforms and runs on a wide range of hardware
|
||||
such as for example STM32, NRF52, ESP32 or X86. When running the
|
||||
LispBM runtime system on a microcontroller it can be built on top of
|
||||
ChibiOS, FreeRTOS or ZephyrOS and it can also be built to run on top
|
||||
of a regular linux.
|
||||
|
||||
![LispBM mascot](https://github.com/svenssonjoel/lispBM/blob/master/mascot/lispbm_llama_small.png)
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ for bench in benches:
|
|||
lgd = plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
|
||||
ax = plt.gca()
|
||||
for tick in ax.get_xticklabels():
|
||||
tick.set_rotation(45)
|
||||
tick.set_rotation(90)
|
||||
ax.tick_params(axis='both', which='major', labelsize=6)
|
||||
ax.tick_params(axis='both', which='minor', labelsize=4)
|
||||
plt.ylabel("Sec")
|
||||
plt.grid()
|
||||
plt.savefig('benchresults.png', dpi=600, bbox_extra_artists=(lgd,), bbox_inches='tight')
|
||||
|
|
|
@ -347,53 +347,6 @@ the argument.
|
|||
|
||||
## Low level operations
|
||||
|
||||
### encode-i32
|
||||
|
||||
The `encode-i32` function converts a list of four (byte sized) values
|
||||
into an i32 value.
|
||||
|
||||
Example that evaluates to the i32 value 1024.
|
||||
```clj
|
||||
(encode-i32 (list 0 0 4 0))
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
### encode-u32
|
||||
|
||||
The `encode-u32` function converts a list of four (byte sized) values
|
||||
into an u32 value.
|
||||
|
||||
Example that evaluates to the u32 value 1024.
|
||||
```clj
|
||||
(encode-u32 (list 0 0 4 0))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### encode-float
|
||||
|
||||
The `encode-float` function converts a list four (byte sized) values
|
||||
into a float value.
|
||||
|
||||
Example that evaluates to 3.14.
|
||||
```clj
|
||||
(encode-float (list 64 72 245 195))
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
### decode
|
||||
|
||||
The `decode` function decodes a value into a list of four (byte sized) values.
|
||||
|
||||
Example that decodes float 3.14 into the list (64 72 245 195).
|
||||
```clj
|
||||
(decode 3.14)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## nil and t
|
||||
|
|
|
@ -141,16 +141,6 @@ void lbm_pause_eval(void);
|
|||
* \param num_free Perform GC if there are less than this many elements free on the heap.
|
||||
*/
|
||||
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
|
||||
* EVAL_CPS_STATE_PUASED state.
|
||||
*/
|
||||
void lbm_step_eval(void);
|
||||
/** Perform multiple steps of evaluation.
|
||||
* \param n Number of eval steps to perform.
|
||||
*/
|
||||
void lbm_step_n_eval(uint32_t n);
|
||||
/** Resume from being in EVAL_CPS_STATE_PAUSED.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -833,12 +833,6 @@ int main(int argc, char **argv) {
|
|||
} else if (strncmp(str, ":continue", 9) == 0) {
|
||||
lbm_continue_eval();
|
||||
free(str);
|
||||
} else if (strncmp(str, ":step", 5) == 0) {
|
||||
|
||||
int num = atoi(str + 5);
|
||||
|
||||
lbm_step_n_eval((uint32_t)num);
|
||||
free(str);
|
||||
} else if (strncmp(str, ":inspect", 8) == 0) {
|
||||
|
||||
int i = 8;
|
||||
|
|
|
@ -137,9 +137,10 @@ void lbm_set_eval_step_quota(uint32_t quota) {
|
|||
eval_steps_refill = quota;
|
||||
}
|
||||
|
||||
static uint32_t eval_cps_run_state = EVAL_CPS_STATE_INIT;
|
||||
static volatile uint32_t eval_cps_next_state = EVAL_CPS_STATE_INIT;
|
||||
static uint32_t eval_cps_run_state = EVAL_CPS_STATE_RUNNING;
|
||||
static volatile uint32_t eval_cps_next_state = EVAL_CPS_STATE_RUNNING;
|
||||
static volatile uint32_t eval_cps_next_state_arg = 0;
|
||||
static volatile bool eval_cps_state_changed = false;
|
||||
|
||||
/*
|
||||
On ChibiOs the CH_CFG_ST_FREQUENCY setting in chconf.h sets the
|
||||
|
@ -2884,29 +2885,23 @@ static void evaluation_step(void){
|
|||
void lbm_pause_eval(void ) {
|
||||
eval_cps_next_state_arg = 0;
|
||||
eval_cps_next_state = EVAL_CPS_STATE_PAUSED;
|
||||
if (eval_cps_next_state != eval_cps_run_state) eval_cps_state_changed = true;
|
||||
}
|
||||
|
||||
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_arg = 1;
|
||||
eval_cps_next_state = EVAL_CPS_STATE_STEP;
|
||||
}
|
||||
|
||||
void lbm_step_n_eval(uint32_t n) {
|
||||
eval_cps_next_state_arg = n;
|
||||
eval_cps_next_state = EVAL_CPS_STATE_STEP;
|
||||
if (eval_cps_next_state != eval_cps_run_state) eval_cps_state_changed = true;
|
||||
}
|
||||
|
||||
void lbm_continue_eval(void) {
|
||||
eval_cps_next_state = EVAL_CPS_STATE_RUNNING;
|
||||
if (eval_cps_next_state != eval_cps_run_state) eval_cps_state_changed = true;
|
||||
}
|
||||
|
||||
void lbm_kill_eval(void) {
|
||||
eval_cps_next_state = EVAL_CPS_STATE_KILL;
|
||||
if (eval_cps_next_state != eval_cps_run_state) eval_cps_state_changed = true;
|
||||
}
|
||||
|
||||
uint32_t lbm_get_eval_state(void) {
|
||||
|
@ -2920,19 +2915,8 @@ uint32_t lbm_get_eval_state(void) {
|
|||
void lbm_run_eval(void){
|
||||
|
||||
while (eval_running) {
|
||||
|
||||
eval_cps_state_changed = false;
|
||||
switch (eval_cps_next_state) {
|
||||
case EVAL_CPS_STATE_INIT:
|
||||
eval_cps_run_state = EVAL_CPS_STATE_RUNNING;
|
||||
break;
|
||||
case EVAL_CPS_STATE_STEP:
|
||||
if (eval_cps_next_state_arg > 1) {
|
||||
eval_cps_next_state = EVAL_CPS_STATE_STEP;
|
||||
eval_cps_next_state_arg --;
|
||||
} else {
|
||||
eval_cps_next_state = EVAL_CPS_STATE_PAUSED;
|
||||
}
|
||||
break;
|
||||
case EVAL_CPS_STATE_PAUSED:
|
||||
if (eval_cps_run_state != EVAL_CPS_STATE_PAUSED) {
|
||||
if (lbm_heap_num_free() < eval_cps_next_state_arg) {
|
||||
|
@ -2946,46 +2930,49 @@ void lbm_run_eval(void){
|
|||
case EVAL_CPS_STATE_KILL:
|
||||
eval_running = false;
|
||||
continue;
|
||||
default:
|
||||
default: // running state
|
||||
eval_cps_run_state = eval_cps_next_state;
|
||||
break;
|
||||
}
|
||||
|
||||
eval_context_t *next_to_run = NULL;
|
||||
if (eval_steps_quota <= 0 || !ctx_running) {
|
||||
uint32_t us = EVAL_CPS_MIN_SLEEP;
|
||||
|
||||
if (is_atomic) {
|
||||
if (ctx_running) {
|
||||
next_to_run = ctx_running;
|
||||
ctx_running = NULL;
|
||||
} else {
|
||||
is_atomic = false;
|
||||
// This is not right!
|
||||
// but there is no context available to
|
||||
// report an error in.
|
||||
}
|
||||
while (true) {
|
||||
eval_context_t *next_to_run = NULL;
|
||||
if (eval_steps_quota && ctx_running) {
|
||||
eval_steps_quota--;
|
||||
evaluation_step();
|
||||
} else {
|
||||
next_to_run = dequeue_ctx(&sleeping, &us);
|
||||
}
|
||||
if (eval_cps_state_changed) break;
|
||||
uint32_t us = EVAL_CPS_MIN_SLEEP;
|
||||
|
||||
if (!next_to_run) {
|
||||
next_to_run = enqueue_dequeue_ctx(&queue, ctx_running);
|
||||
} else if (ctx_running) {
|
||||
enqueue_ctx(&queue, ctx_running);
|
||||
}
|
||||
if (is_atomic) {
|
||||
if (ctx_running) {
|
||||
next_to_run = ctx_running;
|
||||
ctx_running = NULL;
|
||||
} else {
|
||||
is_atomic = false;
|
||||
// This is not right!
|
||||
// but there is no context available to
|
||||
// report an error in.
|
||||
}
|
||||
} else {
|
||||
next_to_run = dequeue_ctx(&sleeping, &us);
|
||||
}
|
||||
|
||||
eval_steps_quota = eval_steps_refill;
|
||||
ctx_running = next_to_run;
|
||||
if (!next_to_run) {
|
||||
next_to_run = enqueue_dequeue_ctx(&queue, ctx_running);
|
||||
} else if (ctx_running) {
|
||||
enqueue_ctx(&queue, ctx_running);
|
||||
}
|
||||
|
||||
if (!ctx_running) {
|
||||
usleep_callback(us);
|
||||
continue;
|
||||
eval_steps_quota = eval_steps_refill;
|
||||
ctx_running = next_to_run;
|
||||
|
||||
if (!ctx_running) {
|
||||
usleep_callback(us);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eval_steps_quota--;
|
||||
evaluation_step();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3010,7 +2997,7 @@ int lbm_eval_init() {
|
|||
done.last = NULL;
|
||||
ctx_running = NULL;
|
||||
|
||||
eval_cps_run_state = EVAL_CPS_STATE_INIT;
|
||||
eval_cps_run_state = EVAL_CPS_STATE_RUNNING;
|
||||
|
||||
mutex_init(&qmutex);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2018,2020 Joel Svensson svenssonjoel@yahoo.se
|
||||
Copyright 2018,2020 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
|
||||
|
@ -109,8 +109,8 @@ bool dyn_load(const char *str, const char **code) {
|
|||
} else if (strlen(str) == 7 && strncmp(str, "reverse", 7) == 0) {
|
||||
*code = "(define reverse (lambda (xs)"
|
||||
"(let ((revacc (lambda (acc xs)"
|
||||
"(if (eq nil xs) acc"
|
||||
"(revacc (cons (car xs) acc) (cdr xs))))))"
|
||||
"(if (eq nil xs) acc"
|
||||
"(revacc (cons (car xs) acc) (cdr xs))))))"
|
||||
"(revacc nil xs))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 4 && strncmp(str, "iota", 4) == 0) {
|
||||
|
@ -122,45 +122,45 @@ bool dyn_load(const char *str, const char **code) {
|
|||
res = true;
|
||||
} else if (strlen(str) == 6 && strncmp(str, "length", 6) == 0) {
|
||||
*code = "(define length (lambda (xs)"
|
||||
"(let ((len (lambda (l xs)"
|
||||
"(if (eq xs nil) l"
|
||||
"(len (+ l 1) (cdr xs))))))"
|
||||
"(let ((len (lambda (l xs)"
|
||||
"(if (eq xs nil) l"
|
||||
"(len (+ l 1) (cdr xs))))))"
|
||||
"(len 0 xs))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 4 && strncmp(str, "take", 4) == 0) {
|
||||
*code = "(define take (lambda (n xs)"
|
||||
"(let ((take-tail (lambda (acc n xs)"
|
||||
"(if (= n 0) acc"
|
||||
"(take-tail (cons (car xs) acc) (- n 1) (cdr xs))))))"
|
||||
"(let ((take-tail (lambda (acc n xs)"
|
||||
"(if (= n 0) acc"
|
||||
"(take-tail (cons (car xs) acc) (- n 1) (cdr xs))))))"
|
||||
"(reverse (take-tail nil n xs)))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 4 && strncmp(str, "drop", 4) == 0) {
|
||||
*code = "(define drop (lambda (n xs)"
|
||||
"(if (= n 0) xs"
|
||||
"(if (eq xs nil) nil"
|
||||
"(if (= n 0) xs"
|
||||
"(if (eq xs nil) nil"
|
||||
"(drop (- n 1) (cdr xs))))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 3 && strncmp(str, "zip", 3) == 0) {
|
||||
*code = "(define zip (lambda (xs ys)"
|
||||
"(if (eq xs nil) nil"
|
||||
"(if (eq ys nil) nil"
|
||||
"(if (eq xs nil) nil"
|
||||
"(if (eq ys nil) nil"
|
||||
"(cons (cons (car xs) (car ys)) (zip (cdr xs) (cdr ys)))))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 3 && strncmp(str, "map", 3) == 0) {
|
||||
*code = "(define map (lambda (f xs)"
|
||||
"(if (eq xs nil) nil"
|
||||
"(if (eq xs nil) nil"
|
||||
"(cons (f (car xs)) (map f (cdr xs))))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 6 && strncmp(str, "lookup", 6) == 0) {
|
||||
*code = "(define lookup (lambda (x xs)"
|
||||
"(if (eq xs nil) nil"
|
||||
"(if (eq (car (car xs)) x)"
|
||||
"(car (cdr (car xs)))"
|
||||
"(if (eq xs nil) nil"
|
||||
"(if (eq (car (car xs)) x)"
|
||||
"(car (cdr (car xs)))"
|
||||
"(lookup x (cdr xs))))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 5 && strncmp(str, "foldr", 5) == 0) {
|
||||
*code = "(define foldr (lambda (f i xs)"
|
||||
"(if (eq xs nil) i"
|
||||
"(if (eq xs nil) i"
|
||||
"(f (car xs) (foldr f i (cdr xs))))))";
|
||||
res = true;
|
||||
} else if (strlen(str) == 5 && strncmp(str, "foldl", 5) == 0) {
|
||||
|
@ -212,7 +212,7 @@ LBM_EXTENSION(ext_numbers, args, argn) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return lbm_enc_sym(b ? SYM_TRUE : SYM_NIL);
|
||||
return lbm_enc_sym(b ? SYM_TRUE : SYM_NIL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,7 +225,7 @@ int main(int argc, char **argv) {
|
|||
// bool compress_decompress = false;
|
||||
|
||||
bool stream_source = false;
|
||||
|
||||
|
||||
pthread_t lispbm_thd;
|
||||
lbm_cons_t *heap_storage = NULL;
|
||||
|
||||
|
@ -378,7 +378,7 @@ int main(int argc, char **argv) {
|
|||
printf("Error adding extension.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
lbm_set_dynamic_load_callback(dyn_load);
|
||||
lbm_set_timestamp_us_callback(timestamp_callback);
|
||||
lbm_set_usleep_callback(sleep_callback);
|
||||
|
@ -427,6 +427,11 @@ int main(int argc, char **argv) {
|
|||
//lbm_create_char_stream_from_string(&string_tok_state,
|
||||
// &string_tok,
|
||||
// code_buffer);
|
||||
|
||||
lbm_pause_eval_with_gc(20);
|
||||
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED) {
|
||||
sleep_callback(1000);
|
||||
}
|
||||
if (stream_source) {
|
||||
lbm_create_buffered_char_channel(&buffered_tok_state,
|
||||
&string_tok);
|
||||
|
@ -455,7 +460,7 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
}
|
||||
int ch_res = lbm_channel_write(&string_tok, code_buffer[i]);
|
||||
|
||||
|
||||
if (ch_res == CHANNEL_SUCCESS) {
|
||||
//printf("wrote: %c\n", code_buffer[i]);
|
||||
i ++;
|
||||
|
|
Loading…
Reference in New Issue