2 * *****************************************************************************
4 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
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.
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.
30 * *****************************************************************************
32 * Definitions for bc programs.
48 /// The index of ibase in the globals array.
49 #define BC_PROG_GLOBALS_IBASE (0)
51 /// The index of obase in the globals array.
52 #define BC_PROG_GLOBALS_OBASE (1)
54 /// The index of scale in the globals array.
55 #define BC_PROG_GLOBALS_SCALE (2)
57 #if BC_ENABLE_EXTRA_MATH
59 /// The index of the rand max in the maxes array.
60 #define BC_PROG_MAX_RAND (3)
62 #endif // BC_ENABLE_EXTRA_MATH
64 /// The length of the globals array.
65 #define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
67 typedef struct BcProgram
69 /// The array of globals values.
70 BcBigDig globals[BC_PROG_GLOBALS_LEN];
73 /// The array of globals stacks.
74 BcVec globals_v[BC_PROG_GLOBALS_LEN];
77 #if BC_ENABLE_EXTRA_MATH
79 /// The pseudo-random number generator.
82 #endif // BC_ENABLE_EXTRA_MATH
84 /// The results stack.
87 /// The execution stack.
90 /// The constants encountered in the program. They are global to the program
91 /// to prevent bad accesses when functions that used non-auto variables are
95 /// The map of constants to go with consts.
98 /// The strings encountered in the program. They are global to the program
99 /// to prevent bad accesses when functions that used non-auto variables are
103 /// The map of strings to go with strs.
106 /// The array of functions.
109 /// The map of functions to go with fns.
112 /// The array of variables.
115 /// The map of variables to go with vars.
118 /// The array of arrays.
121 /// The map of arrays to go with arrs.
126 /// A vector of tail calls. These are just integers, which are the number of
127 /// tail calls that have been executed for each function (string) on the
128 /// stack for dc. This is to prevent dc from constantly growing memory use
129 /// because of pushing more and more string executions on the stack.
134 /// A BcNum that has the proper base for asciify.
137 // A BcNum to run asciify. This is to prevent GCC longjmp() clobbering
143 /// The last printed value for bc.
148 // The BcDig array for strmb. This uses BC_NUM_LONG_LOG10 because it is used
149 // in bc_num_ulong2num(), which attempts to realloc, unless it is big
150 // enough. This is big enough.
151 BcDig strmb_num[BC_NUM_BIGDIG_LOG10];
156 * Returns true if the stack @a s has at least @a n items, false otherwise.
157 * @param s The stack to check.
158 * @param n The number of items the stack must have.
159 * @return True if @a s has at least @a n items, false otherwise.
161 #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
164 * Get a pointer to the top value in a global value stack.
165 * @param v The global value stack.
166 * @return A pointer to the top value in @a v.
168 #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
171 * Get the top value in a global value stack.
172 * @param v The global value stack.
173 * @return The top value in @a v.
175 #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
178 * Returns the current value of ibase.
179 * @param p The program.
180 * @return The current ibase.
182 #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
185 * Returns the current value of obase.
186 * @param p The program.
187 * @return The current obase.
189 #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
192 * Returns the current value of scale.
193 * @param p The program.
194 * @return The current scale.
196 #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
198 /// The index for the main function in the functions array.//
199 #define BC_PROG_MAIN (0)
201 /// The index for the read function in the functions array.
202 #define BC_PROG_READ (1)
205 * Retires (completes the execution of) an instruction. Some instructions
206 * require special retirement, but most can use this. This basically pops the
207 * operands while preserving the result (which we assumed was pushed before the
209 * @param p The program.
210 * @param nres The number of results returned by the instruction.
211 * @param nops The number of operands used by the instruction.
213 #define bc_program_retire(p, nres, nops) \
214 (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
218 /// A constant that tells how many functions are required in dc.
219 #define BC_PROG_REQ_FUNCS (2)
223 /// Returns true if the calculator should pop after printing.
224 #define BC_PROGRAM_POP(pop) (pop)
228 /// Returns true if the calculator should pop after printing.
229 #define BC_PROGRAM_POP(pop) (BC_IS_BC || (pop))
231 #endif // !BC_ENABLED
233 // This is here to satisfy a clang warning about recursive macros.
234 #define bc_program_pushVar(p, code, bgn, pop, copy) \
235 bc_program_pushVar_impl(p, code, bgn, pop, copy)
239 // This define disappears pop and copy because for bc, 'pop' and 'copy' are
241 #define bc_program_pushVar(p, code, bgn, pop, copy) \
242 bc_program_pushVar_impl(p, code, bgn)
244 /// Returns true if the calculator should pop after printing.
245 #define BC_PROGRAM_POP(pop) (BC_IS_BC)
247 // In debug mode, we want bc to check the stack, but otherwise, we don't because
248 // the bc language implicitly mandates that the stack should always have enough
251 #define BC_PROG_NO_STACK_CHECK
257 * Returns true if the BcNum @a n is acting as a string.
258 * @param n The BcNum to test.
259 * @return True if @a n is acting as a string, false otherwise.
261 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
266 * Returns true if the result @a r and @a n is a number.
267 * @param r The result.
268 * @param n The number corresponding to the result.
269 * @return True if the result holds a number, false otherwise.
271 #define BC_PROG_NUM(r, n) \
272 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
277 * Returns true if the result @a r and @a n is a number.
278 * @param r The result.
279 * @param n The number corresponding to the result.
280 * @return True if the result holds a number, false otherwise.
282 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
287 * This is a function type for unary operations. Currently, these include
288 * boolean not, negation, and truncation with extra math.
289 * @param r The BcResult to store the result into.
290 * @param n The parameter to the unary operation.
292 typedef void (*BcProgramUnary)(BcResult* r, BcNum* n);
295 * Initializes the BcProgram.
296 * @param p The program to initialize.
299 bc_program_init(BcProgram* p);
304 * Frees a BcProgram. This is only used in debug builds because a BcProgram is
305 * only freed on program exit, and we don't care about freeing resources on
307 * @param p The program to initialize.
310 bc_program_free(BcProgram* p);
315 * Prints a stack trace of the bc functions or dc strings currently executing.
316 * @param p The program.
319 bc_program_printStackTrace(BcProgram* p);
322 #if BC_ENABLED && DC_ENABLED
325 * Prints the bytecode in a function. This is a debug-only function.
326 * @param p The program.
329 bc_program_code(const BcProgram* p);
332 * Prints an instruction. This is a debug-only function.
333 * @param p The program.
334 * @param code The bytecode array.
335 * @param bgn A pointer to the current index. It is also updated to the next
339 bc_program_printInst(const BcProgram* p, const char* code,
340 size_t* restrict bgn);
343 * Prints the stack. This is a debug-only function.
344 * @param p The program.
347 bc_program_printStackDebug(BcProgram* p);
349 #endif // BC_ENABLED && DC_ENABLED
350 #endif // BC_DEBUG_CODE
353 * Returns the index of the variable or array in their respective arrays.
354 * @param p The program.
355 * @param name The name of the variable or array.
356 * @param var True if the search should be for a variable, false for an array.
357 * @return The index of the variable or array in the correct array.
360 bc_program_search(BcProgram* p, const char* name, bool var);
363 * Adds a string to the program and returns the string's index in the program.
364 * @param p The program.
365 * @param str The string to add.
366 * @return The string's index in the program.
369 bc_program_addString(BcProgram* p, const char* str);
372 * Inserts a function into the program and returns the index of the function in
374 * @param p The program.
375 * @param name The name of the function.
376 * @return The index of the function after insertion.
379 bc_program_insertFunc(BcProgram* p, const char* name);
382 * Resets a program, usually because of resetting after an error.
383 * @param p The program to reset.
386 bc_program_reset(BcProgram* p);
389 * Executes bc or dc code in the BcProgram.
390 * @param p The program.
393 bc_program_exec(BcProgram* p);
396 * Negates a copy of a BcNum. This is a BcProgramUnary function.
397 * @param r The BcResult to store the result into.
398 * @param n The parameter to the unary operation.
401 bc_program_negate(BcResult* r, BcNum* n);
404 * Returns a boolean not of a BcNum. This is a BcProgramUnary function.
405 * @param r The BcResult to store the result into.
406 * @param n The parameter to the unary operation.
409 bc_program_not(BcResult* r, BcNum* n);
411 #if BC_ENABLE_EXTRA_MATH
414 * Truncates a copy of a BcNum. This is a BcProgramUnary function.
415 * @param r The BcResult to store the result into.
416 * @param n The parameter to the unary operation.
419 bc_program_trunc(BcResult* r, BcNum* n);
422 * Assigns a value to the seed builtin variable.
423 * @param p The program.
424 * @param val The value to assign to the seed.
427 bc_program_assignSeed(BcProgram* p, BcNum* val);
429 #endif // BC_ENABLE_EXTRA_MATH
432 * Assigns a value to a builtin value that is not seed.
433 * @param p The program.
434 * @param scale True if the builtin is scale.
435 * @param obase True if the builtin is obase. This cannot be true at the same
437 * @param val The value to assign to the builtin.
440 bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val);
442 /// A reference to an array of binary operator functions.
443 extern const BcNumBinaryOp bc_program_ops[];
445 /// A reference to an array of binary operator allocation request functions.
446 extern const BcNumBinaryOpReq bc_program_opReqs[];
448 /// A reference to an array of unary operator functions.
449 extern const BcProgramUnary bc_program_unarys[];
451 /// A reference to a filename for command-line expressions.
452 extern const char bc_program_exprs_name[];
454 /// A reference to a filename for stdin.
455 extern const char bc_program_stdin_name[];
457 /// A reference to the ready message printed on SIGINT.
458 extern const char bc_program_ready_msg[];
460 /// A reference to the length of the ready message.
461 extern const size_t bc_program_ready_msg_len;
463 /// A reference to an array of escape characters for the print statement.
464 extern const char bc_program_esc_chars[];
466 /// A reference to an array of the characters corresponding to the escape
467 /// characters in bc_program_esc_chars.
468 extern const char bc_program_esc_seqs[];
470 #if BC_HAS_COMPUTED_GOTO
475 #define BC_PROG_JUMP(inst, code, ip) \
478 inst = (uchar) (code)[(ip)->idx++]; \
479 bc_file_printf(&vm->ferr, "inst: %s\n", bc_inst_names[inst]); \
480 bc_file_flush(&vm->ferr, bc_flush_none); \
481 goto *bc_program_inst_lbls[inst]; \
486 #else // BC_DEBUG_CODE
489 #define BC_PROG_JUMP(inst, code, ip) \
492 inst = (uchar) (code)[(ip)->idx++]; \
493 goto *bc_program_inst_lbls[inst]; \
498 #endif // BC_DEBUG_CODE
500 #define BC_PROG_DIRECT_JUMP(l) goto lbl_##l;
501 #define BC_PROG_LBL(l) lbl_##l
502 #define BC_PROG_FALLTHROUGH
506 #define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))
507 #define BC_PROG_LBLS_ASSERT \
508 _Static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1, \
509 "bc_program_inst_lbls[] mismatches the instructions")
513 #define BC_PROG_LBLS_ASSERT
521 #if BC_ENABLE_EXTRA_MATH
523 #define BC_PROG_LBLS \
524 static const void* const bc_program_inst_lbls[] = { \
528 &&lbl_BC_INST_BOOL_NOT, \
529 &&lbl_BC_INST_TRUNC, \
530 &&lbl_BC_INST_POWER, \
531 &&lbl_BC_INST_MULTIPLY, \
532 &&lbl_BC_INST_DIVIDE, \
533 &&lbl_BC_INST_MODULUS, \
534 &&lbl_BC_INST_PLUS, \
535 &&lbl_BC_INST_MINUS, \
536 &&lbl_BC_INST_PLACES, \
537 &&lbl_BC_INST_LSHIFT, \
538 &&lbl_BC_INST_RSHIFT, \
539 &&lbl_BC_INST_REL_EQ, \
540 &&lbl_BC_INST_REL_LE, \
541 &&lbl_BC_INST_REL_GE, \
542 &&lbl_BC_INST_REL_NE, \
543 &&lbl_BC_INST_REL_LT, \
544 &&lbl_BC_INST_REL_GT, \
545 &&lbl_BC_INST_BOOL_OR, \
546 &&lbl_BC_INST_BOOL_AND, \
547 &&lbl_BC_INST_ASSIGN_POWER, \
548 &&lbl_BC_INST_ASSIGN_MULTIPLY, \
549 &&lbl_BC_INST_ASSIGN_DIVIDE, \
550 &&lbl_BC_INST_ASSIGN_MODULUS, \
551 &&lbl_BC_INST_ASSIGN_PLUS, \
552 &&lbl_BC_INST_ASSIGN_MINUS, \
553 &&lbl_BC_INST_ASSIGN_PLACES, \
554 &&lbl_BC_INST_ASSIGN_LSHIFT, \
555 &&lbl_BC_INST_ASSIGN_RSHIFT, \
556 &&lbl_BC_INST_ASSIGN, \
557 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
558 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
559 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
560 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
561 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
562 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
563 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \
564 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \
565 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \
566 &&lbl_BC_INST_ASSIGN_NO_VAL, \
569 &&lbl_BC_INST_ARRAY_ELEM, \
570 &&lbl_BC_INST_ARRAY, \
571 &&lbl_BC_INST_ZERO, \
573 &&lbl_BC_INST_LAST, \
574 &&lbl_BC_INST_IBASE, \
575 &&lbl_BC_INST_OBASE, \
576 &&lbl_BC_INST_SCALE, \
577 &&lbl_BC_INST_SEED, \
578 &&lbl_BC_INST_LENGTH, \
579 &&lbl_BC_INST_SCALE_FUNC, \
580 &&lbl_BC_INST_SQRT, \
582 &&lbl_BC_INST_IS_NUMBER, \
583 &&lbl_BC_INST_IS_STRING, \
584 &&lbl_BC_INST_IRAND, \
585 &&lbl_BC_INST_ASCIIFY, \
586 &&lbl_BC_INST_READ, \
587 &&lbl_BC_INST_RAND, \
588 &&lbl_BC_INST_MAXIBASE, \
589 &&lbl_BC_INST_MAXOBASE, \
590 &&lbl_BC_INST_MAXSCALE, \
591 &&lbl_BC_INST_MAXRAND, \
592 &&lbl_BC_INST_LINE_LENGTH, \
593 &&lbl_BC_INST_GLOBAL_STACKS, \
594 &&lbl_BC_INST_LEADING_ZERO, \
595 &&lbl_BC_INST_PRINT, \
596 &&lbl_BC_INST_PRINT_POP, \
598 &&lbl_BC_INST_PRINT_STR, \
599 &&lbl_BC_INST_JUMP, \
600 &&lbl_BC_INST_JUMP_ZERO, \
601 &&lbl_BC_INST_CALL, \
603 &&lbl_BC_INST_RET0, \
604 &&lbl_BC_INST_RET_VOID, \
605 &&lbl_BC_INST_HALT, \
607 &&lbl_BC_INST_SWAP, \
608 &&lbl_BC_INST_MODEXP, \
609 &&lbl_BC_INST_DIVMOD, \
610 &&lbl_BC_INST_PRINT_STREAM, \
611 &&lbl_BC_INST_EXTENDED_REGISTERS, \
612 &&lbl_BC_INST_POP_EXEC, \
613 &&lbl_BC_INST_EXECUTE, \
614 &&lbl_BC_INST_EXEC_COND, \
615 &&lbl_BC_INST_PRINT_STACK, \
616 &&lbl_BC_INST_CLEAR_STACK, \
617 &&lbl_BC_INST_REG_STACK_LEN, \
618 &&lbl_BC_INST_STACK_LEN, \
619 &&lbl_BC_INST_DUPLICATE, \
620 &&lbl_BC_INST_LOAD, \
621 &&lbl_BC_INST_PUSH_VAR, \
622 &&lbl_BC_INST_PUSH_TO_VAR, \
623 &&lbl_BC_INST_QUIT, \
624 &&lbl_BC_INST_NQUIT, \
625 &&lbl_BC_INST_EXEC_STACK_LEN, \
626 &&lbl_BC_INST_INVALID, \
629 #else // BC_ENABLE_EXTRA_MATH
631 #define BC_PROG_LBLS \
632 static const void* const bc_program_inst_lbls[] = { \
636 &&lbl_BC_INST_BOOL_NOT, \
637 &&lbl_BC_INST_POWER, \
638 &&lbl_BC_INST_MULTIPLY, \
639 &&lbl_BC_INST_DIVIDE, \
640 &&lbl_BC_INST_MODULUS, \
641 &&lbl_BC_INST_PLUS, \
642 &&lbl_BC_INST_MINUS, \
643 &&lbl_BC_INST_REL_EQ, \
644 &&lbl_BC_INST_REL_LE, \
645 &&lbl_BC_INST_REL_GE, \
646 &&lbl_BC_INST_REL_NE, \
647 &&lbl_BC_INST_REL_LT, \
648 &&lbl_BC_INST_REL_GT, \
649 &&lbl_BC_INST_BOOL_OR, \
650 &&lbl_BC_INST_BOOL_AND, \
651 &&lbl_BC_INST_ASSIGN_POWER, \
652 &&lbl_BC_INST_ASSIGN_MULTIPLY, \
653 &&lbl_BC_INST_ASSIGN_DIVIDE, \
654 &&lbl_BC_INST_ASSIGN_MODULUS, \
655 &&lbl_BC_INST_ASSIGN_PLUS, \
656 &&lbl_BC_INST_ASSIGN_MINUS, \
657 &&lbl_BC_INST_ASSIGN, \
658 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
659 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
660 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
661 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
662 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
663 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
664 &&lbl_BC_INST_ASSIGN_NO_VAL, \
667 &&lbl_BC_INST_ARRAY_ELEM, \
668 &&lbl_BC_INST_ARRAY, \
669 &&lbl_BC_INST_ZERO, \
671 &&lbl_BC_INST_LAST, \
672 &&lbl_BC_INST_IBASE, \
673 &&lbl_BC_INST_OBASE, \
674 &&lbl_BC_INST_SCALE, \
675 &&lbl_BC_INST_LENGTH, \
676 &&lbl_BC_INST_SCALE_FUNC, \
677 &&lbl_BC_INST_SQRT, \
679 &&lbl_BC_INST_IS_NUMBER, \
680 &&lbl_BC_INST_IS_STRING, \
681 &&lbl_BC_INST_ASCIIFY, \
682 &&lbl_BC_INST_READ, \
683 &&lbl_BC_INST_MAXIBASE, \
684 &&lbl_BC_INST_MAXOBASE, \
685 &&lbl_BC_INST_MAXSCALE, \
686 &&lbl_BC_INST_LINE_LENGTH, \
687 &&lbl_BC_INST_GLOBAL_STACKS, \
688 &&lbl_BC_INST_LEADING_ZERO, \
689 &&lbl_BC_INST_PRINT, \
690 &&lbl_BC_INST_PRINT_POP, \
692 &&lbl_BC_INST_PRINT_STR, \
693 &&lbl_BC_INST_JUMP, \
694 &&lbl_BC_INST_JUMP_ZERO, \
695 &&lbl_BC_INST_CALL, \
697 &&lbl_BC_INST_RET0, \
698 &&lbl_BC_INST_RET_VOID, \
699 &&lbl_BC_INST_HALT, \
701 &&lbl_BC_INST_SWAP, \
702 &&lbl_BC_INST_MODEXP, \
703 &&lbl_BC_INST_DIVMOD, \
704 &&lbl_BC_INST_PRINT_STREAM, \
705 &&lbl_BC_INST_EXTENDED_REGISTERS, \
706 &&lbl_BC_INST_POP_EXEC, \
707 &&lbl_BC_INST_EXECUTE, \
708 &&lbl_BC_INST_EXEC_COND, \
709 &&lbl_BC_INST_PRINT_STACK, \
710 &&lbl_BC_INST_CLEAR_STACK, \
711 &&lbl_BC_INST_REG_STACK_LEN, \
712 &&lbl_BC_INST_STACK_LEN, \
713 &&lbl_BC_INST_DUPLICATE, \
714 &&lbl_BC_INST_LOAD, \
715 &&lbl_BC_INST_PUSH_VAR, \
716 &&lbl_BC_INST_PUSH_TO_VAR, \
717 &&lbl_BC_INST_QUIT, \
718 &&lbl_BC_INST_NQUIT, \
719 &&lbl_BC_INST_EXEC_STACK_LEN, \
720 &&lbl_BC_INST_INVALID, \
723 #endif // BC_ENABLE_EXTRA_MATH
727 #if BC_ENABLE_EXTRA_MATH
729 #define BC_PROG_LBLS \
730 static const void* const bc_program_inst_lbls[] = { \
734 &&lbl_BC_INST_BOOL_NOT, \
735 &&lbl_BC_INST_TRUNC, \
736 &&lbl_BC_INST_POWER, \
737 &&lbl_BC_INST_MULTIPLY, \
738 &&lbl_BC_INST_DIVIDE, \
739 &&lbl_BC_INST_MODULUS, \
740 &&lbl_BC_INST_PLUS, \
741 &&lbl_BC_INST_MINUS, \
742 &&lbl_BC_INST_PLACES, \
743 &&lbl_BC_INST_LSHIFT, \
744 &&lbl_BC_INST_RSHIFT, \
745 &&lbl_BC_INST_REL_EQ, \
746 &&lbl_BC_INST_REL_LE, \
747 &&lbl_BC_INST_REL_GE, \
748 &&lbl_BC_INST_REL_NE, \
749 &&lbl_BC_INST_REL_LT, \
750 &&lbl_BC_INST_REL_GT, \
751 &&lbl_BC_INST_BOOL_OR, \
752 &&lbl_BC_INST_BOOL_AND, \
753 &&lbl_BC_INST_ASSIGN_POWER, \
754 &&lbl_BC_INST_ASSIGN_MULTIPLY, \
755 &&lbl_BC_INST_ASSIGN_DIVIDE, \
756 &&lbl_BC_INST_ASSIGN_MODULUS, \
757 &&lbl_BC_INST_ASSIGN_PLUS, \
758 &&lbl_BC_INST_ASSIGN_MINUS, \
759 &&lbl_BC_INST_ASSIGN_PLACES, \
760 &&lbl_BC_INST_ASSIGN_LSHIFT, \
761 &&lbl_BC_INST_ASSIGN_RSHIFT, \
762 &&lbl_BC_INST_ASSIGN, \
763 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
764 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
765 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
766 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
767 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
768 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
769 &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \
770 &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \
771 &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \
772 &&lbl_BC_INST_ASSIGN_NO_VAL, \
775 &&lbl_BC_INST_ARRAY_ELEM, \
776 &&lbl_BC_INST_ARRAY, \
777 &&lbl_BC_INST_ZERO, \
779 &&lbl_BC_INST_LAST, \
780 &&lbl_BC_INST_IBASE, \
781 &&lbl_BC_INST_OBASE, \
782 &&lbl_BC_INST_SCALE, \
783 &&lbl_BC_INST_SEED, \
784 &&lbl_BC_INST_LENGTH, \
785 &&lbl_BC_INST_SCALE_FUNC, \
786 &&lbl_BC_INST_SQRT, \
788 &&lbl_BC_INST_IS_NUMBER, \
789 &&lbl_BC_INST_IS_STRING, \
790 &&lbl_BC_INST_IRAND, \
791 &&lbl_BC_INST_ASCIIFY, \
792 &&lbl_BC_INST_READ, \
793 &&lbl_BC_INST_RAND, \
794 &&lbl_BC_INST_MAXIBASE, \
795 &&lbl_BC_INST_MAXOBASE, \
796 &&lbl_BC_INST_MAXSCALE, \
797 &&lbl_BC_INST_MAXRAND, \
798 &&lbl_BC_INST_LINE_LENGTH, \
799 &&lbl_BC_INST_GLOBAL_STACKS, \
800 &&lbl_BC_INST_LEADING_ZERO, \
801 &&lbl_BC_INST_PRINT, \
802 &&lbl_BC_INST_PRINT_POP, \
804 &&lbl_BC_INST_PRINT_STR, \
805 &&lbl_BC_INST_JUMP, \
806 &&lbl_BC_INST_JUMP_ZERO, \
807 &&lbl_BC_INST_CALL, \
809 &&lbl_BC_INST_RET0, \
810 &&lbl_BC_INST_RET_VOID, \
811 &&lbl_BC_INST_HALT, \
813 &&lbl_BC_INST_SWAP, \
814 &&lbl_BC_INST_MODEXP, \
815 &&lbl_BC_INST_DIVMOD, \
816 &&lbl_BC_INST_PRINT_STREAM, \
817 &&lbl_BC_INST_INVALID, \
820 #else // BC_ENABLE_EXTRA_MATH
822 #define BC_PROG_LBLS \
823 static const void* const bc_program_inst_lbls[] = { \
827 &&lbl_BC_INST_BOOL_NOT, \
828 &&lbl_BC_INST_POWER, \
829 &&lbl_BC_INST_MULTIPLY, \
830 &&lbl_BC_INST_DIVIDE, \
831 &&lbl_BC_INST_MODULUS, \
832 &&lbl_BC_INST_PLUS, \
833 &&lbl_BC_INST_MINUS, \
834 &&lbl_BC_INST_REL_EQ, \
835 &&lbl_BC_INST_REL_LE, \
836 &&lbl_BC_INST_REL_GE, \
837 &&lbl_BC_INST_REL_NE, \
838 &&lbl_BC_INST_REL_LT, \
839 &&lbl_BC_INST_REL_GT, \
840 &&lbl_BC_INST_BOOL_OR, \
841 &&lbl_BC_INST_BOOL_AND, \
842 &&lbl_BC_INST_ASSIGN_POWER, \
843 &&lbl_BC_INST_ASSIGN_MULTIPLY, \
844 &&lbl_BC_INST_ASSIGN_DIVIDE, \
845 &&lbl_BC_INST_ASSIGN_MODULUS, \
846 &&lbl_BC_INST_ASSIGN_PLUS, \
847 &&lbl_BC_INST_ASSIGN_MINUS, \
848 &&lbl_BC_INST_ASSIGN, \
849 &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
850 &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
851 &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
852 &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
853 &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
854 &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
855 &&lbl_BC_INST_ASSIGN_NO_VAL, \
858 &&lbl_BC_INST_ARRAY_ELEM, \
859 &&lbl_BC_INST_ARRAY, \
860 &&lbl_BC_INST_ZERO, \
862 &&lbl_BC_INST_LAST, \
863 &&lbl_BC_INST_IBASE, \
864 &&lbl_BC_INST_OBASE, \
865 &&lbl_BC_INST_SCALE, \
866 &&lbl_BC_INST_LENGTH, \
867 &&lbl_BC_INST_SCALE_FUNC, \
868 &&lbl_BC_INST_SQRT, \
870 &&lbl_BC_INST_IS_NUMBER, \
871 &&lbl_BC_INST_IS_STRING, \
872 &&lbl_BC_INST_ASCIIFY, \
873 &&lbl_BC_INST_READ, \
874 &&lbl_BC_INST_MAXIBASE, \
875 &&lbl_BC_INST_MAXOBASE, \
876 &&lbl_BC_INST_MAXSCALE, \
877 &&lbl_BC_INST_LINE_LENGTH, \
878 &&lbl_BC_INST_GLOBAL_STACKS, \
879 &&lbl_BC_INST_LEADING_ZERO, \
880 &&lbl_BC_INST_PRINT, \
881 &&lbl_BC_INST_PRINT_POP, \
883 &&lbl_BC_INST_PRINT_STR, \
884 &&lbl_BC_INST_JUMP, \
885 &&lbl_BC_INST_JUMP_ZERO, \
886 &&lbl_BC_INST_CALL, \
888 &&lbl_BC_INST_RET0, \
889 &&lbl_BC_INST_RET_VOID, \
890 &&lbl_BC_INST_HALT, \
892 &&lbl_BC_INST_SWAP, \
893 &&lbl_BC_INST_MODEXP, \
894 &&lbl_BC_INST_DIVMOD, \
895 &&lbl_BC_INST_PRINT_STREAM, \
896 &&lbl_BC_INST_INVALID, \
899 #endif // BC_ENABLE_EXTRA_MATH
905 #if BC_ENABLE_EXTRA_MATH
907 #define BC_PROG_LBLS \
908 static const void* const bc_program_inst_lbls[] = { \
910 &&lbl_BC_INST_BOOL_NOT, \
911 &&lbl_BC_INST_TRUNC, \
912 &&lbl_BC_INST_POWER, \
913 &&lbl_BC_INST_MULTIPLY, \
914 &&lbl_BC_INST_DIVIDE, \
915 &&lbl_BC_INST_MODULUS, \
916 &&lbl_BC_INST_PLUS, \
917 &&lbl_BC_INST_MINUS, \
918 &&lbl_BC_INST_PLACES, \
919 &&lbl_BC_INST_LSHIFT, \
920 &&lbl_BC_INST_RSHIFT, \
921 &&lbl_BC_INST_REL_EQ, \
922 &&lbl_BC_INST_REL_LE, \
923 &&lbl_BC_INST_REL_GE, \
924 &&lbl_BC_INST_REL_NE, \
925 &&lbl_BC_INST_REL_LT, \
926 &&lbl_BC_INST_REL_GT, \
927 &&lbl_BC_INST_BOOL_OR, \
928 &&lbl_BC_INST_BOOL_AND, \
929 &&lbl_BC_INST_ASSIGN_NO_VAL, \
932 &&lbl_BC_INST_ARRAY_ELEM, \
933 &&lbl_BC_INST_ARRAY, \
934 &&lbl_BC_INST_ZERO, \
936 &&lbl_BC_INST_IBASE, \
937 &&lbl_BC_INST_OBASE, \
938 &&lbl_BC_INST_SCALE, \
939 &&lbl_BC_INST_SEED, \
940 &&lbl_BC_INST_LENGTH, \
941 &&lbl_BC_INST_SCALE_FUNC, \
942 &&lbl_BC_INST_SQRT, \
944 &&lbl_BC_INST_IS_NUMBER, \
945 &&lbl_BC_INST_IS_STRING, \
946 &&lbl_BC_INST_IRAND, \
947 &&lbl_BC_INST_ASCIIFY, \
948 &&lbl_BC_INST_READ, \
949 &&lbl_BC_INST_RAND, \
950 &&lbl_BC_INST_MAXIBASE, \
951 &&lbl_BC_INST_MAXOBASE, \
952 &&lbl_BC_INST_MAXSCALE, \
953 &&lbl_BC_INST_MAXRAND, \
954 &&lbl_BC_INST_LINE_LENGTH, \
955 &&lbl_BC_INST_LEADING_ZERO, \
956 &&lbl_BC_INST_PRINT, \
957 &&lbl_BC_INST_PRINT_POP, \
960 &&lbl_BC_INST_SWAP, \
961 &&lbl_BC_INST_MODEXP, \
962 &&lbl_BC_INST_DIVMOD, \
963 &&lbl_BC_INST_PRINT_STREAM, \
964 &&lbl_BC_INST_EXTENDED_REGISTERS, \
965 &&lbl_BC_INST_POP_EXEC, \
966 &&lbl_BC_INST_EXECUTE, \
967 &&lbl_BC_INST_EXEC_COND, \
968 &&lbl_BC_INST_PRINT_STACK, \
969 &&lbl_BC_INST_CLEAR_STACK, \
970 &&lbl_BC_INST_REG_STACK_LEN, \
971 &&lbl_BC_INST_STACK_LEN, \
972 &&lbl_BC_INST_DUPLICATE, \
973 &&lbl_BC_INST_LOAD, \
974 &&lbl_BC_INST_PUSH_VAR, \
975 &&lbl_BC_INST_PUSH_TO_VAR, \
976 &&lbl_BC_INST_QUIT, \
977 &&lbl_BC_INST_NQUIT, \
978 &&lbl_BC_INST_EXEC_STACK_LEN, \
979 &&lbl_BC_INST_INVALID, \
982 #else // BC_ENABLE_EXTRA_MATH
984 #define BC_PROG_LBLS \
985 static const void* const bc_program_inst_lbls[] = { \
987 &&lbl_BC_INST_BOOL_NOT, \
988 &&lbl_BC_INST_POWER, \
989 &&lbl_BC_INST_MULTIPLY, \
990 &&lbl_BC_INST_DIVIDE, \
991 &&lbl_BC_INST_MODULUS, \
992 &&lbl_BC_INST_PLUS, \
993 &&lbl_BC_INST_MINUS, \
994 &&lbl_BC_INST_REL_EQ, \
995 &&lbl_BC_INST_REL_LE, \
996 &&lbl_BC_INST_REL_GE, \
997 &&lbl_BC_INST_REL_NE, \
998 &&lbl_BC_INST_REL_LT, \
999 &&lbl_BC_INST_REL_GT, \
1000 &&lbl_BC_INST_BOOL_OR, \
1001 &&lbl_BC_INST_BOOL_AND, \
1002 &&lbl_BC_INST_ASSIGN_NO_VAL, \
1003 &&lbl_BC_INST_NUM, \
1004 &&lbl_BC_INST_VAR, \
1005 &&lbl_BC_INST_ARRAY_ELEM, \
1006 &&lbl_BC_INST_ARRAY, \
1007 &&lbl_BC_INST_ZERO, \
1008 &&lbl_BC_INST_ONE, \
1009 &&lbl_BC_INST_IBASE, \
1010 &&lbl_BC_INST_OBASE, \
1011 &&lbl_BC_INST_SCALE, \
1012 &&lbl_BC_INST_LENGTH, \
1013 &&lbl_BC_INST_SCALE_FUNC, \
1014 &&lbl_BC_INST_SQRT, \
1015 &&lbl_BC_INST_ABS, \
1016 &&lbl_BC_INST_IS_NUMBER, \
1017 &&lbl_BC_INST_IS_STRING, \
1018 &&lbl_BC_INST_ASCIIFY, \
1019 &&lbl_BC_INST_READ, \
1020 &&lbl_BC_INST_MAXIBASE, \
1021 &&lbl_BC_INST_MAXOBASE, \
1022 &&lbl_BC_INST_MAXSCALE, \
1023 &&lbl_BC_INST_LINE_LENGTH, \
1024 &&lbl_BC_INST_LEADING_ZERO, \
1025 &&lbl_BC_INST_PRINT, \
1026 &&lbl_BC_INST_PRINT_POP, \
1027 &&lbl_BC_INST_STR, \
1028 &&lbl_BC_INST_POP, \
1029 &&lbl_BC_INST_SWAP, \
1030 &&lbl_BC_INST_MODEXP, \
1031 &&lbl_BC_INST_DIVMOD, \
1032 &&lbl_BC_INST_PRINT_STREAM, \
1033 &&lbl_BC_INST_EXTENDED_REGISTERS, \
1034 &&lbl_BC_INST_POP_EXEC, \
1035 &&lbl_BC_INST_EXECUTE, \
1036 &&lbl_BC_INST_EXEC_COND, \
1037 &&lbl_BC_INST_PRINT_STACK, \
1038 &&lbl_BC_INST_CLEAR_STACK, \
1039 &&lbl_BC_INST_REG_STACK_LEN, \
1040 &&lbl_BC_INST_STACK_LEN, \
1041 &&lbl_BC_INST_DUPLICATE, \
1042 &&lbl_BC_INST_LOAD, \
1043 &&lbl_BC_INST_PUSH_VAR, \
1044 &&lbl_BC_INST_PUSH_TO_VAR, \
1045 &&lbl_BC_INST_QUIT, \
1046 &&lbl_BC_INST_NQUIT, \
1047 &&lbl_BC_INST_EXEC_STACK_LEN, \
1048 &&lbl_BC_INST_INVALID, \
1051 #endif // BC_ENABLE_EXTRA_MATH
1053 #endif // BC_ENABLED
1055 #else // BC_HAS_COMPUTED_GOTO
1057 #define BC_PROG_JUMP(inst, code, ip) break
1058 #define BC_PROG_DIRECT_JUMP(l)
1059 #define BC_PROG_LBL(l) case l
1060 #define BC_PROG_FALLTHROUGH BC_FALLTHROUGH
1062 #define BC_PROG_LBLS
1064 #endif // BC_HAS_COMPUTED_GOTO
1066 #endif // BC_PROGRAM_H