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 59typedef 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 152typedef void (*BcProgramUnary)(BcResult*, BcNum*); 153 154void bc_program_init(BcProgram *p); 155void bc_program_free(BcProgram *p); 156 157#if BC_DEBUG_CODE 158#if BC_ENABLED && DC_ENABLED 159void bc_program_code(const BcProgram *p); 160void bc_program_printInst(const BcProgram *p, const char *code, 161 size_t *restrict bgn); 162void bc_program_printStackDebug(BcProgram* p); 163#endif // BC_ENABLED && DC_ENABLED 164#endif // BC_DEBUG_CODE 165 166size_t bc_program_search(BcProgram *p, const char* id, bool var); 167size_t bc_program_insertFunc(BcProgram *p, const char *name); 168void bc_program_reset(BcProgram *p); 169void bc_program_exec(BcProgram *p); 170 171void bc_program_negate(BcResult *r, BcNum *n); 172void bc_program_not(BcResult *r, BcNum *n); 173#if BC_ENABLE_EXTRA_MATH 174void bc_program_trunc(BcResult *r, BcNum *n); 175#endif // BC_ENABLE_EXTRA_MATH 176 177extern const BcNumBinaryOp bc_program_ops[]; 178extern const BcNumBinaryOpReq bc_program_opReqs[]; 179extern const BcProgramUnary bc_program_unarys[]; 180extern const char bc_program_exprs_name[]; 181extern const char bc_program_stdin_name[]; 182extern const char bc_program_ready_msg[]; 183extern const size_t bc_program_ready_msg_len; 184extern const char bc_program_esc_chars[]; 185extern const char bc_program_esc_seqs[]; 186 187#endif // BC_PROGRAM_H 188