1 /* 2 * ***************************************************************************** 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2018-2021 Gavin D. Howard and contributors. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * * Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ***************************************************************************** 31 * 32 * Definitions for bc programs. 33 * 34 */ 35 36 #ifndef BC_PROGRAM_H 37 #define BC_PROGRAM_H 38 39 #include <assert.h> 40 #include <stddef.h> 41 42 #include <status.h> 43 #include <parse.h> 44 #include <lang.h> 45 #include <num.h> 46 #include <rand.h> 47 48 /// The index of ibase in the globals array. 49 #define BC_PROG_GLOBALS_IBASE (0) 50 51 /// The index of obase in the globals array. 52 #define BC_PROG_GLOBALS_OBASE (1) 53 54 /// The index of scale in the globals array. 55 #define BC_PROG_GLOBALS_SCALE (2) 56 57 #if BC_ENABLE_EXTRA_MATH 58 59 /// The index of the rand max in the maxes array. 60 #define BC_PROG_MAX_RAND (3) 61 62 #endif // BC_ENABLE_EXTRA_MATH 63 64 /// The length of the globals array. 65 #define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH) 66 67 typedef struct BcProgram { 68 69 /// The array of globals values. 70 BcBigDig globals[BC_PROG_GLOBALS_LEN]; 71 72 /// The array of globals stacks. 73 BcVec globals_v[BC_PROG_GLOBALS_LEN]; 74 75 #if BC_ENABLE_EXTRA_MATH 76 77 /// The pseudo-random number generator. 78 BcRNG rng; 79 80 #endif // BC_ENABLE_EXTRA_MATH 81 82 /// The results stack. 83 BcVec results; 84 85 /// The execution stack. 86 BcVec stack; 87 88 /// A pointer to the current function's constants. 89 BcVec *consts; 90 91 /// A pointer to the current function's strings. 92 BcVec *strs; 93 94 /// The array of functions. 95 BcVec fns; 96 97 /// The map of functions to go with fns. 98 BcVec fn_map; 99 100 /// The array of variables. 101 BcVec vars; 102 103 /// The map of variables to go with vars. 104 BcVec var_map; 105 106 /// The array of arrays. 107 BcVec arrs; 108 109 /// The map of arrays to go with arrs. 110 BcVec arr_map; 111 112 #if DC_ENABLED 113 114 /// A vector of tail calls. These are just integers, which are the number of 115 /// tail calls that have been executed for each function (string) on the 116 /// stack for dc. This is to prevent dc from constantly growing memory use 117 /// because of pushing more and more string executions on the stack. 118 BcVec tail_calls; 119 120 #endif // DC_ENABLED 121 122 /// A BcNum that has the proper base for asciify. 123 BcNum strmb; 124 125 #if BC_ENABLED 126 127 /// The last printed value for bc. 128 BcNum last; 129 130 #endif // BC_ENABLED 131 132 // The BcDig array for strmb. This uses BC_NUM_LONG_LOG10 because it is used 133 // in bc_num_ulong2num(), which attempts to realloc, unless it is big 134 // enough. This is big enough. 135 BcDig strmb_num[BC_NUM_BIGDIG_LOG10]; 136 137 } BcProgram; 138 139 /** 140 * Returns true if the stack @a s has at least @a n items, false otherwise. 141 * @param s The stack to check. 142 * @param n The number of items the stack must have. 143 * @return True if @a s has at least @a n items, false otherwise. 144 */ 145 #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n))) 146 147 /** 148 * Get a pointer to the top value in a global value stack. 149 * @param v The global value stack. 150 * @return A pointer to the top value in @a v. 151 */ 152 #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v)) 153 154 /** 155 * Get the top value in a global value stack. 156 * @param v The global value stack. 157 * @return The top value in @a v. 158 */ 159 #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v))) 160 161 /** 162 * Returns the current value of ibase. 163 * @param p The program. 164 * @return The current ibase. 165 */ 166 #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE]) 167 168 /** 169 * Returns the current value of obase. 170 * @param p The program. 171 * @return The current obase. 172 */ 173 #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE]) 174 175 /** 176 * Returns the current value of scale. 177 * @param p The program. 178 * @return The current scale. 179 */ 180 #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE]) 181 182 /// The index for the main function in the functions array.// 183 #define BC_PROG_MAIN (0) 184 185 /// The index for the read function in the functions array. 186 #define BC_PROG_READ (1) 187 188 /** 189 * Retires (completes the execution of) an instruction. Some instructions 190 * require special retirement, but most can use this. This basically pops the 191 * operands while preserving the result (which we assumed was pushed before the 192 * actual operation). 193 * @param p The program. 194 * @param nres The number of results returned by the instruction. 195 * @param nops The number of operands used by the instruction. 196 */ 197 #define bc_program_retire(p, nres, nops) \ 198 (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops))) 199 200 #if DC_ENABLED 201 202 /// A constant that tells how many functions are required in dc. 203 #define BC_PROG_REQ_FUNCS (2) 204 205 #if !BC_ENABLED 206 207 /// This define disappears the parameter last because for dc only, last is 208 /// always true. 209 #define bc_program_copyToVar(p, name, t, last) \ 210 bc_program_copyToVar(p, name, t) 211 212 #endif // !BC_ENABLED 213 214 #else // DC_ENABLED 215 216 /// This define disappears pop and copy because for bc, 'pop' and 'copy' are 217 /// always false. 218 #define bc_program_pushVar(p, code, bgn, pop, copy) \ 219 bc_program_pushVar(p, code, bgn) 220 221 // In debug mode, we want bc to check the stack, but otherwise, we don't because 222 // the bc language implicitly mandates that the stack should always have enough 223 // items. 224 #ifdef NDEBUG 225 #define BC_PROG_NO_STACK_CHECK 226 #endif // NDEBUG 227 228 #endif // DC_ENABLED 229 230 /** 231 * Returns true if the BcNum @a n is acting as a string. 232 * @param n The BcNum to test. 233 * @return True if @a n is acting as a string, false otherwise. 234 */ 235 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap) 236 237 #if BC_ENABLED 238 239 /** 240 * Returns true if the result @a r and @a n is a number. 241 * @param r The result. 242 * @param n The number corresponding to the result. 243 * @return True if the result holds a number, false otherwise. 244 */ 245 #define BC_PROG_NUM(r, n) \ 246 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 247 248 #else // BC_ENABLED 249 250 /** 251 * Returns true if the result @a r and @a n is a number. 252 * @param r The result. 253 * @param n The number corresponding to the result. 254 * @return True if the result holds a number, false otherwise. 255 */ 256 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 257 258 #endif // BC_ENABLED 259 260 /** 261 * This is a function type for unary operations. Currently, these include 262 * boolean not, negation, and truncation with extra math. 263 * @param r The BcResult to store the result into. 264 * @param n The parameter to the unary operation. 265 */ 266 typedef void (*BcProgramUnary)(BcResult *r, BcNum *n); 267 268 /** 269 * Initializes the BcProgram. 270 * @param p The program to initialize. 271 */ 272 void bc_program_init(BcProgram *p); 273 274 #ifndef NDEBUG 275 276 /** 277 * Frees a BcProgram. This is only used in debug builds because a BcProgram is 278 * only freed on program exit, and we don't care about freeing resources on 279 * exit. 280 * @param p The program to initialize. 281 */ 282 void bc_program_free(BcProgram *p); 283 284 #endif // NDEBUG 285 286 #if BC_DEBUG_CODE 287 #if BC_ENABLED && DC_ENABLED 288 289 /** 290 * Prints the bytecode in a function. This is a debug-only function. 291 * @param p The program. 292 */ 293 void bc_program_code(const BcProgram *p); 294 295 /** 296 * Prints an instruction. This is a debug-only function. 297 * @param p The program. 298 * @param code The bytecode array. 299 * @param bgn A pointer to the current index. It is also updated to the next 300 * index. 301 */ 302 void bc_program_printInst(const BcProgram *p, const char *code, 303 size_t *restrict bgn); 304 305 /** 306 * Prints the stack. This is a debug-only function. 307 * @param p The program. 308 */ 309 void bc_program_printStackDebug(BcProgram* p); 310 311 #endif // BC_ENABLED && DC_ENABLED 312 #endif // BC_DEBUG_CODE 313 314 /** 315 * Returns the index of the variable or array in their respective arrays. 316 * @param p The program. 317 * @param id The BcId of the variable or array. 318 * @param var True if the search should be for a variable, false for an array. 319 * @return The index of the variable or array in the correct array. 320 */ 321 size_t bc_program_search(BcProgram *p, const char* id, bool var); 322 323 /** 324 * Adds a string to a function and returns the string's index in the function. 325 * @param p The program. 326 * @param str The string to add. 327 * @param fidx The index of the function to add to. 328 */ 329 size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx); 330 331 /** 332 * Inserts a function into the program and returns the index of the function in 333 * the fns array. 334 * @param p The program. 335 * @param name The name of the function. 336 * @return The index of the function after insertion. 337 */ 338 size_t bc_program_insertFunc(BcProgram *p, const char *name); 339 340 /** 341 * Resets a program, usually because of resetting after an error. 342 * @param p The program to reset. 343 */ 344 void bc_program_reset(BcProgram *p); 345 346 /** 347 * Executes bc or dc code in the BcProgram. 348 * @param p The program. 349 */ 350 void bc_program_exec(BcProgram *p); 351 352 /** 353 * Negates a copy of a BcNum. This is a BcProgramUnary function. 354 * @param r The BcResult to store the result into. 355 * @param n The parameter to the unary operation. 356 */ 357 void bc_program_negate(BcResult *r, BcNum *n); 358 359 /** 360 * Returns a boolean not of a BcNum. This is a BcProgramUnary function. 361 * @param r The BcResult to store the result into. 362 * @param n The parameter to the unary operation. 363 */ 364 void bc_program_not(BcResult *r, BcNum *n); 365 366 #if BC_ENABLE_EXTRA_MATH 367 368 /** 369 * Truncates a copy of a BcNum. This is a BcProgramUnary function. 370 * @param r The BcResult to store the result into. 371 * @param n The parameter to the unary operation. 372 */ 373 void bc_program_trunc(BcResult *r, BcNum *n); 374 375 #endif // BC_ENABLE_EXTRA_MATH 376 377 /// A reference to an array of binary operator functions. 378 extern const BcNumBinaryOp bc_program_ops[]; 379 380 /// A reference to an array of binary operator allocation request functions. 381 extern const BcNumBinaryOpReq bc_program_opReqs[]; 382 383 /// A reference to an array of unary operator functions. 384 extern const BcProgramUnary bc_program_unarys[]; 385 386 /// A reference to a filename for command-line expressions. 387 extern const char bc_program_exprs_name[]; 388 389 /// A reference to a filename for stdin. 390 extern const char bc_program_stdin_name[]; 391 392 /// A reference to the ready message printed on SIGINT. 393 extern const char bc_program_ready_msg[]; 394 395 /// A reference to the length of the ready message. 396 extern const size_t bc_program_ready_msg_len; 397 398 /// A reference to an array of escape characters for the print statement. 399 extern const char bc_program_esc_chars[]; 400 401 /// A reference to an array of the characters corresponding to the escape 402 /// characters in bc_program_esc_chars. 403 extern const char bc_program_esc_seqs[]; 404 405 #if BC_HAS_COMPUTED_GOTO 406 407 #if BC_DEBUG_CODE 408 409 #define BC_PROG_JUMP(inst, code, ip) \ 410 do { \ 411 inst = (uchar) (code)[(ip)->idx++]; \ 412 bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]); \ 413 bc_file_flush(&vm.ferr, bc_flush_none); \ 414 goto *bc_program_inst_lbls[inst]; \ 415 } while (0) 416 417 #else // BC_DEBUG_CODE 418 419 #define BC_PROG_JUMP(inst, code, ip) \ 420 do { \ 421 inst = (uchar) (code)[(ip)->idx++]; \ 422 goto *bc_program_inst_lbls[inst]; \ 423 } while (0) 424 425 #endif // BC_DEBUG_CODE 426 427 #define BC_PROG_DIRECT_JUMP(l) goto lbl_ ## l; 428 #define BC_PROG_LBL(l) lbl_ ## l 429 #define BC_PROG_FALLTHROUGH 430 431 #if BC_C11 432 433 #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*)) 434 #define BC_PROG_LBLS_ASSERT \ 435 static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1,\ 436 "bc_program_inst_lbls[] mismatches the instructions") 437 438 #else // BC_C11 439 440 #define BC_PROG_LBLS_ASSERT 441 442 #endif // BC_C11 443 444 #if BC_ENABLED 445 446 #if DC_ENABLED 447 448 #if BC_ENABLE_EXTRA_MATH 449 450 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ 451 &&lbl_BC_INST_INC, \ 452 &&lbl_BC_INST_DEC, \ 453 &&lbl_BC_INST_NEG, \ 454 &&lbl_BC_INST_BOOL_NOT, \ 455 &&lbl_BC_INST_TRUNC, \ 456 &&lbl_BC_INST_POWER, \ 457 &&lbl_BC_INST_MULTIPLY, \ 458 &&lbl_BC_INST_DIVIDE, \ 459 &&lbl_BC_INST_MODULUS, \ 460 &&lbl_BC_INST_PLUS, \ 461 &&lbl_BC_INST_MINUS, \ 462 &&lbl_BC_INST_PLACES, \ 463 &&lbl_BC_INST_LSHIFT, \ 464 &&lbl_BC_INST_RSHIFT, \ 465 &&lbl_BC_INST_REL_EQ, \ 466 &&lbl_BC_INST_REL_LE, \ 467 &&lbl_BC_INST_REL_GE, \ 468 &&lbl_BC_INST_REL_NE, \ 469 &&lbl_BC_INST_REL_LT, \ 470 &&lbl_BC_INST_REL_GT, \ 471 &&lbl_BC_INST_BOOL_OR, \ 472 &&lbl_BC_INST_BOOL_AND, \ 473 &&lbl_BC_INST_ASSIGN_POWER, \ 474 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 475 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 476 &&lbl_BC_INST_ASSIGN_MODULUS, \ 477 &&lbl_BC_INST_ASSIGN_PLUS, \ 478 &&lbl_BC_INST_ASSIGN_MINUS, \ 479 &&lbl_BC_INST_ASSIGN_PLACES, \ 480 &&lbl_BC_INST_ASSIGN_LSHIFT, \ 481 &&lbl_BC_INST_ASSIGN_RSHIFT, \ 482 &&lbl_BC_INST_ASSIGN, \ 483 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 484 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 485 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 486 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 487 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 488 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 489 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \ 490 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \ 491 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \ 492 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 493 &&lbl_BC_INST_NUM, \ 494 &&lbl_BC_INST_VAR, \ 495 &&lbl_BC_INST_ARRAY_ELEM, \ 496 &&lbl_BC_INST_ARRAY, \ 497 &&lbl_BC_INST_ZERO, \ 498 &&lbl_BC_INST_ONE, \ 499 &&lbl_BC_INST_LAST, \ 500 &&lbl_BC_INST_IBASE, \ 501 &&lbl_BC_INST_OBASE, \ 502 &&lbl_BC_INST_SCALE, \ 503 &&lbl_BC_INST_SEED, \ 504 &&lbl_BC_INST_LENGTH, \ 505 &&lbl_BC_INST_SCALE_FUNC, \ 506 &&lbl_BC_INST_SQRT, \ 507 &&lbl_BC_INST_ABS, \ 508 &&lbl_BC_INST_IRAND, \ 509 &&lbl_BC_INST_ASCIIFY, \ 510 &&lbl_BC_INST_READ, \ 511 &&lbl_BC_INST_RAND, \ 512 &&lbl_BC_INST_MAXIBASE, \ 513 &&lbl_BC_INST_MAXOBASE, \ 514 &&lbl_BC_INST_MAXSCALE, \ 515 &&lbl_BC_INST_MAXRAND, \ 516 &&lbl_BC_INST_LINE_LENGTH, \ 517 &&lbl_BC_INST_GLOBAL_STACKS, \ 518 &&lbl_BC_INST_LEADING_ZERO, \ 519 &&lbl_BC_INST_PRINT, \ 520 &&lbl_BC_INST_PRINT_POP, \ 521 &&lbl_BC_INST_STR, \ 522 &&lbl_BC_INST_PRINT_STR, \ 523 &&lbl_BC_INST_JUMP, \ 524 &&lbl_BC_INST_JUMP_ZERO, \ 525 &&lbl_BC_INST_CALL, \ 526 &&lbl_BC_INST_RET, \ 527 &&lbl_BC_INST_RET0, \ 528 &&lbl_BC_INST_RET_VOID, \ 529 &&lbl_BC_INST_HALT, \ 530 &&lbl_BC_INST_POP, \ 531 &&lbl_BC_INST_SWAP, \ 532 &&lbl_BC_INST_MODEXP, \ 533 &&lbl_BC_INST_DIVMOD, \ 534 &&lbl_BC_INST_PRINT_STREAM, \ 535 &&lbl_BC_INST_POP_EXEC, \ 536 &&lbl_BC_INST_EXECUTE, \ 537 &&lbl_BC_INST_EXEC_COND, \ 538 &&lbl_BC_INST_PRINT_STACK, \ 539 &&lbl_BC_INST_CLEAR_STACK, \ 540 &&lbl_BC_INST_REG_STACK_LEN, \ 541 &&lbl_BC_INST_STACK_LEN, \ 542 &&lbl_BC_INST_DUPLICATE, \ 543 &&lbl_BC_INST_LOAD, \ 544 &&lbl_BC_INST_PUSH_VAR, \ 545 &&lbl_BC_INST_PUSH_TO_VAR, \ 546 &&lbl_BC_INST_QUIT, \ 547 &&lbl_BC_INST_NQUIT, \ 548 &&lbl_BC_INST_EXEC_STACK_LEN, \ 549 &&lbl_BC_INST_INVALID, \ 550 } 551 552 #else // BC_ENABLE_EXTRA_MATH 553 554 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ 555 &&lbl_BC_INST_INC, \ 556 &&lbl_BC_INST_DEC, \ 557 &&lbl_BC_INST_NEG, \ 558 &&lbl_BC_INST_BOOL_NOT, \ 559 &&lbl_BC_INST_POWER, \ 560 &&lbl_BC_INST_MULTIPLY, \ 561 &&lbl_BC_INST_DIVIDE, \ 562 &&lbl_BC_INST_MODULUS, \ 563 &&lbl_BC_INST_PLUS, \ 564 &&lbl_BC_INST_MINUS, \ 565 &&lbl_BC_INST_REL_EQ, \ 566 &&lbl_BC_INST_REL_LE, \ 567 &&lbl_BC_INST_REL_GE, \ 568 &&lbl_BC_INST_REL_NE, \ 569 &&lbl_BC_INST_REL_LT, \ 570 &&lbl_BC_INST_REL_GT, \ 571 &&lbl_BC_INST_BOOL_OR, \ 572 &&lbl_BC_INST_BOOL_AND, \ 573 &&lbl_BC_INST_ASSIGN_POWER, \ 574 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 575 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 576 &&lbl_BC_INST_ASSIGN_MODULUS, \ 577 &&lbl_BC_INST_ASSIGN_PLUS, \ 578 &&lbl_BC_INST_ASSIGN_MINUS, \ 579 &&lbl_BC_INST_ASSIGN, \ 580 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 581 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 582 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 583 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 584 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 585 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 586 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 587 &&lbl_BC_INST_NUM, \ 588 &&lbl_BC_INST_VAR, \ 589 &&lbl_BC_INST_ARRAY_ELEM, \ 590 &&lbl_BC_INST_ARRAY, \ 591 &&lbl_BC_INST_ZERO, \ 592 &&lbl_BC_INST_ONE, \ 593 &&lbl_BC_INST_LAST, \ 594 &&lbl_BC_INST_IBASE, \ 595 &&lbl_BC_INST_OBASE, \ 596 &&lbl_BC_INST_SCALE, \ 597 &&lbl_BC_INST_LENGTH, \ 598 &&lbl_BC_INST_SCALE_FUNC, \ 599 &&lbl_BC_INST_SQRT, \ 600 &&lbl_BC_INST_ABS, \ 601 &&lbl_BC_INST_ASCIIFY, \ 602 &&lbl_BC_INST_READ, \ 603 &&lbl_BC_INST_MAXIBASE, \ 604 &&lbl_BC_INST_MAXOBASE, \ 605 &&lbl_BC_INST_MAXSCALE, \ 606 &&lbl_BC_INST_LINE_LENGTH, \ 607 &&lbl_BC_INST_GLOBAL_STACKS, \ 608 &&lbl_BC_INST_LEADING_ZERO, \ 609 &&lbl_BC_INST_PRINT, \ 610 &&lbl_BC_INST_PRINT_POP, \ 611 &&lbl_BC_INST_STR, \ 612 &&lbl_BC_INST_PRINT_STR, \ 613 &&lbl_BC_INST_JUMP, \ 614 &&lbl_BC_INST_JUMP_ZERO, \ 615 &&lbl_BC_INST_CALL, \ 616 &&lbl_BC_INST_RET, \ 617 &&lbl_BC_INST_RET0, \ 618 &&lbl_BC_INST_RET_VOID, \ 619 &&lbl_BC_INST_HALT, \ 620 &&lbl_BC_INST_POP, \ 621 &&lbl_BC_INST_SWAP, \ 622 &&lbl_BC_INST_MODEXP, \ 623 &&lbl_BC_INST_DIVMOD, \ 624 &&lbl_BC_INST_PRINT_STREAM, \ 625 &&lbl_BC_INST_POP_EXEC, \ 626 &&lbl_BC_INST_EXECUTE, \ 627 &&lbl_BC_INST_EXEC_COND, \ 628 &&lbl_BC_INST_PRINT_STACK, \ 629 &&lbl_BC_INST_CLEAR_STACK, \ 630 &&lbl_BC_INST_REG_STACK_LEN, \ 631 &&lbl_BC_INST_STACK_LEN, \ 632 &&lbl_BC_INST_DUPLICATE, \ 633 &&lbl_BC_INST_LOAD, \ 634 &&lbl_BC_INST_PUSH_VAR, \ 635 &&lbl_BC_INST_PUSH_TO_VAR, \ 636 &&lbl_BC_INST_QUIT, \ 637 &&lbl_BC_INST_NQUIT, \ 638 &&lbl_BC_INST_EXEC_STACK_LEN, \ 639 &&lbl_BC_INST_INVALID, \ 640 } 641 642 #endif // BC_ENABLE_EXTRA_MATH 643 644 #else // DC_ENABLED 645 646 #if BC_ENABLE_EXTRA_MATH 647 648 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ 649 &&lbl_BC_INST_INC, \ 650 &&lbl_BC_INST_DEC, \ 651 &&lbl_BC_INST_NEG, \ 652 &&lbl_BC_INST_BOOL_NOT, \ 653 &&lbl_BC_INST_TRUNC, \ 654 &&lbl_BC_INST_POWER, \ 655 &&lbl_BC_INST_MULTIPLY, \ 656 &&lbl_BC_INST_DIVIDE, \ 657 &&lbl_BC_INST_MODULUS, \ 658 &&lbl_BC_INST_PLUS, \ 659 &&lbl_BC_INST_MINUS, \ 660 &&lbl_BC_INST_PLACES, \ 661 &&lbl_BC_INST_LSHIFT, \ 662 &&lbl_BC_INST_RSHIFT, \ 663 &&lbl_BC_INST_REL_EQ, \ 664 &&lbl_BC_INST_REL_LE, \ 665 &&lbl_BC_INST_REL_GE, \ 666 &&lbl_BC_INST_REL_NE, \ 667 &&lbl_BC_INST_REL_LT, \ 668 &&lbl_BC_INST_REL_GT, \ 669 &&lbl_BC_INST_BOOL_OR, \ 670 &&lbl_BC_INST_BOOL_AND, \ 671 &&lbl_BC_INST_ASSIGN_POWER, \ 672 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 673 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 674 &&lbl_BC_INST_ASSIGN_MODULUS, \ 675 &&lbl_BC_INST_ASSIGN_PLUS, \ 676 &&lbl_BC_INST_ASSIGN_MINUS, \ 677 &&lbl_BC_INST_ASSIGN_PLACES, \ 678 &&lbl_BC_INST_ASSIGN_LSHIFT, \ 679 &&lbl_BC_INST_ASSIGN_RSHIFT, \ 680 &&lbl_BC_INST_ASSIGN, \ 681 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 682 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 683 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 684 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 685 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 686 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 687 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \ 688 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \ 689 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \ 690 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 691 &&lbl_BC_INST_NUM, \ 692 &&lbl_BC_INST_VAR, \ 693 &&lbl_BC_INST_ARRAY_ELEM, \ 694 &&lbl_BC_INST_ARRAY, \ 695 &&lbl_BC_INST_ZERO, \ 696 &&lbl_BC_INST_ONE, \ 697 &&lbl_BC_INST_LAST, \ 698 &&lbl_BC_INST_IBASE, \ 699 &&lbl_BC_INST_OBASE, \ 700 &&lbl_BC_INST_SCALE, \ 701 &&lbl_BC_INST_SEED, \ 702 &&lbl_BC_INST_LENGTH, \ 703 &&lbl_BC_INST_SCALE_FUNC, \ 704 &&lbl_BC_INST_SQRT, \ 705 &&lbl_BC_INST_ABS, \ 706 &&lbl_BC_INST_IRAND, \ 707 &&lbl_BC_INST_ASCIIFY, \ 708 &&lbl_BC_INST_READ, \ 709 &&lbl_BC_INST_RAND, \ 710 &&lbl_BC_INST_MAXIBASE, \ 711 &&lbl_BC_INST_MAXOBASE, \ 712 &&lbl_BC_INST_MAXSCALE, \ 713 &&lbl_BC_INST_MAXRAND, \ 714 &&lbl_BC_INST_LINE_LENGTH, \ 715 &&lbl_BC_INST_GLOBAL_STACKS, \ 716 &&lbl_BC_INST_LEADING_ZERO, \ 717 &&lbl_BC_INST_PRINT, \ 718 &&lbl_BC_INST_PRINT_POP, \ 719 &&lbl_BC_INST_STR, \ 720 &&lbl_BC_INST_PRINT_STR, \ 721 &&lbl_BC_INST_JUMP, \ 722 &&lbl_BC_INST_JUMP_ZERO, \ 723 &&lbl_BC_INST_CALL, \ 724 &&lbl_BC_INST_RET, \ 725 &&lbl_BC_INST_RET0, \ 726 &&lbl_BC_INST_RET_VOID, \ 727 &&lbl_BC_INST_HALT, \ 728 &&lbl_BC_INST_POP, \ 729 &&lbl_BC_INST_SWAP, \ 730 &&lbl_BC_INST_MODEXP, \ 731 &&lbl_BC_INST_DIVMOD, \ 732 &&lbl_BC_INST_PRINT_STREAM, \ 733 &&lbl_BC_INST_INVALID, \ 734 } 735 736 #else // BC_ENABLE_EXTRA_MATH 737 738 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ 739 &&lbl_BC_INST_INC, \ 740 &&lbl_BC_INST_DEC, \ 741 &&lbl_BC_INST_NEG, \ 742 &&lbl_BC_INST_BOOL_NOT, \ 743 &&lbl_BC_INST_POWER, \ 744 &&lbl_BC_INST_MULTIPLY, \ 745 &&lbl_BC_INST_DIVIDE, \ 746 &&lbl_BC_INST_MODULUS, \ 747 &&lbl_BC_INST_PLUS, \ 748 &&lbl_BC_INST_MINUS, \ 749 &&lbl_BC_INST_REL_EQ, \ 750 &&lbl_BC_INST_REL_LE, \ 751 &&lbl_BC_INST_REL_GE, \ 752 &&lbl_BC_INST_REL_NE, \ 753 &&lbl_BC_INST_REL_LT, \ 754 &&lbl_BC_INST_REL_GT, \ 755 &&lbl_BC_INST_BOOL_OR, \ 756 &&lbl_BC_INST_BOOL_AND, \ 757 &&lbl_BC_INST_ASSIGN_POWER, \ 758 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 759 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 760 &&lbl_BC_INST_ASSIGN_MODULUS, \ 761 &&lbl_BC_INST_ASSIGN_PLUS, \ 762 &&lbl_BC_INST_ASSIGN_MINUS, \ 763 &&lbl_BC_INST_ASSIGN, \ 764 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 765 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 766 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 767 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 768 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 769 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 770 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 771 &&lbl_BC_INST_NUM, \ 772 &&lbl_BC_INST_VAR, \ 773 &&lbl_BC_INST_ARRAY_ELEM, \ 774 &&lbl_BC_INST_ARRAY, \ 775 &&lbl_BC_INST_ZERO, \ 776 &&lbl_BC_INST_ONE, \ 777 &&lbl_BC_INST_LAST, \ 778 &&lbl_BC_INST_IBASE, \ 779 &&lbl_BC_INST_OBASE, \ 780 &&lbl_BC_INST_SCALE, \ 781 &&lbl_BC_INST_LENGTH, \ 782 &&lbl_BC_INST_SCALE_FUNC, \ 783 &&lbl_BC_INST_SQRT, \ 784 &&lbl_BC_INST_ABS, \ 785 &&lbl_BC_INST_ASCIIFY, \ 786 &&lbl_BC_INST_READ, \ 787 &&lbl_BC_INST_MAXIBASE, \ 788 &&lbl_BC_INST_MAXOBASE, \ 789 &&lbl_BC_INST_MAXSCALE, \ 790 &&lbl_BC_INST_LINE_LENGTH, \ 791 &&lbl_BC_INST_GLOBAL_STACKS, \ 792 &&lbl_BC_INST_LEADING_ZERO, \ 793 &&lbl_BC_INST_PRINT, \ 794 &&lbl_BC_INST_PRINT_POP, \ 795 &&lbl_BC_INST_STR, \ 796 &&lbl_BC_INST_PRINT_STR, \ 797 &&lbl_BC_INST_JUMP, \ 798 &&lbl_BC_INST_JUMP_ZERO, \ 799 &&lbl_BC_INST_CALL, \ 800 &&lbl_BC_INST_RET, \ 801 &&lbl_BC_INST_RET0, \ 802 &&lbl_BC_INST_RET_VOID, \ 803 &&lbl_BC_INST_HALT, \ 804 &&lbl_BC_INST_POP, \ 805 &&lbl_BC_INST_SWAP, \ 806 &&lbl_BC_INST_MODEXP, \ 807 &&lbl_BC_INST_DIVMOD, \ 808 &&lbl_BC_INST_PRINT_STREAM, \ 809 &&lbl_BC_INST_INVALID, \ 810 } 811 812 #endif // BC_ENABLE_EXTRA_MATH 813 814 #endif // DC_ENABLED 815 816 #else // BC_ENABLED 817 818 #if BC_ENABLE_EXTRA_MATH 819 820 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ 821 &&lbl_BC_INST_NEG, \ 822 &&lbl_BC_INST_BOOL_NOT, \ 823 &&lbl_BC_INST_TRUNC, \ 824 &&lbl_BC_INST_POWER, \ 825 &&lbl_BC_INST_MULTIPLY, \ 826 &&lbl_BC_INST_DIVIDE, \ 827 &&lbl_BC_INST_MODULUS, \ 828 &&lbl_BC_INST_PLUS, \ 829 &&lbl_BC_INST_MINUS, \ 830 &&lbl_BC_INST_PLACES, \ 831 &&lbl_BC_INST_LSHIFT, \ 832 &&lbl_BC_INST_RSHIFT, \ 833 &&lbl_BC_INST_REL_EQ, \ 834 &&lbl_BC_INST_REL_LE, \ 835 &&lbl_BC_INST_REL_GE, \ 836 &&lbl_BC_INST_REL_NE, \ 837 &&lbl_BC_INST_REL_LT, \ 838 &&lbl_BC_INST_REL_GT, \ 839 &&lbl_BC_INST_BOOL_OR, \ 840 &&lbl_BC_INST_BOOL_AND, \ 841 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 842 &&lbl_BC_INST_NUM, \ 843 &&lbl_BC_INST_VAR, \ 844 &&lbl_BC_INST_ARRAY_ELEM, \ 845 &&lbl_BC_INST_ARRAY, \ 846 &&lbl_BC_INST_ZERO, \ 847 &&lbl_BC_INST_ONE, \ 848 &&lbl_BC_INST_IBASE, \ 849 &&lbl_BC_INST_OBASE, \ 850 &&lbl_BC_INST_SCALE, \ 851 &&lbl_BC_INST_SEED, \ 852 &&lbl_BC_INST_LENGTH, \ 853 &&lbl_BC_INST_SCALE_FUNC, \ 854 &&lbl_BC_INST_SQRT, \ 855 &&lbl_BC_INST_ABS, \ 856 &&lbl_BC_INST_IRAND, \ 857 &&lbl_BC_INST_ASCIIFY, \ 858 &&lbl_BC_INST_READ, \ 859 &&lbl_BC_INST_RAND, \ 860 &&lbl_BC_INST_MAXIBASE, \ 861 &&lbl_BC_INST_MAXOBASE, \ 862 &&lbl_BC_INST_MAXSCALE, \ 863 &&lbl_BC_INST_MAXRAND, \ 864 &&lbl_BC_INST_LINE_LENGTH, \ 865 &&lbl_BC_INST_LEADING_ZERO, \ 866 &&lbl_BC_INST_PRINT, \ 867 &&lbl_BC_INST_PRINT_POP, \ 868 &&lbl_BC_INST_STR, \ 869 &&lbl_BC_INST_POP, \ 870 &&lbl_BC_INST_SWAP, \ 871 &&lbl_BC_INST_MODEXP, \ 872 &&lbl_BC_INST_DIVMOD, \ 873 &&lbl_BC_INST_PRINT_STREAM, \ 874 &&lbl_BC_INST_POP_EXEC, \ 875 &&lbl_BC_INST_EXECUTE, \ 876 &&lbl_BC_INST_EXEC_COND, \ 877 &&lbl_BC_INST_PRINT_STACK, \ 878 &&lbl_BC_INST_CLEAR_STACK, \ 879 &&lbl_BC_INST_REG_STACK_LEN, \ 880 &&lbl_BC_INST_STACK_LEN, \ 881 &&lbl_BC_INST_DUPLICATE, \ 882 &&lbl_BC_INST_LOAD, \ 883 &&lbl_BC_INST_PUSH_VAR, \ 884 &&lbl_BC_INST_PUSH_TO_VAR, \ 885 &&lbl_BC_INST_QUIT, \ 886 &&lbl_BC_INST_NQUIT, \ 887 &&lbl_BC_INST_EXEC_STACK_LEN, \ 888 &&lbl_BC_INST_INVALID, \ 889 } 890 891 #else // BC_ENABLE_EXTRA_MATH 892 893 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \ 894 &&lbl_BC_INST_NEG, \ 895 &&lbl_BC_INST_BOOL_NOT, \ 896 &&lbl_BC_INST_POWER, \ 897 &&lbl_BC_INST_MULTIPLY, \ 898 &&lbl_BC_INST_DIVIDE, \ 899 &&lbl_BC_INST_MODULUS, \ 900 &&lbl_BC_INST_PLUS, \ 901 &&lbl_BC_INST_MINUS, \ 902 &&lbl_BC_INST_REL_EQ, \ 903 &&lbl_BC_INST_REL_LE, \ 904 &&lbl_BC_INST_REL_GE, \ 905 &&lbl_BC_INST_REL_NE, \ 906 &&lbl_BC_INST_REL_LT, \ 907 &&lbl_BC_INST_REL_GT, \ 908 &&lbl_BC_INST_BOOL_OR, \ 909 &&lbl_BC_INST_BOOL_AND, \ 910 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 911 &&lbl_BC_INST_NUM, \ 912 &&lbl_BC_INST_VAR, \ 913 &&lbl_BC_INST_ARRAY_ELEM, \ 914 &&lbl_BC_INST_ARRAY, \ 915 &&lbl_BC_INST_ZERO, \ 916 &&lbl_BC_INST_ONE, \ 917 &&lbl_BC_INST_IBASE, \ 918 &&lbl_BC_INST_OBASE, \ 919 &&lbl_BC_INST_SCALE, \ 920 &&lbl_BC_INST_LENGTH, \ 921 &&lbl_BC_INST_SCALE_FUNC, \ 922 &&lbl_BC_INST_SQRT, \ 923 &&lbl_BC_INST_ABS, \ 924 &&lbl_BC_INST_ASCIIFY, \ 925 &&lbl_BC_INST_READ, \ 926 &&lbl_BC_INST_MAXIBASE, \ 927 &&lbl_BC_INST_MAXOBASE, \ 928 &&lbl_BC_INST_MAXSCALE, \ 929 &&lbl_BC_INST_LINE_LENGTH, \ 930 &&lbl_BC_INST_LEADING_ZERO, \ 931 &&lbl_BC_INST_PRINT, \ 932 &&lbl_BC_INST_PRINT_POP, \ 933 &&lbl_BC_INST_STR, \ 934 &&lbl_BC_INST_POP, \ 935 &&lbl_BC_INST_SWAP, \ 936 &&lbl_BC_INST_MODEXP, \ 937 &&lbl_BC_INST_DIVMOD, \ 938 &&lbl_BC_INST_PRINT_STREAM, \ 939 &&lbl_BC_INST_POP_EXEC, \ 940 &&lbl_BC_INST_EXECUTE, \ 941 &&lbl_BC_INST_EXEC_COND, \ 942 &&lbl_BC_INST_PRINT_STACK, \ 943 &&lbl_BC_INST_CLEAR_STACK, \ 944 &&lbl_BC_INST_REG_STACK_LEN, \ 945 &&lbl_BC_INST_STACK_LEN, \ 946 &&lbl_BC_INST_DUPLICATE, \ 947 &&lbl_BC_INST_LOAD, \ 948 &&lbl_BC_INST_PUSH_VAR, \ 949 &&lbl_BC_INST_PUSH_TO_VAR, \ 950 &&lbl_BC_INST_QUIT, \ 951 &&lbl_BC_INST_NQUIT, \ 952 &&lbl_BC_INST_EXEC_STACK_LEN, \ 953 &&lbl_BC_INST_INVALID, \ 954 } 955 956 #endif // BC_ENABLE_EXTRA_MATH 957 958 #endif // BC_ENABLED 959 960 #else // BC_HAS_COMPUTED_GOTO 961 962 #define BC_PROG_JUMP(inst, code, ip) break 963 #define BC_PROG_DIRECT_JUMP(l) 964 #define BC_PROG_LBL(l) case l 965 #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH 966 967 #define BC_PROG_LBLS 968 969 #endif // BC_HAS_COMPUTED_GOTO 970 971 #endif // BC_PROGRAM_H 972