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