mirror of https://github.com/rusefi/bldc.git
148 lines
3.4 KiB
C
148 lines
3.4 KiB
C
|
/*
|
||
|
Copyright 2023 Rasmus Söderhielm rasmus.soderhielm@gmail.com
|
||
|
|
||
|
This file is part of the VESC firmware.
|
||
|
|
||
|
The VESC firmware 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.
|
||
|
|
||
|
The VESC firmware 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 <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include <stdbool.h>
|
||
|
|
||
|
#include "symrepr.h"
|
||
|
#include "lbm_defines.h"
|
||
|
#include "lbm_types.h"
|
||
|
#include "heap.h"
|
||
|
#include "eval_cps.h"
|
||
|
#include "lbm_flat_value.h"
|
||
|
#include "commands.h"
|
||
|
|
||
|
#include "lbm_vesc_utils.h"
|
||
|
|
||
|
bool lbm_add_symbol_const_if_new(char *name, lbm_uint *id) {
|
||
|
if (!lbm_get_symbol_by_name(name, id) && !lbm_add_symbol_const(name, id)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
lbm_array_header_t *lbm_dec_array_header(lbm_value value) {
|
||
|
if (!lbm_is_array_r(value)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return (lbm_array_header_t *)lbm_car(value);
|
||
|
}
|
||
|
|
||
|
void *lbm_dec_array_data(lbm_value value) {
|
||
|
if (!lbm_is_array_r(value)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
lbm_array_header_t *header = lbm_dec_array_header(value);
|
||
|
if (!header->data) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return header->data;
|
||
|
}
|
||
|
|
||
|
lbm_value lbm_allocate_empty_list(lbm_uint len) {
|
||
|
lbm_value res = ENC_SYM_NIL;
|
||
|
for (lbm_uint i = 0; i < len; i++) {
|
||
|
res = lbm_cons(ENC_SYM_NIL, res);
|
||
|
if (res == ENC_SYM_MERROR) {
|
||
|
return ENC_SYM_MERROR;
|
||
|
}
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
lbm_value lbm_allocate_empty_list_grid(lbm_uint height, lbm_uint width) {
|
||
|
lbm_value outer = ENC_SYM_NIL;
|
||
|
for (lbm_uint i = 0; i < height; i++) {
|
||
|
lbm_value inner = ENC_SYM_NIL;
|
||
|
for (lbm_uint j = 0; j < width; j++) {
|
||
|
inner = lbm_cons(ENC_SYM_NIL, inner);
|
||
|
if (inner == ENC_SYM_MERROR) {
|
||
|
return ENC_SYM_MERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
outer = lbm_cons(inner, outer);
|
||
|
if (outer == ENC_SYM_MERROR) {
|
||
|
return ENC_SYM_MERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return outer;
|
||
|
}
|
||
|
|
||
|
bool lbm_memory_shrink_bytes(void *array, lbm_uint size_bytes) {
|
||
|
lbm_uint size_words = size_bytes / LBM_WORD_SIZE;
|
||
|
if (size_bytes % LBM_WORD_SIZE != 0) {
|
||
|
size_words += 1;
|
||
|
}
|
||
|
|
||
|
return lbm_memory_shrink((lbm_uint *)array, size_words) > 0;
|
||
|
}
|
||
|
|
||
|
bool lbm_array_shrink(lbm_value array, lbm_uint new_size) {
|
||
|
if (!lbm_is_array_rw(array)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
lbm_array_header_t *header = (lbm_array_header_t *)lbm_car(array);
|
||
|
|
||
|
if (!lbm_memory_shrink_bytes(header->data, new_size)) {
|
||
|
return false;
|
||
|
}
|
||
|
header->size = new_size;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
extern const char *lbm_error_str_num_args;
|
||
|
bool lbm_check_argn_range(lbm_uint argn, lbm_uint n_min, lbm_uint n_max) {
|
||
|
if (!(n_min <= argn && argn <= n_max)) {
|
||
|
lbm_set_error_reason((char *)lbm_error_str_num_args);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool lbm_check_argn_least(lbm_uint argn, lbm_uint n_min) {
|
||
|
if (!(n_min <= argn)) {
|
||
|
lbm_set_error_reason((char *)lbm_error_str_num_args);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool f_pack_array(lbm_flat_value_t *result, void *data, size_t size) {
|
||
|
if (!lbm_start_flatten(result, 5 + size)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (!f_lbm_array(result, size, data)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (!lbm_finish_flatten(result)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|