2 * *****************************************************************************
4 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2018-2021 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];
72 /// The array of globals stacks.
73 BcVec globals_v[BC_PROG_GLOBALS_LEN];
75 #if BC_ENABLE_EXTRA_MATH
77 /// The pseudo-random number generator.
80 #endif // BC_ENABLE_EXTRA_MATH
82 /// The results stack.
85 /// The execution stack.
88 /// A pointer to the current function's constants.
91 /// A pointer to the current function's strings.
94 /// The array of functions.
97 /// The map of functions to go with fns.
100 /// The array of variables.
103 /// The map of variables to go with vars.
106 /// The array of arrays.
109 /// The map of arrays to go with arrs.
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.
122 /// A BcNum that has the proper base for asciify.
127 /// The last printed value for bc.
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];
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.
145 #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
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.
152 #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
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.
159 #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
162 * Returns the current value of ibase.
163 * @param p The program.
164 * @return The current ibase.
166 #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
169 * Returns the current value of obase.
170 * @param p The program.
171 * @return The current obase.
173 #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
176 * Returns the current value of scale.
177 * @param p The program.
178 * @return The current scale.
180 #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
182 /// The index for the main function in the functions array.//
183 #define BC_PROG_MAIN (0)
185 /// The index for the read function in the functions array.
186 #define BC_PROG_READ (1)
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
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.
197 #define bc_program_retire(p, nres, nops) \
198 (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
202 /// A constant that tells how many functions are required in dc.
203 #define BC_PROG_REQ_FUNCS (2)
207 /// This define disappears the parameter last because for dc only, last is
209 #define bc_program_copyToVar(p, name, t, last) bc_program_copyToVar(p, name, t)
211 #endif // !BC_ENABLED
215 /// This define disappears pop and copy because for bc, 'pop' and 'copy' are
217 #define bc_program_pushVar(p, code, bgn, pop, copy) \
218 bc_program_pushVar(p, code, bgn)
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
224 #define BC_PROG_NO_STACK_CHECK
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.
234 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
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.
244 #define BC_PROG_NUM(r, n) \
245 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
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.
255 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
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.
265 typedef void (*BcProgramUnary)(BcResult* r, BcNum* n);
268 * Initializes the BcProgram.
269 * @param p The program to initialize.
272 bc_program_init(BcProgram* p);
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
280 * @param p The program to initialize.
283 bc_program_free(BcProgram* p);
288 #if BC_ENABLED && DC_ENABLED
291 * Prints the bytecode in a function. This is a debug-only function.
292 * @param p The program.
295 bc_program_code(const BcProgram* p);
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
305 bc_program_printInst(const BcProgram* p, const char* code,
306 size_t* restrict bgn);
309 * Prints the stack. This is a debug-only function.
310 * @param p The program.
313 bc_program_printStackDebug(BcProgram* p);
315 #endif // BC_ENABLED && DC_ENABLED
316 #endif // BC_DEBUG_CODE
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.
326 bc_program_search(BcProgram* p, const char* id, bool var);
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.
335 bc_program_addString(BcProgram* p, const char* str, size_t fidx);
338 * Inserts a function into the program and returns the index of the function in
340 * @param p The program.
341 * @param name The name of the function.
342 * @return The index of the function after insertion.
345 bc_program_insertFunc(BcProgram* p, const char* name);
348 * Resets a program, usually because of resetting after an error.
349 * @param p The program to reset.
352 bc_program_reset(BcProgram* p);
355 * Executes bc or dc code in the BcProgram.
356 * @param p The program.
359 bc_program_exec(BcProgram* p);
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.
367 bc_program_negate(BcResult* r, BcNum* n);
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.
375 bc_program_not(BcResult* r, BcNum* n);
377 #if BC_ENABLE_EXTRA_MATH
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.
385 bc_program_trunc(BcResult* r, BcNum* n);
388 * Assigns a value to the seed builtin variable.
389 * @param p The program.
390 * @param val The value to assign to the seed.
393 bc_program_assignSeed(BcProgram* p, BcNum* val);
395 #endif // BC_ENABLE_EXTRA_MATH
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
403 * @param val The value to assign to the builtin.
406 bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val);
408 /// A reference to an array of binary operator functions.
409 extern const BcNumBinaryOp bc_program_ops[];
411 /// A reference to an array of binary operator allocation request functions.
412 extern const BcNumBinaryOpReq bc_program_opReqs[];
414 /// A reference to an array of unary operator functions.
415 extern const BcProgramUnary bc_program_unarys[];
417 /// A reference to a filename for command-line expressions.
418 extern const char bc_program_exprs_name[];
420 /// A reference to a filename for stdin.
421 extern const char bc_program_stdin_name[];
423 /// A reference to the ready message printed on SIGINT.
424 extern const char bc_program_ready_msg[];
426 /// A reference to the length of the ready message.
427 extern const size_t bc_program_ready_msg_len;
429 /// A reference to an array of escape characters for the print statement.
430 extern const char bc_program_esc_chars[];
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[];
436 #if BC_HAS_COMPUTED_GOTO
441 #define BC_PROG_JUMP(inst, code, ip) \
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]; \
452 #else // BC_DEBUG_CODE
455 #define BC_PROG_JUMP(inst, code, ip) \
458 inst = (uchar) (code)[(ip)->idx++]; \
459 goto *bc_program_inst_lbls[inst]; \
464 #endif // BC_DEBUG_CODE
466 #define BC_PROG_DIRECT_JUMP(l) goto lbl_##l;
467 #define BC_PROG_LBL(l) lbl_##l
468 #define BC_PROG_FALLTHROUGH
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")
479 #define BC_PROG_LBLS_ASSERT
487 #if BC_ENABLE_EXTRA_MATH
489 #define BC_PROG_LBLS \
490 static const void* const bc_program_inst_lbls[] = { \
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, \
535 &&lbl_BC_INST_ARRAY_ELEM, \
536 &&lbl_BC_INST_ARRAY, \
537 &&lbl_BC_INST_ZERO, \
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, \
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, \
562 &&lbl_BC_INST_PRINT_STR, \
563 &&lbl_BC_INST_JUMP, \
564 &&lbl_BC_INST_JUMP_ZERO, \
565 &&lbl_BC_INST_CALL, \
567 &&lbl_BC_INST_RET0, \
568 &&lbl_BC_INST_RET_VOID, \
569 &&lbl_BC_INST_HALT, \
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, \
592 #else // BC_ENABLE_EXTRA_MATH
594 #define BC_PROG_LBLS \
595 static const void* const bc_program_inst_lbls[] = { \
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, \
630 &&lbl_BC_INST_ARRAY_ELEM, \
631 &&lbl_BC_INST_ARRAY, \
632 &&lbl_BC_INST_ZERO, \
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, \
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, \
653 &&lbl_BC_INST_PRINT_STR, \
654 &&lbl_BC_INST_JUMP, \
655 &&lbl_BC_INST_JUMP_ZERO, \
656 &&lbl_BC_INST_CALL, \
658 &&lbl_BC_INST_RET0, \
659 &&lbl_BC_INST_RET_VOID, \
660 &&lbl_BC_INST_HALT, \
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, \
683 #endif // BC_ENABLE_EXTRA_MATH
687 #if BC_ENABLE_EXTRA_MATH
689 #define BC_PROG_LBLS \
690 static const void* const bc_program_inst_lbls[] = { \
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, \
735 &&lbl_BC_INST_ARRAY_ELEM, \
736 &&lbl_BC_INST_ARRAY, \
737 &&lbl_BC_INST_ZERO, \
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, \
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, \
762 &&lbl_BC_INST_PRINT_STR, \
763 &&lbl_BC_INST_JUMP, \
764 &&lbl_BC_INST_JUMP_ZERO, \
765 &&lbl_BC_INST_CALL, \
767 &&lbl_BC_INST_RET0, \
768 &&lbl_BC_INST_RET_VOID, \
769 &&lbl_BC_INST_HALT, \
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, \
778 #else // BC_ENABLE_EXTRA_MATH
780 #define BC_PROG_LBLS \
781 static const void* const bc_program_inst_lbls[] = { \
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, \
816 &&lbl_BC_INST_ARRAY_ELEM, \
817 &&lbl_BC_INST_ARRAY, \
818 &&lbl_BC_INST_ZERO, \
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, \
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, \
839 &&lbl_BC_INST_PRINT_STR, \
840 &&lbl_BC_INST_JUMP, \
841 &&lbl_BC_INST_JUMP_ZERO, \
842 &&lbl_BC_INST_CALL, \
844 &&lbl_BC_INST_RET0, \
845 &&lbl_BC_INST_RET_VOID, \
846 &&lbl_BC_INST_HALT, \
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, \
855 #endif // BC_ENABLE_EXTRA_MATH
861 #if BC_ENABLE_EXTRA_MATH
863 #define BC_PROG_LBLS \
864 static const void* const bc_program_inst_lbls[] = { \
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, \
888 &&lbl_BC_INST_ARRAY_ELEM, \
889 &&lbl_BC_INST_ARRAY, \
890 &&lbl_BC_INST_ZERO, \
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, \
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, \
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, \
935 #else // BC_ENABLE_EXTRA_MATH
937 #define BC_PROG_LBLS \
938 static const void* const bc_program_inst_lbls[] = { \
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, \
958 &&lbl_BC_INST_ARRAY_ELEM, \
959 &&lbl_BC_INST_ARRAY, \
960 &&lbl_BC_INST_ZERO, \
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, \
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, \
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, \
1001 #endif // BC_ENABLE_EXTRA_MATH
1003 #endif // BC_ENABLED
1005 #else // BC_HAS_COMPUTED_GOTO
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
1012 #define BC_PROG_LBLS
1014 #endif // BC_HAS_COMPUTED_GOTO
1016 #endif // BC_PROGRAM_H