1 /* 2 * ***************************************************************************** 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2018-2021 Gavin D. Howard and contributors. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * * Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ***************************************************************************** 31 * 32 * Definitions for bc programs. 33 * 34 */ 35 36 #ifndef BC_PROGRAM_H 37 #define BC_PROGRAM_H 38 39 #include <stddef.h> 40 41 #include <status.h> 42 #include <parse.h> 43 #include <lang.h> 44 #include <num.h> 45 #include <rand.h> 46 47 #define BC_PROG_GLOBALS_IBASE (0) 48 #define BC_PROG_GLOBALS_OBASE (1) 49 #define BC_PROG_GLOBALS_SCALE (2) 50 51 #if BC_ENABLE_EXTRA_MATH 52 #define BC_PROG_MAX_RAND (3) 53 #endif // BC_ENABLE_EXTRA_MATH 54 55 #define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH) 56 57 #define BC_PROG_ONE_CAP (1) 58 59 typedef struct BcProgram { 60 61 BcBigDig globals[BC_PROG_GLOBALS_LEN]; 62 BcVec globals_v[BC_PROG_GLOBALS_LEN]; 63 64 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 65 BcRNG rng; 66 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 67 68 BcVec results; 69 BcVec stack; 70 71 BcVec *consts; 72 BcVec *strs; 73 74 BcVec fns; 75 BcVec fn_map; 76 77 BcVec vars; 78 BcVec var_map; 79 80 BcVec arrs; 81 BcVec arr_map; 82 83 #if DC_ENABLED 84 BcVec strs_v; 85 86 BcVec tail_calls; 87 88 BcBigDig strm; 89 BcNum strmb; 90 #endif // DC_ENABLED 91 92 BcNum zero; 93 BcNum one; 94 95 #if BC_ENABLED 96 BcNum last; 97 #endif // BC_ENABLED 98 99 #if DC_ENABLED 100 // This uses BC_NUM_LONG_LOG10 because it is used in bc_num_ulong2num(), 101 // which attempts to realloc, unless it is big enough. This is big enough. 102 BcDig strmb_num[BC_NUM_BIGDIG_LOG10]; 103 #endif // DC_ENABLED 104 105 BcDig zero_num[BC_PROG_ONE_CAP]; 106 BcDig one_num[BC_PROG_ONE_CAP]; 107 108 } BcProgram; 109 110 #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n))) 111 112 #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v)) 113 #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v))) 114 115 #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE]) 116 #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE]) 117 #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE]) 118 119 #define BC_PROG_MAIN (0) 120 #define BC_PROG_READ (1) 121 122 #define bc_program_retire(p, nres, nops) \ 123 (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops))) 124 125 #if DC_ENABLED 126 #define BC_PROG_REQ_FUNCS (2) 127 #if !BC_ENABLED 128 // For dc only, last is always true. 129 #define bc_program_copyToVar(p, name, t, last) \ 130 bc_program_copyToVar(p, name, t) 131 #endif // !BC_ENABLED 132 #else // DC_ENABLED 133 // For bc, 'pop' and 'copy' are always false. 134 #define bc_program_pushVar(p, code, bgn, pop, copy) \ 135 bc_program_pushVar(p, code, bgn) 136 #ifdef NDEBUG 137 #define BC_PROG_NO_STACK_CHECK 138 #endif // NDEBUG 139 #endif // DC_ENABLED 140 141 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap) 142 #if BC_ENABLED 143 #define BC_PROG_NUM(r, n) \ 144 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 145 #else // BC_ENABLED 146 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 147 // For dc, inst is always BC_INST_ARRAY_ELEM. 148 #define bc_program_pushArray(p, code, bgn, inst) \ 149 bc_program_pushArray(p, code, bgn) 150 #endif // BC_ENABLED 151 152 typedef void (*BcProgramUnary)(BcResult*, BcNum*); 153 154 void bc_program_init(BcProgram *p); 155 void bc_program_free(BcProgram *p); 156 157 #if BC_DEBUG_CODE 158 #if BC_ENABLED && DC_ENABLED 159 void bc_program_code(const BcProgram *p); 160 void bc_program_printInst(const BcProgram *p, const char *code, 161 size_t *restrict bgn); 162 void bc_program_printStackDebug(BcProgram* p); 163 #endif // BC_ENABLED && DC_ENABLED 164 #endif // BC_DEBUG_CODE 165 166 size_t bc_program_search(BcProgram *p, const char* id, bool var); 167 size_t bc_program_insertFunc(BcProgram *p, const char *name); 168 void bc_program_reset(BcProgram *p); 169 void bc_program_exec(BcProgram *p); 170 171 void bc_program_negate(BcResult *r, BcNum *n); 172 void bc_program_not(BcResult *r, BcNum *n); 173 #if BC_ENABLE_EXTRA_MATH 174 void bc_program_trunc(BcResult *r, BcNum *n); 175 #endif // BC_ENABLE_EXTRA_MATH 176 177 extern const BcNumBinaryOp bc_program_ops[]; 178 extern const BcNumBinaryOpReq bc_program_opReqs[]; 179 extern const BcProgramUnary bc_program_unarys[]; 180 extern const char bc_program_exprs_name[]; 181 extern const char bc_program_stdin_name[]; 182 extern const char bc_program_ready_msg[]; 183 extern const size_t bc_program_ready_msg_len; 184 extern const char bc_program_esc_chars[]; 185 extern const char bc_program_esc_seqs[]; 186 187 #endif // BC_PROGRAM_H 188