1*5a6e8488SAndroid Build Coastguard Worker /* 2*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 3*5a6e8488SAndroid Build Coastguard Worker * 4*5a6e8488SAndroid Build Coastguard Worker * SPDX-License-Identifier: BSD-2-Clause 5*5a6e8488SAndroid Build Coastguard Worker * 6*5a6e8488SAndroid Build Coastguard Worker * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7*5a6e8488SAndroid Build Coastguard Worker * 8*5a6e8488SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 9*5a6e8488SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 10*5a6e8488SAndroid Build Coastguard Worker * 11*5a6e8488SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright notice, this 12*5a6e8488SAndroid Build Coastguard Worker * list of conditions and the following disclaimer. 13*5a6e8488SAndroid Build Coastguard Worker * 14*5a6e8488SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright notice, 15*5a6e8488SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation 16*5a6e8488SAndroid Build Coastguard Worker * and/or other materials provided with the distribution. 17*5a6e8488SAndroid Build Coastguard Worker * 18*5a6e8488SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*5a6e8488SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*5a6e8488SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*5a6e8488SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*5a6e8488SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*5a6e8488SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*5a6e8488SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*5a6e8488SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*5a6e8488SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*5a6e8488SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*5a6e8488SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE. 29*5a6e8488SAndroid Build Coastguard Worker * 30*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 31*5a6e8488SAndroid Build Coastguard Worker * 32*5a6e8488SAndroid Build Coastguard Worker * Definitions for program data. 33*5a6e8488SAndroid Build Coastguard Worker * 34*5a6e8488SAndroid Build Coastguard Worker */ 35*5a6e8488SAndroid Build Coastguard Worker 36*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_LANG_H 37*5a6e8488SAndroid Build Coastguard Worker #define BC_LANG_H 38*5a6e8488SAndroid Build Coastguard Worker 39*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h> 40*5a6e8488SAndroid Build Coastguard Worker 41*5a6e8488SAndroid Build Coastguard Worker // These have to come first to silence a warning on BC_C11 below. 42*5a6e8488SAndroid Build Coastguard Worker #include <status.h> 43*5a6e8488SAndroid Build Coastguard Worker #include <vector.h> 44*5a6e8488SAndroid Build Coastguard Worker #include <num.h> 45*5a6e8488SAndroid Build Coastguard Worker 46*5a6e8488SAndroid Build Coastguard Worker #if BC_C11 47*5a6e8488SAndroid Build Coastguard Worker #include <assert.h> 48*5a6e8488SAndroid Build Coastguard Worker #endif // BC_C11 49*5a6e8488SAndroid Build Coastguard Worker 50*5a6e8488SAndroid Build Coastguard Worker /// The instructions for bytecode. 51*5a6e8488SAndroid Build Coastguard Worker typedef enum BcInst 52*5a6e8488SAndroid Build Coastguard Worker { 53*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 54*5a6e8488SAndroid Build Coastguard Worker /// Postfix increment and decrement. Prefix are translated into 55*5a6e8488SAndroid Build Coastguard Worker /// BC_INST_ONE with either BC_INST_ASSIGN_PLUS or BC_INST_ASSIGN_MINUS. 56*5a6e8488SAndroid Build Coastguard Worker BC_INST_INC = 0, 57*5a6e8488SAndroid Build Coastguard Worker BC_INST_DEC, 58*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 59*5a6e8488SAndroid Build Coastguard Worker 60*5a6e8488SAndroid Build Coastguard Worker /// Unary negation. 61*5a6e8488SAndroid Build Coastguard Worker BC_INST_NEG, 62*5a6e8488SAndroid Build Coastguard Worker 63*5a6e8488SAndroid Build Coastguard Worker /// Boolean not. 64*5a6e8488SAndroid Build Coastguard Worker BC_INST_BOOL_NOT, 65*5a6e8488SAndroid Build Coastguard Worker 66*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 67*5a6e8488SAndroid Build Coastguard Worker /// Truncation operator. 68*5a6e8488SAndroid Build Coastguard Worker BC_INST_TRUNC, 69*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 70*5a6e8488SAndroid Build Coastguard Worker 71*5a6e8488SAndroid Build Coastguard Worker /// These should be self-explanatory. 72*5a6e8488SAndroid Build Coastguard Worker BC_INST_POWER, 73*5a6e8488SAndroid Build Coastguard Worker BC_INST_MULTIPLY, 74*5a6e8488SAndroid Build Coastguard Worker BC_INST_DIVIDE, 75*5a6e8488SAndroid Build Coastguard Worker BC_INST_MODULUS, 76*5a6e8488SAndroid Build Coastguard Worker BC_INST_PLUS, 77*5a6e8488SAndroid Build Coastguard Worker BC_INST_MINUS, 78*5a6e8488SAndroid Build Coastguard Worker 79*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 80*5a6e8488SAndroid Build Coastguard Worker /// Places operator. 81*5a6e8488SAndroid Build Coastguard Worker BC_INST_PLACES, 82*5a6e8488SAndroid Build Coastguard Worker 83*5a6e8488SAndroid Build Coastguard Worker /// Shift operators. 84*5a6e8488SAndroid Build Coastguard Worker BC_INST_LSHIFT, 85*5a6e8488SAndroid Build Coastguard Worker BC_INST_RSHIFT, 86*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 87*5a6e8488SAndroid Build Coastguard Worker 88*5a6e8488SAndroid Build Coastguard Worker /// Comparison operators. 89*5a6e8488SAndroid Build Coastguard Worker BC_INST_REL_EQ, 90*5a6e8488SAndroid Build Coastguard Worker BC_INST_REL_LE, 91*5a6e8488SAndroid Build Coastguard Worker BC_INST_REL_GE, 92*5a6e8488SAndroid Build Coastguard Worker BC_INST_REL_NE, 93*5a6e8488SAndroid Build Coastguard Worker BC_INST_REL_LT, 94*5a6e8488SAndroid Build Coastguard Worker BC_INST_REL_GT, 95*5a6e8488SAndroid Build Coastguard Worker 96*5a6e8488SAndroid Build Coastguard Worker /// Boolean or and and. 97*5a6e8488SAndroid Build Coastguard Worker BC_INST_BOOL_OR, 98*5a6e8488SAndroid Build Coastguard Worker BC_INST_BOOL_AND, 99*5a6e8488SAndroid Build Coastguard Worker 100*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 101*5a6e8488SAndroid Build Coastguard Worker /// Same as the normal operators, but assigment. So ^=, *=, /=, etc. 102*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_POWER, 103*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_MULTIPLY, 104*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_DIVIDE, 105*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_MODULUS, 106*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_PLUS, 107*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_MINUS, 108*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 109*5a6e8488SAndroid Build Coastguard Worker /// Places and shift assignment operators. 110*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_PLACES, 111*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_LSHIFT, 112*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_RSHIFT, 113*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 114*5a6e8488SAndroid Build Coastguard Worker 115*5a6e8488SAndroid Build Coastguard Worker /// Normal assignment. 116*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN, 117*5a6e8488SAndroid Build Coastguard Worker 118*5a6e8488SAndroid Build Coastguard Worker /// bc and dc detect when the value from an assignment is not necessary. 119*5a6e8488SAndroid Build Coastguard Worker /// For example, a plain assignment statement means the value is never used. 120*5a6e8488SAndroid Build Coastguard Worker /// In those cases, we can get lots of performance back by not even creating 121*5a6e8488SAndroid Build Coastguard Worker /// a copy at all. In fact, it saves a copy, a push onto the results stack, 122*5a6e8488SAndroid Build Coastguard Worker /// a pop from the results stack, and a free. Definitely worth it to detect. 123*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_POWER_NO_VAL, 124*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_MULTIPLY_NO_VAL, 125*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_DIVIDE_NO_VAL, 126*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_MODULUS_NO_VAL, 127*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_PLUS_NO_VAL, 128*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_MINUS_NO_VAL, 129*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 130*5a6e8488SAndroid Build Coastguard Worker /// Same as above. 131*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_PLACES_NO_VAL, 132*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_LSHIFT_NO_VAL, 133*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_RSHIFT_NO_VAL, 134*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 135*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 136*5a6e8488SAndroid Build Coastguard Worker 137*5a6e8488SAndroid Build Coastguard Worker /// Normal assignment that pushes no value on the stack. 138*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASSIGN_NO_VAL, 139*5a6e8488SAndroid Build Coastguard Worker 140*5a6e8488SAndroid Build Coastguard Worker /// Push a constant onto the results stack. 141*5a6e8488SAndroid Build Coastguard Worker BC_INST_NUM, 142*5a6e8488SAndroid Build Coastguard Worker 143*5a6e8488SAndroid Build Coastguard Worker /// Push a variable onto the results stack. 144*5a6e8488SAndroid Build Coastguard Worker BC_INST_VAR, 145*5a6e8488SAndroid Build Coastguard Worker 146*5a6e8488SAndroid Build Coastguard Worker /// Push an array element onto the results stack. 147*5a6e8488SAndroid Build Coastguard Worker BC_INST_ARRAY_ELEM, 148*5a6e8488SAndroid Build Coastguard Worker 149*5a6e8488SAndroid Build Coastguard Worker /// Push an array onto the results stack. This is different from pushing an 150*5a6e8488SAndroid Build Coastguard Worker /// array *element* onto the results stack; it pushes a reference to the 151*5a6e8488SAndroid Build Coastguard Worker /// whole array. This is needed in bc for function arguments that are 152*5a6e8488SAndroid Build Coastguard Worker /// arrays. It is also needed for returning the length of an array. 153*5a6e8488SAndroid Build Coastguard Worker BC_INST_ARRAY, 154*5a6e8488SAndroid Build Coastguard Worker 155*5a6e8488SAndroid Build Coastguard Worker /// Push a zero or a one onto the stack. These are special cased because it 156*5a6e8488SAndroid Build Coastguard Worker /// does help performance, particularly for one since inc/dec operators 157*5a6e8488SAndroid Build Coastguard Worker /// use it. 158*5a6e8488SAndroid Build Coastguard Worker BC_INST_ZERO, 159*5a6e8488SAndroid Build Coastguard Worker BC_INST_ONE, 160*5a6e8488SAndroid Build Coastguard Worker 161*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 162*5a6e8488SAndroid Build Coastguard Worker /// Push the last printed value onto the stack. 163*5a6e8488SAndroid Build Coastguard Worker BC_INST_LAST, 164*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 165*5a6e8488SAndroid Build Coastguard Worker 166*5a6e8488SAndroid Build Coastguard Worker /// Push the value of any of the globals onto the stack. 167*5a6e8488SAndroid Build Coastguard Worker BC_INST_IBASE, 168*5a6e8488SAndroid Build Coastguard Worker BC_INST_OBASE, 169*5a6e8488SAndroid Build Coastguard Worker BC_INST_SCALE, 170*5a6e8488SAndroid Build Coastguard Worker 171*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 172*5a6e8488SAndroid Build Coastguard Worker /// Push the value of the seed global onto the stack. 173*5a6e8488SAndroid Build Coastguard Worker BC_INST_SEED, 174*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 175*5a6e8488SAndroid Build Coastguard Worker 176*5a6e8488SAndroid Build Coastguard Worker /// These are builtin functions. 177*5a6e8488SAndroid Build Coastguard Worker BC_INST_LENGTH, 178*5a6e8488SAndroid Build Coastguard Worker BC_INST_SCALE_FUNC, 179*5a6e8488SAndroid Build Coastguard Worker BC_INST_SQRT, 180*5a6e8488SAndroid Build Coastguard Worker BC_INST_ABS, 181*5a6e8488SAndroid Build Coastguard Worker BC_INST_IS_NUMBER, 182*5a6e8488SAndroid Build Coastguard Worker BC_INST_IS_STRING, 183*5a6e8488SAndroid Build Coastguard Worker 184*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 185*5a6e8488SAndroid Build Coastguard Worker /// Another builtin function. 186*5a6e8488SAndroid Build Coastguard Worker BC_INST_IRAND, 187*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 188*5a6e8488SAndroid Build Coastguard Worker 189*5a6e8488SAndroid Build Coastguard Worker /// Asciify. 190*5a6e8488SAndroid Build Coastguard Worker BC_INST_ASCIIFY, 191*5a6e8488SAndroid Build Coastguard Worker 192*5a6e8488SAndroid Build Coastguard Worker /// Another builtin function. 193*5a6e8488SAndroid Build Coastguard Worker BC_INST_READ, 194*5a6e8488SAndroid Build Coastguard Worker 195*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 196*5a6e8488SAndroid Build Coastguard Worker /// Another builtin function. 197*5a6e8488SAndroid Build Coastguard Worker BC_INST_RAND, 198*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 199*5a6e8488SAndroid Build Coastguard Worker 200*5a6e8488SAndroid Build Coastguard Worker /// Return the max for the various globals. 201*5a6e8488SAndroid Build Coastguard Worker BC_INST_MAXIBASE, 202*5a6e8488SAndroid Build Coastguard Worker BC_INST_MAXOBASE, 203*5a6e8488SAndroid Build Coastguard Worker BC_INST_MAXSCALE, 204*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 205*5a6e8488SAndroid Build Coastguard Worker /// Return the max value returned by rand(). 206*5a6e8488SAndroid Build Coastguard Worker BC_INST_MAXRAND, 207*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 208*5a6e8488SAndroid Build Coastguard Worker 209*5a6e8488SAndroid Build Coastguard Worker /// bc line_length() builtin function. 210*5a6e8488SAndroid Build Coastguard Worker BC_INST_LINE_LENGTH, 211*5a6e8488SAndroid Build Coastguard Worker 212*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 213*5a6e8488SAndroid Build Coastguard Worker 214*5a6e8488SAndroid Build Coastguard Worker /// bc global_stacks() builtin function. 215*5a6e8488SAndroid Build Coastguard Worker BC_INST_GLOBAL_STACKS, 216*5a6e8488SAndroid Build Coastguard Worker 217*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 218*5a6e8488SAndroid Build Coastguard Worker 219*5a6e8488SAndroid Build Coastguard Worker /// bc leading_zero() builtin function. 220*5a6e8488SAndroid Build Coastguard Worker BC_INST_LEADING_ZERO, 221*5a6e8488SAndroid Build Coastguard Worker 222*5a6e8488SAndroid Build Coastguard Worker /// This is slightly misnamed versus BC_INST_PRINT_POP. Well, it is in bc. 223*5a6e8488SAndroid Build Coastguard Worker /// dc uses this instruction to print, but not pop. That's valid in dc. 224*5a6e8488SAndroid Build Coastguard Worker /// However, in bc, it is *never* valid to print without popping. In bc, 225*5a6e8488SAndroid Build Coastguard Worker /// BC_INST_PRINT_POP is used to indicate when a string should be printed 226*5a6e8488SAndroid Build Coastguard Worker /// because of a print statement or whether it should be printed raw. The 227*5a6e8488SAndroid Build Coastguard Worker /// reason for this is because a print statement handles escaped characters. 228*5a6e8488SAndroid Build Coastguard Worker /// So BC_INST_PRINT_POP is for printing a string from a print statement, 229*5a6e8488SAndroid Build Coastguard Worker /// BC_INST_PRINT_STR is for printing a string by itself. 230*5a6e8488SAndroid Build Coastguard Worker /// 231*5a6e8488SAndroid Build Coastguard Worker /// In dc, BC_INST_PRINT_POP prints and pops, and BC_INST_PRINT just prints. 232*5a6e8488SAndroid Build Coastguard Worker /// 233*5a6e8488SAndroid Build Coastguard Worker /// Oh, and BC_INST_STR pushes a string onto the results stack. 234*5a6e8488SAndroid Build Coastguard Worker BC_INST_PRINT, 235*5a6e8488SAndroid Build Coastguard Worker BC_INST_PRINT_POP, 236*5a6e8488SAndroid Build Coastguard Worker BC_INST_STR, 237*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 238*5a6e8488SAndroid Build Coastguard Worker BC_INST_PRINT_STR, 239*5a6e8488SAndroid Build Coastguard Worker 240*5a6e8488SAndroid Build Coastguard Worker /// Jumps unconditionally. 241*5a6e8488SAndroid Build Coastguard Worker BC_INST_JUMP, 242*5a6e8488SAndroid Build Coastguard Worker 243*5a6e8488SAndroid Build Coastguard Worker /// Jumps if the top of the results stack is zero (condition failed). It 244*5a6e8488SAndroid Build Coastguard Worker /// turns out that we only want to jump when conditions fail to "skip" code. 245*5a6e8488SAndroid Build Coastguard Worker BC_INST_JUMP_ZERO, 246*5a6e8488SAndroid Build Coastguard Worker 247*5a6e8488SAndroid Build Coastguard Worker /// Call a function. 248*5a6e8488SAndroid Build Coastguard Worker BC_INST_CALL, 249*5a6e8488SAndroid Build Coastguard Worker 250*5a6e8488SAndroid Build Coastguard Worker /// Return the top of the stack to the caller. 251*5a6e8488SAndroid Build Coastguard Worker BC_INST_RET, 252*5a6e8488SAndroid Build Coastguard Worker 253*5a6e8488SAndroid Build Coastguard Worker /// Return 0 to the caller. 254*5a6e8488SAndroid Build Coastguard Worker BC_INST_RET0, 255*5a6e8488SAndroid Build Coastguard Worker 256*5a6e8488SAndroid Build Coastguard Worker /// Special return instruction for void functions. 257*5a6e8488SAndroid Build Coastguard Worker BC_INST_RET_VOID, 258*5a6e8488SAndroid Build Coastguard Worker 259*5a6e8488SAndroid Build Coastguard Worker /// Special halt instruction. 260*5a6e8488SAndroid Build Coastguard Worker BC_INST_HALT, 261*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 262*5a6e8488SAndroid Build Coastguard Worker 263*5a6e8488SAndroid Build Coastguard Worker /// Pop an item off of the results stack. 264*5a6e8488SAndroid Build Coastguard Worker BC_INST_POP, 265*5a6e8488SAndroid Build Coastguard Worker 266*5a6e8488SAndroid Build Coastguard Worker /// Swaps the top two items on the results stack. 267*5a6e8488SAndroid Build Coastguard Worker BC_INST_SWAP, 268*5a6e8488SAndroid Build Coastguard Worker 269*5a6e8488SAndroid Build Coastguard Worker /// Modular exponentiation. 270*5a6e8488SAndroid Build Coastguard Worker BC_INST_MODEXP, 271*5a6e8488SAndroid Build Coastguard Worker 272*5a6e8488SAndroid Build Coastguard Worker /// Do divide and modulus at the same time. 273*5a6e8488SAndroid Build Coastguard Worker BC_INST_DIVMOD, 274*5a6e8488SAndroid Build Coastguard Worker 275*5a6e8488SAndroid Build Coastguard Worker /// Turns a number into a string and prints it. 276*5a6e8488SAndroid Build Coastguard Worker BC_INST_PRINT_STREAM, 277*5a6e8488SAndroid Build Coastguard Worker 278*5a6e8488SAndroid Build Coastguard Worker #if DC_ENABLED 279*5a6e8488SAndroid Build Coastguard Worker 280*5a6e8488SAndroid Build Coastguard Worker /// dc extended registers command. 281*5a6e8488SAndroid Build Coastguard Worker BC_INST_EXTENDED_REGISTERS, 282*5a6e8488SAndroid Build Coastguard Worker 283*5a6e8488SAndroid Build Coastguard Worker /// dc's return; it pops an executing string off of the stack. 284*5a6e8488SAndroid Build Coastguard Worker BC_INST_POP_EXEC, 285*5a6e8488SAndroid Build Coastguard Worker 286*5a6e8488SAndroid Build Coastguard Worker /// Unconditionally execute a string. 287*5a6e8488SAndroid Build Coastguard Worker BC_INST_EXECUTE, 288*5a6e8488SAndroid Build Coastguard Worker 289*5a6e8488SAndroid Build Coastguard Worker /// Conditionally execute a string. 290*5a6e8488SAndroid Build Coastguard Worker BC_INST_EXEC_COND, 291*5a6e8488SAndroid Build Coastguard Worker 292*5a6e8488SAndroid Build Coastguard Worker /// Prints each item on the results stack, separated by newlines. 293*5a6e8488SAndroid Build Coastguard Worker BC_INST_PRINT_STACK, 294*5a6e8488SAndroid Build Coastguard Worker 295*5a6e8488SAndroid Build Coastguard Worker /// Pops everything off of the results stack. 296*5a6e8488SAndroid Build Coastguard Worker BC_INST_CLEAR_STACK, 297*5a6e8488SAndroid Build Coastguard Worker 298*5a6e8488SAndroid Build Coastguard Worker /// Pushes the current length of a register stack onto the results stack. 299*5a6e8488SAndroid Build Coastguard Worker BC_INST_REG_STACK_LEN, 300*5a6e8488SAndroid Build Coastguard Worker 301*5a6e8488SAndroid Build Coastguard Worker /// Pushes the current length of the results stack onto the results stack. 302*5a6e8488SAndroid Build Coastguard Worker BC_INST_STACK_LEN, 303*5a6e8488SAndroid Build Coastguard Worker 304*5a6e8488SAndroid Build Coastguard Worker /// Pushes a copy of the item on the top of the results stack onto the 305*5a6e8488SAndroid Build Coastguard Worker /// results stack. 306*5a6e8488SAndroid Build Coastguard Worker BC_INST_DUPLICATE, 307*5a6e8488SAndroid Build Coastguard Worker 308*5a6e8488SAndroid Build Coastguard Worker /// Copies the value in a register and pushes the copy onto the results 309*5a6e8488SAndroid Build Coastguard Worker /// stack. 310*5a6e8488SAndroid Build Coastguard Worker BC_INST_LOAD, 311*5a6e8488SAndroid Build Coastguard Worker 312*5a6e8488SAndroid Build Coastguard Worker /// Pops an item off of a register stack and pushes it onto the results 313*5a6e8488SAndroid Build Coastguard Worker /// stack. 314*5a6e8488SAndroid Build Coastguard Worker BC_INST_PUSH_VAR, 315*5a6e8488SAndroid Build Coastguard Worker 316*5a6e8488SAndroid Build Coastguard Worker /// Pops an item off of the results stack and pushes it onto a register's 317*5a6e8488SAndroid Build Coastguard Worker /// stack. 318*5a6e8488SAndroid Build Coastguard Worker BC_INST_PUSH_TO_VAR, 319*5a6e8488SAndroid Build Coastguard Worker 320*5a6e8488SAndroid Build Coastguard Worker /// Quit. 321*5a6e8488SAndroid Build Coastguard Worker BC_INST_QUIT, 322*5a6e8488SAndroid Build Coastguard Worker 323*5a6e8488SAndroid Build Coastguard Worker /// Quit executing some number of strings. 324*5a6e8488SAndroid Build Coastguard Worker BC_INST_NQUIT, 325*5a6e8488SAndroid Build Coastguard Worker 326*5a6e8488SAndroid Build Coastguard Worker /// Push the depth of the execution stack onto the stack. 327*5a6e8488SAndroid Build Coastguard Worker BC_INST_EXEC_STACK_LEN, 328*5a6e8488SAndroid Build Coastguard Worker 329*5a6e8488SAndroid Build Coastguard Worker #endif // DC_ENABLED 330*5a6e8488SAndroid Build Coastguard Worker 331*5a6e8488SAndroid Build Coastguard Worker /// Invalid instruction. 332*5a6e8488SAndroid Build Coastguard Worker BC_INST_INVALID, 333*5a6e8488SAndroid Build Coastguard Worker 334*5a6e8488SAndroid Build Coastguard Worker } BcInst; 335*5a6e8488SAndroid Build Coastguard Worker 336*5a6e8488SAndroid Build Coastguard Worker #if BC_C11 337*5a6e8488SAndroid Build Coastguard Worker _Static_assert(BC_INST_INVALID <= UCHAR_MAX, 338*5a6e8488SAndroid Build Coastguard Worker "Too many instructions to fit into an unsigned char"); 339*5a6e8488SAndroid Build Coastguard Worker #endif // BC_C11 340*5a6e8488SAndroid Build Coastguard Worker 341*5a6e8488SAndroid Build Coastguard Worker /// Used by maps to identify where items are in the array. 342*5a6e8488SAndroid Build Coastguard Worker typedef struct BcId 343*5a6e8488SAndroid Build Coastguard Worker { 344*5a6e8488SAndroid Build Coastguard Worker /// The name of the item. 345*5a6e8488SAndroid Build Coastguard Worker char* name; 346*5a6e8488SAndroid Build Coastguard Worker 347*5a6e8488SAndroid Build Coastguard Worker /// The index into the array where the item is. 348*5a6e8488SAndroid Build Coastguard Worker size_t idx; 349*5a6e8488SAndroid Build Coastguard Worker 350*5a6e8488SAndroid Build Coastguard Worker } BcId; 351*5a6e8488SAndroid Build Coastguard Worker 352*5a6e8488SAndroid Build Coastguard Worker /// The location of a var, array, or array element. 353*5a6e8488SAndroid Build Coastguard Worker typedef struct BcLoc 354*5a6e8488SAndroid Build Coastguard Worker { 355*5a6e8488SAndroid Build Coastguard Worker /// The index of the var or array. 356*5a6e8488SAndroid Build Coastguard Worker size_t loc; 357*5a6e8488SAndroid Build Coastguard Worker 358*5a6e8488SAndroid Build Coastguard Worker /// The index of the array or variable in the array stack. This is to 359*5a6e8488SAndroid Build Coastguard Worker /// prevent a bug with getting the wrong array element or variable after a 360*5a6e8488SAndroid Build Coastguard Worker /// function call. See the tests/bc/scripts/array.bc test for the array 361*5a6e8488SAndroid Build Coastguard Worker /// case; the variable case is in various variable tests. 362*5a6e8488SAndroid Build Coastguard Worker size_t stack_idx; 363*5a6e8488SAndroid Build Coastguard Worker 364*5a6e8488SAndroid Build Coastguard Worker /// The index of the array element. Only used for array elements. 365*5a6e8488SAndroid Build Coastguard Worker size_t idx; 366*5a6e8488SAndroid Build Coastguard Worker 367*5a6e8488SAndroid Build Coastguard Worker } BcLoc; 368*5a6e8488SAndroid Build Coastguard Worker 369*5a6e8488SAndroid Build Coastguard Worker /// An entry for a constant. 370*5a6e8488SAndroid Build Coastguard Worker typedef struct BcConst 371*5a6e8488SAndroid Build Coastguard Worker { 372*5a6e8488SAndroid Build Coastguard Worker /// The original string as parsed from the source code. 373*5a6e8488SAndroid Build Coastguard Worker char* val; 374*5a6e8488SAndroid Build Coastguard Worker 375*5a6e8488SAndroid Build Coastguard Worker /// The last base that the constant was parsed in. 376*5a6e8488SAndroid Build Coastguard Worker BcBigDig base; 377*5a6e8488SAndroid Build Coastguard Worker 378*5a6e8488SAndroid Build Coastguard Worker /// The parsed constant. 379*5a6e8488SAndroid Build Coastguard Worker BcNum num; 380*5a6e8488SAndroid Build Coastguard Worker 381*5a6e8488SAndroid Build Coastguard Worker } BcConst; 382*5a6e8488SAndroid Build Coastguard Worker 383*5a6e8488SAndroid Build Coastguard Worker /// A function. This is also used in dc, not just bc. The reason is that strings 384*5a6e8488SAndroid Build Coastguard Worker /// are executed in dc, and they are converted to functions in order to be 385*5a6e8488SAndroid Build Coastguard Worker /// executed. 386*5a6e8488SAndroid Build Coastguard Worker typedef struct BcFunc 387*5a6e8488SAndroid Build Coastguard Worker { 388*5a6e8488SAndroid Build Coastguard Worker /// The bytecode instructions. 389*5a6e8488SAndroid Build Coastguard Worker BcVec code; 390*5a6e8488SAndroid Build Coastguard Worker 391*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 392*5a6e8488SAndroid Build Coastguard Worker 393*5a6e8488SAndroid Build Coastguard Worker /// The labels. This is a vector of indices. The index is the index into 394*5a6e8488SAndroid Build Coastguard Worker /// the bytecode vector where the label is. 395*5a6e8488SAndroid Build Coastguard Worker BcVec labels; 396*5a6e8488SAndroid Build Coastguard Worker 397*5a6e8488SAndroid Build Coastguard Worker /// The autos for the function. The first items are the parameters, and the 398*5a6e8488SAndroid Build Coastguard Worker /// arguments to the parameters must match the types in this vector. 399*5a6e8488SAndroid Build Coastguard Worker BcVec autos; 400*5a6e8488SAndroid Build Coastguard Worker 401*5a6e8488SAndroid Build Coastguard Worker /// The number of parameters the function takes. 402*5a6e8488SAndroid Build Coastguard Worker size_t nparams; 403*5a6e8488SAndroid Build Coastguard Worker 404*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 405*5a6e8488SAndroid Build Coastguard Worker 406*5a6e8488SAndroid Build Coastguard Worker /// The function's name. 407*5a6e8488SAndroid Build Coastguard Worker const char* name; 408*5a6e8488SAndroid Build Coastguard Worker 409*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 410*5a6e8488SAndroid Build Coastguard Worker /// True if the function is a void function. 411*5a6e8488SAndroid Build Coastguard Worker bool voidfn; 412*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 413*5a6e8488SAndroid Build Coastguard Worker 414*5a6e8488SAndroid Build Coastguard Worker } BcFunc; 415*5a6e8488SAndroid Build Coastguard Worker 416*5a6e8488SAndroid Build Coastguard Worker /// Types of results that can be pushed onto the results stack. 417*5a6e8488SAndroid Build Coastguard Worker typedef enum BcResultType 418*5a6e8488SAndroid Build Coastguard Worker { 419*5a6e8488SAndroid Build Coastguard Worker /// Result is a variable. 420*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_VAR, 421*5a6e8488SAndroid Build Coastguard Worker 422*5a6e8488SAndroid Build Coastguard Worker /// Result is an array element. 423*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_ARRAY_ELEM, 424*5a6e8488SAndroid Build Coastguard Worker 425*5a6e8488SAndroid Build Coastguard Worker /// Result is an array. This is only allowed for function arguments or 426*5a6e8488SAndroid Build Coastguard Worker /// returning the length of the array. 427*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_ARRAY, 428*5a6e8488SAndroid Build Coastguard Worker 429*5a6e8488SAndroid Build Coastguard Worker /// Result is a string. 430*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_STR, 431*5a6e8488SAndroid Build Coastguard Worker 432*5a6e8488SAndroid Build Coastguard Worker /// Result is a temporary. This is used for the result of almost all 433*5a6e8488SAndroid Build Coastguard Worker /// expressions. 434*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_TEMP, 435*5a6e8488SAndroid Build Coastguard Worker 436*5a6e8488SAndroid Build Coastguard Worker /// Special casing the two below gave performance improvements. 437*5a6e8488SAndroid Build Coastguard Worker 438*5a6e8488SAndroid Build Coastguard Worker /// Result is a 0. 439*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_ZERO, 440*5a6e8488SAndroid Build Coastguard Worker 441*5a6e8488SAndroid Build Coastguard Worker /// Result is a 1. Useful for inc/dec operators. 442*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_ONE, 443*5a6e8488SAndroid Build Coastguard Worker 444*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 445*5a6e8488SAndroid Build Coastguard Worker 446*5a6e8488SAndroid Build Coastguard Worker /// Result is the special "last" variable. 447*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_LAST, 448*5a6e8488SAndroid Build Coastguard Worker 449*5a6e8488SAndroid Build Coastguard Worker /// Result is the return value of a void function. 450*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_VOID, 451*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 452*5a6e8488SAndroid Build Coastguard Worker 453*5a6e8488SAndroid Build Coastguard Worker /// Result is the value of ibase. 454*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_IBASE, 455*5a6e8488SAndroid Build Coastguard Worker 456*5a6e8488SAndroid Build Coastguard Worker /// Result is the value of obase. 457*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_OBASE, 458*5a6e8488SAndroid Build Coastguard Worker 459*5a6e8488SAndroid Build Coastguard Worker /// Result is the value of scale. 460*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_SCALE, 461*5a6e8488SAndroid Build Coastguard Worker 462*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 463*5a6e8488SAndroid Build Coastguard Worker 464*5a6e8488SAndroid Build Coastguard Worker /// Result is the value of seed. 465*5a6e8488SAndroid Build Coastguard Worker BC_RESULT_SEED, 466*5a6e8488SAndroid Build Coastguard Worker 467*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 468*5a6e8488SAndroid Build Coastguard Worker 469*5a6e8488SAndroid Build Coastguard Worker } BcResultType; 470*5a6e8488SAndroid Build Coastguard Worker 471*5a6e8488SAndroid Build Coastguard Worker /// A union to store data for various result types. 472*5a6e8488SAndroid Build Coastguard Worker typedef union BcResultData 473*5a6e8488SAndroid Build Coastguard Worker { 474*5a6e8488SAndroid Build Coastguard Worker /// A number. Strings are stored here too; they are numbers with 475*5a6e8488SAndroid Build Coastguard Worker /// cap == 0 && num == NULL. The string's index into the strings vector is 476*5a6e8488SAndroid Build Coastguard Worker /// stored in the scale field. But this is only used for strings stored in 477*5a6e8488SAndroid Build Coastguard Worker /// variables. 478*5a6e8488SAndroid Build Coastguard Worker BcNum n; 479*5a6e8488SAndroid Build Coastguard Worker 480*5a6e8488SAndroid Build Coastguard Worker /// A vector. 481*5a6e8488SAndroid Build Coastguard Worker BcVec v; 482*5a6e8488SAndroid Build Coastguard Worker 483*5a6e8488SAndroid Build Coastguard Worker /// A variable, array, or array element reference. This could also be a 484*5a6e8488SAndroid Build Coastguard Worker /// string if a string is not stored in a variable (dc only). 485*5a6e8488SAndroid Build Coastguard Worker BcLoc loc; 486*5a6e8488SAndroid Build Coastguard Worker 487*5a6e8488SAndroid Build Coastguard Worker } BcResultData; 488*5a6e8488SAndroid Build Coastguard Worker 489*5a6e8488SAndroid Build Coastguard Worker /// A tagged union for results. 490*5a6e8488SAndroid Build Coastguard Worker typedef struct BcResult 491*5a6e8488SAndroid Build Coastguard Worker { 492*5a6e8488SAndroid Build Coastguard Worker /// The tag. The type of the result. 493*5a6e8488SAndroid Build Coastguard Worker BcResultType t; 494*5a6e8488SAndroid Build Coastguard Worker 495*5a6e8488SAndroid Build Coastguard Worker /// The data. The data for the result. 496*5a6e8488SAndroid Build Coastguard Worker BcResultData d; 497*5a6e8488SAndroid Build Coastguard Worker 498*5a6e8488SAndroid Build Coastguard Worker } BcResult; 499*5a6e8488SAndroid Build Coastguard Worker 500*5a6e8488SAndroid Build Coastguard Worker /// An instruction pointer. This is how bc knows where in the bytecode vector, 501*5a6e8488SAndroid Build Coastguard Worker /// and which function, the current execution is. 502*5a6e8488SAndroid Build Coastguard Worker typedef struct BcInstPtr 503*5a6e8488SAndroid Build Coastguard Worker { 504*5a6e8488SAndroid Build Coastguard Worker /// The index of the currently executing function in the fns vector. 505*5a6e8488SAndroid Build Coastguard Worker size_t func; 506*5a6e8488SAndroid Build Coastguard Worker 507*5a6e8488SAndroid Build Coastguard Worker /// The index into the bytecode vector of the *next* instruction. 508*5a6e8488SAndroid Build Coastguard Worker size_t idx; 509*5a6e8488SAndroid Build Coastguard Worker 510*5a6e8488SAndroid Build Coastguard Worker /// The length of the results vector when this function started executing. 511*5a6e8488SAndroid Build Coastguard Worker /// This is mostly used for bc where functions should not affect the results 512*5a6e8488SAndroid Build Coastguard Worker /// of their callers. 513*5a6e8488SAndroid Build Coastguard Worker size_t len; 514*5a6e8488SAndroid Build Coastguard Worker 515*5a6e8488SAndroid Build Coastguard Worker } BcInstPtr; 516*5a6e8488SAndroid Build Coastguard Worker 517*5a6e8488SAndroid Build Coastguard Worker /// Types of identifiers. 518*5a6e8488SAndroid Build Coastguard Worker typedef enum BcType 519*5a6e8488SAndroid Build Coastguard Worker { 520*5a6e8488SAndroid Build Coastguard Worker /// Variable. 521*5a6e8488SAndroid Build Coastguard Worker BC_TYPE_VAR, 522*5a6e8488SAndroid Build Coastguard Worker 523*5a6e8488SAndroid Build Coastguard Worker /// Array. 524*5a6e8488SAndroid Build Coastguard Worker BC_TYPE_ARRAY, 525*5a6e8488SAndroid Build Coastguard Worker 526*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 527*5a6e8488SAndroid Build Coastguard Worker 528*5a6e8488SAndroid Build Coastguard Worker /// Array reference. 529*5a6e8488SAndroid Build Coastguard Worker BC_TYPE_REF, 530*5a6e8488SAndroid Build Coastguard Worker 531*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 532*5a6e8488SAndroid Build Coastguard Worker 533*5a6e8488SAndroid Build Coastguard Worker } BcType; 534*5a6e8488SAndroid Build Coastguard Worker 535*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 536*5a6e8488SAndroid Build Coastguard Worker /// An auto variable in bc. 537*5a6e8488SAndroid Build Coastguard Worker typedef struct BcAuto 538*5a6e8488SAndroid Build Coastguard Worker { 539*5a6e8488SAndroid Build Coastguard Worker /// The index of the variable in the vars or arrs vectors. 540*5a6e8488SAndroid Build Coastguard Worker size_t idx; 541*5a6e8488SAndroid Build Coastguard Worker 542*5a6e8488SAndroid Build Coastguard Worker /// The type of the variable. 543*5a6e8488SAndroid Build Coastguard Worker BcType type; 544*5a6e8488SAndroid Build Coastguard Worker 545*5a6e8488SAndroid Build Coastguard Worker } BcAuto; 546*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 547*5a6e8488SAndroid Build Coastguard Worker 548*5a6e8488SAndroid Build Coastguard Worker /// Forward declaration. 549*5a6e8488SAndroid Build Coastguard Worker struct BcProgram; 550*5a6e8488SAndroid Build Coastguard Worker 551*5a6e8488SAndroid Build Coastguard Worker /** 552*5a6e8488SAndroid Build Coastguard Worker * Initializes a function. 553*5a6e8488SAndroid Build Coastguard Worker * @param f The function to initialize. 554*5a6e8488SAndroid Build Coastguard Worker * @param name The name of the function. The string is assumed to be owned by 555*5a6e8488SAndroid Build Coastguard Worker * some other entity. 556*5a6e8488SAndroid Build Coastguard Worker */ 557*5a6e8488SAndroid Build Coastguard Worker void 558*5a6e8488SAndroid Build Coastguard Worker bc_func_init(BcFunc* f, const char* name); 559*5a6e8488SAndroid Build Coastguard Worker 560*5a6e8488SAndroid Build Coastguard Worker /** 561*5a6e8488SAndroid Build Coastguard Worker * Inserts an auto into the function. 562*5a6e8488SAndroid Build Coastguard Worker * @param f The function to insert into. 563*5a6e8488SAndroid Build Coastguard Worker * @param p The program. This is to search for the variable or array name. 564*5a6e8488SAndroid Build Coastguard Worker * @param name The name of the auto to insert. 565*5a6e8488SAndroid Build Coastguard Worker * @param type The type of the auto. 566*5a6e8488SAndroid Build Coastguard Worker * @param line The line in the source code where the insert happened. This is 567*5a6e8488SAndroid Build Coastguard Worker * solely for error reporting. 568*5a6e8488SAndroid Build Coastguard Worker */ 569*5a6e8488SAndroid Build Coastguard Worker void 570*5a6e8488SAndroid Build Coastguard Worker bc_func_insert(BcFunc* f, struct BcProgram* p, char* name, BcType type, 571*5a6e8488SAndroid Build Coastguard Worker size_t line); 572*5a6e8488SAndroid Build Coastguard Worker 573*5a6e8488SAndroid Build Coastguard Worker /** 574*5a6e8488SAndroid Build Coastguard Worker * Resets a function in preparation for it to be reused. This can happen in bc 575*5a6e8488SAndroid Build Coastguard Worker * because it is a dynamic language and functions can be redefined. 576*5a6e8488SAndroid Build Coastguard Worker * @param f The functio to reset. 577*5a6e8488SAndroid Build Coastguard Worker */ 578*5a6e8488SAndroid Build Coastguard Worker void 579*5a6e8488SAndroid Build Coastguard Worker bc_func_reset(BcFunc* f); 580*5a6e8488SAndroid Build Coastguard Worker 581*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG 582*5a6e8488SAndroid Build Coastguard Worker /** 583*5a6e8488SAndroid Build Coastguard Worker * Frees a function. This is a destructor. This is only used in debug builds 584*5a6e8488SAndroid Build Coastguard Worker * because all functions are freed at exit. We free them in debug builds to 585*5a6e8488SAndroid Build Coastguard Worker * check for memory leaks. 586*5a6e8488SAndroid Build Coastguard Worker * @param func The function to free as a void pointer. 587*5a6e8488SAndroid Build Coastguard Worker */ 588*5a6e8488SAndroid Build Coastguard Worker void 589*5a6e8488SAndroid Build Coastguard Worker bc_func_free(void* func); 590*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG 591*5a6e8488SAndroid Build Coastguard Worker 592*5a6e8488SAndroid Build Coastguard Worker /** 593*5a6e8488SAndroid Build Coastguard Worker * Initializes an array, which is the array type in bc and dc source code. Since 594*5a6e8488SAndroid Build Coastguard Worker * variables and arrays are both arrays (see the development manual, 595*5a6e8488SAndroid Build Coastguard Worker * manuals/development.md#execution, for more information), the @a nums 596*5a6e8488SAndroid Build Coastguard Worker * parameter tells bc whether to initialize an array of numbers or an array of 597*5a6e8488SAndroid Build Coastguard Worker * arrays of numbers. If the latter, it does a recursive call with nums set to 598*5a6e8488SAndroid Build Coastguard Worker * true. 599*5a6e8488SAndroid Build Coastguard Worker * @param a The array to initialize. 600*5a6e8488SAndroid Build Coastguard Worker * @param nums True if the array should be for numbers, false if it should be 601*5a6e8488SAndroid Build Coastguard Worker * for vectors. 602*5a6e8488SAndroid Build Coastguard Worker */ 603*5a6e8488SAndroid Build Coastguard Worker void 604*5a6e8488SAndroid Build Coastguard Worker bc_array_init(BcVec* a, bool nums); 605*5a6e8488SAndroid Build Coastguard Worker 606*5a6e8488SAndroid Build Coastguard Worker /** 607*5a6e8488SAndroid Build Coastguard Worker * Copies an array to another array. This is used to do pass arrays to functions 608*5a6e8488SAndroid Build Coastguard Worker * that do not take references to arrays. The arrays are passed entirely by 609*5a6e8488SAndroid Build Coastguard Worker * value, which means that they need to be copied. 610*5a6e8488SAndroid Build Coastguard Worker * @param d The destination array. 611*5a6e8488SAndroid Build Coastguard Worker * @param s The source array. 612*5a6e8488SAndroid Build Coastguard Worker */ 613*5a6e8488SAndroid Build Coastguard Worker void 614*5a6e8488SAndroid Build Coastguard Worker bc_array_copy(BcVec* d, const BcVec* s); 615*5a6e8488SAndroid Build Coastguard Worker 616*5a6e8488SAndroid Build Coastguard Worker /** 617*5a6e8488SAndroid Build Coastguard Worker * Frees a string stored in a function. This is a destructor. 618*5a6e8488SAndroid Build Coastguard Worker * @param string The string to free as a void pointer. 619*5a6e8488SAndroid Build Coastguard Worker */ 620*5a6e8488SAndroid Build Coastguard Worker void 621*5a6e8488SAndroid Build Coastguard Worker bc_string_free(void* string); 622*5a6e8488SAndroid Build Coastguard Worker 623*5a6e8488SAndroid Build Coastguard Worker /** 624*5a6e8488SAndroid Build Coastguard Worker * Frees a constant stored in a function. This is a destructor. 625*5a6e8488SAndroid Build Coastguard Worker * @param constant The constant to free as a void pointer. 626*5a6e8488SAndroid Build Coastguard Worker */ 627*5a6e8488SAndroid Build Coastguard Worker void 628*5a6e8488SAndroid Build Coastguard Worker bc_const_free(void* constant); 629*5a6e8488SAndroid Build Coastguard Worker 630*5a6e8488SAndroid Build Coastguard Worker /** 631*5a6e8488SAndroid Build Coastguard Worker * Clears a result. It sets the type to BC_RESULT_TEMP and clears the union by 632*5a6e8488SAndroid Build Coastguard Worker * clearing the BcNum in the union. This is to ensure that bc does not use 633*5a6e8488SAndroid Build Coastguard Worker * uninitialized data. 634*5a6e8488SAndroid Build Coastguard Worker * @param r The result to clear. 635*5a6e8488SAndroid Build Coastguard Worker */ 636*5a6e8488SAndroid Build Coastguard Worker void 637*5a6e8488SAndroid Build Coastguard Worker bc_result_clear(BcResult* r); 638*5a6e8488SAndroid Build Coastguard Worker 639*5a6e8488SAndroid Build Coastguard Worker /** 640*5a6e8488SAndroid Build Coastguard Worker * Copies a result into another. This is done for things like duplicating the 641*5a6e8488SAndroid Build Coastguard Worker * top of the results stack or copying the result of an assignment to put back 642*5a6e8488SAndroid Build Coastguard Worker * on the results stack. 643*5a6e8488SAndroid Build Coastguard Worker * @param d The destination result. 644*5a6e8488SAndroid Build Coastguard Worker * @param src The source result. 645*5a6e8488SAndroid Build Coastguard Worker */ 646*5a6e8488SAndroid Build Coastguard Worker void 647*5a6e8488SAndroid Build Coastguard Worker bc_result_copy(BcResult* d, BcResult* src); 648*5a6e8488SAndroid Build Coastguard Worker 649*5a6e8488SAndroid Build Coastguard Worker /** 650*5a6e8488SAndroid Build Coastguard Worker * Frees a result. This is a destructor. 651*5a6e8488SAndroid Build Coastguard Worker * @param result The result to free as a void pointer. 652*5a6e8488SAndroid Build Coastguard Worker */ 653*5a6e8488SAndroid Build Coastguard Worker void 654*5a6e8488SAndroid Build Coastguard Worker bc_result_free(void* result); 655*5a6e8488SAndroid Build Coastguard Worker 656*5a6e8488SAndroid Build Coastguard Worker /** 657*5a6e8488SAndroid Build Coastguard Worker * Expands an array to @a len. This can happen because in bc, you do not have to 658*5a6e8488SAndroid Build Coastguard Worker * explicitly initialize elements of an array. If you access an element that is 659*5a6e8488SAndroid Build Coastguard Worker * not initialized, the array is expanded to fit it, and all missing elements 660*5a6e8488SAndroid Build Coastguard Worker * are initialized to 0 if they are numbers, or arrays with one element of 0. 661*5a6e8488SAndroid Build Coastguard Worker * This function does that expansion. 662*5a6e8488SAndroid Build Coastguard Worker * @param a The array to expand. 663*5a6e8488SAndroid Build Coastguard Worker * @param len The length to expand to. 664*5a6e8488SAndroid Build Coastguard Worker */ 665*5a6e8488SAndroid Build Coastguard Worker void 666*5a6e8488SAndroid Build Coastguard Worker bc_array_expand(BcVec* a, size_t len); 667*5a6e8488SAndroid Build Coastguard Worker 668*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 669*5a6e8488SAndroid Build Coastguard Worker 670*5a6e8488SAndroid Build Coastguard Worker /** 671*5a6e8488SAndroid Build Coastguard Worker * Returns non-zero if the bytecode instruction i is an assignment instruction. 672*5a6e8488SAndroid Build Coastguard Worker * @param i The instruction to test. 673*5a6e8488SAndroid Build Coastguard Worker * @return Non-zero if i is an assignment instruction, zero otherwise. 674*5a6e8488SAndroid Build Coastguard Worker */ 675*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_IS_ASSIGN(i) \ 676*5a6e8488SAndroid Build Coastguard Worker ((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL) 677*5a6e8488SAndroid Build Coastguard Worker 678*5a6e8488SAndroid Build Coastguard Worker /** 679*5a6e8488SAndroid Build Coastguard Worker * Returns true if the bytecode instruction @a i requires the value to be 680*5a6e8488SAndroid Build Coastguard Worker * returned for use. 681*5a6e8488SAndroid Build Coastguard Worker * @param i The instruction to test. 682*5a6e8488SAndroid Build Coastguard Worker * @return True if @a i requires the value to be returned for use, false 683*5a6e8488SAndroid Build Coastguard Worker * otherwise. 684*5a6e8488SAndroid Build Coastguard Worker */ 685*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN) 686*5a6e8488SAndroid Build Coastguard Worker 687*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLED 688*5a6e8488SAndroid Build Coastguard Worker 689*5a6e8488SAndroid Build Coastguard Worker /** 690*5a6e8488SAndroid Build Coastguard Worker * Returns non-zero if the bytecode instruction i is an assignment instruction. 691*5a6e8488SAndroid Build Coastguard Worker * @param i The instruction to test. 692*5a6e8488SAndroid Build Coastguard Worker * @return Non-zero if i is an assignment instruction, zero otherwise. 693*5a6e8488SAndroid Build Coastguard Worker */ 694*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL) 695*5a6e8488SAndroid Build Coastguard Worker 696*5a6e8488SAndroid Build Coastguard Worker /** 697*5a6e8488SAndroid Build Coastguard Worker * Returns true if the bytecode instruction @a i requires the value to be 698*5a6e8488SAndroid Build Coastguard Worker * returned for use. 699*5a6e8488SAndroid Build Coastguard Worker * @param i The instruction to test. 700*5a6e8488SAndroid Build Coastguard Worker * @return True if @a i requires the value to be returned for use, false 701*5a6e8488SAndroid Build Coastguard Worker * otherwise. 702*5a6e8488SAndroid Build Coastguard Worker */ 703*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_USE_VAL(i) (false) 704*5a6e8488SAndroid Build Coastguard Worker 705*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 706*5a6e8488SAndroid Build Coastguard Worker 707*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG_CODE 708*5a6e8488SAndroid Build Coastguard Worker /// Reference to string names for all of the instructions. For debugging. 709*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_inst_names[]; 710*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE 711*5a6e8488SAndroid Build Coastguard Worker 712*5a6e8488SAndroid Build Coastguard Worker /// References to the names of the main and read functions. 713*5a6e8488SAndroid Build Coastguard Worker extern const char bc_func_main[]; 714*5a6e8488SAndroid Build Coastguard Worker extern const char bc_func_read[]; 715*5a6e8488SAndroid Build Coastguard Worker 716*5a6e8488SAndroid Build Coastguard Worker #endif // BC_LANG_H 717