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 bc only. 33*5a6e8488SAndroid Build Coastguard Worker * 34*5a6e8488SAndroid Build Coastguard Worker */ 35*5a6e8488SAndroid Build Coastguard Worker 36*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_BC_H 37*5a6e8488SAndroid Build Coastguard Worker #define BC_BC_H 38*5a6e8488SAndroid Build Coastguard Worker 39*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 40*5a6e8488SAndroid Build Coastguard Worker 41*5a6e8488SAndroid Build Coastguard Worker #include <limits.h> 42*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h> 43*5a6e8488SAndroid Build Coastguard Worker 44*5a6e8488SAndroid Build Coastguard Worker #include <status.h> 45*5a6e8488SAndroid Build Coastguard Worker #include <lex.h> 46*5a6e8488SAndroid Build Coastguard Worker #include <parse.h> 47*5a6e8488SAndroid Build Coastguard Worker 48*5a6e8488SAndroid Build Coastguard Worker /** 49*5a6e8488SAndroid Build Coastguard Worker * The main function for bc. It just sets variables and passes its arguments 50*5a6e8488SAndroid Build Coastguard Worker * through to @a bc_vm_boot(). 51*5a6e8488SAndroid Build Coastguard Worker * @return A status. 52*5a6e8488SAndroid Build Coastguard Worker */ 53*5a6e8488SAndroid Build Coastguard Worker BcStatus 54*5a6e8488SAndroid Build Coastguard Worker bc_main(int argc, const char* argv[]); 55*5a6e8488SAndroid Build Coastguard Worker 56*5a6e8488SAndroid Build Coastguard Worker // These are references to the help text, the library text, and the "filename" 57*5a6e8488SAndroid Build Coastguard Worker // for the library. 58*5a6e8488SAndroid Build Coastguard Worker extern const char bc_help[]; 59*5a6e8488SAndroid Build Coastguard Worker extern const char bc_lib[]; 60*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_lib_name; 61*5a6e8488SAndroid Build Coastguard Worker 62*5a6e8488SAndroid Build Coastguard Worker // These are references to the second math library and its "filename." 63*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 64*5a6e8488SAndroid Build Coastguard Worker extern const char bc_lib2[]; 65*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_lib2_name; 66*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 67*5a6e8488SAndroid Build Coastguard Worker 68*5a6e8488SAndroid Build Coastguard Worker /** 69*5a6e8488SAndroid Build Coastguard Worker * A struct containing information about a bc keyword. 70*5a6e8488SAndroid Build Coastguard Worker */ 71*5a6e8488SAndroid Build Coastguard Worker typedef struct BcLexKeyword 72*5a6e8488SAndroid Build Coastguard Worker { 73*5a6e8488SAndroid Build Coastguard Worker /// Holds the length of the keyword along with a bit that, if set, means the 74*5a6e8488SAndroid Build Coastguard Worker /// keyword is used in POSIX bc. 75*5a6e8488SAndroid Build Coastguard Worker uchar data; 76*5a6e8488SAndroid Build Coastguard Worker 77*5a6e8488SAndroid Build Coastguard Worker /// The keyword text. 78*5a6e8488SAndroid Build Coastguard Worker const char name[14]; 79*5a6e8488SAndroid Build Coastguard Worker } BcLexKeyword; 80*5a6e8488SAndroid Build Coastguard Worker 81*5a6e8488SAndroid Build Coastguard Worker /// Sets the most significant bit. Used for setting the POSIX bit in 82*5a6e8488SAndroid Build Coastguard Worker /// BcLexKeyword's data field. 83*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1)) 84*5a6e8488SAndroid Build Coastguard Worker 85*5a6e8488SAndroid Build Coastguard Worker /// Returns non-zero if the keyword is POSIX, zero otherwise. 86*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1))) 87*5a6e8488SAndroid Build Coastguard Worker 88*5a6e8488SAndroid Build Coastguard Worker /// Returns the length of the keyword. 89*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1)))) 90*5a6e8488SAndroid Build Coastguard Worker 91*5a6e8488SAndroid Build Coastguard Worker /// A macro to easily build a keyword entry. See bc_lex_kws in src/data.c. 92*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_KW_ENTRY(a, b, c) \ 93*5a6e8488SAndroid Build Coastguard Worker { .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c), .name = a } 94*5a6e8488SAndroid Build Coastguard Worker 95*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 96*5a6e8488SAndroid Build Coastguard Worker 97*5a6e8488SAndroid Build Coastguard Worker /// A macro for the number of keywords bc has. This has to be updated if any are 98*5a6e8488SAndroid Build Coastguard Worker /// added. This is for the redefined_kws field of the BcVm struct. 99*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_NKWS (37) 100*5a6e8488SAndroid Build Coastguard Worker 101*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_EXTRA_MATH 102*5a6e8488SAndroid Build Coastguard Worker 103*5a6e8488SAndroid Build Coastguard Worker /// A macro for the number of keywords bc has. This has to be updated if any are 104*5a6e8488SAndroid Build Coastguard Worker /// added. This is for the redefined_kws field of the BcVm struct. 105*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_NKWS (33) 106*5a6e8488SAndroid Build Coastguard Worker 107*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 108*5a6e8488SAndroid Build Coastguard Worker 109*5a6e8488SAndroid Build Coastguard Worker // The array of keywords and its length. 110*5a6e8488SAndroid Build Coastguard Worker extern const BcLexKeyword bc_lex_kws[]; 111*5a6e8488SAndroid Build Coastguard Worker extern const size_t bc_lex_kws_len; 112*5a6e8488SAndroid Build Coastguard Worker 113*5a6e8488SAndroid Build Coastguard Worker /** 114*5a6e8488SAndroid Build Coastguard Worker * The @a BcLexNext function for bc. (See include/lex.h for a definition of 115*5a6e8488SAndroid Build Coastguard Worker * @a BcLexNext.) 116*5a6e8488SAndroid Build Coastguard Worker * @param l The lexer. 117*5a6e8488SAndroid Build Coastguard Worker */ 118*5a6e8488SAndroid Build Coastguard Worker void 119*5a6e8488SAndroid Build Coastguard Worker bc_lex_token(BcLex* l); 120*5a6e8488SAndroid Build Coastguard Worker 121*5a6e8488SAndroid Build Coastguard Worker // The following section is for flags needed when parsing bc code. These flags 122*5a6e8488SAndroid Build Coastguard Worker // are complicated, but necessary. Why you ask? Because bc's standard is awful. 123*5a6e8488SAndroid Build Coastguard Worker // 124*5a6e8488SAndroid Build Coastguard Worker // If you don't believe me, go read the bc Parsing section of the Development 125*5a6e8488SAndroid Build Coastguard Worker // manual (manuals/development.md). Then come back. 126*5a6e8488SAndroid Build Coastguard Worker // 127*5a6e8488SAndroid Build Coastguard Worker // In other words, these flags are the sign declaring, "Here be dragons." 128*5a6e8488SAndroid Build Coastguard Worker 129*5a6e8488SAndroid Build Coastguard Worker /** 130*5a6e8488SAndroid Build Coastguard Worker * This returns a pointer to the set of flags at the top of the flag stack. 131*5a6e8488SAndroid Build Coastguard Worker * @a p is expected to be a BcParse pointer. 132*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 133*5a6e8488SAndroid Build Coastguard Worker * @return A pointer to the top flag set. 134*5a6e8488SAndroid Build Coastguard Worker */ 135*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags)) 136*5a6e8488SAndroid Build Coastguard Worker 137*5a6e8488SAndroid Build Coastguard Worker /** 138*5a6e8488SAndroid Build Coastguard Worker * This returns the flag set at the top of the flag stack. @a p is expected to 139*5a6e8488SAndroid Build Coastguard Worker * be a BcParse pointer. 140*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 141*5a6e8488SAndroid Build Coastguard Worker * @return The top flag set. 142*5a6e8488SAndroid Build Coastguard Worker */ 143*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p))) 144*5a6e8488SAndroid Build Coastguard Worker 145*5a6e8488SAndroid Build Coastguard Worker // After this point, all flag #defines are in sets of 2: one to define the flag, 146*5a6e8488SAndroid Build Coastguard Worker // and one to define a way to grab the flag from the flag set at the top of the 147*5a6e8488SAndroid Build Coastguard Worker // flag stack. All `p` arguments are pointers to a BcParse. 148*5a6e8488SAndroid Build Coastguard Worker 149*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser has seen a left brace. 150*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_BRACE (UINTMAX_C(1) << 0) 151*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE) 152*5a6e8488SAndroid Build Coastguard Worker 153*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser is parsing inside of the braces of a function 154*5a6e8488SAndroid Build Coastguard Worker // body. 155*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_FUNC_INNER (UINTMAX_C(1) << 1) 156*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FUNC_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC_INNER) 157*5a6e8488SAndroid Build Coastguard Worker 158*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser is parsing a function. It is different from 159*5a6e8488SAndroid Build Coastguard Worker // the one above because it is set if it is parsing a function body *or* header, 160*5a6e8488SAndroid Build Coastguard Worker // not just if it's parsing a function body. 161*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_FUNC (UINTMAX_C(1) << 2) 162*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC) 163*5a6e8488SAndroid Build Coastguard Worker 164*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser is expecting to parse a body, whether of a 165*5a6e8488SAndroid Build Coastguard Worker // function, an if statement, or a loop. 166*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_BODY (UINTMAX_C(1) << 3) 167*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY) 168*5a6e8488SAndroid Build Coastguard Worker 169*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing a loop. This is important because the break 170*5a6e8488SAndroid Build Coastguard Worker // and continue keywords are only valid inside of a loop. 171*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_LOOP (UINTMAX_C(1) << 4) 172*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP) 173*5a6e8488SAndroid Build Coastguard Worker 174*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing the body of a loop. It is different from 175*5a6e8488SAndroid Build Coastguard Worker // the one above the same way @a BC_PARSE_FLAG_FUNC_INNER is different from 176*5a6e8488SAndroid Build Coastguard Worker // @a BC_PARSE_FLAG_FUNC. 177*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_LOOP_INNER (UINTMAX_C(1) << 5) 178*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_LOOP_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP_INNER) 179*5a6e8488SAndroid Build Coastguard Worker 180*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing an if statement. 181*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_IF (UINTMAX_C(1) << 6) 182*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF) 183*5a6e8488SAndroid Build Coastguard Worker 184*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing an else statement. This is important 185*5a6e8488SAndroid Build Coastguard Worker // because of "else if" constructions, among other things. 186*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_ELSE (UINTMAX_C(1) << 7) 187*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE) 188*5a6e8488SAndroid Build Coastguard Worker 189*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc just finished parsing an if statement and its body. 190*5a6e8488SAndroid Build Coastguard Worker // It tells the parser that it can probably expect an else statement next. This 191*5a6e8488SAndroid Build Coastguard Worker // flag is, thus, one of the most subtle. 192*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_IF_END (UINTMAX_C(1) << 8) 193*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_IF_END(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF_END) 194*5a6e8488SAndroid Build Coastguard Worker 195*5a6e8488SAndroid Build Coastguard Worker /** 196*5a6e8488SAndroid Build Coastguard Worker * This returns true if bc is in a state where it should not execute any code 197*5a6e8488SAndroid Build Coastguard Worker * at all. 198*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 199*5a6e8488SAndroid Build Coastguard Worker * @return True if execution cannot proceed, false otherwise. 200*5a6e8488SAndroid Build Coastguard Worker */ 201*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0) 202*5a6e8488SAndroid Build Coastguard Worker 203*5a6e8488SAndroid Build Coastguard Worker /** 204*5a6e8488SAndroid Build Coastguard Worker * This returns true if the token @a t is a statement delimiter, which is 205*5a6e8488SAndroid Build Coastguard Worker * either a newline or a semicolon. 206*5a6e8488SAndroid Build Coastguard Worker * @param t The token to check. 207*5a6e8488SAndroid Build Coastguard Worker * @return True if t is a statement delimiter token; false otherwise. 208*5a6e8488SAndroid Build Coastguard Worker */ 209*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_DELIMITER(t) \ 210*5a6e8488SAndroid Build Coastguard Worker ((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF) 211*5a6e8488SAndroid Build Coastguard Worker 212*5a6e8488SAndroid Build Coastguard Worker /** 213*5a6e8488SAndroid Build Coastguard Worker * This is poorly named, but it basically returns whether or not the current 214*5a6e8488SAndroid Build Coastguard Worker * state is valid for the end of an else statement. 215*5a6e8488SAndroid Build Coastguard Worker * @param f The flag set to be checked. 216*5a6e8488SAndroid Build Coastguard Worker * @return True if the state is valid for the end of an else statement. 217*5a6e8488SAndroid Build Coastguard Worker */ 218*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_BLOCK_STMT(f) \ 219*5a6e8488SAndroid Build Coastguard Worker ((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER)) 220*5a6e8488SAndroid Build Coastguard Worker 221*5a6e8488SAndroid Build Coastguard Worker /** 222*5a6e8488SAndroid Build Coastguard Worker * This returns the value of the data for an operator with precedence @a p and 223*5a6e8488SAndroid Build Coastguard Worker * associativity @a l (true if left associative, false otherwise). This is used 224*5a6e8488SAndroid Build Coastguard Worker * to construct an array of operators, bc_parse_ops, in src/data.c. 225*5a6e8488SAndroid Build Coastguard Worker * @param p The precedence. 226*5a6e8488SAndroid Build Coastguard Worker * @param l True if the operator is left associative, false otherwise. 227*5a6e8488SAndroid Build Coastguard Worker * @return The data for the operator. 228*5a6e8488SAndroid Build Coastguard Worker */ 229*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l))) 230*5a6e8488SAndroid Build Coastguard Worker 231*5a6e8488SAndroid Build Coastguard Worker /** 232*5a6e8488SAndroid Build Coastguard Worker * Returns the operator data for the lex token @a t. 233*5a6e8488SAndroid Build Coastguard Worker * @param t The token to return operator data for. 234*5a6e8488SAndroid Build Coastguard Worker * @return The operator data for @a t. 235*5a6e8488SAndroid Build Coastguard Worker */ 236*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)] 237*5a6e8488SAndroid Build Coastguard Worker 238*5a6e8488SAndroid Build Coastguard Worker /** 239*5a6e8488SAndroid Build Coastguard Worker * Returns non-zero if operator @a op is left associative, zero otherwise. 240*5a6e8488SAndroid Build Coastguard Worker * @param op The operator to test for associativity. 241*5a6e8488SAndroid Build Coastguard Worker * @return Non-zero if the operator is left associative, zero otherwise. 242*5a6e8488SAndroid Build Coastguard Worker */ 243*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1)) 244*5a6e8488SAndroid Build Coastguard Worker 245*5a6e8488SAndroid Build Coastguard Worker /** 246*5a6e8488SAndroid Build Coastguard Worker * Returns the precedence of operator @a op. Lower number means higher 247*5a6e8488SAndroid Build Coastguard Worker * precedence. 248*5a6e8488SAndroid Build Coastguard Worker * @param op The operator to return the precedence of. 249*5a6e8488SAndroid Build Coastguard Worker * @return The precedence of @a op. 250*5a6e8488SAndroid Build Coastguard Worker */ 251*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1))) 252*5a6e8488SAndroid Build Coastguard Worker 253*5a6e8488SAndroid Build Coastguard Worker /** 254*5a6e8488SAndroid Build Coastguard Worker * A macro to easily define a series of bits for whether a lex token is an 255*5a6e8488SAndroid Build Coastguard Worker * expression token or not. It takes 8 expression bits, corresponding to the 8 256*5a6e8488SAndroid Build Coastguard Worker * bits in a uint8_t. You can see this in use for bc_parse_exprs in src/data.c. 257*5a6e8488SAndroid Build Coastguard Worker * @param e1 The first bit. 258*5a6e8488SAndroid Build Coastguard Worker * @param e2 The second bit. 259*5a6e8488SAndroid Build Coastguard Worker * @param e3 The third bit. 260*5a6e8488SAndroid Build Coastguard Worker * @param e4 The fourth bit. 261*5a6e8488SAndroid Build Coastguard Worker * @param e5 The fifth bit. 262*5a6e8488SAndroid Build Coastguard Worker * @param e6 The sixth bit. 263*5a6e8488SAndroid Build Coastguard Worker * @param e7 The seventh bit. 264*5a6e8488SAndroid Build Coastguard Worker * @param e8 The eighth bit. 265*5a6e8488SAndroid Build Coastguard Worker * @return An expression entry for bc_parse_exprs[]. 266*5a6e8488SAndroid Build Coastguard Worker */ 267*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_EXPR_ENTRY(e1, e2, e3, e4, e5, e6, e7, e8) \ 268*5a6e8488SAndroid Build Coastguard Worker ((UINTMAX_C(e1) << 7) | (UINTMAX_C(e2) << 6) | (UINTMAX_C(e3) << 5) | \ 269*5a6e8488SAndroid Build Coastguard Worker (UINTMAX_C(e4) << 4) | (UINTMAX_C(e5) << 3) | (UINTMAX_C(e6) << 2) | \ 270*5a6e8488SAndroid Build Coastguard Worker (UINTMAX_C(e7) << 1) | (UINTMAX_C(e8) << 0)) 271*5a6e8488SAndroid Build Coastguard Worker 272*5a6e8488SAndroid Build Coastguard Worker /** 273*5a6e8488SAndroid Build Coastguard Worker * Returns true if token @a i is a token that belongs in an expression. 274*5a6e8488SAndroid Build Coastguard Worker * @param i The token to test. 275*5a6e8488SAndroid Build Coastguard Worker * @return True if i is an expression token, false otherwise. 276*5a6e8488SAndroid Build Coastguard Worker */ 277*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_EXPR(i) \ 278*5a6e8488SAndroid Build Coastguard Worker (bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07)))) 279*5a6e8488SAndroid Build Coastguard Worker 280*5a6e8488SAndroid Build Coastguard Worker /** 281*5a6e8488SAndroid Build Coastguard Worker * Returns the operator (by lex token) that is at the top of the operator 282*5a6e8488SAndroid Build Coastguard Worker * stack. 283*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 284*5a6e8488SAndroid Build Coastguard Worker * @return The operator that is at the top of the operator stack, as a lex 285*5a6e8488SAndroid Build Coastguard Worker * token. 286*5a6e8488SAndroid Build Coastguard Worker */ 287*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops))) 288*5a6e8488SAndroid Build Coastguard Worker 289*5a6e8488SAndroid Build Coastguard Worker /** 290*5a6e8488SAndroid Build Coastguard Worker * Returns true if bc has a "leaf" token. A "leaf" token is one that can stand 291*5a6e8488SAndroid Build Coastguard Worker * alone in an expression. For example, a number by itself can be an expression, 292*5a6e8488SAndroid Build Coastguard Worker * but a binary operator, while valid for an expression, cannot be alone in the 293*5a6e8488SAndroid Build Coastguard Worker * expression. It must have an expression to the left and right of itself. See 294*5a6e8488SAndroid Build Coastguard Worker * the documentation for @a bc_parse_expr_err() in src/bc_parse.c. 295*5a6e8488SAndroid Build Coastguard Worker * @param prev The previous token as an instruction. 296*5a6e8488SAndroid Build Coastguard Worker * @param bin_last True if that last operator was a binary operator, false 297*5a6e8488SAndroid Build Coastguard Worker * otherwise. 298*5a6e8488SAndroid Build Coastguard Worker * @param rparen True if the last operator was a right paren. 299*5a6e8488SAndroid Build Coastguard Worker * return True if the last token was a leaf token, false otherwise. 300*5a6e8488SAndroid Build Coastguard Worker */ 301*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_LEAF(prev, bin_last, rparen) \ 302*5a6e8488SAndroid Build Coastguard Worker (!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev))) 303*5a6e8488SAndroid Build Coastguard Worker 304*5a6e8488SAndroid Build Coastguard Worker /** 305*5a6e8488SAndroid Build Coastguard Worker * This returns true if the token @a t should be treated as though it's a 306*5a6e8488SAndroid Build Coastguard Worker * variable. This goes for actual variables, array elements, and globals. 307*5a6e8488SAndroid Build Coastguard Worker * @param t The token to test. 308*5a6e8488SAndroid Build Coastguard Worker * @return True if @a t should be treated as though it's a variable, false 309*5a6e8488SAndroid Build Coastguard Worker * otherwise. 310*5a6e8488SAndroid Build Coastguard Worker */ 311*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH 312*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_INST_VAR(t) \ 313*5a6e8488SAndroid Build Coastguard Worker ((t) >= BC_INST_VAR && (t) <= BC_INST_SEED && (t) != BC_INST_ARRAY) 314*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_EXTRA_MATH 315*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_INST_VAR(t) \ 316*5a6e8488SAndroid Build Coastguard Worker ((t) >= BC_INST_VAR && (t) <= BC_INST_SCALE && (t) != BC_INST_ARRAY) 317*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 318*5a6e8488SAndroid Build Coastguard Worker 319*5a6e8488SAndroid Build Coastguard Worker /** 320*5a6e8488SAndroid Build Coastguard Worker * Returns true if the previous token @a p (in the form of a bytecode 321*5a6e8488SAndroid Build Coastguard Worker * instruction) is a prefix operator. The fact that it is for bytecode 322*5a6e8488SAndroid Build Coastguard Worker * instructions is what makes it different from @a BC_PARSE_OP_PREFIX below. 323*5a6e8488SAndroid Build Coastguard Worker * @param p The previous token. 324*5a6e8488SAndroid Build Coastguard Worker * @return True if @a p is a prefix operator. 325*5a6e8488SAndroid Build Coastguard Worker */ 326*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_PREV_PREFIX(p) ((p) >= BC_INST_NEG && (p) <= BC_INST_BOOL_NOT) 327*5a6e8488SAndroid Build Coastguard Worker 328*5a6e8488SAndroid Build Coastguard Worker /** 329*5a6e8488SAndroid Build Coastguard Worker * Returns true if token @a t is a prefix operator. 330*5a6e8488SAndroid Build Coastguard Worker * @param t The token to test. 331*5a6e8488SAndroid Build Coastguard Worker * @return True if @a t is a prefix operator, false otherwise. 332*5a6e8488SAndroid Build Coastguard Worker */ 333*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG) 334*5a6e8488SAndroid Build Coastguard Worker 335*5a6e8488SAndroid Build Coastguard Worker /** 336*5a6e8488SAndroid Build Coastguard Worker * We can calculate the conversion between tokens and bytecode instructions by 337*5a6e8488SAndroid Build Coastguard Worker * subtracting the position of the first operator in the lex enum and adding the 338*5a6e8488SAndroid Build Coastguard Worker * position of the first in the instruction enum. Note: This only works for 339*5a6e8488SAndroid Build Coastguard Worker * binary operators. 340*5a6e8488SAndroid Build Coastguard Worker * @param t The token to turn into an instruction. 341*5a6e8488SAndroid Build Coastguard Worker * @return The token as an instruction. 342*5a6e8488SAndroid Build Coastguard Worker */ 343*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG)) 344*5a6e8488SAndroid Build Coastguard Worker 345*5a6e8488SAndroid Build Coastguard Worker /** 346*5a6e8488SAndroid Build Coastguard Worker * Returns true if the token is a bc keyword. 347*5a6e8488SAndroid Build Coastguard Worker * @param t The token to check. 348*5a6e8488SAndroid Build Coastguard Worker * @return True if @a t is a bc keyword, false otherwise. 349*5a6e8488SAndroid Build Coastguard Worker */ 350*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_IS_KEYWORD(t) ((t) >= BC_LEX_KW_AUTO && (t) <= BC_LEX_KW_ELSE) 351*5a6e8488SAndroid Build Coastguard Worker 352*5a6e8488SAndroid Build Coastguard Worker /// A struct that holds data about what tokens should be expected next. There 353*5a6e8488SAndroid Build Coastguard Worker /// are a few instances of these, all named because they are used in specific 354*5a6e8488SAndroid Build Coastguard Worker /// cases. Basically, in certain situations, it's useful to use the same code, 355*5a6e8488SAndroid Build Coastguard Worker /// but have a list of valid tokens. 356*5a6e8488SAndroid Build Coastguard Worker /// 357*5a6e8488SAndroid Build Coastguard Worker /// Obviously, @a len is the number of tokens in the @a tokens array. If more 358*5a6e8488SAndroid Build Coastguard Worker /// than 4 is needed in the future, @a tokens will have to be changed. 359*5a6e8488SAndroid Build Coastguard Worker typedef struct BcParseNext 360*5a6e8488SAndroid Build Coastguard Worker { 361*5a6e8488SAndroid Build Coastguard Worker /// The number of tokens in the tokens array. 362*5a6e8488SAndroid Build Coastguard Worker uchar len; 363*5a6e8488SAndroid Build Coastguard Worker 364*5a6e8488SAndroid Build Coastguard Worker /// The tokens that can be expected next. 365*5a6e8488SAndroid Build Coastguard Worker uchar tokens[4]; 366*5a6e8488SAndroid Build Coastguard Worker 367*5a6e8488SAndroid Build Coastguard Worker } BcParseNext; 368*5a6e8488SAndroid Build Coastguard Worker 369*5a6e8488SAndroid Build Coastguard Worker /// A macro to construct an array literal of tokens from a parameter list. 370*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ } 371*5a6e8488SAndroid Build Coastguard Worker 372*5a6e8488SAndroid Build Coastguard Worker /// A macro to generate a BcParseNext literal from BcParseNext data. See 373*5a6e8488SAndroid Build Coastguard Worker /// src/data.c for examples. 374*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NEXT(a, ...) \ 375*5a6e8488SAndroid Build Coastguard Worker { .len = (uchar) (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) } 376*5a6e8488SAndroid Build Coastguard Worker 377*5a6e8488SAndroid Build Coastguard Worker /// A status returned by @a bc_parse_expr_err(). It can either return success or 378*5a6e8488SAndroid Build Coastguard Worker /// an error indicating an empty expression. 379*5a6e8488SAndroid Build Coastguard Worker typedef enum BcParseStatus 380*5a6e8488SAndroid Build Coastguard Worker { 381*5a6e8488SAndroid Build Coastguard Worker BC_PARSE_STATUS_SUCCESS, 382*5a6e8488SAndroid Build Coastguard Worker BC_PARSE_STATUS_EMPTY_EXPR, 383*5a6e8488SAndroid Build Coastguard Worker 384*5a6e8488SAndroid Build Coastguard Worker } BcParseStatus; 385*5a6e8488SAndroid Build Coastguard Worker 386*5a6e8488SAndroid Build Coastguard Worker /** 387*5a6e8488SAndroid Build Coastguard Worker * The @a BcParseExpr function for bc. (See include/parse.h for a definition of 388*5a6e8488SAndroid Build Coastguard Worker * @a BcParseExpr.) 389*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 390*5a6e8488SAndroid Build Coastguard Worker * @param flags Flags that define the requirements that the parsed code must 391*5a6e8488SAndroid Build Coastguard Worker * meet or an error will result. See @a BcParseExpr for more info. 392*5a6e8488SAndroid Build Coastguard Worker */ 393*5a6e8488SAndroid Build Coastguard Worker void 394*5a6e8488SAndroid Build Coastguard Worker bc_parse_expr(BcParse* p, uint8_t flags); 395*5a6e8488SAndroid Build Coastguard Worker 396*5a6e8488SAndroid Build Coastguard Worker /** 397*5a6e8488SAndroid Build Coastguard Worker * The @a BcParseParse function for bc. (See include/parse.h for a definition of 398*5a6e8488SAndroid Build Coastguard Worker * @a BcParseParse.) 399*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 400*5a6e8488SAndroid Build Coastguard Worker */ 401*5a6e8488SAndroid Build Coastguard Worker void 402*5a6e8488SAndroid Build Coastguard Worker bc_parse_parse(BcParse* p); 403*5a6e8488SAndroid Build Coastguard Worker 404*5a6e8488SAndroid Build Coastguard Worker /** 405*5a6e8488SAndroid Build Coastguard Worker * Ends a series of if statements. This is to ensure that full parses happen 406*5a6e8488SAndroid Build Coastguard Worker * when a file finishes or before defining a function. Without this, bc thinks 407*5a6e8488SAndroid Build Coastguard Worker * that it cannot parse any further. But if we reach the end of a file or a 408*5a6e8488SAndroid Build Coastguard Worker * function definition, we know we can add an empty else clause. 409*5a6e8488SAndroid Build Coastguard Worker * @param p The parser. 410*5a6e8488SAndroid Build Coastguard Worker */ 411*5a6e8488SAndroid Build Coastguard Worker void 412*5a6e8488SAndroid Build Coastguard Worker bc_parse_endif(BcParse* p); 413*5a6e8488SAndroid Build Coastguard Worker 414*5a6e8488SAndroid Build Coastguard Worker /// References to the signal message and its length. 415*5a6e8488SAndroid Build Coastguard Worker extern const char bc_sig_msg[]; 416*5a6e8488SAndroid Build Coastguard Worker extern const uchar bc_sig_msg_len; 417*5a6e8488SAndroid Build Coastguard Worker 418*5a6e8488SAndroid Build Coastguard Worker /// A reference to an array of bits that are set if the corresponding lex token 419*5a6e8488SAndroid Build Coastguard Worker /// is valid in an expression. 420*5a6e8488SAndroid Build Coastguard Worker extern const uint8_t bc_parse_exprs[]; 421*5a6e8488SAndroid Build Coastguard Worker 422*5a6e8488SAndroid Build Coastguard Worker /// A reference to an array of bc operators. 423*5a6e8488SAndroid Build Coastguard Worker extern const uchar bc_parse_ops[]; 424*5a6e8488SAndroid Build Coastguard Worker 425*5a6e8488SAndroid Build Coastguard Worker // References to the various instances of BcParseNext's. 426*5a6e8488SAndroid Build Coastguard Worker 427*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing normal 428*5a6e8488SAndroid Build Coastguard Worker /// expressions. More accurately. these are the tokens that are valid for 429*5a6e8488SAndroid Build Coastguard Worker /// *ending* the expression. 430*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_expr; 431*5a6e8488SAndroid Build Coastguard Worker 432*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing function 433*5a6e8488SAndroid Build Coastguard Worker /// parameters (well, actually arguments). 434*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_arg; 435*5a6e8488SAndroid Build Coastguard Worker 436*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing a print 437*5a6e8488SAndroid Build Coastguard Worker /// statement. 438*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_print; 439*5a6e8488SAndroid Build Coastguard Worker 440*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing things like 441*5a6e8488SAndroid Build Coastguard Worker /// loop headers and builtin functions where the only thing expected is a right 442*5a6e8488SAndroid Build Coastguard Worker /// paren. 443*5a6e8488SAndroid Build Coastguard Worker /// 444*5a6e8488SAndroid Build Coastguard Worker /// The name is an artifact of history, and is related to @a BC_PARSE_REL (see 445*5a6e8488SAndroid Build Coastguard Worker /// include/parse.h). It refers to how POSIX only allows some operators as part 446*5a6e8488SAndroid Build Coastguard Worker /// of the conditional of for loops, while loops, and if statements. 447*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_rel; 448*5a6e8488SAndroid Build Coastguard Worker 449*5a6e8488SAndroid Build Coastguard Worker // What tokens are valid as next tokens when parsing an array element 450*5a6e8488SAndroid Build Coastguard Worker // expression. 451*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_elem; 452*5a6e8488SAndroid Build Coastguard Worker 453*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing the first 454*5a6e8488SAndroid Build Coastguard Worker /// two parts of a for loop header. 455*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_for; 456*5a6e8488SAndroid Build Coastguard Worker 457*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing a read 458*5a6e8488SAndroid Build Coastguard Worker /// expression. 459*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_read; 460*5a6e8488SAndroid Build Coastguard Worker 461*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing a builtin 462*5a6e8488SAndroid Build Coastguard Worker /// function with multiple arguments. 463*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_builtin; 464*5a6e8488SAndroid Build Coastguard Worker 465*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLED 466*5a6e8488SAndroid Build Coastguard Worker 467*5a6e8488SAndroid Build Coastguard Worker // If bc is not enabled, execution is always possible because dc has strict 468*5a6e8488SAndroid Build Coastguard Worker // rules that ensure execution can always proceed safely. 469*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NO_EXEC(p) (0) 470*5a6e8488SAndroid Build Coastguard Worker 471*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 472*5a6e8488SAndroid Build Coastguard Worker 473*5a6e8488SAndroid Build Coastguard Worker #endif // BC_BC_H 474