1 /* 2 * ***************************************************************************** 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2018-2020 Gavin D. Howard and contributors. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * * Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ***************************************************************************** 31 * 32 * Definitions for bc's lexer. 33 * 34 */ 35 36 #ifndef BC_LEX_H 37 #define BC_LEX_H 38 39 #include <stdbool.h> 40 #include <stddef.h> 41 42 #include <status.h> 43 #include <vector.h> 44 #include <lang.h> 45 46 #define bc_lex_err(l, e) (bc_vm_error((e), (l)->line)) 47 #define bc_lex_verr(l, e, ...) (bc_vm_error((e), (l)->line, __VA_ARGS__)) 48 49 #if BC_ENABLED 50 51 #if DC_ENABLED 52 #define BC_LEX_NEG_CHAR (BC_IS_BC ? '-' : '_') 53 #define BC_LEX_LAST_NUM_CHAR (BC_IS_BC ? 'Z' : 'F') 54 #else // DC_ENABLED 55 #define BC_LEX_NEG_CHAR ('-') 56 #define BC_LEX_LAST_NUM_CHAR ('Z') 57 #endif // DC_ENABLED 58 59 #else // BC_ENABLED 60 61 #define BC_LEX_NEG_CHAR ('_') 62 #define BC_LEX_LAST_NUM_CHAR ('F') 63 64 #endif // BC_ENABLED 65 66 #define BC_LEX_NUM_CHAR(c, pt, int_only) \ 67 (isdigit(c) || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \ 68 ((c) == '.' && !(pt) && !(int_only))) 69 70 // BC_LEX_NEG is not used in lexing; it is only for parsing. 71 typedef enum BcLexType { 72 73 BC_LEX_EOF, 74 BC_LEX_INVALID, 75 76 #if BC_ENABLED 77 BC_LEX_OP_INC, 78 BC_LEX_OP_DEC, 79 #endif // BC_ENABLED 80 81 BC_LEX_NEG, 82 BC_LEX_OP_BOOL_NOT, 83 #if BC_ENABLE_EXTRA_MATH 84 BC_LEX_OP_TRUNC, 85 #endif // BC_ENABLE_EXTRA_MATH 86 87 BC_LEX_OP_POWER, 88 BC_LEX_OP_MULTIPLY, 89 BC_LEX_OP_DIVIDE, 90 BC_LEX_OP_MODULUS, 91 BC_LEX_OP_PLUS, 92 BC_LEX_OP_MINUS, 93 94 #if BC_ENABLE_EXTRA_MATH 95 BC_LEX_OP_PLACES, 96 97 BC_LEX_OP_LSHIFT, 98 BC_LEX_OP_RSHIFT, 99 #endif // BC_ENABLE_EXTRA_MATH 100 101 BC_LEX_OP_REL_EQ, 102 BC_LEX_OP_REL_LE, 103 BC_LEX_OP_REL_GE, 104 BC_LEX_OP_REL_NE, 105 BC_LEX_OP_REL_LT, 106 BC_LEX_OP_REL_GT, 107 108 BC_LEX_OP_BOOL_OR, 109 BC_LEX_OP_BOOL_AND, 110 111 #if BC_ENABLED 112 BC_LEX_OP_ASSIGN_POWER, 113 BC_LEX_OP_ASSIGN_MULTIPLY, 114 BC_LEX_OP_ASSIGN_DIVIDE, 115 BC_LEX_OP_ASSIGN_MODULUS, 116 BC_LEX_OP_ASSIGN_PLUS, 117 BC_LEX_OP_ASSIGN_MINUS, 118 #if BC_ENABLE_EXTRA_MATH 119 BC_LEX_OP_ASSIGN_PLACES, 120 BC_LEX_OP_ASSIGN_LSHIFT, 121 BC_LEX_OP_ASSIGN_RSHIFT, 122 #endif // BC_ENABLE_EXTRA_MATH 123 #endif // BC_ENABLED 124 BC_LEX_OP_ASSIGN, 125 126 BC_LEX_NLINE, 127 BC_LEX_WHITESPACE, 128 129 BC_LEX_LPAREN, 130 BC_LEX_RPAREN, 131 132 BC_LEX_LBRACKET, 133 BC_LEX_COMMA, 134 BC_LEX_RBRACKET, 135 136 BC_LEX_LBRACE, 137 BC_LEX_SCOLON, 138 BC_LEX_RBRACE, 139 140 BC_LEX_STR, 141 BC_LEX_NAME, 142 BC_LEX_NUMBER, 143 144 #if BC_ENABLED 145 BC_LEX_KW_AUTO, 146 BC_LEX_KW_BREAK, 147 BC_LEX_KW_CONTINUE, 148 BC_LEX_KW_DEFINE, 149 BC_LEX_KW_FOR, 150 BC_LEX_KW_IF, 151 BC_LEX_KW_LIMITS, 152 BC_LEX_KW_RETURN, 153 BC_LEX_KW_WHILE, 154 BC_LEX_KW_HALT, 155 BC_LEX_KW_LAST, 156 #endif // BC_ENABLED 157 BC_LEX_KW_IBASE, 158 BC_LEX_KW_OBASE, 159 BC_LEX_KW_SCALE, 160 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 161 BC_LEX_KW_SEED, 162 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 163 BC_LEX_KW_LENGTH, 164 BC_LEX_KW_PRINT, 165 BC_LEX_KW_SQRT, 166 BC_LEX_KW_ABS, 167 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 168 BC_LEX_KW_IRAND, 169 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 170 BC_LEX_KW_QUIT, 171 BC_LEX_KW_READ, 172 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 173 BC_LEX_KW_RAND, 174 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 175 BC_LEX_KW_MAXIBASE, 176 BC_LEX_KW_MAXOBASE, 177 BC_LEX_KW_MAXSCALE, 178 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 179 BC_LEX_KW_MAXRAND, 180 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND 181 BC_LEX_KW_ELSE, 182 183 #if DC_ENABLED 184 BC_LEX_EQ_NO_REG, 185 BC_LEX_OP_MODEXP, 186 BC_LEX_OP_DIVMOD, 187 188 BC_LEX_COLON, 189 BC_LEX_EXECUTE, 190 BC_LEX_PRINT_STACK, 191 BC_LEX_CLEAR_STACK, 192 BC_LEX_STACK_LEVEL, 193 BC_LEX_DUPLICATE, 194 BC_LEX_SWAP, 195 BC_LEX_POP, 196 197 BC_LEX_ASCIIFY, 198 BC_LEX_PRINT_STREAM, 199 200 BC_LEX_STORE_IBASE, 201 BC_LEX_STORE_OBASE, 202 BC_LEX_STORE_SCALE, 203 #if BC_ENABLE_EXTRA_MATH 204 BC_LEX_STORE_SEED, 205 #endif // BC_ENABLE_EXTRA_MATH 206 BC_LEX_LOAD, 207 BC_LEX_LOAD_POP, 208 BC_LEX_STORE_PUSH, 209 BC_LEX_PRINT_POP, 210 BC_LEX_NQUIT, 211 BC_LEX_SCALE_FACTOR, 212 #endif // DC_ENABLED 213 214 } BcLexType; 215 216 struct BcLex; 217 typedef void (*BcLexNext)(struct BcLex*); 218 219 typedef struct BcLex { 220 221 const char *buf; 222 size_t i; 223 size_t line; 224 size_t len; 225 226 BcLexType t; 227 BcLexType last; 228 BcVec str; 229 230 } BcLex; 231 232 void bc_lex_init(BcLex *l); 233 void bc_lex_free(BcLex *l); 234 void bc_lex_file(BcLex *l, const char *file); 235 void bc_lex_text(BcLex *l, const char *text); 236 void bc_lex_next(BcLex *l); 237 238 void bc_lex_lineComment(BcLex *l); 239 void bc_lex_comment(BcLex *l); 240 void bc_lex_whitespace(BcLex *l); 241 void bc_lex_number(BcLex *l, char start); 242 void bc_lex_name(BcLex *l); 243 void bc_lex_commonTokens(BcLex *l, char c); 244 245 void bc_lex_invalidChar(BcLex *l, char c); 246 247 #endif // BC_LEX_H 248