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) \
210 bc_program_copyToVar(p, name, t)
212 #endif // !BC_ENABLED
216 /// This define disappears pop and copy because for bc, 'pop' and 'copy' are
218 #define bc_program_pushVar(p, code, bgn, pop, copy) \
219 bc_program_pushVar(p, code, bgn)
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
225 #define BC_PROG_NO_STACK_CHECK
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.
235 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
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.
245 #define BC_PROG_NUM(r, n) \
246 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
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.
256 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
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.
266 typedef void (*BcProgramUnary)(BcResult *r, BcNum *n);
269 * Initializes the BcProgram.
270 * @param p The program to initialize.
272 void 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.
282 void bc_program_free(BcProgram *p);
287 #if BC_ENABLED && DC_ENABLED
290 * Prints the bytecode in a function. This is a debug-only function.
291 * @param p The program.
293 void bc_program_code(const BcProgram *p);
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
302 void bc_program_printInst(const BcProgram *p, const char *code,
303 size_t *restrict bgn);
306 * Prints the stack. This is a debug-only function.
307 * @param p The program.
309 void bc_program_printStackDebug(BcProgram* p);
311 #endif // BC_ENABLED && DC_ENABLED
312 #endif // BC_DEBUG_CODE
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.
321 size_t bc_program_search(BcProgram *p, const char* id, bool var);
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.
329 size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx);
332 * Inserts a function into the program and returns the index of the function in
334 * @param p The program.
335 * @param name The name of the function.
336 * @return The index of the function after insertion.
338 size_t bc_program_insertFunc(BcProgram *p, const char *name);
341 * Resets a program, usually because of resetting after an error.
342 * @param p The program to reset.
344 void bc_program_reset(BcProgram *p);
347 * Executes bc or dc code in the BcProgram.
348 * @param p The program.
350 void bc_program_exec(BcProgram *p);
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.
357 void bc_program_negate(BcResult *r, BcNum *n);
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.
364 void bc_program_not(BcResult *r, BcNum *n);
366 #if BC_ENABLE_EXTRA_MATH
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.
373 void bc_program_trunc(BcResult *r, BcNum *n);
375 #endif // BC_ENABLE_EXTRA_MATH
377 /// A reference to an array of binary operator functions.
378 extern const BcNumBinaryOp bc_program_ops[];
380 /// A reference to an array of binary operator allocation request functions.
381 extern const BcNumBinaryOpReq bc_program_opReqs[];
383 /// A reference to an array of unary operator functions.
384 extern const BcProgramUnary bc_program_unarys[];
386 /// A reference to a filename for command-line expressions.
387 extern const char bc_program_exprs_name[];
389 /// A reference to a filename for stdin.
390 extern const char bc_program_stdin_name[];
392 /// A reference to the ready message printed on SIGINT.
393 extern const char bc_program_ready_msg[];
395 /// A reference to the length of the ready message.
396 extern const size_t bc_program_ready_msg_len;
398 /// A reference to an array of escape characters for the print statement.
399 extern const char bc_program_esc_chars[];
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[];
405 #if BC_HAS_COMPUTED_GOTO
409 #define BC_PROG_JUMP(inst, code, ip) \
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]; \
417 #else // BC_DEBUG_CODE
419 #define BC_PROG_JUMP(inst, code, ip) \
421 inst = (uchar) (code)[(ip)->idx++]; \
422 goto *bc_program_inst_lbls[inst]; \
425 #endif // BC_DEBUG_CODE
427 #define BC_PROG_DIRECT_JUMP(l) goto lbl_ ## l;
428 #define BC_PROG_LBL(l) lbl_ ## l
429 #define BC_PROG_FALLTHROUGH
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")
440 #define BC_PROG_LBLS_ASSERT
448 #if BC_ENABLE_EXTRA_MATH
450 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
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, \
495 &&lbl_BC_INST_ARRAY_ELEM, \
496 &&lbl_BC_INST_ARRAY, \
497 &&lbl_BC_INST_ZERO, \
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, \
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, \
522 &&lbl_BC_INST_PRINT_STR, \
523 &&lbl_BC_INST_JUMP, \
524 &&lbl_BC_INST_JUMP_ZERO, \
525 &&lbl_BC_INST_CALL, \
527 &&lbl_BC_INST_RET0, \
528 &&lbl_BC_INST_RET_VOID, \
529 &&lbl_BC_INST_HALT, \
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, \
552 #else // BC_ENABLE_EXTRA_MATH
554 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
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, \
589 &&lbl_BC_INST_ARRAY_ELEM, \
590 &&lbl_BC_INST_ARRAY, \
591 &&lbl_BC_INST_ZERO, \
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, \
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, \
612 &&lbl_BC_INST_PRINT_STR, \
613 &&lbl_BC_INST_JUMP, \
614 &&lbl_BC_INST_JUMP_ZERO, \
615 &&lbl_BC_INST_CALL, \
617 &&lbl_BC_INST_RET0, \
618 &&lbl_BC_INST_RET_VOID, \
619 &&lbl_BC_INST_HALT, \
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, \
642 #endif // BC_ENABLE_EXTRA_MATH
646 #if BC_ENABLE_EXTRA_MATH
648 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
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, \
693 &&lbl_BC_INST_ARRAY_ELEM, \
694 &&lbl_BC_INST_ARRAY, \
695 &&lbl_BC_INST_ZERO, \
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, \
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, \
720 &&lbl_BC_INST_PRINT_STR, \
721 &&lbl_BC_INST_JUMP, \
722 &&lbl_BC_INST_JUMP_ZERO, \
723 &&lbl_BC_INST_CALL, \
725 &&lbl_BC_INST_RET0, \
726 &&lbl_BC_INST_RET_VOID, \
727 &&lbl_BC_INST_HALT, \
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, \
736 #else // BC_ENABLE_EXTRA_MATH
738 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
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, \
773 &&lbl_BC_INST_ARRAY_ELEM, \
774 &&lbl_BC_INST_ARRAY, \
775 &&lbl_BC_INST_ZERO, \
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, \
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, \
796 &&lbl_BC_INST_PRINT_STR, \
797 &&lbl_BC_INST_JUMP, \
798 &&lbl_BC_INST_JUMP_ZERO, \
799 &&lbl_BC_INST_CALL, \
801 &&lbl_BC_INST_RET0, \
802 &&lbl_BC_INST_RET_VOID, \
803 &&lbl_BC_INST_HALT, \
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, \
812 #endif // BC_ENABLE_EXTRA_MATH
818 #if BC_ENABLE_EXTRA_MATH
820 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
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, \
844 &&lbl_BC_INST_ARRAY_ELEM, \
845 &&lbl_BC_INST_ARRAY, \
846 &&lbl_BC_INST_ZERO, \
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, \
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, \
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, \
891 #else // BC_ENABLE_EXTRA_MATH
893 #define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
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, \
913 &&lbl_BC_INST_ARRAY_ELEM, \
914 &&lbl_BC_INST_ARRAY, \
915 &&lbl_BC_INST_ZERO, \
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, \
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, \
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, \
956 #endif // BC_ENABLE_EXTRA_MATH
960 #else // BC_HAS_COMPUTED_GOTO
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
969 #endif // BC_HAS_COMPUTED_GOTO
971 #endif // BC_PROGRAM_H