| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 | {"$custom" , SYM_CUSTOM_TYPE}, | ||
| 111 | {"$array" , SYM_LISPARRAY_TYPE}, | ||
| 112 | {"$nonsense" , SYM_NONSENSE}, | ||
| 113 | |||
| 114 | // tokenizer symbols with unparsable names | ||
| 115 | {"[openpar]" , SYM_OPENPAR}, | ||
| 116 | {"[closepar]" , SYM_CLOSEPAR}, | ||
| 117 | {"[backquote]" , SYM_BACKQUOTE}, | ||
| 118 | {"[comma]" , SYM_COMMA}, | ||
| 119 | {"[commaat]" , SYM_COMMAAT}, | ||
| 120 | {"[dot]" , SYM_DOT}, | ||
| 121 | {"[done]" , SYM_TOKENIZER_DONE}, | ||
| 122 | {"[quote_it]" , SYM_QUOTE_IT}, | ||
| 123 | {"[colon]" , SYM_COLON}, | ||
| 124 | {"[wait]" , SYM_TOKENIZER_WAIT}, | ||
| 125 | {"[openbrack]" , SYM_OPENBRACK}, | ||
| 126 | {"[closebrack]" , SYM_CLOSEBRACK}, | ||
| 127 | {"[rerror]" , SYM_TOKENIZER_RERROR}, | ||
| 128 | {"[appcont]" , SYM_APP_CONT}, | ||
| 129 | |||
| 130 | // special symbols with parseable names | ||
| 131 | {"type-list" , SYM_TYPE_LIST}, | ||
| 132 | {"type-i" , SYM_TYPE_I}, | ||
| 133 | {"type-u" , SYM_TYPE_U}, | ||
| 134 | {"type-float" , SYM_TYPE_FLOAT}, | ||
| 135 | {"type-i32" , SYM_TYPE_I32}, | ||
| 136 | {"type-u32" , SYM_TYPE_U32}, | ||
| 137 | {"type-double" , SYM_TYPE_DOUBLE}, | ||
| 138 | {"type-i64" , SYM_TYPE_I64}, | ||
| 139 | {"type-u64" , SYM_TYPE_U64}, | ||
| 140 | {"type-array" , SYM_TYPE_ARRAY}, | ||
| 141 | {"type-symbol" , SYM_TYPE_SYMBOL}, | ||
| 142 | {"type-char" , SYM_TYPE_CHAR}, | ||
| 143 | {"type-byte" , SYM_TYPE_BYTE}, | ||
| 144 | {"type-channel" , SYM_TYPE_CHANNEL}, | ||
| 145 | {"type-lisparray" , SYM_TYPE_LISPARRAY}, | ||
| 146 | |||
| 147 | // Fundamental operations | ||
| 148 | {"+" , SYM_ADD}, | ||
| 149 | {"-" , SYM_SUB}, | ||
| 150 | {"*" , SYM_MUL}, | ||
| 151 | {"/" , SYM_DIV}, | ||
| 152 | {"mod" , SYM_MOD}, | ||
| 153 | {"=" , SYM_NUMEQ}, | ||
| 154 | {"!=" , SYM_NUM_NOT_EQ}, | ||
| 155 | {"<" , SYM_LT}, | ||
| 156 | {">" , SYM_GT}, | ||
| 157 | {"<=" , SYM_LEQ}, | ||
| 158 | {">=" , SYM_GEQ}, | ||
| 159 | {"eval" , SYM_EVAL}, | ||
| 160 | {"eval-program" , SYM_EVAL_PROGRAM}, | ||
| 161 | {"and" , SYM_AND}, | ||
| 162 | {"or" , SYM_OR}, | ||
| 163 | {"not" , SYM_NOT}, | ||
| 164 | {"yield" , SYM_YIELD}, | ||
| 165 | {"wait" , SYM_WAIT}, | ||
| 166 | {"spawn" , SYM_SPAWN}, | ||
| 167 | {"atomic" , SYM_ATOMIC}, | ||
| 168 | {"self" , SYM_SELF}, | ||
| 169 | {"spawn-trap" , SYM_SPAWN_TRAP}, | ||
| 170 | {"set-mailbox-size" , SYM_SET_MAILBOX_SIZE}, | ||
| 171 | {"eq" , SYM_EQ}, | ||
| 172 | {"not-eq" , SYM_NOT_EQ}, | ||
| 173 | {"car" , SYM_CAR}, | ||
| 174 | {"cdr" , SYM_CDR}, | ||
| 175 | {"cons" , SYM_CONS}, | ||
| 176 | {"list" , SYM_LIST}, | ||
| 177 | {"append" , SYM_APPEND}, | ||
| 178 | {"undefine" , SYM_UNDEFINE}, | ||
| 179 | {"bufcreate" , SYM_BYTEARRAY_CREATE}, | ||
| 180 | {"type-of" , SYM_TYPE_OF}, | ||
| 181 | {"sym2str" , SYM_SYMBOL_TO_STRING}, | ||
| 182 | {"str2sym" , SYM_STRING_TO_SYMBOL}, | ||
| 183 | {"sym2u" , SYM_SYMBOL_TO_UINT}, | ||
| 184 | {"u2sym" , SYM_UINT_TO_SYMBOL}, | ||
| 185 | {"setcar" , SYM_SET_CAR}, | ||
| 186 | {"setcdr" , SYM_SET_CDR}, | ||
| 187 | {"setix" , SYM_SET_IX}, | ||
| 188 | {"length" , SYM_LIST_LENGTH}, | ||
| 189 | {"range" , SYM_RANGE}, | ||
| 190 | |||
| 191 | {"assoc" , SYM_ASSOC}, // lookup an association | ||
| 192 | {"cossa" , SYM_COSSA}, // lookup an association "backwards" | ||
| 193 | {"acons" , SYM_ACONS}, // Add to alist | ||
| 194 | {"setassoc" , SYM_SET_ASSOC}, // Change association | ||
| 195 | |||
| 196 | {"shl" , SYM_SHL}, | ||
| 197 | {"shr" , SYM_SHR}, | ||
| 198 | {"bitwise-and" , SYM_BITWISE_AND}, | ||
| 199 | {"bitwise-or" , SYM_BITWISE_OR}, | ||
| 200 | {"bitwise-xor" , SYM_BITWISE_XOR}, | ||
| 201 | {"bitwise-not" , SYM_BITWISE_NOT}, | ||
| 202 | |||
| 203 | {"custom-destruct", SYM_CUSTOM_DESTRUCT}, | ||
| 204 | |||
| 205 | {"to-i" , SYM_TO_I}, | ||
| 206 | {"to-i32" , SYM_TO_I32}, | ||
| 207 | {"to-u" , SYM_TO_U}, | ||
| 208 | {"to-u32" , SYM_TO_U32}, | ||
| 209 | {"to-float" , SYM_TO_FLOAT}, | ||
| 210 | {"to-i64" , SYM_TO_I64}, | ||
| 211 | {"to-u64" , SYM_TO_U64}, | ||
| 212 | {"to-double" , SYM_TO_DOUBLE}, | ||
| 213 | {"to-byte" , SYM_TO_BYTE}, | ||
| 214 | |||
| 215 | {"event-register-handler", SYM_REG_EVENT_HANDLER}, | ||
| 216 | {"take" , SYM_TAKE}, | ||
| 217 | {"drop" , SYM_DROP}, | ||
| 218 | {"mkarray" , SYM_MKARRAY}, | ||
| 219 | {"array-to-list" , SYM_ARRAY_TO_LIST}, | ||
| 220 | {"list-to-array" , SYM_LIST_TO_ARRAY}, | ||
| 221 | |||
| 222 | // fast access in list | ||
| 223 | {"ix" , SYM_IX}, | ||
| 224 | |||
| 225 | // aliases | ||
| 226 | {"first" , SYM_CAR}, | ||
| 227 | {"rest" , SYM_CDR}, | ||
| 228 | {"fn" , SYM_LAMBDA}, | ||
| 229 | {"def" , SYM_DEFINE}, | ||
| 230 | {"true" , SYM_TRUE}, | ||
| 231 | {"false" , SYM_NIL}, | ||
| 232 | {"setvar" , SYM_SETVAR}, | ||
| 233 | {"type-f32" , SYM_TYPE_FLOAT}, | ||
| 234 | {"type-f64" , SYM_TYPE_DOUBLE}, | ||
| 235 | {"array-create" , SYM_BYTEARRAY_CREATE}, | ||
| 236 | }; | ||
| 237 | |||
| 238 | static lbm_uint *symlist = NULL; | ||
| 239 | static lbm_uint next_symbol_id = RUNTIME_SYMBOLS_START; | ||
| 240 | static lbm_uint symbol_table_size_list = 0; | ||
| 241 | static lbm_uint symbol_table_size_list_flash = 0; | ||
| 242 | static lbm_uint symbol_table_size_strings = 0; | ||
| 243 | static lbm_uint symbol_table_size_strings_flash = 0; | ||
| 244 | |||
| 245 | lbm_value symbol_x = ENC_SYM_NIL; | ||
| 246 | lbm_value symbol_y = ENC_SYM_NIL; | ||
| 247 | |||
| 248 | 17444 | int lbm_symrepr_init(void) { | |
| 249 | 17444 | symlist = NULL; | |
| 250 | 17444 | next_symbol_id = RUNTIME_SYMBOLS_START; | |
| 251 | 17444 | symbol_table_size_list = 0; | |
| 252 | 17444 | symbol_table_size_list_flash = 0; | |
| 253 | 17444 | symbol_table_size_strings = 0; | |
| 254 | 17444 | symbol_table_size_strings_flash = 0; | |
| 255 | |||
| 256 | 17444 | lbm_uint x = 0; | |
| 257 | 17444 | lbm_uint y = 0; | |
| 258 | 17444 | lbm_add_symbol("x", &x); | |
| 259 | 17444 | lbm_add_symbol("y", &y); | |
| 260 | 17444 | symbol_x = lbm_enc_sym(x); | |
| 261 | 17444 | symbol_y = lbm_enc_sym(y); | |
| 262 | 17444 | return 1; | |
| 263 | } | ||
| 264 | |||
| 265 | ✗ | void lbm_symrepr_name_iterator(symrepr_name_iterator_fun f) { | |
| 266 | |||
| 267 | ✗ | lbm_uint *curr = symlist; | |
| 268 | ✗ | while (curr) { | |
| 269 | ✗ | f((const char *)curr[NAME]); | |
| 270 | ✗ | curr = (lbm_uint *)curr[NEXT]; | |
| 271 | } | ||
| 272 | ✗ | } | |
| 273 | |||
| 274 | 4720 | const char *lookup_symrepr_name_memory(lbm_uint id) { | |
| 275 | |||
| 276 | 4720 | lbm_uint *curr = symlist; | |
| 277 |
1/2✓ Branch 0 taken 22110 times.
✗ Branch 1 not taken.
|
22110 | while (curr) { |
| 278 |
2/2✓ Branch 0 taken 4720 times.
✓ Branch 1 taken 17390 times.
|
22110 | if (id == curr[ID]) { |
| 279 | 4720 | return (const char *)curr[NAME]; | |
| 280 | } | ||
| 281 | 17390 | curr = (lbm_uint*)curr[NEXT]; | |
| 282 | } | ||
| 283 | ✗ | return NULL; | |
| 284 | } | ||
| 285 | |||
| 286 | // Lookup symbol name given a symbol id | ||
| 287 | 40947 | const char *lbm_get_name_by_symbol(lbm_uint id) { | |
| 288 | 40947 | lbm_uint sym_kind = SYMBOL_KIND(id); | |
| 289 |
3/3✓ Branch 0 taken 36219 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 4720 times.
|
40947 | switch (sym_kind) { |
| 290 | 36219 | case SYMBOL_KIND_SPECIAL: /* fall through */ | |
| 291 | case SYMBOL_KIND_FUNDAMENTAL: | ||
| 292 | case SYMBOL_KIND_APPFUN: | ||
| 293 |
1/2✓ Branch 0 taken 126435 times.
✗ Branch 1 not taken.
|
126435 | for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { |
| 294 |
2/2✓ Branch 0 taken 36219 times.
✓ Branch 1 taken 90216 times.
|
126435 | if (id == special_symbols[i].id) { |
| 295 | 36219 | return (special_symbols[i].name); | |
| 296 | } | ||
| 297 | } | ||
| 298 | ✗ | return NULL; | |
| 299 | break; | ||
| 300 | 8 | case SYMBOL_KIND_EXTENSION: { | |
| 301 | 8 | lbm_uint ext_id = id - EXTENSION_SYMBOLS_START; | |
| 302 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | if (ext_id < lbm_get_max_extensions()) { |
| 303 | 8 | return extension_table[ext_id].name; | |
| 304 | } | ||
| 305 | ✗ | return NULL; | |
| 306 | } break; | ||
| 307 | 4720 | default: | |
| 308 | 4720 | return lookup_symrepr_name_memory(id); | |
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | ✗ | lbm_uint *lbm_get_symbol_list_entry_by_name(char *name) { | |
| 313 | ✗ | lbm_uint *curr = symlist; | |
| 314 | ✗ | while (curr) { | |
| 315 | ✗ | char *str = (char*)curr[NAME]; | |
| 316 | ✗ | if (str_eq(name, str)) { | |
| 317 | ✗ | return (lbm_uint *)curr; | |
| 318 | } | ||
| 319 | ✗ | curr = (lbm_uint*)curr[NEXT]; | |
| 320 | } | ||
| 321 | ✗ | return NULL; | |
| 322 | } | ||
| 323 | |||
| 324 | // Lookup symbol id given symbol name | ||
| 325 | 2505258 | int lbm_get_symbol_by_name(char *name, lbm_uint* id) { | |
| 326 | |||
| 327 | // loop through special symbols | ||
| 328 |
2/2✓ Branch 0 taken 412356336 times.
✓ Branch 1 taken 2326254 times.
|
414682590 | for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) { |
| 329 |
2/2✓ Branch 1 taken 179004 times.
✓ Branch 2 taken 412177332 times.
|
412356336 | if (str_eq(name, (char *)special_symbols[i].name)) { |
| 330 | 179004 | *id = special_symbols[i].id; | |
| 331 | 179004 | return 1; | |
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 335 | // loop through extensions | ||
| 336 |
2/2✓ Branch 1 taken 228575900 times.
✓ Branch 2 taken 2299766 times.
|
230875666 | for (unsigned int i = 0; i < lbm_get_max_extensions(); i ++) { |
| 337 |
4/4✓ Branch 0 taken 121615060 times.
✓ Branch 1 taken 106960840 times.
✓ Branch 3 taken 26488 times.
✓ Branch 4 taken 121588572 times.
|
228575900 | if (extension_table[i].name && str_eq(name, extension_table[i].name)) { |
| 338 | 26488 | *id = EXTENSION_SYMBOLS_START + i; | |
| 339 | 26488 | return 1; | |
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | 2299766 | lbm_uint *curr = symlist; | |
| 344 |
2/2✓ Branch 0 taken 26753076 times.
✓ Branch 1 taken 2183202 times.
|
28936278 | while (curr) { |
| 345 | 26753076 | char *str = (char*)curr[NAME]; | |
| 346 |
2/2✓ Branch 1 taken 116564 times.
✓ Branch 2 taken 26636512 times.
|
26753076 | if (str_eq(name, str)) { |
| 347 | 116564 | *id = curr[ID]; | |
| 348 | 116564 | return 1; | |
| 349 | } | ||
| 350 | 26636512 | curr = (lbm_uint*)curr[NEXT]; | |
| 351 | } | ||
| 352 | 2183202 | return 0; | |
| 353 | } | ||
| 354 | |||
| 355 | extern lbm_flash_status lbm_write_const_array_padded(uint8_t *data, lbm_uint n, lbm_uint *res); | ||
| 356 | |||
| 357 | |||
| 358 | ✗ | static bool store_symbol_name_flash(char *name, lbm_uint *res) { | |
| 359 | ✗ | size_t n = strlen(name) + 1; | |
| 360 | ✗ | if (n == 1) return 0; // failure if empty symbol | |
| 361 | |||
| 362 | lbm_uint alloc_size; | ||
| 363 | ✗ | if (n % sizeof(lbm_uint) == 0) { | |
| 364 | ✗ | alloc_size = n/(sizeof(lbm_uint)); | |
| 365 | } else { | ||
| 366 | ✗ | alloc_size = (n/(sizeof(lbm_uint))) + 1; | |
| 367 | } | ||
| 368 | |||
| 369 | ✗ | lbm_uint symbol_addr = 0; | |
| 370 | ✗ | lbm_flash_status s = lbm_write_const_array_padded((uint8_t*)name, n, &symbol_addr); | |
| 371 | ✗ | if (s != LBM_FLASH_WRITE_OK || symbol_addr == 0) { | |
| 372 | ✗ | return false; | |
| 373 | } | ||
| 374 | ✗ | symbol_table_size_strings_flash += alloc_size; | |
| 375 | ✗ | *res = symbol_addr; | |
| 376 | ✗ | return true; | |
| 377 | } | ||
| 378 | |||
| 379 | 107324 | static bool add_symbol_to_symtab(char* name, lbm_uint id) { | |
| 380 | 107324 | size_t n = strlen(name) + 1; | |
| 381 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107324 times.
|
107324 | if (n == 1) return 0; // failure if empty symbol |
| 382 | |||
| 383 | lbm_uint alloc_size; | ||
| 384 |
2/2✓ Branch 0 taken 16016 times.
✓ Branch 1 taken 91308 times.
|
107324 | if (n % sizeof(lbm_uint) == 0) { |
| 385 | 16016 | alloc_size = n/(sizeof(lbm_uint)); | |
| 386 | } else { | ||
| 387 | 91308 | alloc_size = (n/(sizeof(lbm_uint))) + 1; | |
| 388 | } | ||
| 389 | |||
| 390 | 107324 | lbm_uint *storage = lbm_memory_allocate(alloc_size + 3); | |
| 391 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107324 times.
|
107324 | if (storage == NULL) return false; |
| 392 | 107324 | strncpy(((char*)storage) + (3 * sizeof(lbm_uint)), name, n); | |
| 393 | 107324 | lbm_uint *m = storage; | |
| 394 | |||
| 395 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107324 times.
|
107324 | if (m == NULL) return false; |
| 396 | |||
| 397 | 107324 | symbol_table_size_list += 3; | |
| 398 | 107324 | m[NAME] = (lbm_uint)&storage[3]; | |
| 399 | 107324 | m[NEXT] = (lbm_uint) symlist; | |
| 400 | 107324 | symlist = m; | |
| 401 | 107324 | m[ID] =id; | |
| 402 | 107324 | return true; | |
| 403 | } | ||
| 404 | |||
| 405 | ✗ | static bool add_symbol_to_symtab_flash(lbm_uint name, lbm_uint id) { | |
| 406 | lbm_uint entry[3]; | ||
| 407 | ✗ | entry[NAME] = name; | |
| 408 | ✗ | entry[NEXT] = (lbm_uint) symlist; | |
| 409 | ✗ | entry[ID] = id; | |
| 410 | ✗ | lbm_uint entry_addr = 0; | |
| 411 | ✗ | if (lbm_write_const_raw(entry,3, &entry_addr) == LBM_FLASH_WRITE_OK) { | |
| 412 | ✗ | symlist = (lbm_uint*)entry_addr; | |
| 413 | ✗ | symbol_table_size_list_flash += 3; | |
| 414 | ✗ | return true; | |
| 415 | } | ||
| 416 | ✗ | return false; | |
| 417 | } | ||
| 418 | |||
| 419 | 107324 | int lbm_add_symbol_base(char *name, lbm_uint *id, bool flash) { | |
| 420 | lbm_uint symbol_name_storage; | ||
| 421 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 107324 times.
|
107324 | if (flash) { |
| 422 | ✗ | if (!store_symbol_name_flash(name, &symbol_name_storage)) return 0; | |
| 423 | ✗ | if (!add_symbol_to_symtab_flash(symbol_name_storage, next_symbol_id)) return 0; | |
| 424 | } else { | ||
| 425 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 107324 times.
|
107324 | if (!add_symbol_to_symtab(name, next_symbol_id)) { |
| 426 | ✗ | return 0; | |
| 427 | } | ||
| 428 | } | ||
| 429 | 107324 | *id = next_symbol_id ++; | |
| 430 | 107324 | return 1; | |
| 431 | } | ||
| 432 | |||
| 433 | 34888 | int lbm_add_symbol(char *name, lbm_uint* id) { | |
| 434 | lbm_uint sym_id; | ||
| 435 |
1/2✓ Branch 1 taken 34888 times.
✗ Branch 2 not taken.
|
34888 | if (!lbm_get_symbol_by_name(name, &sym_id)) { |
| 436 | 34888 | return lbm_add_symbol_base(name, id, false); | |
| 437 | } else { | ||
| 438 | ✗ | *id = sym_id; | |
| 439 | ✗ | return 1; | |
| 440 | } | ||
| 441 | return 0; | ||
| 442 | } | ||
| 443 | |||
| 444 | ✗ | int lbm_add_symbol_flash(char *name, lbm_uint* id) { | |
| 445 | lbm_uint sym_id; | ||
| 446 | ✗ | if (!lbm_get_symbol_by_name(name, &sym_id)) { | |
| 447 | ✗ | return lbm_add_symbol_base(name, id, true); | |
| 448 | } else { | ||
| 449 | ✗ | *id = sym_id; | |
| 450 | ✗ | return 1; | |
| 451 | } | ||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | |||
| 455 | 331436 | int lbm_add_symbol_const_base(char *name, lbm_uint* id) { | |
| 456 | 331436 | lbm_uint *m = lbm_memory_allocate(3); | |
| 457 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 331436 times.
|
331436 | if (m == NULL) return 0; |
| 458 | 331436 | symbol_table_size_list += 3; | |
| 459 | 331436 | m[NAME] = (lbm_uint) name; | |
| 460 | 331436 | m[NEXT] = (lbm_uint) symlist; | |
| 461 | 331436 | symlist = m; | |
| 462 | 331436 | m[ID] = next_symbol_id; | |
| 463 | 331436 | *id = next_symbol_id ++; | |
| 464 | 331436 | return 1; | |
| 465 | } | ||
| 466 | |||
| 467 | 331436 | int lbm_add_symbol_const(char *name, lbm_uint* id) { | |
| 468 | lbm_uint sym_id; | ||
| 469 |
1/2✓ Branch 1 taken 331436 times.
✗ Branch 2 not taken.
|
331436 | if (!lbm_get_symbol_by_name(name, &sym_id)) { |
| 470 | 331436 | return lbm_add_symbol_const_base(name, id); | |
| 471 | } else { | ||
| 472 | ✗ | *id = sym_id; | |
| 473 | ✗ | return 1; | |
| 474 | } | ||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | ✗ | int lbm_str_to_symbol(char *name, lbm_uint *sym_id) { | |
| 479 | ✗ | if (lbm_get_symbol_by_name(name, sym_id)) | |
| 480 | ✗ | return 1; | |
| 481 | ✗ | else if (lbm_add_symbol(name, sym_id)) | |
| 482 | ✗ | return 1; | |
| 483 | ✗ | return 0; | |
| 484 | } | ||
| 485 | |||
| 486 | ✗ | lbm_uint lbm_get_symbol_table_size(void) { | |
| 487 | ✗ | return (symbol_table_size_list + | |
| 488 | ✗ | symbol_table_size_strings) * sizeof(lbm_uint); | |
| 489 | } | ||
| 490 | |||
| 491 | ✗ | lbm_uint lbm_get_symbol_table_size_flash(void) { | |
| 492 | ✗ | return (symbol_table_size_list_flash + | |
| 493 | ✗ | symbol_table_size_strings_flash) * sizeof(lbm_uint); | |
| 494 | } | ||
| 495 | |||
| 496 | ✗ | lbm_uint lbm_get_symbol_table_size_names(void) { | |
| 497 | ✗ | return symbol_table_size_strings * sizeof(lbm_uint); | |
| 498 | } | ||
| 499 | |||
| 500 | ✗ | lbm_uint lbm_get_symbol_table_size_names_flash(void) { | |
| 501 | ✗ | return symbol_table_size_strings_flash * sizeof(lbm_uint); | |
| 502 | } | ||
| 503 | |||
| 504 | ✗ | bool lbm_symbol_in_flash(char *str) { | |
| 505 | ✗ | return !lbm_memory_ptr_inside((lbm_uint*)str); | |
| 506 | } | ||
| 507 | |||
| 508 | ✗ | bool lbm_symbol_list_entry_in_flash(char *str) { | |
| 509 | ✗ | lbm_uint *entry = lbm_get_symbol_list_entry_by_name(str); | |
| 510 | ✗ | return (entry == NULL || !lbm_memory_ptr_inside(entry)); | |
| 511 | } | ||
| 512 |