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) bc_program_copyToVar(p, name, t) 210 211 #endif // !BC_ENABLED 212 213 #else // DC_ENABLED 214 215 /// This define disappears pop and copy because for bc, 'pop' and 'copy' are 216 /// always false. 217 #define bc_program_pushVar(p, code, bgn, pop, copy) \ 218 bc_program_pushVar(p, code, bgn) 219 220 // In debug mode, we want bc to check the stack, but otherwise, we don't because 221 // the bc language implicitly mandates that the stack should always have enough 222 // items. 223 #ifdef NDEBUG 224 #define BC_PROG_NO_STACK_CHECK 225 #endif // NDEBUG 226 227 #endif // DC_ENABLED 228 229 /** 230 * Returns true if the BcNum @a n is acting as a string. 231 * @param n The BcNum to test. 232 * @return True if @a n is acting as a string, false otherwise. 233 */ 234 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap) 235 236 #if BC_ENABLED 237 238 /** 239 * Returns true if the result @a r and @a n is a number. 240 * @param r The result. 241 * @param n The number corresponding to the result. 242 * @return True if the result holds a number, false otherwise. 243 */ 244 #define BC_PROG_NUM(r, n) \ 245 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 246 247 #else // BC_ENABLED 248 249 /** 250 * Returns true if the result @a r and @a n is a number. 251 * @param r The result. 252 * @param n The number corresponding to the result. 253 * @return True if the result holds a number, false otherwise. 254 */ 255 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 256 257 #endif // BC_ENABLED 258 259 /** 260 * This is a function type for unary operations. Currently, these include 261 * boolean not, negation, and truncation with extra math. 262 * @param r The BcResult to store the result into. 263 * @param n The parameter to the unary operation. 264 */ 265 typedef void (*BcProgramUnary)(BcResult* r, BcNum* n); 266 267 /** 268 * Initializes the BcProgram. 269 * @param p The program to initialize. 270 */ 271 void 272 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 283 bc_program_free(BcProgram* p); 284 285 #endif // NDEBUG 286 287 #if BC_DEBUG_CODE 288 #if BC_ENABLED && DC_ENABLED 289 290 /** 291 * Prints the bytecode in a function. This is a debug-only function. 292 * @param p The program. 293 */ 294 void 295 bc_program_code(const BcProgram* p); 296 297 /** 298 * Prints an instruction. This is a debug-only function. 299 * @param p The program. 300 * @param code The bytecode array. 301 * @param bgn A pointer to the current index. It is also updated to the next 302 * index. 303 */ 304 void 305 bc_program_printInst(const BcProgram* p, const char* code, 306 size_t* restrict bgn); 307 308 /** 309 * Prints the stack. This is a debug-only function. 310 * @param p The program. 311 */ 312 void 313 bc_program_printStackDebug(BcProgram* p); 314 315 #endif // BC_ENABLED && DC_ENABLED 316 #endif // BC_DEBUG_CODE 317 318 /** 319 * Returns the index of the variable or array in their respective arrays. 320 * @param p The program. 321 * @param id The BcId of the variable or array. 322 * @param var True if the search should be for a variable, false for an array. 323 * @return The index of the variable or array in the correct array. 324 */ 325 size_t 326 bc_program_search(BcProgram* p, const char* id, bool var); 327 328 /** 329 * Adds a string to a function and returns the string's index in the function. 330 * @param p The program. 331 * @param str The string to add. 332 * @param fidx The index of the function to add to. 333 */ 334 size_t 335 bc_program_addString(BcProgram* p, const char* str, size_t fidx); 336 337 /** 338 * Inserts a function into the program and returns the index of the function in 339 * the fns array. 340 * @param p The program. 341 * @param name The name of the function. 342 * @return The index of the function after insertion. 343 */ 344 size_t 345 bc_program_insertFunc(BcProgram* p, const char* name); 346 347 /** 348 * Resets a program, usually because of resetting after an error. 349 * @param p The program to reset. 350 */ 351 void 352 bc_program_reset(BcProgram* p); 353 354 /** 355 * Executes bc or dc code in the BcProgram. 356 * @param p The program. 357 */ 358 void 359 bc_program_exec(BcProgram* p); 360 361 /** 362 * Negates a copy of a BcNum. This is a BcProgramUnary function. 363 * @param r The BcResult to store the result into. 364 * @param n The parameter to the unary operation. 365 */ 366 void 367 bc_program_negate(BcResult* r, BcNum* n); 368 369 /** 370 * Returns a boolean not of a BcNum. This is a BcProgramUnary function. 371 * @param r The BcResult to store the result into. 372 * @param n The parameter to the unary operation. 373 */ 374 void 375 bc_program_not(BcResult* r, BcNum* n); 376 377 #if BC_ENABLE_EXTRA_MATH 378 379 /** 380 * Truncates a copy of a BcNum. This is a BcProgramUnary function. 381 * @param r The BcResult to store the result into. 382 * @param n The parameter to the unary operation. 383 */ 384 void 385 bc_program_trunc(BcResult* r, BcNum* n); 386 387 /** 388 * Assigns a value to the seed builtin variable. 389 * @param p The program. 390 * @param val The value to assign to the seed. 391 */ 392 void 393 bc_program_assignSeed(BcProgram* p, BcNum* val); 394 395 #endif // BC_ENABLE_EXTRA_MATH 396 397 /** 398 * Assigns a value to a builtin value that is not seed. 399 * @param p The program. 400 * @param scale True if the builtin is scale. 401 * @param obase True if the builtin is obase. This cannot be true at the same 402 * time @a scale is. 403 * @param val The value to assign to the builtin. 404 */ 405 void 406 bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val); 407 408 /// A reference to an array of binary operator functions. 409 extern const BcNumBinaryOp bc_program_ops[]; 410 411 /// A reference to an array of binary operator allocation request functions. 412 extern const BcNumBinaryOpReq bc_program_opReqs[]; 413 414 /// A reference to an array of unary operator functions. 415 extern const BcProgramUnary bc_program_unarys[]; 416 417 /// A reference to a filename for command-line expressions. 418 extern const char bc_program_exprs_name[]; 419 420 /// A reference to a filename for stdin. 421 extern const char bc_program_stdin_name[]; 422 423 /// A reference to the ready message printed on SIGINT. 424 extern const char bc_program_ready_msg[]; 425 426 /// A reference to the length of the ready message. 427 extern const size_t bc_program_ready_msg_len; 428 429 /// A reference to an array of escape characters for the print statement. 430 extern const char bc_program_esc_chars[]; 431 432 /// A reference to an array of the characters corresponding to the escape 433 /// characters in bc_program_esc_chars. 434 extern const char bc_program_esc_seqs[]; 435 436 #if BC_HAS_COMPUTED_GOTO 437 438 #if BC_DEBUG_CODE 439 440 // clang-format off 441 #define BC_PROG_JUMP(inst, code, ip) \ 442 do \ 443 { \ 444 inst = (uchar) (code)[(ip)->idx++]; \ 445 bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]); \ 446 bc_file_flush(&vm.ferr, bc_flush_none); \ 447 goto *bc_program_inst_lbls[inst]; \ 448 } \ 449 while (0) 450 // clang-format on 451 452 #else // BC_DEBUG_CODE 453 454 // clang-format off 455 #define BC_PROG_JUMP(inst, code, ip) \ 456 do \ 457 { \ 458 inst = (uchar) (code)[(ip)->idx++]; \ 459 goto *bc_program_inst_lbls[inst]; \ 460 } \ 461 while (0) 462 // clang-format on 463 464 #endif // BC_DEBUG_CODE 465 466 #define BC_PROG_DIRECT_JUMP(l) goto lbl_##l; 467 #define BC_PROG_LBL(l) lbl_##l 468 #define BC_PROG_FALLTHROUGH 469 470 #if BC_C11 471 472 #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*)) 473 #define BC_PROG_LBLS_ASSERT \ 474 _Static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1, \ 475 "bc_program_inst_lbls[] mismatches the instructions") 476 477 #else // BC_C11 478 479 #define BC_PROG_LBLS_ASSERT 480 481 #endif // BC_C11 482 483 #if BC_ENABLED 484 485 #if DC_ENABLED 486 487 #if BC_ENABLE_EXTRA_MATH 488 489 #define BC_PROG_LBLS \ 490 static const void* const bc_program_inst_lbls[] = { \ 491 &&lbl_BC_INST_INC, \ 492 &&lbl_BC_INST_DEC, \ 493 &&lbl_BC_INST_NEG, \ 494 &&lbl_BC_INST_BOOL_NOT, \ 495 &&lbl_BC_INST_TRUNC, \ 496 &&lbl_BC_INST_POWER, \ 497 &&lbl_BC_INST_MULTIPLY, \ 498 &&lbl_BC_INST_DIVIDE, \ 499 &&lbl_BC_INST_MODULUS, \ 500 &&lbl_BC_INST_PLUS, \ 501 &&lbl_BC_INST_MINUS, \ 502 &&lbl_BC_INST_PLACES, \ 503 &&lbl_BC_INST_LSHIFT, \ 504 &&lbl_BC_INST_RSHIFT, \ 505 &&lbl_BC_INST_REL_EQ, \ 506 &&lbl_BC_INST_REL_LE, \ 507 &&lbl_BC_INST_REL_GE, \ 508 &&lbl_BC_INST_REL_NE, \ 509 &&lbl_BC_INST_REL_LT, \ 510 &&lbl_BC_INST_REL_GT, \ 511 &&lbl_BC_INST_BOOL_OR, \ 512 &&lbl_BC_INST_BOOL_AND, \ 513 &&lbl_BC_INST_ASSIGN_POWER, \ 514 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 515 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 516 &&lbl_BC_INST_ASSIGN_MODULUS, \ 517 &&lbl_BC_INST_ASSIGN_PLUS, \ 518 &&lbl_BC_INST_ASSIGN_MINUS, \ 519 &&lbl_BC_INST_ASSIGN_PLACES, \ 520 &&lbl_BC_INST_ASSIGN_LSHIFT, \ 521 &&lbl_BC_INST_ASSIGN_RSHIFT, \ 522 &&lbl_BC_INST_ASSIGN, \ 523 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 524 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 525 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 526 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 527 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 528 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 529 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \ 530 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \ 531 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \ 532 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 533 &&lbl_BC_INST_NUM, \ 534 &&lbl_BC_INST_VAR, \ 535 &&lbl_BC_INST_ARRAY_ELEM, \ 536 &&lbl_BC_INST_ARRAY, \ 537 &&lbl_BC_INST_ZERO, \ 538 &&lbl_BC_INST_ONE, \ 539 &&lbl_BC_INST_LAST, \ 540 &&lbl_BC_INST_IBASE, \ 541 &&lbl_BC_INST_OBASE, \ 542 &&lbl_BC_INST_SCALE, \ 543 &&lbl_BC_INST_SEED, \ 544 &&lbl_BC_INST_LENGTH, \ 545 &&lbl_BC_INST_SCALE_FUNC, \ 546 &&lbl_BC_INST_SQRT, \ 547 &&lbl_BC_INST_ABS, \ 548 &&lbl_BC_INST_IRAND, \ 549 &&lbl_BC_INST_ASCIIFY, \ 550 &&lbl_BC_INST_READ, \ 551 &&lbl_BC_INST_RAND, \ 552 &&lbl_BC_INST_MAXIBASE, \ 553 &&lbl_BC_INST_MAXOBASE, \ 554 &&lbl_BC_INST_MAXSCALE, \ 555 &&lbl_BC_INST_MAXRAND, \ 556 &&lbl_BC_INST_LINE_LENGTH, \ 557 &&lbl_BC_INST_GLOBAL_STACKS, \ 558 &&lbl_BC_INST_LEADING_ZERO, \ 559 &&lbl_BC_INST_PRINT, \ 560 &&lbl_BC_INST_PRINT_POP, \ 561 &&lbl_BC_INST_STR, \ 562 &&lbl_BC_INST_PRINT_STR, \ 563 &&lbl_BC_INST_JUMP, \ 564 &&lbl_BC_INST_JUMP_ZERO, \ 565 &&lbl_BC_INST_CALL, \ 566 &&lbl_BC_INST_RET, \ 567 &&lbl_BC_INST_RET0, \ 568 &&lbl_BC_INST_RET_VOID, \ 569 &&lbl_BC_INST_HALT, \ 570 &&lbl_BC_INST_POP, \ 571 &&lbl_BC_INST_SWAP, \ 572 &&lbl_BC_INST_MODEXP, \ 573 &&lbl_BC_INST_DIVMOD, \ 574 &&lbl_BC_INST_PRINT_STREAM, \ 575 &&lbl_BC_INST_POP_EXEC, \ 576 &&lbl_BC_INST_EXECUTE, \ 577 &&lbl_BC_INST_EXEC_COND, \ 578 &&lbl_BC_INST_PRINT_STACK, \ 579 &&lbl_BC_INST_CLEAR_STACK, \ 580 &&lbl_BC_INST_REG_STACK_LEN, \ 581 &&lbl_BC_INST_STACK_LEN, \ 582 &&lbl_BC_INST_DUPLICATE, \ 583 &&lbl_BC_INST_LOAD, \ 584 &&lbl_BC_INST_PUSH_VAR, \ 585 &&lbl_BC_INST_PUSH_TO_VAR, \ 586 &&lbl_BC_INST_QUIT, \ 587 &&lbl_BC_INST_NQUIT, \ 588 &&lbl_BC_INST_EXEC_STACK_LEN, \ 589 &&lbl_BC_INST_INVALID, \ 590 } 591 592 #else // BC_ENABLE_EXTRA_MATH 593 594 #define BC_PROG_LBLS \ 595 static const void* const bc_program_inst_lbls[] = { \ 596 &&lbl_BC_INST_INC, \ 597 &&lbl_BC_INST_DEC, \ 598 &&lbl_BC_INST_NEG, \ 599 &&lbl_BC_INST_BOOL_NOT, \ 600 &&lbl_BC_INST_POWER, \ 601 &&lbl_BC_INST_MULTIPLY, \ 602 &&lbl_BC_INST_DIVIDE, \ 603 &&lbl_BC_INST_MODULUS, \ 604 &&lbl_BC_INST_PLUS, \ 605 &&lbl_BC_INST_MINUS, \ 606 &&lbl_BC_INST_REL_EQ, \ 607 &&lbl_BC_INST_REL_LE, \ 608 &&lbl_BC_INST_REL_GE, \ 609 &&lbl_BC_INST_REL_NE, \ 610 &&lbl_BC_INST_REL_LT, \ 611 &&lbl_BC_INST_REL_GT, \ 612 &&lbl_BC_INST_BOOL_OR, \ 613 &&lbl_BC_INST_BOOL_AND, \ 614 &&lbl_BC_INST_ASSIGN_POWER, \ 615 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 616 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 617 &&lbl_BC_INST_ASSIGN_MODULUS, \ 618 &&lbl_BC_INST_ASSIGN_PLUS, \ 619 &&lbl_BC_INST_ASSIGN_MINUS, \ 620 &&lbl_BC_INST_ASSIGN, \ 621 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 622 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 623 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 624 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 625 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 626 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 627 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 628 &&lbl_BC_INST_NUM, \ 629 &&lbl_BC_INST_VAR, \ 630 &&lbl_BC_INST_ARRAY_ELEM, \ 631 &&lbl_BC_INST_ARRAY, \ 632 &&lbl_BC_INST_ZERO, \ 633 &&lbl_BC_INST_ONE, \ 634 &&lbl_BC_INST_LAST, \ 635 &&lbl_BC_INST_IBASE, \ 636 &&lbl_BC_INST_OBASE, \ 637 &&lbl_BC_INST_SCALE, \ 638 &&lbl_BC_INST_LENGTH, \ 639 &&lbl_BC_INST_SCALE_FUNC, \ 640 &&lbl_BC_INST_SQRT, \ 641 &&lbl_BC_INST_ABS, \ 642 &&lbl_BC_INST_ASCIIFY, \ 643 &&lbl_BC_INST_READ, \ 644 &&lbl_BC_INST_MAXIBASE, \ 645 &&lbl_BC_INST_MAXOBASE, \ 646 &&lbl_BC_INST_MAXSCALE, \ 647 &&lbl_BC_INST_LINE_LENGTH, \ 648 &&lbl_BC_INST_GLOBAL_STACKS, \ 649 &&lbl_BC_INST_LEADING_ZERO, \ 650 &&lbl_BC_INST_PRINT, \ 651 &&lbl_BC_INST_PRINT_POP, \ 652 &&lbl_BC_INST_STR, \ 653 &&lbl_BC_INST_PRINT_STR, \ 654 &&lbl_BC_INST_JUMP, \ 655 &&lbl_BC_INST_JUMP_ZERO, \ 656 &&lbl_BC_INST_CALL, \ 657 &&lbl_BC_INST_RET, \ 658 &&lbl_BC_INST_RET0, \ 659 &&lbl_BC_INST_RET_VOID, \ 660 &&lbl_BC_INST_HALT, \ 661 &&lbl_BC_INST_POP, \ 662 &&lbl_BC_INST_SWAP, \ 663 &&lbl_BC_INST_MODEXP, \ 664 &&lbl_BC_INST_DIVMOD, \ 665 &&lbl_BC_INST_PRINT_STREAM, \ 666 &&lbl_BC_INST_POP_EXEC, \ 667 &&lbl_BC_INST_EXECUTE, \ 668 &&lbl_BC_INST_EXEC_COND, \ 669 &&lbl_BC_INST_PRINT_STACK, \ 670 &&lbl_BC_INST_CLEAR_STACK, \ 671 &&lbl_BC_INST_REG_STACK_LEN, \ 672 &&lbl_BC_INST_STACK_LEN, \ 673 &&lbl_BC_INST_DUPLICATE, \ 674 &&lbl_BC_INST_LOAD, \ 675 &&lbl_BC_INST_PUSH_VAR, \ 676 &&lbl_BC_INST_PUSH_TO_VAR, \ 677 &&lbl_BC_INST_QUIT, \ 678 &&lbl_BC_INST_NQUIT, \ 679 &&lbl_BC_INST_EXEC_STACK_LEN, \ 680 &&lbl_BC_INST_INVALID, \ 681 } 682 683 #endif // BC_ENABLE_EXTRA_MATH 684 685 #else // DC_ENABLED 686 687 #if BC_ENABLE_EXTRA_MATH 688 689 #define BC_PROG_LBLS \ 690 static const void* const bc_program_inst_lbls[] = { \ 691 &&lbl_BC_INST_INC, \ 692 &&lbl_BC_INST_DEC, \ 693 &&lbl_BC_INST_NEG, \ 694 &&lbl_BC_INST_BOOL_NOT, \ 695 &&lbl_BC_INST_TRUNC, \ 696 &&lbl_BC_INST_POWER, \ 697 &&lbl_BC_INST_MULTIPLY, \ 698 &&lbl_BC_INST_DIVIDE, \ 699 &&lbl_BC_INST_MODULUS, \ 700 &&lbl_BC_INST_PLUS, \ 701 &&lbl_BC_INST_MINUS, \ 702 &&lbl_BC_INST_PLACES, \ 703 &&lbl_BC_INST_LSHIFT, \ 704 &&lbl_BC_INST_RSHIFT, \ 705 &&lbl_BC_INST_REL_EQ, \ 706 &&lbl_BC_INST_REL_LE, \ 707 &&lbl_BC_INST_REL_GE, \ 708 &&lbl_BC_INST_REL_NE, \ 709 &&lbl_BC_INST_REL_LT, \ 710 &&lbl_BC_INST_REL_GT, \ 711 &&lbl_BC_INST_BOOL_OR, \ 712 &&lbl_BC_INST_BOOL_AND, \ 713 &&lbl_BC_INST_ASSIGN_POWER, \ 714 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 715 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 716 &&lbl_BC_INST_ASSIGN_MODULUS, \ 717 &&lbl_BC_INST_ASSIGN_PLUS, \ 718 &&lbl_BC_INST_ASSIGN_MINUS, \ 719 &&lbl_BC_INST_ASSIGN_PLACES, \ 720 &&lbl_BC_INST_ASSIGN_LSHIFT, \ 721 &&lbl_BC_INST_ASSIGN_RSHIFT, \ 722 &&lbl_BC_INST_ASSIGN, \ 723 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 724 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 725 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 726 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 727 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 728 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 729 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \ 730 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \ 731 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \ 732 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 733 &&lbl_BC_INST_NUM, \ 734 &&lbl_BC_INST_VAR, \ 735 &&lbl_BC_INST_ARRAY_ELEM, \ 736 &&lbl_BC_INST_ARRAY, \ 737 &&lbl_BC_INST_ZERO, \ 738 &&lbl_BC_INST_ONE, \ 739 &&lbl_BC_INST_LAST, \ 740 &&lbl_BC_INST_IBASE, \ 741 &&lbl_BC_INST_OBASE, \ 742 &&lbl_BC_INST_SCALE, \ 743 &&lbl_BC_INST_SEED, \ 744 &&lbl_BC_INST_LENGTH, \ 745 &&lbl_BC_INST_SCALE_FUNC, \ 746 &&lbl_BC_INST_SQRT, \ 747 &&lbl_BC_INST_ABS, \ 748 &&lbl_BC_INST_IRAND, \ 749 &&lbl_BC_INST_ASCIIFY, \ 750 &&lbl_BC_INST_READ, \ 751 &&lbl_BC_INST_RAND, \ 752 &&lbl_BC_INST_MAXIBASE, \ 753 &&lbl_BC_INST_MAXOBASE, \ 754 &&lbl_BC_INST_MAXSCALE, \ 755 &&lbl_BC_INST_MAXRAND, \ 756 &&lbl_BC_INST_LINE_LENGTH, \ 757 &&lbl_BC_INST_GLOBAL_STACKS, \ 758 &&lbl_BC_INST_LEADING_ZERO, \ 759 &&lbl_BC_INST_PRINT, \ 760 &&lbl_BC_INST_PRINT_POP, \ 761 &&lbl_BC_INST_STR, \ 762 &&lbl_BC_INST_PRINT_STR, \ 763 &&lbl_BC_INST_JUMP, \ 764 &&lbl_BC_INST_JUMP_ZERO, \ 765 &&lbl_BC_INST_CALL, \ 766 &&lbl_BC_INST_RET, \ 767 &&lbl_BC_INST_RET0, \ 768 &&lbl_BC_INST_RET_VOID, \ 769 &&lbl_BC_INST_HALT, \ 770 &&lbl_BC_INST_POP, \ 771 &&lbl_BC_INST_SWAP, \ 772 &&lbl_BC_INST_MODEXP, \ 773 &&lbl_BC_INST_DIVMOD, \ 774 &&lbl_BC_INST_PRINT_STREAM, \ 775 &&lbl_BC_INST_INVALID, \ 776 } 777 778 #else // BC_ENABLE_EXTRA_MATH 779 780 #define BC_PROG_LBLS \ 781 static const void* const bc_program_inst_lbls[] = { \ 782 &&lbl_BC_INST_INC, \ 783 &&lbl_BC_INST_DEC, \ 784 &&lbl_BC_INST_NEG, \ 785 &&lbl_BC_INST_BOOL_NOT, \ 786 &&lbl_BC_INST_POWER, \ 787 &&lbl_BC_INST_MULTIPLY, \ 788 &&lbl_BC_INST_DIVIDE, \ 789 &&lbl_BC_INST_MODULUS, \ 790 &&lbl_BC_INST_PLUS, \ 791 &&lbl_BC_INST_MINUS, \ 792 &&lbl_BC_INST_REL_EQ, \ 793 &&lbl_BC_INST_REL_LE, \ 794 &&lbl_BC_INST_REL_GE, \ 795 &&lbl_BC_INST_REL_NE, \ 796 &&lbl_BC_INST_REL_LT, \ 797 &&lbl_BC_INST_REL_GT, \ 798 &&lbl_BC_INST_BOOL_OR, \ 799 &&lbl_BC_INST_BOOL_AND, \ 800 &&lbl_BC_INST_ASSIGN_POWER, \ 801 &&lbl_BC_INST_ASSIGN_MULTIPLY, \ 802 &&lbl_BC_INST_ASSIGN_DIVIDE, \ 803 &&lbl_BC_INST_ASSIGN_MODULUS, \ 804 &&lbl_BC_INST_ASSIGN_PLUS, \ 805 &&lbl_BC_INST_ASSIGN_MINUS, \ 806 &&lbl_BC_INST_ASSIGN, \ 807 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \ 808 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \ 809 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \ 810 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \ 811 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \ 812 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \ 813 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 814 &&lbl_BC_INST_NUM, \ 815 &&lbl_BC_INST_VAR, \ 816 &&lbl_BC_INST_ARRAY_ELEM, \ 817 &&lbl_BC_INST_ARRAY, \ 818 &&lbl_BC_INST_ZERO, \ 819 &&lbl_BC_INST_ONE, \ 820 &&lbl_BC_INST_LAST, \ 821 &&lbl_BC_INST_IBASE, \ 822 &&lbl_BC_INST_OBASE, \ 823 &&lbl_BC_INST_SCALE, \ 824 &&lbl_BC_INST_LENGTH, \ 825 &&lbl_BC_INST_SCALE_FUNC, \ 826 &&lbl_BC_INST_SQRT, \ 827 &&lbl_BC_INST_ABS, \ 828 &&lbl_BC_INST_ASCIIFY, \ 829 &&lbl_BC_INST_READ, \ 830 &&lbl_BC_INST_MAXIBASE, \ 831 &&lbl_BC_INST_MAXOBASE, \ 832 &&lbl_BC_INST_MAXSCALE, \ 833 &&lbl_BC_INST_LINE_LENGTH, \ 834 &&lbl_BC_INST_GLOBAL_STACKS, \ 835 &&lbl_BC_INST_LEADING_ZERO, \ 836 &&lbl_BC_INST_PRINT, \ 837 &&lbl_BC_INST_PRINT_POP, \ 838 &&lbl_BC_INST_STR, \ 839 &&lbl_BC_INST_PRINT_STR, \ 840 &&lbl_BC_INST_JUMP, \ 841 &&lbl_BC_INST_JUMP_ZERO, \ 842 &&lbl_BC_INST_CALL, \ 843 &&lbl_BC_INST_RET, \ 844 &&lbl_BC_INST_RET0, \ 845 &&lbl_BC_INST_RET_VOID, \ 846 &&lbl_BC_INST_HALT, \ 847 &&lbl_BC_INST_POP, \ 848 &&lbl_BC_INST_SWAP, \ 849 &&lbl_BC_INST_MODEXP, \ 850 &&lbl_BC_INST_DIVMOD, \ 851 &&lbl_BC_INST_PRINT_STREAM, \ 852 &&lbl_BC_INST_INVALID, \ 853 } 854 855 #endif // BC_ENABLE_EXTRA_MATH 856 857 #endif // DC_ENABLED 858 859 #else // BC_ENABLED 860 861 #if BC_ENABLE_EXTRA_MATH 862 863 #define BC_PROG_LBLS \ 864 static const void* const bc_program_inst_lbls[] = { \ 865 &&lbl_BC_INST_NEG, \ 866 &&lbl_BC_INST_BOOL_NOT, \ 867 &&lbl_BC_INST_TRUNC, \ 868 &&lbl_BC_INST_POWER, \ 869 &&lbl_BC_INST_MULTIPLY, \ 870 &&lbl_BC_INST_DIVIDE, \ 871 &&lbl_BC_INST_MODULUS, \ 872 &&lbl_BC_INST_PLUS, \ 873 &&lbl_BC_INST_MINUS, \ 874 &&lbl_BC_INST_PLACES, \ 875 &&lbl_BC_INST_LSHIFT, \ 876 &&lbl_BC_INST_RSHIFT, \ 877 &&lbl_BC_INST_REL_EQ, \ 878 &&lbl_BC_INST_REL_LE, \ 879 &&lbl_BC_INST_REL_GE, \ 880 &&lbl_BC_INST_REL_NE, \ 881 &&lbl_BC_INST_REL_LT, \ 882 &&lbl_BC_INST_REL_GT, \ 883 &&lbl_BC_INST_BOOL_OR, \ 884 &&lbl_BC_INST_BOOL_AND, \ 885 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 886 &&lbl_BC_INST_NUM, \ 887 &&lbl_BC_INST_VAR, \ 888 &&lbl_BC_INST_ARRAY_ELEM, \ 889 &&lbl_BC_INST_ARRAY, \ 890 &&lbl_BC_INST_ZERO, \ 891 &&lbl_BC_INST_ONE, \ 892 &&lbl_BC_INST_IBASE, \ 893 &&lbl_BC_INST_OBASE, \ 894 &&lbl_BC_INST_SCALE, \ 895 &&lbl_BC_INST_SEED, \ 896 &&lbl_BC_INST_LENGTH, \ 897 &&lbl_BC_INST_SCALE_FUNC, \ 898 &&lbl_BC_INST_SQRT, \ 899 &&lbl_BC_INST_ABS, \ 900 &&lbl_BC_INST_IRAND, \ 901 &&lbl_BC_INST_ASCIIFY, \ 902 &&lbl_BC_INST_READ, \ 903 &&lbl_BC_INST_RAND, \ 904 &&lbl_BC_INST_MAXIBASE, \ 905 &&lbl_BC_INST_MAXOBASE, \ 906 &&lbl_BC_INST_MAXSCALE, \ 907 &&lbl_BC_INST_MAXRAND, \ 908 &&lbl_BC_INST_LINE_LENGTH, \ 909 &&lbl_BC_INST_LEADING_ZERO, \ 910 &&lbl_BC_INST_PRINT, \ 911 &&lbl_BC_INST_PRINT_POP, \ 912 &&lbl_BC_INST_STR, \ 913 &&lbl_BC_INST_POP, \ 914 &&lbl_BC_INST_SWAP, \ 915 &&lbl_BC_INST_MODEXP, \ 916 &&lbl_BC_INST_DIVMOD, \ 917 &&lbl_BC_INST_PRINT_STREAM, \ 918 &&lbl_BC_INST_POP_EXEC, \ 919 &&lbl_BC_INST_EXECUTE, \ 920 &&lbl_BC_INST_EXEC_COND, \ 921 &&lbl_BC_INST_PRINT_STACK, \ 922 &&lbl_BC_INST_CLEAR_STACK, \ 923 &&lbl_BC_INST_REG_STACK_LEN, \ 924 &&lbl_BC_INST_STACK_LEN, \ 925 &&lbl_BC_INST_DUPLICATE, \ 926 &&lbl_BC_INST_LOAD, \ 927 &&lbl_BC_INST_PUSH_VAR, \ 928 &&lbl_BC_INST_PUSH_TO_VAR, \ 929 &&lbl_BC_INST_QUIT, \ 930 &&lbl_BC_INST_NQUIT, \ 931 &&lbl_BC_INST_EXEC_STACK_LEN, \ 932 &&lbl_BC_INST_INVALID, \ 933 } 934 935 #else // BC_ENABLE_EXTRA_MATH 936 937 #define BC_PROG_LBLS \ 938 static const void* const bc_program_inst_lbls[] = { \ 939 &&lbl_BC_INST_NEG, \ 940 &&lbl_BC_INST_BOOL_NOT, \ 941 &&lbl_BC_INST_POWER, \ 942 &&lbl_BC_INST_MULTIPLY, \ 943 &&lbl_BC_INST_DIVIDE, \ 944 &&lbl_BC_INST_MODULUS, \ 945 &&lbl_BC_INST_PLUS, \ 946 &&lbl_BC_INST_MINUS, \ 947 &&lbl_BC_INST_REL_EQ, \ 948 &&lbl_BC_INST_REL_LE, \ 949 &&lbl_BC_INST_REL_GE, \ 950 &&lbl_BC_INST_REL_NE, \ 951 &&lbl_BC_INST_REL_LT, \ 952 &&lbl_BC_INST_REL_GT, \ 953 &&lbl_BC_INST_BOOL_OR, \ 954 &&lbl_BC_INST_BOOL_AND, \ 955 &&lbl_BC_INST_ASSIGN_NO_VAL, \ 956 &&lbl_BC_INST_NUM, \ 957 &&lbl_BC_INST_VAR, \ 958 &&lbl_BC_INST_ARRAY_ELEM, \ 959 &&lbl_BC_INST_ARRAY, \ 960 &&lbl_BC_INST_ZERO, \ 961 &&lbl_BC_INST_ONE, \ 962 &&lbl_BC_INST_IBASE, \ 963 &&lbl_BC_INST_OBASE, \ 964 &&lbl_BC_INST_SCALE, \ 965 &&lbl_BC_INST_LENGTH, \ 966 &&lbl_BC_INST_SCALE_FUNC, \ 967 &&lbl_BC_INST_SQRT, \ 968 &&lbl_BC_INST_ABS, \ 969 &&lbl_BC_INST_ASCIIFY, \ 970 &&lbl_BC_INST_READ, \ 971 &&lbl_BC_INST_MAXIBASE, \ 972 &&lbl_BC_INST_MAXOBASE, \ 973 &&lbl_BC_INST_MAXSCALE, \ 974 &&lbl_BC_INST_LINE_LENGTH, \ 975 &&lbl_BC_INST_LEADING_ZERO, \ 976 &&lbl_BC_INST_PRINT, \ 977 &&lbl_BC_INST_PRINT_POP, \ 978 &&lbl_BC_INST_STR, \ 979 &&lbl_BC_INST_POP, \ 980 &&lbl_BC_INST_SWAP, \ 981 &&lbl_BC_INST_MODEXP, \ 982 &&lbl_BC_INST_DIVMOD, \ 983 &&lbl_BC_INST_PRINT_STREAM, \ 984 &&lbl_BC_INST_POP_EXEC, \ 985 &&lbl_BC_INST_EXECUTE, \ 986 &&lbl_BC_INST_EXEC_COND, \ 987 &&lbl_BC_INST_PRINT_STACK, \ 988 &&lbl_BC_INST_CLEAR_STACK, \ 989 &&lbl_BC_INST_REG_STACK_LEN, \ 990 &&lbl_BC_INST_STACK_LEN, \ 991 &&lbl_BC_INST_DUPLICATE, \ 992 &&lbl_BC_INST_LOAD, \ 993 &&lbl_BC_INST_PUSH_VAR, \ 994 &&lbl_BC_INST_PUSH_TO_VAR, \ 995 &&lbl_BC_INST_QUIT, \ 996 &&lbl_BC_INST_NQUIT, \ 997 &&lbl_BC_INST_EXEC_STACK_LEN, \ 998 &&lbl_BC_INST_INVALID, \ 999 } 1000 1001 #endif // BC_ENABLE_EXTRA_MATH 1002 1003 #endif // BC_ENABLED 1004 1005 #else // BC_HAS_COMPUTED_GOTO 1006 1007 #define BC_PROG_JUMP(inst, code, ip) break 1008 #define BC_PROG_DIRECT_JUMP(l) 1009 #define BC_PROG_LBL(l) case l 1010 #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH 1011 1012 #define BC_PROG_LBLS 1013 1014 #endif // BC_HAS_COMPUTED_GOTO 1015 1016 #endif // BC_PROGRAM_H 1017