/* * ***************************************************************************** * * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018-2021 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ***************************************************************************** * * Definitions for bc's lexer. * */ #ifndef BC_LEX_H #define BC_LEX_H #include #include #include #include #include #define bc_lex_err(l, e) (bc_vm_handleError((e), (l)->line)) #define bc_lex_verr(l, e, ...) (bc_vm_handleError((e), (l)->line, __VA_ARGS__)) #if BC_ENABLED #if DC_ENABLED #define BC_LEX_NEG_CHAR (BC_IS_BC ? '-' : '_') #define BC_LEX_LAST_NUM_CHAR (BC_IS_BC ? 'Z' : 'F') #else // DC_ENABLED #define BC_LEX_NEG_CHAR ('-') #define BC_LEX_LAST_NUM_CHAR ('Z') #endif // DC_ENABLED #else // BC_ENABLED #define BC_LEX_NEG_CHAR ('_') #define BC_LEX_LAST_NUM_CHAR ('F') #endif // BC_ENABLED #define BC_LEX_NUM_CHAR(c, pt, int_only) \ (isdigit(c) || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \ ((c) == '.' && !(pt) && !(int_only))) // BC_LEX_NEG is not used in lexing; it is only for parsing. typedef enum BcLexType { BC_LEX_EOF, BC_LEX_INVALID, #if BC_ENABLED BC_LEX_OP_INC, BC_LEX_OP_DEC, #endif // BC_ENABLED BC_LEX_NEG, BC_LEX_OP_BOOL_NOT, #if BC_ENABLE_EXTRA_MATH BC_LEX_OP_TRUNC, #endif // BC_ENABLE_EXTRA_MATH BC_LEX_OP_POWER, BC_LEX_OP_MULTIPLY, BC_LEX_OP_DIVIDE, BC_LEX_OP_MODULUS, BC_LEX_OP_PLUS, BC_LEX_OP_MINUS, #if BC_ENABLE_EXTRA_MATH BC_LEX_OP_PLACES, BC_LEX_OP_LSHIFT, BC_LEX_OP_RSHIFT, #endif // BC_ENABLE_EXTRA_MATH BC_LEX_OP_REL_EQ, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_NE, BC_LEX_OP_REL_LT, BC_LEX_OP_REL_GT, BC_LEX_OP_BOOL_OR, BC_LEX_OP_BOOL_AND, #if BC_ENABLED BC_LEX_OP_ASSIGN_POWER, BC_LEX_OP_ASSIGN_MULTIPLY, BC_LEX_OP_ASSIGN_DIVIDE, BC_LEX_OP_ASSIGN_MODULUS, BC_LEX_OP_ASSIGN_PLUS, BC_LEX_OP_ASSIGN_MINUS, #if BC_ENABLE_EXTRA_MATH BC_LEX_OP_ASSIGN_PLACES, BC_LEX_OP_ASSIGN_LSHIFT, BC_LEX_OP_ASSIGN_RSHIFT, #endif // BC_ENABLE_EXTRA_MATH #endif // BC_ENABLED BC_LEX_OP_ASSIGN, BC_LEX_NLINE, BC_LEX_WHITESPACE, BC_LEX_LPAREN, BC_LEX_RPAREN, BC_LEX_LBRACKET, BC_LEX_COMMA, BC_LEX_RBRACKET, BC_LEX_LBRACE, BC_LEX_SCOLON, BC_LEX_RBRACE, BC_LEX_STR, BC_LEX_NAME, BC_LEX_NUMBER, #if BC_ENABLED BC_LEX_KW_AUTO, BC_LEX_KW_BREAK, BC_LEX_KW_CONTINUE, BC_LEX_KW_DEFINE, BC_LEX_KW_FOR, BC_LEX_KW_IF, BC_LEX_KW_LIMITS, BC_LEX_KW_RETURN, BC_LEX_KW_WHILE, BC_LEX_KW_HALT, BC_LEX_KW_LAST, #endif // BC_ENABLED BC_LEX_KW_IBASE, BC_LEX_KW_OBASE, BC_LEX_KW_SCALE, #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_SEED, #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_LENGTH, BC_LEX_KW_PRINT, BC_LEX_KW_SQRT, BC_LEX_KW_ABS, #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_IRAND, #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_QUIT, BC_LEX_KW_READ, #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_RAND, #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_MAXIBASE, BC_LEX_KW_MAXOBASE, BC_LEX_KW_MAXSCALE, #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_MAXRAND, #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ELSE, #if DC_ENABLED BC_LEX_EQ_NO_REG, BC_LEX_OP_MODEXP, BC_LEX_OP_DIVMOD, BC_LEX_COLON, BC_LEX_EXECUTE, BC_LEX_PRINT_STACK, BC_LEX_CLEAR_STACK, BC_LEX_STACK_LEVEL, BC_LEX_DUPLICATE, BC_LEX_SWAP, BC_LEX_POP, BC_LEX_ASCIIFY, BC_LEX_PRINT_STREAM, BC_LEX_STORE_IBASE, BC_LEX_STORE_OBASE, BC_LEX_STORE_SCALE, #if BC_ENABLE_EXTRA_MATH BC_LEX_STORE_SEED, #endif // BC_ENABLE_EXTRA_MATH BC_LEX_LOAD, BC_LEX_LOAD_POP, BC_LEX_STORE_PUSH, BC_LEX_PRINT_POP, BC_LEX_NQUIT, BC_LEX_SCALE_FACTOR, #endif // DC_ENABLED } BcLexType; struct BcLex; typedef void (*BcLexNext)(struct BcLex*); typedef struct BcLex { const char *buf; size_t i; size_t line; size_t len; BcLexType t; BcLexType last; BcVec str; } BcLex; void bc_lex_init(BcLex *l); void bc_lex_free(BcLex *l); void bc_lex_file(BcLex *l, const char *file); void bc_lex_text(BcLex *l, const char *text); void bc_lex_next(BcLex *l); void bc_lex_lineComment(BcLex *l); void bc_lex_comment(BcLex *l); void bc_lex_whitespace(BcLex *l); void bc_lex_number(BcLex *l, char start); void bc_lex_name(BcLex *l); void bc_lex_commonTokens(BcLex *l, char c); void bc_lex_invalidChar(BcLex *l, char c); #endif // BC_LEX_H