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