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 |
|
|
{"identity" , SYM_IDENTITY}, |
249 |
|
|
}; |
250 |
|
|
|
251 |
|
|
static lbm_uint *symlist = NULL; |
252 |
|
|
static lbm_uint next_symbol_id = RUNTIME_SYMBOLS_START; |
253 |
|
|
static lbm_uint symbol_table_size_list = 0; |
254 |
|
|
static lbm_uint symbol_table_size_list_flash = 0; |
255 |
|
|
static lbm_uint symbol_table_size_strings = 0; |
256 |
|
|
static lbm_uint symbol_table_size_strings_flash = 0; |
257 |
|
|
|
258 |
|
|
lbm_value symbol_x = ENC_SYM_NIL; |
259 |
|
|
lbm_value symbol_y = ENC_SYM_NIL; |
260 |
|
|
|
261 |
|
21756 |
int lbm_symrepr_init(void) { |
262 |
|
21756 |
symlist = NULL; |
263 |
|
21756 |
next_symbol_id = RUNTIME_SYMBOLS_START; |
264 |
|
21756 |
symbol_table_size_list = 0; |
265 |
|
21756 |
symbol_table_size_list_flash = 0; |
266 |
|
21756 |
symbol_table_size_strings = 0; |
267 |
|
21756 |
symbol_table_size_strings_flash = 0; |
268 |
|
|
|
269 |
|
21756 |
lbm_uint x = 0; |
270 |
|
21756 |
lbm_uint y = 0; |
271 |
|
21756 |
lbm_add_symbol("x", &x); |
272 |
|
21756 |
lbm_add_symbol("y", &y); |
273 |
|
21756 |
symbol_x = lbm_enc_sym(x); |
274 |
|
21756 |
symbol_y = lbm_enc_sym(y); |
275 |
|
21756 |
return 1; |
276 |
|
|
} |
277 |
|
|
|
278 |
|
|
void lbm_symrepr_name_iterator(symrepr_name_iterator_fun f) { |
279 |
|
|
|
280 |
|
|
lbm_uint *curr = symlist; |
281 |
|
|
while (curr) { |
282 |
|
|
f((const char *)curr[NAME]); |
283 |
|
|
curr = (lbm_uint *)curr[NEXT]; |
284 |
|
|
} |
285 |
|
|
} |
286 |
|
|
|
287 |
|
132116 |
const char *lookup_symrepr_name_memory(lbm_uint id) { |
288 |
|
|
|
289 |
|
132116 |
lbm_uint *curr = symlist; |
290 |
✓✗ |
1477882 |
while (curr) { |
291 |
✓✓ |
1477882 |
if (id == curr[ID]) { |
292 |
|
132116 |
return (const char *)curr[NAME]; |
293 |
|
|
} |
294 |
|
1345766 |
curr = (lbm_uint*)curr[NEXT]; |
295 |
|
|
} |
296 |
|
|
return NULL; |
297 |
|
|
} |
298 |
|
|
|
299 |
|
|
// Lookup symbol name given a symbol id |
300 |
|
393177 |
const char *lbm_get_name_by_symbol(lbm_uint id) { |
301 |
|
393177 |
lbm_uint sym_kind = SYMBOL_KIND(id); |
302 |
✓✓✓ |
393177 |
switch (sym_kind) { |
303 |
|
252877 |
case SYMBOL_KIND_SPECIAL: /* fall through */ |
304 |
|
|
case SYMBOL_KIND_FUNDAMENTAL: |
305 |
|
|
case SYMBOL_KIND_APPFUN: |
306 |
✓✓ |
4681305 |
for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { |
307 |
✓✓ |
4681291 |
if (id == special_symbols[i].id) { |
308 |
|
252863 |
return (special_symbols[i].name); |
309 |
|
|
} |
310 |
|
|
} |
311 |
|
14 |
return NULL; |
312 |
|
|
break; |
313 |
|
8184 |
case SYMBOL_KIND_EXTENSION: { |
314 |
|
8184 |
lbm_uint ext_id = id - EXTENSION_SYMBOLS_START; |
315 |
✓✗ |
8184 |
if (ext_id < lbm_get_max_extensions()) { |
316 |
|
8184 |
return extension_table[ext_id].name; |
317 |
|
|
} |
318 |
|
|
return NULL; |
319 |
|
|
} break; |
320 |
|
132116 |
default: |
321 |
|
132116 |
return lookup_symrepr_name_memory(id); |
322 |
|
|
} |
323 |
|
|
} |
324 |
|
|
|
325 |
|
|
lbm_uint *lbm_get_symbol_list_entry_by_name(char *name) { |
326 |
|
|
lbm_uint *curr = symlist; |
327 |
|
|
while (curr) { |
328 |
|
|
char *str = (char*)curr[NAME]; |
329 |
|
|
if (str_eq(name, str)) { |
330 |
|
|
return (lbm_uint *)curr; |
331 |
|
|
} |
332 |
|
|
curr = (lbm_uint*)curr[NEXT]; |
333 |
|
|
} |
334 |
|
|
return NULL; |
335 |
|
|
} |
336 |
|
|
|
337 |
|
|
// Lookup symbol id given symbol name |
338 |
|
3712606 |
int lbm_get_symbol_by_name(char *name, lbm_uint* id) { |
339 |
|
|
|
340 |
|
|
// loop through special symbols |
341 |
✓✓ |
644612511 |
for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { |
342 |
✓✓ |
641218548 |
if (str_eq(name, (char *)special_symbols[i].name)) { |
343 |
|
318643 |
*id = special_symbols[i].id; |
344 |
|
318643 |
return 1; |
345 |
|
|
} |
346 |
|
|
} |
347 |
|
|
|
348 |
|
|
// loop through extensions |
349 |
✓✓ |
667773087 |
for (unsigned int i = 0; i < lbm_get_max_extensions(); i ++) { |
350 |
✓✓✓✓
|
664423084 |
if (extension_table[i].name && str_eq(name, extension_table[i].name)) { |
351 |
|
43960 |
*id = EXTENSION_SYMBOLS_START + i; |
352 |
|
43960 |
return 1; |
353 |
|
|
} |
354 |
|
|
} |
355 |
|
|
|
356 |
|
3350003 |
lbm_uint *curr = symlist; |
357 |
✓✓ |
42766540 |
while (curr) { |
358 |
|
39903442 |
char *str = (char*)curr[NAME]; |
359 |
✓✓ |
39903442 |
if (str_eq(name, str)) { |
360 |
|
486905 |
*id = curr[ID]; |
361 |
|
486905 |
return 1; |
362 |
|
|
} |
363 |
|
39416537 |
curr = (lbm_uint*)curr[NEXT]; |
364 |
|
|
} |
365 |
|
2863098 |
return 0; |
366 |
|
|
} |
367 |
|
|
|
368 |
|
|
extern lbm_flash_status lbm_write_const_array_padded(uint8_t *data, lbm_uint n, lbm_uint *res); |
369 |
|
|
|
370 |
|
|
|
371 |
|
70 |
static bool store_symbol_name_flash(char *name, lbm_uint *res) { |
372 |
|
70 |
size_t n = strlen(name) + 1; |
373 |
✗✓ |
70 |
if (n == 1) return 0; // failure if empty symbol |
374 |
|
|
|
375 |
|
|
lbm_uint alloc_size; |
376 |
✗✓ |
70 |
if (n % sizeof(lbm_uint) == 0) { |
377 |
|
|
alloc_size = n/(sizeof(lbm_uint)); |
378 |
|
|
} else { |
379 |
|
70 |
alloc_size = (n/(sizeof(lbm_uint))) + 1; |
380 |
|
|
} |
381 |
|
|
|
382 |
|
70 |
lbm_uint symbol_addr = 0; |
383 |
|
70 |
lbm_flash_status s = lbm_write_const_array_padded((uint8_t*)name, n, &symbol_addr); |
384 |
✓✗✗✓
|
70 |
if (s != LBM_FLASH_WRITE_OK || symbol_addr == 0) { |
385 |
|
|
return false; |
386 |
|
|
} |
387 |
|
70 |
symbol_table_size_strings_flash += alloc_size; |
388 |
|
70 |
*res = symbol_addr; |
389 |
|
70 |
return true; |
390 |
|
|
} |
391 |
|
|
|
392 |
|
|
// Symbol table |
393 |
|
|
// non-const name copied into symbol-table-entry: |
394 |
|
|
// Entry |
395 |
|
|
// | |
396 |
|
|
// [name-ptr | symbol-id | next-ptr | name n-bytes] |
397 |
|
|
// | / |
398 |
|
|
// ------------points here ----- |
399 |
|
|
// |
400 |
|
|
// const name referenced by symbol-table-entry: |
401 |
|
|
// Entry |
402 |
|
|
// | |
403 |
|
|
// [name-ptr | symbol-id | next-ptr] |
404 |
|
|
// | |
405 |
|
|
// [name n-bytes] |
406 |
|
|
// |
407 |
|
143458 |
static bool add_symbol_to_symtab(char* name, lbm_uint id) { |
408 |
|
143458 |
bool r = false; |
409 |
|
143458 |
size_t n = strlen(name) + 1; |
410 |
✓✗✓✗
|
143458 |
if (n > 1 && n <= 257) { |
411 |
|
143458 |
size_t alloc_size = n + (3 * sizeof(lbm_uint)); |
412 |
|
143458 |
char *storage = lbm_malloc(alloc_size); |
413 |
✓✗ |
143458 |
if (storage) { |
414 |
|
143458 |
memcpy(storage + (3 * sizeof(lbm_uint)), name, n); |
415 |
|
143458 |
lbm_uint *m = (lbm_uint*)storage; |
416 |
|
|
|
417 |
|
143458 |
symbol_table_size_list += 3 * sizeof(lbm_uint); // Bytes |
418 |
|
143458 |
symbol_table_size_strings += n; // Bytes |
419 |
|
143458 |
m[NAME] = (lbm_uint)&m[3]; |
420 |
|
143458 |
m[NEXT] = (lbm_uint) symlist; |
421 |
|
143458 |
symlist = m; |
422 |
|
143458 |
m[ID] =id; |
423 |
|
143458 |
r = true; |
424 |
|
|
} |
425 |
|
|
} |
426 |
|
143458 |
return r; |
427 |
|
|
} |
428 |
|
|
|
429 |
|
70 |
static bool add_symbol_to_symtab_flash(lbm_uint name, lbm_uint id) { |
430 |
|
|
lbm_uint entry[3]; |
431 |
|
70 |
entry[NAME] = name; |
432 |
|
70 |
entry[NEXT] = (lbm_uint) symlist; |
433 |
|
70 |
entry[ID] = id; |
434 |
|
70 |
lbm_uint entry_addr = 0; |
435 |
✓✗ |
70 |
if (lbm_write_const_raw(entry,3, &entry_addr) == LBM_FLASH_WRITE_OK) { |
436 |
|
70 |
symlist = (lbm_uint*)entry_addr; |
437 |
|
70 |
symbol_table_size_list_flash += 3; |
438 |
|
70 |
return true; |
439 |
|
|
} |
440 |
|
|
return false; |
441 |
|
|
} |
442 |
|
|
|
443 |
|
143528 |
int lbm_add_symbol_base(char *name, lbm_uint *id, bool flash) { |
444 |
|
|
lbm_uint symbol_name_storage; |
445 |
✓✓ |
143528 |
if (flash) { |
446 |
✗✓ |
70 |
if (!store_symbol_name_flash(name, &symbol_name_storage)) return 0; |
447 |
✗✓ |
70 |
if (!add_symbol_to_symtab_flash(symbol_name_storage, next_symbol_id)) return 0; |
448 |
|
|
} else { |
449 |
✗✓ |
143458 |
if (!add_symbol_to_symtab(name, next_symbol_id)) { |
450 |
|
|
return 0; |
451 |
|
|
} |
452 |
|
|
} |
453 |
|
143528 |
*id = next_symbol_id ++; |
454 |
|
143528 |
return 1; |
455 |
|
|
} |
456 |
|
|
|
457 |
|
107062 |
int lbm_add_symbol(char *name, lbm_uint* id) { |
458 |
|
|
lbm_uint sym_id; |
459 |
✓✓ |
107062 |
if (!lbm_get_symbol_by_name(name, &sym_id)) { |
460 |
|
43540 |
return lbm_add_symbol_base(name, id, false); |
461 |
|
|
} else { |
462 |
|
63522 |
*id = sym_id; |
463 |
|
63522 |
return 1; |
464 |
|
|
} |
465 |
|
|
return 0; |
466 |
|
|
} |
467 |
|
|
|
468 |
|
|
int lbm_add_symbol_flash(char *name, lbm_uint* id) { |
469 |
|
|
lbm_uint sym_id; |
470 |
|
|
if (!lbm_get_symbol_by_name(name, &sym_id)) { |
471 |
|
|
return lbm_add_symbol_base(name, id, true); |
472 |
|
|
} else { |
473 |
|
|
*id = sym_id; |
474 |
|
|
return 1; |
475 |
|
|
} |
476 |
|
|
return 0; |
477 |
|
|
} |
478 |
|
|
|
479 |
|
413364 |
int lbm_add_symbol_const_base(char *name, lbm_uint* id) { |
480 |
|
413364 |
lbm_uint *m = lbm_memory_allocate(3); |
481 |
✗✓ |
413364 |
if (m == NULL) return 0; |
482 |
|
413364 |
symbol_table_size_list += 3; |
483 |
|
413364 |
m[NAME] = (lbm_uint) name; |
484 |
|
413364 |
m[NEXT] = (lbm_uint) symlist; |
485 |
|
413364 |
symlist = m; |
486 |
|
413364 |
m[ID] = next_symbol_id; |
487 |
|
413364 |
*id = next_symbol_id ++; |
488 |
|
413364 |
return 1; |
489 |
|
|
} |
490 |
|
|
|
491 |
|
413364 |
int lbm_add_symbol_const(char *name, lbm_uint* id) { |
492 |
|
|
lbm_uint sym_id; |
493 |
✓✗ |
413364 |
if (!lbm_get_symbol_by_name(name, &sym_id)) { |
494 |
|
413364 |
return lbm_add_symbol_const_base(name, id); |
495 |
|
|
} else { |
496 |
|
|
*id = sym_id; |
497 |
|
|
return 1; |
498 |
|
|
} |
499 |
|
|
return 0; |
500 |
|
|
} |
501 |
|
|
|
502 |
|
56 |
int lbm_str_to_symbol(char *name, lbm_uint *sym_id) { |
503 |
✓✓ |
56 |
if (lbm_get_symbol_by_name(name, sym_id)) |
504 |
|
28 |
return 1; |
505 |
✓✗ |
28 |
else if (lbm_add_symbol(name, sym_id)) |
506 |
|
28 |
return 1; |
507 |
|
|
return 0; |
508 |
|
|
} |
509 |
|
|
|
510 |
|
28 |
lbm_uint lbm_get_symbol_table_size(void) { |
511 |
|
28 |
return (symbol_table_size_list +symbol_table_size_strings); |
512 |
|
|
} |
513 |
|
|
|
514 |
|
28 |
lbm_uint lbm_get_symbol_table_size_flash(void) { |
515 |
|
28 |
return (symbol_table_size_list_flash + |
516 |
|
28 |
symbol_table_size_strings_flash) * sizeof(lbm_uint); |
517 |
|
|
} |
518 |
|
|
|
519 |
|
28 |
lbm_uint lbm_get_symbol_table_size_names(void) { |
520 |
|
28 |
return symbol_table_size_strings; // Bytes already |
521 |
|
|
} |
522 |
|
|
|
523 |
|
28 |
lbm_uint lbm_get_symbol_table_size_names_flash(void) { |
524 |
|
28 |
return symbol_table_size_strings_flash * sizeof(lbm_uint); |
525 |
|
|
} |
526 |
|
|
|
527 |
|
|
bool lbm_symbol_in_flash(char *str) { |
528 |
|
|
return !lbm_memory_ptr_inside((lbm_uint*)str); |
529 |
|
|
} |
530 |
|
|
|
531 |
|
|
bool lbm_symbol_list_entry_in_flash(char *str) { |
532 |
|
|
lbm_uint *entry = lbm_get_symbol_list_entry_by_name(str); |
533 |
|
|
return (entry == NULL || !lbm_memory_ptr_inside(entry)); |
534 |
|
|
} |