1 |
|
|
/* |
2 |
|
|
Copyright 2018, 2021, 2022, 2024 Joel Svensson svenssonjoel@yahoo.se |
3 |
|
|
|
4 |
|
|
This program is free software: you can redistribute it and/or modify |
5 |
|
|
it under the terms of the GNU General Public License as published by |
6 |
|
|
the Free Software Foundation, either version 3 of the License, or |
7 |
|
|
(at your option) any later version. |
8 |
|
|
|
9 |
|
|
This program is distributed in the hope that it will be useful, |
10 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
|
|
GNU General Public License for more details. |
13 |
|
|
|
14 |
|
|
You should have received a copy of the GNU General Public License |
15 |
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 |
|
|
*/ |
17 |
|
|
|
18 |
|
|
#include <stdint.h> |
19 |
|
|
#include <stdio.h> |
20 |
|
|
#include <string.h> |
21 |
|
|
#include <stdlib.h> |
22 |
|
|
#include <inttypes.h> |
23 |
|
|
|
24 |
|
|
|
25 |
|
|
#include <lbm_memory.h> |
26 |
|
|
#include <heap.h> |
27 |
|
|
#include "symrepr.h" |
28 |
|
|
#include "extensions.h" |
29 |
|
|
#include "lbm_utils.h" |
30 |
|
|
|
31 |
|
|
#define NUM_SPECIAL_SYMBOLS (sizeof(special_symbols) / sizeof(special_sym)) |
32 |
|
|
#define NAME 0 |
33 |
|
|
#define ID 1 |
34 |
|
|
#define NEXT 2 |
35 |
|
|
|
36 |
|
|
typedef struct { |
37 |
|
|
const char *name; |
38 |
|
|
const lbm_uint id; |
39 |
|
|
} special_sym; |
40 |
|
|
|
41 |
|
|
special_sym const special_symbols[] = { |
42 |
|
|
{"nil" , SYM_NIL}, |
43 |
|
|
{"quote" , SYM_QUOTE}, |
44 |
|
|
{"t" , SYM_TRUE}, |
45 |
|
|
{"if" , SYM_IF}, |
46 |
|
|
{"cond" , SYM_COND}, |
47 |
|
|
{"lambda" , SYM_LAMBDA}, |
48 |
|
|
{"closure" , SYM_CLOSURE}, |
49 |
|
|
{"let" , SYM_LET}, |
50 |
|
|
{"define" , SYM_DEFINE}, |
51 |
|
|
{"progn" , SYM_PROGN}, |
52 |
|
|
{"read" , SYM_READ}, |
53 |
|
|
{"read-program" , SYM_READ_PROGRAM}, |
54 |
|
|
{"read-eval-program", SYM_READ_AND_EVAL_PROGRAM}, |
55 |
|
|
{"match" , SYM_MATCH}, |
56 |
|
|
{"_" , SYM_DONTCARE}, |
57 |
|
|
{"send" , SYM_SEND}, |
58 |
|
|
{"recv" , SYM_RECEIVE}, |
59 |
|
|
{"recv-to" , SYM_RECEIVE_TIMEOUT}, |
60 |
|
|
{"macro" , SYM_MACRO}, |
61 |
|
|
{"call-cc" , SYM_CALLCC}, |
62 |
|
|
{"continuation" , SYM_CONT}, |
63 |
|
|
{"var" , SYM_PROGN_VAR}, |
64 |
|
|
{"timeout" , SYM_TIMEOUT}, |
65 |
|
|
|
66 |
|
|
{"set" , SYM_SETVAR}, |
67 |
|
|
{"setq" , SYM_SETQ}, |
68 |
|
|
{"move-to-flash", SYM_MOVE_TO_FLASH}, |
69 |
|
|
{"exit-ok" , SYM_EXIT_OK}, |
70 |
|
|
{"exit-error" , SYM_EXIT_ERROR}, |
71 |
|
|
{"map" , SYM_MAP}, |
72 |
|
|
{"reverse" , SYM_REVERSE}, |
73 |
|
|
{"flatten" , SYM_FLATTEN}, |
74 |
|
|
{"unflatten" , SYM_UNFLATTEN}, |
75 |
|
|
{"kill" , SYM_KILL}, |
76 |
|
|
{"sleep" , SYM_SLEEP}, |
77 |
|
|
{"merge" , SYM_MERGE}, |
78 |
|
|
{"sort" , SYM_SORT}, |
79 |
|
|
{"gc" , SYM_PERFORM_GC}, |
80 |
|
|
{"loop" , SYM_LOOP}, |
81 |
|
|
{"trap" , SYM_TRAP}, |
82 |
|
|
{"rest-args" , SYM_REST_ARGS}, |
83 |
|
|
{"rotate" , SYM_ROTATE}, |
84 |
|
|
|
85 |
|
|
// pattern matching |
86 |
|
|
{"?" , SYM_MATCH_ANY}, |
87 |
|
|
|
88 |
|
|
// Error symbols with parsable names |
89 |
|
|
{"no_match" , SYM_NO_MATCH}, |
90 |
|
|
{"read_error" , SYM_RERROR}, |
91 |
|
|
{"type_error" , SYM_TERROR}, |
92 |
|
|
{"eval_error" , SYM_EERROR}, |
93 |
|
|
{"out_of_memory" , SYM_MERROR}, |
94 |
|
|
{"fatal_error" , SYM_FATAL_ERROR}, |
95 |
|
|
{"out_of_stack" , SYM_STACK_ERROR}, |
96 |
|
|
{"division_by_zero" , SYM_DIVZERO}, |
97 |
|
|
{"variable_not_bound" , SYM_NOT_FOUND}, |
98 |
|
|
{"flash_full" , SYM_ERROR_FLASH_HEAP_FULL}, |
99 |
|
|
|
100 |
|
|
// Special symbols with unparsable names |
101 |
|
|
{"$barray" , SYM_ARRAY_TYPE}, |
102 |
|
|
{"$raw_i" , SYM_RAW_I_TYPE}, |
103 |
|
|
{"$raw_u" , SYM_RAW_U_TYPE}, |
104 |
|
|
{"$raw_f" , SYM_RAW_F_TYPE}, |
105 |
|
|
{"$ind_i" , SYM_IND_I_TYPE}, |
106 |
|
|
{"$ind_u" , SYM_IND_U_TYPE}, |
107 |
|
|
{"$ind_f" , SYM_IND_F_TYPE}, |
108 |
|
|
{"$channel" , SYM_CHANNEL_TYPE}, |
109 |
|
|
{"$recovered" , SYM_RECOVERED}, |
110 |
|
|
{"$placeholder" , SYM_PLACEHOLDER}, |
111 |
|
|
{"$custom" , SYM_CUSTOM_TYPE}, |
112 |
|
|
{"$array" , SYM_LISPARRAY_TYPE}, |
113 |
|
|
{"$nonsense" , SYM_NONSENSE}, |
114 |
|
|
{"$dm-array" , SYM_DEFRAG_ARRAY_TYPE}, |
115 |
|
|
{"$dm" , SYM_DEFRAG_MEM_TYPE}, |
116 |
|
|
|
117 |
|
|
// tokenizer symbols with unparsable names |
118 |
|
|
{"[openpar]" , SYM_OPENPAR}, |
119 |
|
|
{"[closepar]" , SYM_CLOSEPAR}, |
120 |
|
|
{"[backquote]" , SYM_BACKQUOTE}, |
121 |
|
|
{"[comma]" , SYM_COMMA}, |
122 |
|
|
{"[commaat]" , SYM_COMMAAT}, |
123 |
|
|
{"[dot]" , SYM_DOT}, |
124 |
|
|
{"[done]" , SYM_TOKENIZER_DONE}, |
125 |
|
|
{"[quote_it]" , SYM_QUOTE_IT}, |
126 |
|
|
{"[colon]" , SYM_COLON}, |
127 |
|
|
{"[wait]" , SYM_TOKENIZER_WAIT}, |
128 |
|
|
{"[openbrack]" , SYM_OPENBRACK}, |
129 |
|
|
{"[closebrack]" , SYM_CLOSEBRACK}, |
130 |
|
|
{"[rerror]" , SYM_TOKENIZER_RERROR}, |
131 |
|
|
{"[appcont]" , SYM_APP_CONT}, |
132 |
|
|
|
133 |
|
|
// special symbols with parseable names |
134 |
|
|
{"type-list" , SYM_TYPE_LIST}, |
135 |
|
|
{"type-i" , SYM_TYPE_I}, |
136 |
|
|
{"type-u" , SYM_TYPE_U}, |
137 |
|
|
{"type-float" , SYM_TYPE_FLOAT}, |
138 |
|
|
{"type-i32" , SYM_TYPE_I32}, |
139 |
|
|
{"type-u32" , SYM_TYPE_U32}, |
140 |
|
|
{"type-double" , SYM_TYPE_DOUBLE}, |
141 |
|
|
{"type-i64" , SYM_TYPE_I64}, |
142 |
|
|
{"type-u64" , SYM_TYPE_U64}, |
143 |
|
|
{"type-array" , SYM_TYPE_ARRAY}, |
144 |
|
|
{"type-symbol" , SYM_TYPE_SYMBOL}, |
145 |
|
|
{"type-char" , SYM_TYPE_CHAR}, |
146 |
|
|
{"type-byte" , SYM_TYPE_BYTE}, |
147 |
|
|
{"type-channel" , SYM_TYPE_CHANNEL}, |
148 |
|
|
{"type-lisparray" , SYM_TYPE_LISPARRAY}, |
149 |
|
|
{"type-dm" , SYM_TYPE_DEFRAG_MEM}, |
150 |
|
|
{"type-custom" , SYM_TYPE_CUSTOM}, |
151 |
|
|
|
152 |
|
|
// Fundamental operations |
153 |
|
|
{"+" , SYM_ADD}, |
154 |
|
|
{"-" , SYM_SUB}, |
155 |
|
|
{"*" , SYM_MUL}, |
156 |
|
|
{"/" , SYM_DIV}, |
157 |
|
|
{"//" , SYM_INT_DIV}, |
158 |
|
|
{"mod" , SYM_MOD}, |
159 |
|
|
{"=" , SYM_NUMEQ}, |
160 |
|
|
{"!=" , SYM_NUM_NOT_EQ}, |
161 |
|
|
{"<" , SYM_LT}, |
162 |
|
|
{">" , SYM_GT}, |
163 |
|
|
{"<=" , SYM_LEQ}, |
164 |
|
|
{">=" , SYM_GEQ}, |
165 |
|
|
{"eval" , SYM_EVAL}, |
166 |
|
|
{"eval-program" , SYM_EVAL_PROGRAM}, |
167 |
|
|
{"and" , SYM_AND}, |
168 |
|
|
{"or" , SYM_OR}, |
169 |
|
|
{"not" , SYM_NOT}, |
170 |
|
|
{"yield" , SYM_YIELD}, |
171 |
|
|
{"wait" , SYM_WAIT}, |
172 |
|
|
{"spawn" , SYM_SPAWN}, |
173 |
|
|
{"atomic" , SYM_ATOMIC}, |
174 |
|
|
{"self" , SYM_SELF}, |
175 |
|
|
{"spawn-trap" , SYM_SPAWN_TRAP}, |
176 |
|
|
{"set-mailbox-size" , SYM_SET_MAILBOX_SIZE}, |
177 |
|
|
{"eq" , SYM_EQ}, |
178 |
|
|
{"not-eq" , SYM_NOT_EQ}, |
179 |
|
|
{"car" , SYM_CAR}, |
180 |
|
|
{"cdr" , SYM_CDR}, |
181 |
|
|
{"cons" , SYM_CONS}, |
182 |
|
|
{"list" , SYM_LIST}, |
183 |
|
|
{"append" , SYM_APPEND}, |
184 |
|
|
{"undefine" , SYM_UNDEFINE}, |
185 |
|
|
{"bufcreate" , SYM_BYTEARRAY_CREATE}, |
186 |
|
|
{"type-of" , SYM_TYPE_OF}, |
187 |
|
|
{"sym2str" , SYM_SYMBOL_TO_STRING}, |
188 |
|
|
{"str2sym" , SYM_STRING_TO_SYMBOL}, |
189 |
|
|
{"sym2u" , SYM_SYMBOL_TO_UINT}, |
190 |
|
|
{"u2sym" , SYM_UINT_TO_SYMBOL}, |
191 |
|
|
{"setcar" , SYM_SET_CAR}, |
192 |
|
|
{"setcdr" , SYM_SET_CDR}, |
193 |
|
|
{"setix" , SYM_SET_IX}, |
194 |
|
|
{"length" , SYM_LIST_LENGTH}, |
195 |
|
|
{"range" , SYM_RANGE}, |
196 |
|
|
|
197 |
|
|
{"assoc" , SYM_ASSOC}, // lookup an association |
198 |
|
|
{"cossa" , SYM_COSSA}, // lookup an association "backwards" |
199 |
|
|
{"acons" , SYM_ACONS}, // Add to alist |
200 |
|
|
{"setassoc" , SYM_SET_ASSOC}, // Change association |
201 |
|
|
|
202 |
|
|
{"shl" , SYM_SHL}, |
203 |
|
|
{"shr" , SYM_SHR}, |
204 |
|
|
{"bitwise-and" , SYM_BITWISE_AND}, |
205 |
|
|
{"bitwise-or" , SYM_BITWISE_OR}, |
206 |
|
|
{"bitwise-xor" , SYM_BITWISE_XOR}, |
207 |
|
|
{"bitwise-not" , SYM_BITWISE_NOT}, |
208 |
|
|
|
209 |
|
|
{"custom-destruct", SYM_CUSTOM_DESTRUCT}, |
210 |
|
|
|
211 |
|
|
{"to-i" , SYM_TO_I}, |
212 |
|
|
{"to-i32" , SYM_TO_I32}, |
213 |
|
|
{"to-u" , SYM_TO_U}, |
214 |
|
|
{"to-u32" , SYM_TO_U32}, |
215 |
|
|
{"to-float" , SYM_TO_FLOAT}, |
216 |
|
|
{"to-i64" , SYM_TO_I64}, |
217 |
|
|
{"to-u64" , SYM_TO_U64}, |
218 |
|
|
{"to-double" , SYM_TO_DOUBLE}, |
219 |
|
|
{"to-byte" , SYM_TO_BYTE}, |
220 |
|
|
|
221 |
|
|
{"event-register-handler", SYM_REG_EVENT_HANDLER}, |
222 |
|
|
{"take" , SYM_TAKE}, |
223 |
|
|
{"drop" , SYM_DROP}, |
224 |
|
|
{"mkarray" , SYM_MKARRAY}, |
225 |
|
|
{"array-to-list" , SYM_ARRAY_TO_LIST}, |
226 |
|
|
{"list-to-array" , SYM_LIST_TO_ARRAY}, |
227 |
|
|
|
228 |
|
|
{"dm-create" , SYM_DM_CREATE}, |
229 |
|
|
{"dm-alloc" , SYM_DM_ALLOC}, |
230 |
|
|
|
231 |
|
|
{"list?" , SYM_IS_LIST}, |
232 |
|
|
{"number?" , SYM_IS_NUMBER}, |
233 |
|
|
|
234 |
|
|
// fast access in list |
235 |
|
|
{"ix" , SYM_IX}, |
236 |
|
|
|
237 |
|
|
// aliases |
238 |
|
|
{"first" , SYM_CAR}, |
239 |
|
|
{"rest" , SYM_CDR}, |
240 |
|
|
{"fn" , SYM_LAMBDA}, |
241 |
|
|
{"def" , SYM_DEFINE}, |
242 |
|
|
{"true" , SYM_TRUE}, |
243 |
|
|
{"false" , SYM_NIL}, |
244 |
|
|
{"setvar" , SYM_SETVAR}, |
245 |
|
|
{"type-f32" , SYM_TYPE_FLOAT}, |
246 |
|
|
{"type-f64" , SYM_TYPE_DOUBLE}, |
247 |
|
|
{"array-create" , SYM_BYTEARRAY_CREATE}, |
248 |
|
|
}; |
249 |
|
|
|
250 |
|
|
static lbm_uint *symlist = NULL; |
251 |
|
|
static lbm_uint next_symbol_id = RUNTIME_SYMBOLS_START; |
252 |
|
|
static lbm_uint symbol_table_size_list = 0; |
253 |
|
|
static lbm_uint symbol_table_size_list_flash = 0; |
254 |
|
|
static lbm_uint symbol_table_size_strings = 0; |
255 |
|
|
static lbm_uint symbol_table_size_strings_flash = 0; |
256 |
|
|
|
257 |
|
|
lbm_value symbol_x = ENC_SYM_NIL; |
258 |
|
|
lbm_value symbol_y = ENC_SYM_NIL; |
259 |
|
|
|
260 |
|
21672 |
int lbm_symrepr_init(void) { |
261 |
|
21672 |
symlist = NULL; |
262 |
|
21672 |
next_symbol_id = RUNTIME_SYMBOLS_START; |
263 |
|
21672 |
symbol_table_size_list = 0; |
264 |
|
21672 |
symbol_table_size_list_flash = 0; |
265 |
|
21672 |
symbol_table_size_strings = 0; |
266 |
|
21672 |
symbol_table_size_strings_flash = 0; |
267 |
|
|
|
268 |
|
21672 |
lbm_uint x = 0; |
269 |
|
21672 |
lbm_uint y = 0; |
270 |
|
21672 |
lbm_add_symbol("x", &x); |
271 |
|
21672 |
lbm_add_symbol("y", &y); |
272 |
|
21672 |
symbol_x = lbm_enc_sym(x); |
273 |
|
21672 |
symbol_y = lbm_enc_sym(y); |
274 |
|
21672 |
return 1; |
275 |
|
|
} |
276 |
|
|
|
277 |
|
|
void lbm_symrepr_name_iterator(symrepr_name_iterator_fun f) { |
278 |
|
|
|
279 |
|
|
lbm_uint *curr = symlist; |
280 |
|
|
while (curr) { |
281 |
|
|
f((const char *)curr[NAME]); |
282 |
|
|
curr = (lbm_uint *)curr[NEXT]; |
283 |
|
|
} |
284 |
|
|
} |
285 |
|
|
|
286 |
|
62368 |
const char *lookup_symrepr_name_memory(lbm_uint id) { |
287 |
|
|
|
288 |
|
62368 |
lbm_uint *curr = symlist; |
289 |
✓✗ |
795592 |
while (curr) { |
290 |
✓✓ |
795592 |
if (id == curr[ID]) { |
291 |
|
62368 |
return (const char *)curr[NAME]; |
292 |
|
|
} |
293 |
|
733224 |
curr = (lbm_uint*)curr[NEXT]; |
294 |
|
|
} |
295 |
|
|
return NULL; |
296 |
|
|
} |
297 |
|
|
|
298 |
|
|
// Lookup symbol name given a symbol id |
299 |
|
175075 |
const char *lbm_get_name_by_symbol(lbm_uint id) { |
300 |
|
175075 |
lbm_uint sym_kind = SYMBOL_KIND(id); |
301 |
✓✓✓ |
175075 |
switch (sym_kind) { |
302 |
|
112699 |
case SYMBOL_KIND_SPECIAL: /* fall through */ |
303 |
|
|
case SYMBOL_KIND_FUNDAMENTAL: |
304 |
|
|
case SYMBOL_KIND_APPFUN: |
305 |
✓✗ |
220349 |
for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { |
306 |
✓✓ |
220349 |
if (id == special_symbols[i].id) { |
307 |
|
112699 |
return (special_symbols[i].name); |
308 |
|
|
} |
309 |
|
|
} |
310 |
|
|
return NULL; |
311 |
|
|
break; |
312 |
|
8 |
case SYMBOL_KIND_EXTENSION: { |
313 |
|
8 |
lbm_uint ext_id = id - EXTENSION_SYMBOLS_START; |
314 |
✓✗ |
8 |
if (ext_id < lbm_get_max_extensions()) { |
315 |
|
8 |
return extension_table[ext_id].name; |
316 |
|
|
} |
317 |
|
|
return NULL; |
318 |
|
|
} break; |
319 |
|
62368 |
default: |
320 |
|
62368 |
return lookup_symrepr_name_memory(id); |
321 |
|
|
} |
322 |
|
|
} |
323 |
|
|
|
324 |
|
|
lbm_uint *lbm_get_symbol_list_entry_by_name(char *name) { |
325 |
|
|
lbm_uint *curr = symlist; |
326 |
|
|
while (curr) { |
327 |
|
|
char *str = (char*)curr[NAME]; |
328 |
|
|
if (str_eq(name, str)) { |
329 |
|
|
return (lbm_uint *)curr; |
330 |
|
|
} |
331 |
|
|
curr = (lbm_uint*)curr[NEXT]; |
332 |
|
|
} |
333 |
|
|
return NULL; |
334 |
|
|
} |
335 |
|
|
|
336 |
|
|
// Lookup symbol id given symbol name |
337 |
|
3701268 |
int lbm_get_symbol_by_name(char *name, lbm_uint* id) { |
338 |
|
|
|
339 |
|
|
// loop through special symbols |
340 |
✓✓ |
639180672 |
for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { |
341 |
✓✓ |
635797684 |
if (str_eq(name, (char *)special_symbols[i].name)) { |
342 |
|
318280 |
*id = special_symbols[i].id; |
343 |
|
318280 |
return 1; |
344 |
|
|
} |
345 |
|
|
} |
346 |
|
|
|
347 |
|
|
// loop through extensions |
348 |
✓✓ |
665608860 |
for (unsigned int i = 0; i < lbm_get_max_extensions(); i ++) { |
349 |
✓✓✓✓
|
662269748 |
if (extension_table[i].name && str_eq(name, extension_table[i].name)) { |
350 |
|
43876 |
*id = EXTENSION_SYMBOLS_START + i; |
351 |
|
43876 |
return 1; |
352 |
|
|
} |
353 |
|
|
} |
354 |
|
|
|
355 |
|
3339112 |
lbm_uint *curr = symlist; |
356 |
✓✓ |
42635756 |
while (curr) { |
357 |
|
39783466 |
char *str = (char*)curr[NAME]; |
358 |
✓✓ |
39783466 |
if (str_eq(name, str)) { |
359 |
|
486822 |
*id = curr[ID]; |
360 |
|
486822 |
return 1; |
361 |
|
|
} |
362 |
|
39296644 |
curr = (lbm_uint*)curr[NEXT]; |
363 |
|
|
} |
364 |
|
2852290 |
return 0; |
365 |
|
|
} |
366 |
|
|
|
367 |
|
|
extern lbm_flash_status lbm_write_const_array_padded(uint8_t *data, lbm_uint n, lbm_uint *res); |
368 |
|
|
|
369 |
|
|
|
370 |
|
70 |
static bool store_symbol_name_flash(char *name, lbm_uint *res) { |
371 |
|
70 |
size_t n = strlen(name) + 1; |
372 |
✗✓ |
70 |
if (n == 1) return 0; // failure if empty symbol |
373 |
|
|
|
374 |
|
|
lbm_uint alloc_size; |
375 |
✗✓ |
70 |
if (n % sizeof(lbm_uint) == 0) { |
376 |
|
|
alloc_size = n/(sizeof(lbm_uint)); |
377 |
|
|
} else { |
378 |
|
70 |
alloc_size = (n/(sizeof(lbm_uint))) + 1; |
379 |
|
|
} |
380 |
|
|
|
381 |
|
70 |
lbm_uint symbol_addr = 0; |
382 |
|
70 |
lbm_flash_status s = lbm_write_const_array_padded((uint8_t*)name, n, &symbol_addr); |
383 |
✓✗✗✓
|
70 |
if (s != LBM_FLASH_WRITE_OK || symbol_addr == 0) { |
384 |
|
|
return false; |
385 |
|
|
} |
386 |
|
70 |
symbol_table_size_strings_flash += alloc_size; |
387 |
|
70 |
*res = symbol_addr; |
388 |
|
70 |
return true; |
389 |
|
|
} |
390 |
|
|
|
391 |
|
|
// Symbol table |
392 |
|
|
// non-const name copied into symbol-table-entry: |
393 |
|
|
// Entry |
394 |
|
|
// | |
395 |
|
|
// [name-ptr | symbol-id | next-ptr | name n-bytes] |
396 |
|
|
// | / |
397 |
|
|
// ------------points here ----- |
398 |
|
|
// |
399 |
|
|
// const name referenced by symbol-table-entry: |
400 |
|
|
// Entry |
401 |
|
|
// | |
402 |
|
|
// [name-ptr | symbol-id | next-ptr] |
403 |
|
|
// | |
404 |
|
|
// [name n-bytes] |
405 |
|
|
// |
406 |
|
143150 |
static bool add_symbol_to_symtab(char* name, lbm_uint id) { |
407 |
|
143150 |
bool r = false; |
408 |
|
143150 |
size_t n = strlen(name) + 1; |
409 |
✓✗✓✗
|
143150 |
if (n > 1 && n <= 257) { |
410 |
|
143150 |
size_t alloc_size = n + (3 * sizeof(lbm_uint)); |
411 |
|
143150 |
char *storage = lbm_malloc(alloc_size); |
412 |
✓✗ |
143150 |
if (storage) { |
413 |
|
143150 |
memcpy(storage + (3 * sizeof(lbm_uint)), name, n); |
414 |
|
143150 |
lbm_uint *m = (lbm_uint*)storage; |
415 |
|
|
|
416 |
|
143150 |
symbol_table_size_list += 3 * sizeof(lbm_uint); // Bytes |
417 |
|
143150 |
symbol_table_size_strings += n; // Bytes |
418 |
|
143150 |
m[NAME] = (lbm_uint)&m[3]; |
419 |
|
143150 |
m[NEXT] = (lbm_uint) symlist; |
420 |
|
143150 |
symlist = m; |
421 |
|
143150 |
m[ID] =id; |
422 |
|
143150 |
r = true; |
423 |
|
|
} |
424 |
|
|
} |
425 |
|
143150 |
return r; |
426 |
|
|
} |
427 |
|
|
|
428 |
|
70 |
static bool add_symbol_to_symtab_flash(lbm_uint name, lbm_uint id) { |
429 |
|
|
lbm_uint entry[3]; |
430 |
|
70 |
entry[NAME] = name; |
431 |
|
70 |
entry[NEXT] = (lbm_uint) symlist; |
432 |
|
70 |
entry[ID] = id; |
433 |
|
70 |
lbm_uint entry_addr = 0; |
434 |
✓✗ |
70 |
if (lbm_write_const_raw(entry,3, &entry_addr) == LBM_FLASH_WRITE_OK) { |
435 |
|
70 |
symlist = (lbm_uint*)entry_addr; |
436 |
|
70 |
symbol_table_size_list_flash += 3; |
437 |
|
70 |
return true; |
438 |
|
|
} |
439 |
|
|
return false; |
440 |
|
|
} |
441 |
|
|
|
442 |
|
143220 |
int lbm_add_symbol_base(char *name, lbm_uint *id, bool flash) { |
443 |
|
|
lbm_uint symbol_name_storage; |
444 |
✓✓ |
143220 |
if (flash) { |
445 |
✗✓ |
70 |
if (!store_symbol_name_flash(name, &symbol_name_storage)) return 0; |
446 |
✗✓ |
70 |
if (!add_symbol_to_symtab_flash(symbol_name_storage, next_symbol_id)) return 0; |
447 |
|
|
} else { |
448 |
✗✓ |
143150 |
if (!add_symbol_to_symtab(name, next_symbol_id)) { |
449 |
|
|
return 0; |
450 |
|
|
} |
451 |
|
|
} |
452 |
|
143220 |
*id = next_symbol_id ++; |
453 |
|
143220 |
return 1; |
454 |
|
|
} |
455 |
|
|
|
456 |
|
106894 |
int lbm_add_symbol(char *name, lbm_uint* id) { |
457 |
|
|
lbm_uint sym_id; |
458 |
✓✓ |
106894 |
if (!lbm_get_symbol_by_name(name, &sym_id)) { |
459 |
|
43372 |
return lbm_add_symbol_base(name, id, false); |
460 |
|
|
} else { |
461 |
|
63522 |
*id = sym_id; |
462 |
|
63522 |
return 1; |
463 |
|
|
} |
464 |
|
|
return 0; |
465 |
|
|
} |
466 |
|
|
|
467 |
|
|
int lbm_add_symbol_flash(char *name, lbm_uint* id) { |
468 |
|
|
lbm_uint sym_id; |
469 |
|
|
if (!lbm_get_symbol_by_name(name, &sym_id)) { |
470 |
|
|
return lbm_add_symbol_base(name, id, true); |
471 |
|
|
} else { |
472 |
|
|
*id = sym_id; |
473 |
|
|
return 1; |
474 |
|
|
} |
475 |
|
|
return 0; |
476 |
|
|
} |
477 |
|
|
|
478 |
|
411768 |
int lbm_add_symbol_const_base(char *name, lbm_uint* id) { |
479 |
|
411768 |
lbm_uint *m = lbm_memory_allocate(3); |
480 |
✗✓ |
411768 |
if (m == NULL) return 0; |
481 |
|
411768 |
symbol_table_size_list += 3; |
482 |
|
411768 |
m[NAME] = (lbm_uint) name; |
483 |
|
411768 |
m[NEXT] = (lbm_uint) symlist; |
484 |
|
411768 |
symlist = m; |
485 |
|
411768 |
m[ID] = next_symbol_id; |
486 |
|
411768 |
*id = next_symbol_id ++; |
487 |
|
411768 |
return 1; |
488 |
|
|
} |
489 |
|
|
|
490 |
|
411768 |
int lbm_add_symbol_const(char *name, lbm_uint* id) { |
491 |
|
|
lbm_uint sym_id; |
492 |
✓✗ |
411768 |
if (!lbm_get_symbol_by_name(name, &sym_id)) { |
493 |
|
411768 |
return lbm_add_symbol_const_base(name, id); |
494 |
|
|
} else { |
495 |
|
|
*id = sym_id; |
496 |
|
|
return 1; |
497 |
|
|
} |
498 |
|
|
return 0; |
499 |
|
|
} |
500 |
|
|
|
501 |
|
56 |
int lbm_str_to_symbol(char *name, lbm_uint *sym_id) { |
502 |
✓✓ |
56 |
if (lbm_get_symbol_by_name(name, sym_id)) |
503 |
|
28 |
return 1; |
504 |
✓✗ |
28 |
else if (lbm_add_symbol(name, sym_id)) |
505 |
|
28 |
return 1; |
506 |
|
|
return 0; |
507 |
|
|
} |
508 |
|
|
|
509 |
|
28 |
lbm_uint lbm_get_symbol_table_size(void) { |
510 |
|
28 |
return (symbol_table_size_list +symbol_table_size_strings); |
511 |
|
|
} |
512 |
|
|
|
513 |
|
28 |
lbm_uint lbm_get_symbol_table_size_flash(void) { |
514 |
|
28 |
return (symbol_table_size_list_flash + |
515 |
|
28 |
symbol_table_size_strings_flash) * sizeof(lbm_uint); |
516 |
|
|
} |
517 |
|
|
|
518 |
|
28 |
lbm_uint lbm_get_symbol_table_size_names(void) { |
519 |
|
28 |
return symbol_table_size_strings; // Bytes already |
520 |
|
|
} |
521 |
|
|
|
522 |
|
28 |
lbm_uint lbm_get_symbol_table_size_names_flash(void) { |
523 |
|
28 |
return symbol_table_size_strings_flash * sizeof(lbm_uint); |
524 |
|
|
} |
525 |
|
|
|
526 |
|
|
bool lbm_symbol_in_flash(char *str) { |
527 |
|
|
return !lbm_memory_ptr_inside((lbm_uint*)str); |
528 |
|
|
} |
529 |
|
|
|
530 |
|
|
bool lbm_symbol_list_entry_in_flash(char *str) { |
531 |
|
|
lbm_uint *entry = lbm_get_symbol_list_entry_by_name(str); |
532 |
|
|
return (entry == NULL || !lbm_memory_ptr_inside(entry)); |
533 |
|
|
} |