1 |
|
|
/* |
2 |
|
|
Copyright 2019, 2021, 2022, 2024 Joel Svensson svenssonjoel@yahoo.se |
3 |
|
|
2022 Benjamin Vedder |
4 |
|
|
|
5 |
|
|
This program is free software: you can redistribute it and/or modify |
6 |
|
|
it under the terms of the GNU General Public License as published by |
7 |
|
|
the Free Software Foundation, either version 3 of the License, or |
8 |
|
|
(at your option) any later version. |
9 |
|
|
|
10 |
|
|
This program is distributed in the hope that it will be useful, |
11 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
|
|
GNU General Public License for more details. |
14 |
|
|
|
15 |
|
|
You should have received a copy of the GNU General Public License |
16 |
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 |
|
|
*/ |
18 |
|
|
|
19 |
|
|
#include <lbm_memory.h> |
20 |
|
|
#include <stdio.h> |
21 |
|
|
#include <stdlib.h> |
22 |
|
|
#include <stdbool.h> |
23 |
|
|
#include <string.h> |
24 |
|
|
#include <eval_cps.h> |
25 |
|
|
|
26 |
|
|
#include "extensions.h" |
27 |
|
|
#include "lbm_utils.h" |
28 |
|
|
|
29 |
|
|
static lbm_uint ext_max = 0; |
30 |
|
|
static lbm_uint ext_num = 0; |
31 |
|
|
static lbm_uint next_extension_ix = 0; |
32 |
|
|
|
33 |
|
|
lbm_extension_t *extension_table = NULL; |
34 |
|
|
|
35 |
|
|
lbm_value lbm_extensions_default(lbm_value *args, lbm_uint argn) { |
36 |
|
|
(void)args; |
37 |
|
|
(void)argn; |
38 |
|
|
return ENC_SYM_EERROR; |
39 |
|
|
} |
40 |
|
|
|
41 |
|
21672 |
int lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) { |
42 |
✓✗✗✓
|
21672 |
if (extension_storage == NULL || extension_storage_size == 0) return 0; |
43 |
|
|
|
44 |
|
21672 |
extension_table = extension_storage; |
45 |
|
21672 |
memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size); |
46 |
|
|
|
47 |
✓✓ |
4356072 |
for (lbm_uint i = 0; i < extension_storage_size; i ++) { |
48 |
|
4334400 |
extension_storage[i].fptr = lbm_extensions_default; |
49 |
|
|
} |
50 |
|
|
|
51 |
|
21672 |
ext_num = 0; |
52 |
|
21672 |
next_extension_ix = 0; |
53 |
|
21672 |
ext_max = (lbm_uint)extension_storage_size; |
54 |
|
|
|
55 |
|
21672 |
return 1; |
56 |
|
|
} |
57 |
|
|
|
58 |
|
665630540 |
lbm_uint lbm_get_max_extensions(void) { |
59 |
|
665630540 |
return ext_max; |
60 |
|
|
} |
61 |
|
|
|
62 |
|
21672 |
lbm_uint lbm_get_num_extensions(void) { |
63 |
|
21672 |
return ext_num; |
64 |
|
|
} |
65 |
|
|
|
66 |
|
14 |
extension_fptr lbm_get_extension(lbm_uint sym) { |
67 |
|
14 |
lbm_uint ext_next = sym - EXTENSION_SYMBOLS_START; |
68 |
✗✓ |
14 |
if (ext_next >= ext_max) { |
69 |
|
|
return NULL; |
70 |
|
|
} |
71 |
|
14 |
return extension_table[ext_next].fptr; |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
bool lbm_clr_extension(lbm_uint sym_id) { |
75 |
|
|
lbm_uint ext_id = SYMBOL_IX(sym_id); |
76 |
|
|
if (ext_id >= ext_max) { |
77 |
|
|
return false; |
78 |
|
|
} |
79 |
|
|
extension_table[ext_id].name = NULL; |
80 |
|
|
extension_table[ext_id].fptr = lbm_extensions_default; |
81 |
|
|
return true; |
82 |
|
|
} |
83 |
|
|
|
84 |
|
14 |
bool lbm_lookup_extension_id(char *sym_str, lbm_uint *ix) { |
85 |
✓✗ |
1498 |
for (lbm_uint i = 0; i < ext_max; i ++) { |
86 |
✓✗ |
1498 |
if(extension_table[i].name) { |
87 |
✓✓ |
1498 |
if (str_eq(extension_table[i].name, sym_str)) { |
88 |
|
14 |
*ix = i + EXTENSION_SYMBOLS_START; |
89 |
|
14 |
return true; |
90 |
|
|
} |
91 |
|
|
} |
92 |
|
|
} |
93 |
|
|
return false; |
94 |
|
|
} |
95 |
|
|
|
96 |
|
2297274 |
bool lbm_add_extension(char *sym_str, extension_fptr ext) { |
97 |
|
|
lbm_value symbol; |
98 |
|
|
|
99 |
|
|
// Check if symbol already exists. |
100 |
✓✓ |
2297274 |
if (lbm_get_symbol_by_name(sym_str, &symbol)) { |
101 |
✓✗ |
14 |
if (lbm_is_extension(lbm_enc_sym(symbol))) { |
102 |
|
|
// update the extension entry. |
103 |
✓✗ |
14 |
if (str_eq(extension_table[SYMBOL_IX(symbol)].name, sym_str)) { |
104 |
|
|
// Do not replace name ptr. |
105 |
|
14 |
extension_table[SYMBOL_IX(symbol)].fptr = ext; |
106 |
|
14 |
return true; |
107 |
|
|
} |
108 |
|
|
} |
109 |
|
|
return false; |
110 |
|
|
} |
111 |
|
|
|
112 |
✓✗ |
2297260 |
if (next_extension_ix < ext_max) { |
113 |
|
2297260 |
lbm_uint sym_ix = next_extension_ix ++; |
114 |
|
2297260 |
extension_table[sym_ix].name = sym_str; |
115 |
|
2297260 |
extension_table[sym_ix].fptr = ext; |
116 |
|
2297260 |
ext_num ++; |
117 |
|
2297260 |
return true; |
118 |
|
|
} |
119 |
|
|
return false; |
120 |
|
|
} |
121 |
|
|
|
122 |
|
|
// Helpers for extension developers: |
123 |
|
|
|
124 |
|
3360 |
static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) { |
125 |
✓✓ |
10836 |
for (lbm_uint i = 0;i < argn;i++) { |
126 |
✗✓ |
7476 |
if (!lbm_is_number(args[i])) { |
127 |
|
|
return false; |
128 |
|
|
} |
129 |
|
|
} |
130 |
|
3360 |
return true; |
131 |
|
|
} |
132 |
|
|
|
133 |
|
|
bool lbm_check_true_false(lbm_value v) { |
134 |
|
|
bool res = lbm_is_symbol_true(v) || lbm_is_symbol_nil(v); |
135 |
|
|
lbm_set_error_reason((char*)lbm_error_str_not_a_boolean); |
136 |
|
|
return res; |
137 |
|
|
} |
138 |
|
|
|
139 |
|
2408 |
bool lbm_check_number_all(lbm_value *args, lbm_uint argn) { |
140 |
✗✓ |
2408 |
if (!lbm_is_number_all(args, argn)) { |
141 |
|
|
lbm_set_error_reason((char*)lbm_error_str_no_number); |
142 |
|
|
return false; |
143 |
|
|
} |
144 |
|
2408 |
return true; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
84 |
bool lbm_check_argn(lbm_uint argn, lbm_uint n) { |
148 |
✓✓ |
84 |
if (argn != n) { |
149 |
|
28 |
lbm_set_error_reason((char*)lbm_error_str_num_args); |
150 |
|
28 |
return false; |
151 |
|
|
} else { |
152 |
|
56 |
return true; |
153 |
|
|
} |
154 |
|
|
} |
155 |
|
|
|
156 |
|
952 |
bool lbm_check_argn_number(lbm_value *args, lbm_uint argn, lbm_uint n) { |
157 |
✗✓ |
952 |
if (!lbm_is_number_all(args, argn)) { |
158 |
|
|
lbm_set_error_reason((char*)lbm_error_str_no_number); |
159 |
|
|
return false; |
160 |
✓✓ |
952 |
} else if (argn != n) { |
161 |
|
420 |
lbm_set_error_reason((char*)lbm_error_str_num_args); |
162 |
|
420 |
return false; |
163 |
|
|
} else { |
164 |
|
532 |
return true; |
165 |
|
|
} |
166 |
|
|
} |