xref: /freebsd/contrib/bc/include/lex.h (revision 50696a6e8cbfdbf4a0d00f2f85f1951aa0d8e23d)
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