1252884aeSStefan Eßer /* 2252884aeSStefan Eßer * ***************************************************************************** 3252884aeSStefan Eßer * 4*3aa99676SStefan Eßer * SPDX-License-Identifier: BSD-2-Clause 5252884aeSStefan Eßer * 6*3aa99676SStefan Eßer * Copyright (c) 2018-2020 Gavin D. Howard and contributors. 7252884aeSStefan Eßer * 8252884aeSStefan Eßer * Redistribution and use in source and binary forms, with or without 9252884aeSStefan Eßer * modification, are permitted provided that the following conditions are met: 10252884aeSStefan Eßer * 11252884aeSStefan Eßer * * Redistributions of source code must retain the above copyright notice, this 12252884aeSStefan Eßer * list of conditions and the following disclaimer. 13252884aeSStefan Eßer * 14252884aeSStefan Eßer * * Redistributions in binary form must reproduce the above copyright notice, 15252884aeSStefan Eßer * this list of conditions and the following disclaimer in the documentation 16252884aeSStefan Eßer * and/or other materials provided with the distribution. 17252884aeSStefan Eßer * 18252884aeSStefan Eßer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19252884aeSStefan Eßer * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20252884aeSStefan Eßer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21252884aeSStefan Eßer * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22252884aeSStefan Eßer * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23252884aeSStefan Eßer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24252884aeSStefan Eßer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25252884aeSStefan Eßer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26252884aeSStefan Eßer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27252884aeSStefan Eßer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28252884aeSStefan Eßer * POSSIBILITY OF SUCH DAMAGE. 29252884aeSStefan Eßer * 30252884aeSStefan Eßer * ***************************************************************************** 31252884aeSStefan Eßer * 32252884aeSStefan Eßer * Definitions for program data. 33252884aeSStefan Eßer * 34252884aeSStefan Eßer */ 35252884aeSStefan Eßer 36252884aeSStefan Eßer #ifndef BC_LANG_H 37252884aeSStefan Eßer #define BC_LANG_H 38252884aeSStefan Eßer 39252884aeSStefan Eßer #include <stdbool.h> 40252884aeSStefan Eßer 41252884aeSStefan Eßer #include <status.h> 42252884aeSStefan Eßer #include <vector.h> 43252884aeSStefan Eßer #include <num.h> 44252884aeSStefan Eßer 45252884aeSStefan Eßer #if BC_ENABLED 46252884aeSStefan Eßer #define BC_INST_IS_ASSIGN(i) \ 47252884aeSStefan Eßer ((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL) 48252884aeSStefan Eßer #define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN) 49252884aeSStefan Eßer #else // BC_ENABLED 50252884aeSStefan Eßer #define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL) 51252884aeSStefan Eßer #define BC_INST_USE_VAL(i) (false) 52252884aeSStefan Eßer #endif // BC_ENABLED 53252884aeSStefan Eßer 54252884aeSStefan Eßer #ifndef NDEBUG 55252884aeSStefan Eßer #define BC_ENABLE_FUNC_FREE (1) 56252884aeSStefan Eßer #else // NDEBUG 57252884aeSStefan Eßer #define BC_ENABLE_FUNC_FREE DC_ENABLED 58252884aeSStefan Eßer #endif // NDEBUG 59252884aeSStefan Eßer 60252884aeSStefan Eßer typedef enum BcInst { 61252884aeSStefan Eßer 62252884aeSStefan Eßer #if BC_ENABLED 63252884aeSStefan Eßer BC_INST_INC = 0, 64252884aeSStefan Eßer BC_INST_DEC, 65252884aeSStefan Eßer #endif // BC_ENABLED 66252884aeSStefan Eßer 67252884aeSStefan Eßer BC_INST_NEG, 68252884aeSStefan Eßer BC_INST_BOOL_NOT, 69252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 70252884aeSStefan Eßer BC_INST_TRUNC, 71252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 72252884aeSStefan Eßer 73252884aeSStefan Eßer BC_INST_POWER, 74252884aeSStefan Eßer BC_INST_MULTIPLY, 75252884aeSStefan Eßer BC_INST_DIVIDE, 76252884aeSStefan Eßer BC_INST_MODULUS, 77252884aeSStefan Eßer BC_INST_PLUS, 78252884aeSStefan Eßer BC_INST_MINUS, 79252884aeSStefan Eßer 80252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 81252884aeSStefan Eßer BC_INST_PLACES, 82252884aeSStefan Eßer 83252884aeSStefan Eßer BC_INST_LSHIFT, 84252884aeSStefan Eßer BC_INST_RSHIFT, 85252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 86252884aeSStefan Eßer 87252884aeSStefan Eßer BC_INST_REL_EQ, 88252884aeSStefan Eßer BC_INST_REL_LE, 89252884aeSStefan Eßer BC_INST_REL_GE, 90252884aeSStefan Eßer BC_INST_REL_NE, 91252884aeSStefan Eßer BC_INST_REL_LT, 92252884aeSStefan Eßer BC_INST_REL_GT, 93252884aeSStefan Eßer 94252884aeSStefan Eßer BC_INST_BOOL_OR, 95252884aeSStefan Eßer BC_INST_BOOL_AND, 96252884aeSStefan Eßer 97252884aeSStefan Eßer #if BC_ENABLED 98252884aeSStefan Eßer BC_INST_ASSIGN_POWER, 99252884aeSStefan Eßer BC_INST_ASSIGN_MULTIPLY, 100252884aeSStefan Eßer BC_INST_ASSIGN_DIVIDE, 101252884aeSStefan Eßer BC_INST_ASSIGN_MODULUS, 102252884aeSStefan Eßer BC_INST_ASSIGN_PLUS, 103252884aeSStefan Eßer BC_INST_ASSIGN_MINUS, 104252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 105252884aeSStefan Eßer BC_INST_ASSIGN_PLACES, 106252884aeSStefan Eßer BC_INST_ASSIGN_LSHIFT, 107252884aeSStefan Eßer BC_INST_ASSIGN_RSHIFT, 108252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 109252884aeSStefan Eßer BC_INST_ASSIGN, 110252884aeSStefan Eßer 111252884aeSStefan Eßer BC_INST_ASSIGN_POWER_NO_VAL, 112252884aeSStefan Eßer BC_INST_ASSIGN_MULTIPLY_NO_VAL, 113252884aeSStefan Eßer BC_INST_ASSIGN_DIVIDE_NO_VAL, 114252884aeSStefan Eßer BC_INST_ASSIGN_MODULUS_NO_VAL, 115252884aeSStefan Eßer BC_INST_ASSIGN_PLUS_NO_VAL, 116252884aeSStefan Eßer BC_INST_ASSIGN_MINUS_NO_VAL, 117252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 118252884aeSStefan Eßer BC_INST_ASSIGN_PLACES_NO_VAL, 119252884aeSStefan Eßer BC_INST_ASSIGN_LSHIFT_NO_VAL, 120252884aeSStefan Eßer BC_INST_ASSIGN_RSHIFT_NO_VAL, 121252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 122252884aeSStefan Eßer #endif // BC_ENABLED 123252884aeSStefan Eßer BC_INST_ASSIGN_NO_VAL, 124252884aeSStefan Eßer 125252884aeSStefan Eßer BC_INST_NUM, 126252884aeSStefan Eßer BC_INST_VAR, 127252884aeSStefan Eßer BC_INST_ARRAY_ELEM, 128252884aeSStefan Eßer #if BC_ENABLED 129252884aeSStefan Eßer BC_INST_ARRAY, 130252884aeSStefan Eßer #endif // BC_ENABLED 131252884aeSStefan Eßer 132*3aa99676SStefan Eßer BC_INST_ZERO, 133252884aeSStefan Eßer BC_INST_ONE, 134252884aeSStefan Eßer 135252884aeSStefan Eßer #if BC_ENABLED 136252884aeSStefan Eßer BC_INST_LAST, 137252884aeSStefan Eßer #endif // BC_ENABLED 138252884aeSStefan Eßer BC_INST_IBASE, 139252884aeSStefan Eßer BC_INST_OBASE, 140252884aeSStefan Eßer BC_INST_SCALE, 141*3aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 142252884aeSStefan Eßer BC_INST_SEED, 143*3aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 144252884aeSStefan Eßer BC_INST_LENGTH, 145252884aeSStefan Eßer BC_INST_SCALE_FUNC, 146252884aeSStefan Eßer BC_INST_SQRT, 147252884aeSStefan Eßer BC_INST_ABS, 148*3aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 149252884aeSStefan Eßer BC_INST_IRAND, 150*3aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 151252884aeSStefan Eßer BC_INST_READ, 152*3aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 153252884aeSStefan Eßer BC_INST_RAND, 154*3aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 155252884aeSStefan Eßer BC_INST_MAXIBASE, 156252884aeSStefan Eßer BC_INST_MAXOBASE, 157252884aeSStefan Eßer BC_INST_MAXSCALE, 158*3aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 159252884aeSStefan Eßer BC_INST_MAXRAND, 160*3aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 161252884aeSStefan Eßer 162252884aeSStefan Eßer BC_INST_PRINT, 163252884aeSStefan Eßer BC_INST_PRINT_POP, 164252884aeSStefan Eßer BC_INST_STR, 165252884aeSStefan Eßer BC_INST_PRINT_STR, 166252884aeSStefan Eßer 167252884aeSStefan Eßer #if BC_ENABLED 168252884aeSStefan Eßer BC_INST_JUMP, 169252884aeSStefan Eßer BC_INST_JUMP_ZERO, 170252884aeSStefan Eßer 171252884aeSStefan Eßer BC_INST_CALL, 172252884aeSStefan Eßer 173252884aeSStefan Eßer BC_INST_RET, 174252884aeSStefan Eßer BC_INST_RET0, 175252884aeSStefan Eßer BC_INST_RET_VOID, 176252884aeSStefan Eßer 177252884aeSStefan Eßer BC_INST_HALT, 178252884aeSStefan Eßer #endif // BC_ENABLED 179252884aeSStefan Eßer 180252884aeSStefan Eßer BC_INST_POP, 181252884aeSStefan Eßer 182252884aeSStefan Eßer #if DC_ENABLED 183252884aeSStefan Eßer BC_INST_POP_EXEC, 184252884aeSStefan Eßer BC_INST_MODEXP, 185252884aeSStefan Eßer BC_INST_DIVMOD, 186252884aeSStefan Eßer 187252884aeSStefan Eßer BC_INST_EXECUTE, 188252884aeSStefan Eßer BC_INST_EXEC_COND, 189252884aeSStefan Eßer 190252884aeSStefan Eßer BC_INST_ASCIIFY, 191252884aeSStefan Eßer BC_INST_PRINT_STREAM, 192252884aeSStefan Eßer 193252884aeSStefan Eßer BC_INST_PRINT_STACK, 194252884aeSStefan Eßer BC_INST_CLEAR_STACK, 195252884aeSStefan Eßer BC_INST_STACK_LEN, 196252884aeSStefan Eßer BC_INST_DUPLICATE, 197252884aeSStefan Eßer BC_INST_SWAP, 198252884aeSStefan Eßer 199252884aeSStefan Eßer BC_INST_LOAD, 200252884aeSStefan Eßer BC_INST_PUSH_VAR, 201252884aeSStefan Eßer BC_INST_PUSH_TO_VAR, 202252884aeSStefan Eßer 203252884aeSStefan Eßer BC_INST_QUIT, 204252884aeSStefan Eßer BC_INST_NQUIT, 205252884aeSStefan Eßer #endif // DC_ENABLED 206252884aeSStefan Eßer 207252884aeSStefan Eßer BC_INST_INVALID = UCHAR_MAX, 208252884aeSStefan Eßer 209252884aeSStefan Eßer } BcInst; 210252884aeSStefan Eßer 211252884aeSStefan Eßer typedef struct BcId { 212252884aeSStefan Eßer char *name; 213252884aeSStefan Eßer size_t idx; 214252884aeSStefan Eßer } BcId; 215252884aeSStefan Eßer 216252884aeSStefan Eßer typedef struct BcLoc { 217252884aeSStefan Eßer size_t loc; 218252884aeSStefan Eßer size_t idx; 219252884aeSStefan Eßer } BcLoc; 220252884aeSStefan Eßer 221252884aeSStefan Eßer typedef struct BcConst { 222252884aeSStefan Eßer char *val; 223252884aeSStefan Eßer BcBigDig base; 224252884aeSStefan Eßer BcNum num; 225252884aeSStefan Eßer } BcConst; 226252884aeSStefan Eßer 227252884aeSStefan Eßer typedef struct BcFunc { 228252884aeSStefan Eßer 229252884aeSStefan Eßer BcVec code; 230252884aeSStefan Eßer #if BC_ENABLED 231252884aeSStefan Eßer BcVec labels; 232252884aeSStefan Eßer BcVec autos; 233252884aeSStefan Eßer size_t nparams; 234252884aeSStefan Eßer #endif // BC_ENABLED 235252884aeSStefan Eßer 236252884aeSStefan Eßer BcVec strs; 237252884aeSStefan Eßer BcVec consts; 238252884aeSStefan Eßer 239252884aeSStefan Eßer const char *name; 240252884aeSStefan Eßer #if BC_ENABLED 241252884aeSStefan Eßer bool voidfn; 242252884aeSStefan Eßer #endif // BC_ENABLED 243252884aeSStefan Eßer 244252884aeSStefan Eßer } BcFunc; 245252884aeSStefan Eßer 246252884aeSStefan Eßer typedef enum BcResultType { 247252884aeSStefan Eßer 248252884aeSStefan Eßer BC_RESULT_VAR, 249252884aeSStefan Eßer BC_RESULT_ARRAY_ELEM, 250252884aeSStefan Eßer #if BC_ENABLED 251252884aeSStefan Eßer BC_RESULT_ARRAY, 252252884aeSStefan Eßer #endif // BC_ENABLED 253252884aeSStefan Eßer 254252884aeSStefan Eßer BC_RESULT_STR, 255252884aeSStefan Eßer 256252884aeSStefan Eßer BC_RESULT_TEMP, 257252884aeSStefan Eßer 258*3aa99676SStefan Eßer BC_RESULT_ZERO, 259252884aeSStefan Eßer BC_RESULT_ONE, 260252884aeSStefan Eßer 261252884aeSStefan Eßer #if BC_ENABLED 262252884aeSStefan Eßer BC_RESULT_LAST, 263252884aeSStefan Eßer BC_RESULT_VOID, 264252884aeSStefan Eßer #endif // BC_ENABLED 265252884aeSStefan Eßer BC_RESULT_IBASE, 266252884aeSStefan Eßer BC_RESULT_OBASE, 267252884aeSStefan Eßer BC_RESULT_SCALE, 268252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 269252884aeSStefan Eßer BC_RESULT_SEED, 270252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 271252884aeSStefan Eßer 272252884aeSStefan Eßer } BcResultType; 273252884aeSStefan Eßer 274252884aeSStefan Eßer typedef union BcResultData { 275252884aeSStefan Eßer BcNum n; 276252884aeSStefan Eßer BcVec v; 277252884aeSStefan Eßer BcLoc loc; 278252884aeSStefan Eßer } BcResultData; 279252884aeSStefan Eßer 280252884aeSStefan Eßer typedef struct BcResult { 281252884aeSStefan Eßer BcResultType t; 282252884aeSStefan Eßer BcResultData d; 283252884aeSStefan Eßer } BcResult; 284252884aeSStefan Eßer 285252884aeSStefan Eßer typedef struct BcInstPtr { 286252884aeSStefan Eßer size_t func; 287252884aeSStefan Eßer size_t idx; 288252884aeSStefan Eßer size_t len; 289252884aeSStefan Eßer } BcInstPtr; 290252884aeSStefan Eßer 291252884aeSStefan Eßer typedef enum BcType { 292252884aeSStefan Eßer BC_TYPE_VAR, 293252884aeSStefan Eßer BC_TYPE_ARRAY, 294252884aeSStefan Eßer #if BC_ENABLED 295252884aeSStefan Eßer BC_TYPE_REF, 296252884aeSStefan Eßer #endif // BC_ENABLED 297252884aeSStefan Eßer } BcType; 298252884aeSStefan Eßer 299252884aeSStefan Eßer struct BcProgram; 300252884aeSStefan Eßer 301252884aeSStefan Eßer void bc_func_init(BcFunc *f, const char* name); 302252884aeSStefan Eßer void bc_func_insert(BcFunc *f, struct BcProgram* p, char* name, 303252884aeSStefan Eßer BcType type, size_t line); 304252884aeSStefan Eßer void bc_func_reset(BcFunc *f); 305252884aeSStefan Eßer void bc_func_free(void *func); 306252884aeSStefan Eßer 307252884aeSStefan Eßer void bc_array_init(BcVec *a, bool nums); 308252884aeSStefan Eßer void bc_array_copy(BcVec *d, const BcVec *s); 309252884aeSStefan Eßer 310252884aeSStefan Eßer void bc_string_free(void *string); 311252884aeSStefan Eßer void bc_const_free(void *constant); 312252884aeSStefan Eßer void bc_id_free(void *id); 313252884aeSStefan Eßer void bc_result_clear(BcResult *r); 314252884aeSStefan Eßer void bc_result_copy(BcResult *d, BcResult *src); 315252884aeSStefan Eßer void bc_result_free(void *result); 316252884aeSStefan Eßer 317252884aeSStefan Eßer void bc_array_expand(BcVec *a, size_t len); 318252884aeSStefan Eßer int bc_id_cmp(const BcId *e1, const BcId *e2); 319252884aeSStefan Eßer 320252884aeSStefan Eßer #if BC_DEBUG_CODE 321252884aeSStefan Eßer extern const char* bc_inst_names[]; 322252884aeSStefan Eßer #endif // BC_DEBUG_CODE 323252884aeSStefan Eßer 324252884aeSStefan Eßer extern const char bc_func_main[]; 325252884aeSStefan Eßer extern const char bc_func_read[]; 326252884aeSStefan Eßer 327252884aeSStefan Eßer #endif // BC_LANG_H 328