1252884aeSStefan Eßer /* 2252884aeSStefan Eßer * ***************************************************************************** 3252884aeSStefan Eßer * 43aa99676SStefan Eßer * SPDX-License-Identifier: BSD-2-Clause 5252884aeSStefan Eßer * 63aa99676SStefan 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 bc's lexer. 33252884aeSStefan Eßer * 34252884aeSStefan Eßer */ 35252884aeSStefan Eßer 36252884aeSStefan Eßer #ifndef BC_LEX_H 37252884aeSStefan Eßer #define BC_LEX_H 38252884aeSStefan Eßer 39252884aeSStefan Eßer #include <stdbool.h> 40252884aeSStefan Eßer #include <stddef.h> 41252884aeSStefan Eßer 42252884aeSStefan Eßer #include <status.h> 43252884aeSStefan Eßer #include <vector.h> 44252884aeSStefan Eßer #include <lang.h> 45252884aeSStefan Eßer 46*50696a6eSStefan Eßer #define bc_lex_err(l, e) (bc_vm_handleError((e), (l)->line)) 47*50696a6eSStefan Eßer #define bc_lex_verr(l, e, ...) (bc_vm_handleError((e), (l)->line, __VA_ARGS__)) 48252884aeSStefan Eßer 493aa99676SStefan Eßer #if BC_ENABLED 503aa99676SStefan Eßer 513aa99676SStefan Eßer #if DC_ENABLED 52252884aeSStefan Eßer #define BC_LEX_NEG_CHAR (BC_IS_BC ? '-' : '_') 53252884aeSStefan Eßer #define BC_LEX_LAST_NUM_CHAR (BC_IS_BC ? 'Z' : 'F') 543aa99676SStefan Eßer #else // DC_ENABLED 553aa99676SStefan Eßer #define BC_LEX_NEG_CHAR ('-') 563aa99676SStefan Eßer #define BC_LEX_LAST_NUM_CHAR ('Z') 573aa99676SStefan Eßer #endif // DC_ENABLED 583aa99676SStefan Eßer 593aa99676SStefan Eßer #else // BC_ENABLED 603aa99676SStefan Eßer 613aa99676SStefan Eßer #define BC_LEX_NEG_CHAR ('_') 623aa99676SStefan Eßer #define BC_LEX_LAST_NUM_CHAR ('F') 633aa99676SStefan Eßer 643aa99676SStefan Eßer #endif // BC_ENABLED 653aa99676SStefan Eßer 66252884aeSStefan Eßer #define BC_LEX_NUM_CHAR(c, pt, int_only) \ 67252884aeSStefan Eßer (isdigit(c) || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \ 68252884aeSStefan Eßer ((c) == '.' && !(pt) && !(int_only))) 69252884aeSStefan Eßer 70252884aeSStefan Eßer // BC_LEX_NEG is not used in lexing; it is only for parsing. 71252884aeSStefan Eßer typedef enum BcLexType { 72252884aeSStefan Eßer 73252884aeSStefan Eßer BC_LEX_EOF, 74252884aeSStefan Eßer BC_LEX_INVALID, 75252884aeSStefan Eßer 76252884aeSStefan Eßer #if BC_ENABLED 77252884aeSStefan Eßer BC_LEX_OP_INC, 78252884aeSStefan Eßer BC_LEX_OP_DEC, 79252884aeSStefan Eßer #endif // BC_ENABLED 80252884aeSStefan Eßer 81252884aeSStefan Eßer BC_LEX_NEG, 82252884aeSStefan Eßer BC_LEX_OP_BOOL_NOT, 83252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 84252884aeSStefan Eßer BC_LEX_OP_TRUNC, 85252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 86252884aeSStefan Eßer 87252884aeSStefan Eßer BC_LEX_OP_POWER, 88252884aeSStefan Eßer BC_LEX_OP_MULTIPLY, 89252884aeSStefan Eßer BC_LEX_OP_DIVIDE, 90252884aeSStefan Eßer BC_LEX_OP_MODULUS, 91252884aeSStefan Eßer BC_LEX_OP_PLUS, 92252884aeSStefan Eßer BC_LEX_OP_MINUS, 93252884aeSStefan Eßer 94252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 95252884aeSStefan Eßer BC_LEX_OP_PLACES, 96252884aeSStefan Eßer 97252884aeSStefan Eßer BC_LEX_OP_LSHIFT, 98252884aeSStefan Eßer BC_LEX_OP_RSHIFT, 99252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 100252884aeSStefan Eßer 101252884aeSStefan Eßer BC_LEX_OP_REL_EQ, 102252884aeSStefan Eßer BC_LEX_OP_REL_LE, 103252884aeSStefan Eßer BC_LEX_OP_REL_GE, 104252884aeSStefan Eßer BC_LEX_OP_REL_NE, 105252884aeSStefan Eßer BC_LEX_OP_REL_LT, 106252884aeSStefan Eßer BC_LEX_OP_REL_GT, 107252884aeSStefan Eßer 108252884aeSStefan Eßer BC_LEX_OP_BOOL_OR, 109252884aeSStefan Eßer BC_LEX_OP_BOOL_AND, 110252884aeSStefan Eßer 111252884aeSStefan Eßer #if BC_ENABLED 112252884aeSStefan Eßer BC_LEX_OP_ASSIGN_POWER, 113252884aeSStefan Eßer BC_LEX_OP_ASSIGN_MULTIPLY, 114252884aeSStefan Eßer BC_LEX_OP_ASSIGN_DIVIDE, 115252884aeSStefan Eßer BC_LEX_OP_ASSIGN_MODULUS, 116252884aeSStefan Eßer BC_LEX_OP_ASSIGN_PLUS, 117252884aeSStefan Eßer BC_LEX_OP_ASSIGN_MINUS, 118252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 119252884aeSStefan Eßer BC_LEX_OP_ASSIGN_PLACES, 120252884aeSStefan Eßer BC_LEX_OP_ASSIGN_LSHIFT, 121252884aeSStefan Eßer BC_LEX_OP_ASSIGN_RSHIFT, 122252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 123252884aeSStefan Eßer #endif // BC_ENABLED 124252884aeSStefan Eßer BC_LEX_OP_ASSIGN, 125252884aeSStefan Eßer 126252884aeSStefan Eßer BC_LEX_NLINE, 127252884aeSStefan Eßer BC_LEX_WHITESPACE, 128252884aeSStefan Eßer 129252884aeSStefan Eßer BC_LEX_LPAREN, 130252884aeSStefan Eßer BC_LEX_RPAREN, 131252884aeSStefan Eßer 132252884aeSStefan Eßer BC_LEX_LBRACKET, 133252884aeSStefan Eßer BC_LEX_COMMA, 134252884aeSStefan Eßer BC_LEX_RBRACKET, 135252884aeSStefan Eßer 136252884aeSStefan Eßer BC_LEX_LBRACE, 137252884aeSStefan Eßer BC_LEX_SCOLON, 138252884aeSStefan Eßer BC_LEX_RBRACE, 139252884aeSStefan Eßer 140252884aeSStefan Eßer BC_LEX_STR, 141252884aeSStefan Eßer BC_LEX_NAME, 142252884aeSStefan Eßer BC_LEX_NUMBER, 143252884aeSStefan Eßer 144252884aeSStefan Eßer #if BC_ENABLED 145252884aeSStefan Eßer BC_LEX_KW_AUTO, 146252884aeSStefan Eßer BC_LEX_KW_BREAK, 147252884aeSStefan Eßer BC_LEX_KW_CONTINUE, 148252884aeSStefan Eßer BC_LEX_KW_DEFINE, 149252884aeSStefan Eßer BC_LEX_KW_FOR, 150252884aeSStefan Eßer BC_LEX_KW_IF, 151252884aeSStefan Eßer BC_LEX_KW_LIMITS, 152252884aeSStefan Eßer BC_LEX_KW_RETURN, 153252884aeSStefan Eßer BC_LEX_KW_WHILE, 154252884aeSStefan Eßer BC_LEX_KW_HALT, 155252884aeSStefan Eßer BC_LEX_KW_LAST, 156252884aeSStefan Eßer #endif // BC_ENABLED 157252884aeSStefan Eßer BC_LEX_KW_IBASE, 158252884aeSStefan Eßer BC_LEX_KW_OBASE, 159252884aeSStefan Eßer BC_LEX_KW_SCALE, 1603aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 161252884aeSStefan Eßer BC_LEX_KW_SEED, 1623aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 163252884aeSStefan Eßer BC_LEX_KW_LENGTH, 164252884aeSStefan Eßer BC_LEX_KW_PRINT, 165252884aeSStefan Eßer BC_LEX_KW_SQRT, 166252884aeSStefan Eßer BC_LEX_KW_ABS, 1673aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 168252884aeSStefan Eßer BC_LEX_KW_IRAND, 1693aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 170252884aeSStefan Eßer BC_LEX_KW_QUIT, 171252884aeSStefan Eßer BC_LEX_KW_READ, 1723aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 173252884aeSStefan Eßer BC_LEX_KW_RAND, 1743aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 175252884aeSStefan Eßer BC_LEX_KW_MAXIBASE, 176252884aeSStefan Eßer BC_LEX_KW_MAXOBASE, 177252884aeSStefan Eßer BC_LEX_KW_MAXSCALE, 1783aa99676SStefan Eßer #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 179252884aeSStefan Eßer BC_LEX_KW_MAXRAND, 1803aa99676SStefan Eßer #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 181252884aeSStefan Eßer BC_LEX_KW_ELSE, 182252884aeSStefan Eßer 183252884aeSStefan Eßer #if DC_ENABLED 184252884aeSStefan Eßer BC_LEX_EQ_NO_REG, 185252884aeSStefan Eßer BC_LEX_OP_MODEXP, 186252884aeSStefan Eßer BC_LEX_OP_DIVMOD, 187252884aeSStefan Eßer 188252884aeSStefan Eßer BC_LEX_COLON, 189252884aeSStefan Eßer BC_LEX_EXECUTE, 190252884aeSStefan Eßer BC_LEX_PRINT_STACK, 191252884aeSStefan Eßer BC_LEX_CLEAR_STACK, 192252884aeSStefan Eßer BC_LEX_STACK_LEVEL, 193252884aeSStefan Eßer BC_LEX_DUPLICATE, 194252884aeSStefan Eßer BC_LEX_SWAP, 195252884aeSStefan Eßer BC_LEX_POP, 196252884aeSStefan Eßer 197252884aeSStefan Eßer BC_LEX_ASCIIFY, 198252884aeSStefan Eßer BC_LEX_PRINT_STREAM, 199252884aeSStefan Eßer 200252884aeSStefan Eßer BC_LEX_STORE_IBASE, 201252884aeSStefan Eßer BC_LEX_STORE_OBASE, 202252884aeSStefan Eßer BC_LEX_STORE_SCALE, 203252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 204252884aeSStefan Eßer BC_LEX_STORE_SEED, 205252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 206252884aeSStefan Eßer BC_LEX_LOAD, 207252884aeSStefan Eßer BC_LEX_LOAD_POP, 208252884aeSStefan Eßer BC_LEX_STORE_PUSH, 209252884aeSStefan Eßer BC_LEX_PRINT_POP, 210252884aeSStefan Eßer BC_LEX_NQUIT, 211252884aeSStefan Eßer BC_LEX_SCALE_FACTOR, 212252884aeSStefan Eßer #endif // DC_ENABLED 213252884aeSStefan Eßer 214252884aeSStefan Eßer } BcLexType; 215252884aeSStefan Eßer 216252884aeSStefan Eßer struct BcLex; 217252884aeSStefan Eßer typedef void (*BcLexNext)(struct BcLex*); 218252884aeSStefan Eßer 219252884aeSStefan Eßer typedef struct BcLex { 220252884aeSStefan Eßer 221252884aeSStefan Eßer const char *buf; 222252884aeSStefan Eßer size_t i; 223252884aeSStefan Eßer size_t line; 224252884aeSStefan Eßer size_t len; 225252884aeSStefan Eßer 226252884aeSStefan Eßer BcLexType t; 227252884aeSStefan Eßer BcLexType last; 228252884aeSStefan Eßer BcVec str; 229252884aeSStefan Eßer 230252884aeSStefan Eßer } BcLex; 231252884aeSStefan Eßer 232252884aeSStefan Eßer void bc_lex_init(BcLex *l); 233252884aeSStefan Eßer void bc_lex_free(BcLex *l); 234252884aeSStefan Eßer void bc_lex_file(BcLex *l, const char *file); 235252884aeSStefan Eßer void bc_lex_text(BcLex *l, const char *text); 236252884aeSStefan Eßer void bc_lex_next(BcLex *l); 237252884aeSStefan Eßer 238252884aeSStefan Eßer void bc_lex_lineComment(BcLex *l); 239252884aeSStefan Eßer void bc_lex_comment(BcLex *l); 240252884aeSStefan Eßer void bc_lex_whitespace(BcLex *l); 241252884aeSStefan Eßer void bc_lex_number(BcLex *l, char start); 242252884aeSStefan Eßer void bc_lex_name(BcLex *l); 243252884aeSStefan Eßer void bc_lex_commonTokens(BcLex *l, char c); 244252884aeSStefan Eßer 245252884aeSStefan Eßer void bc_lex_invalidChar(BcLex *l, char c); 246252884aeSStefan Eßer 247252884aeSStefan Eßer #endif // BC_LEX_H 248