1 /* 2 * ***************************************************************************** 3 * 4 * Copyright (c) 2018-2020 Gavin D. Howard and contributors. 5 * 6 * All rights reserved. 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 65 BcRNG rng; 66 #endif // BC_ENABLE_EXTRA_MATH 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 tail_calls; 85 86 BcBigDig strm; 87 BcNum strmb; 88 #endif // DC_ENABLED 89 90 BcNum one; 91 92 #if BC_ENABLED 93 BcNum last; 94 #endif // BC_ENABLED 95 96 #if DC_ENABLED 97 // This uses BC_NUM_LONG_LOG10 because it is used in bc_num_ulong2num(), 98 // which attempts to realloc, unless it is big enough. This is big enough. 99 BcDig strmb_num[BC_NUM_BIGDIG_LOG10]; 100 #endif // DC_ENABLED 101 102 BcDig one_num[BC_PROG_ONE_CAP]; 103 104 } BcProgram; 105 106 #define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n))) 107 108 #define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v)) 109 #define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v))) 110 111 #define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE]) 112 #define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE]) 113 #define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE]) 114 115 #define BC_PROG_MAIN (0) 116 #define BC_PROG_READ (1) 117 118 #define bc_program_retire(p, nres, nops) \ 119 (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops))) 120 121 #if DC_ENABLED 122 #define BC_PROG_REQ_FUNCS (2) 123 #if !BC_ENABLED 124 // For dc only, last is always true. 125 #define bc_program_copyToVar(p, name, t, last) \ 126 bc_program_copyToVar(p, name, t) 127 #endif // !BC_ENABLED 128 #else // DC_ENABLED 129 // For bc, 'pop' and 'copy' are always false. 130 #define bc_program_pushVar(p, code, bgn, pop, copy) \ 131 bc_program_pushVar(p, code, bgn) 132 #ifdef NDEBUG 133 #define BC_PROG_NO_STACK_CHECK 134 #endif // NDEBUG 135 #endif // DC_ENABLED 136 137 #define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap) 138 #if BC_ENABLED 139 #define BC_PROG_NUM(r, n) \ 140 ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 141 #else // BC_ENABLED 142 #define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n)) 143 // For dc, inst is always BC_INST_ARRAY_ELEM. 144 #define bc_program_pushArray(p, code, bgn, inst) \ 145 bc_program_pushArray(p, code, bgn) 146 #endif // BC_ENABLED 147 148 typedef void (*BcProgramUnary)(BcResult*, BcNum*); 149 150 void bc_program_init(BcProgram *p); 151 void bc_program_free(BcProgram *p); 152 153 #if BC_DEBUG_CODE 154 #if BC_ENABLED && DC_ENABLED 155 void bc_program_code(const BcProgram *p); 156 void bc_program_printInst(const BcProgram *p, const char *code, 157 size_t *restrict bgn); 158 void bc_program_printStackDebug(BcProgram* p); 159 #endif // BC_ENABLED && DC_ENABLED 160 #endif // BC_DEBUG_CODE 161 162 size_t bc_program_search(BcProgram *p, const char* id, bool var); 163 size_t bc_program_insertFunc(BcProgram *p, const char *name); 164 void bc_program_reset(BcProgram *p); 165 void bc_program_exec(BcProgram *p); 166 167 void bc_program_negate(BcResult *r, BcNum *n); 168 void bc_program_not(BcResult *r, BcNum *n); 169 #if BC_ENABLE_EXTRA_MATH 170 void bc_program_trunc(BcResult *r, BcNum *n); 171 #endif // BC_ENABLE_EXTRA_MATH 172 173 extern const BcNumBinaryOp bc_program_ops[]; 174 extern const BcNumBinaryOpReq bc_program_opReqs[]; 175 extern const BcProgramUnary bc_program_unarys[]; 176 extern const char bc_program_exprs_name[]; 177 extern const char bc_program_stdin_name[]; 178 extern const char bc_program_ready_msg[]; 179 extern const size_t bc_program_ready_msg_len; 180 extern const char bc_program_esc_chars[]; 181 extern const char bc_program_esc_seqs[]; 182 183 #endif // BC_PROGRAM_H 184