xref: /freebsd/contrib/bc/include/lex.h (revision 4e22eafc994140e0c0ddfb5688258ad819e1078e)
1 /*
2  * *****************************************************************************
3  *
4  * Copyright (c) 2018-2020 Gavin D. Howard and contributors.
5  *
6  * All rights reserved.
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 #define BC_LEX_NEG_CHAR (BC_IS_BC ? '-' : '_')
50 #define BC_LEX_LAST_NUM_CHAR (BC_IS_BC ? 'Z' : 'F')
51 #define BC_LEX_NUM_CHAR(c, pt, int_only)                          \
52 	(isdigit(c) || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \
53 	 ((c) == '.' && !(pt) && !(int_only)))
54 
55 // BC_LEX_NEG is not used in lexing; it is only for parsing.
56 typedef enum BcLexType {
57 
58 	BC_LEX_EOF,
59 	BC_LEX_INVALID,
60 
61 #if BC_ENABLED
62 	BC_LEX_OP_INC,
63 	BC_LEX_OP_DEC,
64 #endif // BC_ENABLED
65 
66 	BC_LEX_NEG,
67 	BC_LEX_OP_BOOL_NOT,
68 #if BC_ENABLE_EXTRA_MATH
69 	BC_LEX_OP_TRUNC,
70 #endif // BC_ENABLE_EXTRA_MATH
71 
72 	BC_LEX_OP_POWER,
73 	BC_LEX_OP_MULTIPLY,
74 	BC_LEX_OP_DIVIDE,
75 	BC_LEX_OP_MODULUS,
76 	BC_LEX_OP_PLUS,
77 	BC_LEX_OP_MINUS,
78 
79 #if BC_ENABLE_EXTRA_MATH
80 	BC_LEX_OP_PLACES,
81 
82 	BC_LEX_OP_LSHIFT,
83 	BC_LEX_OP_RSHIFT,
84 #endif // BC_ENABLE_EXTRA_MATH
85 
86 	BC_LEX_OP_REL_EQ,
87 	BC_LEX_OP_REL_LE,
88 	BC_LEX_OP_REL_GE,
89 	BC_LEX_OP_REL_NE,
90 	BC_LEX_OP_REL_LT,
91 	BC_LEX_OP_REL_GT,
92 
93 	BC_LEX_OP_BOOL_OR,
94 	BC_LEX_OP_BOOL_AND,
95 
96 #if BC_ENABLED
97 	BC_LEX_OP_ASSIGN_POWER,
98 	BC_LEX_OP_ASSIGN_MULTIPLY,
99 	BC_LEX_OP_ASSIGN_DIVIDE,
100 	BC_LEX_OP_ASSIGN_MODULUS,
101 	BC_LEX_OP_ASSIGN_PLUS,
102 	BC_LEX_OP_ASSIGN_MINUS,
103 #if BC_ENABLE_EXTRA_MATH
104 	BC_LEX_OP_ASSIGN_PLACES,
105 	BC_LEX_OP_ASSIGN_LSHIFT,
106 	BC_LEX_OP_ASSIGN_RSHIFT,
107 #endif // BC_ENABLE_EXTRA_MATH
108 #endif // BC_ENABLED
109 	BC_LEX_OP_ASSIGN,
110 
111 	BC_LEX_NLINE,
112 	BC_LEX_WHITESPACE,
113 
114 	BC_LEX_LPAREN,
115 	BC_LEX_RPAREN,
116 
117 	BC_LEX_LBRACKET,
118 	BC_LEX_COMMA,
119 	BC_LEX_RBRACKET,
120 
121 	BC_LEX_LBRACE,
122 	BC_LEX_SCOLON,
123 	BC_LEX_RBRACE,
124 
125 	BC_LEX_STR,
126 	BC_LEX_NAME,
127 	BC_LEX_NUMBER,
128 
129 #if BC_ENABLED
130 	BC_LEX_KW_AUTO,
131 	BC_LEX_KW_BREAK,
132 	BC_LEX_KW_CONTINUE,
133 	BC_LEX_KW_DEFINE,
134 	BC_LEX_KW_FOR,
135 	BC_LEX_KW_IF,
136 	BC_LEX_KW_LIMITS,
137 	BC_LEX_KW_RETURN,
138 	BC_LEX_KW_WHILE,
139 	BC_LEX_KW_HALT,
140 	BC_LEX_KW_LAST,
141 #endif // BC_ENABLED
142 	BC_LEX_KW_IBASE,
143 	BC_LEX_KW_OBASE,
144 	BC_LEX_KW_SCALE,
145 #if BC_ENABLE_EXTRA_MATH
146 	BC_LEX_KW_SEED,
147 #endif // BC_ENABLE_EXTRA_MATH
148 	BC_LEX_KW_LENGTH,
149 	BC_LEX_KW_PRINT,
150 	BC_LEX_KW_SQRT,
151 	BC_LEX_KW_ABS,
152 #if BC_ENABLE_EXTRA_MATH
153 	BC_LEX_KW_IRAND,
154 #endif // BC_ENABLE_EXTRA_MATH
155 	BC_LEX_KW_QUIT,
156 	BC_LEX_KW_READ,
157 #if BC_ENABLE_EXTRA_MATH
158 	BC_LEX_KW_RAND,
159 #endif // BC_ENABLE_EXTRA_MATH
160 	BC_LEX_KW_MAXIBASE,
161 	BC_LEX_KW_MAXOBASE,
162 	BC_LEX_KW_MAXSCALE,
163 #if BC_ENABLE_EXTRA_MATH
164 	BC_LEX_KW_MAXRAND,
165 #endif // BC_ENABLE_EXTRA_MATH
166 	BC_LEX_KW_ELSE,
167 
168 #if DC_ENABLED
169 	BC_LEX_EQ_NO_REG,
170 	BC_LEX_OP_MODEXP,
171 	BC_LEX_OP_DIVMOD,
172 
173 	BC_LEX_COLON,
174 	BC_LEX_EXECUTE,
175 	BC_LEX_PRINT_STACK,
176 	BC_LEX_CLEAR_STACK,
177 	BC_LEX_STACK_LEVEL,
178 	BC_LEX_DUPLICATE,
179 	BC_LEX_SWAP,
180 	BC_LEX_POP,
181 
182 	BC_LEX_ASCIIFY,
183 	BC_LEX_PRINT_STREAM,
184 
185 	BC_LEX_STORE_IBASE,
186 	BC_LEX_STORE_OBASE,
187 	BC_LEX_STORE_SCALE,
188 #if BC_ENABLE_EXTRA_MATH
189 	BC_LEX_STORE_SEED,
190 #endif // BC_ENABLE_EXTRA_MATH
191 	BC_LEX_LOAD,
192 	BC_LEX_LOAD_POP,
193 	BC_LEX_STORE_PUSH,
194 	BC_LEX_PRINT_POP,
195 	BC_LEX_NQUIT,
196 	BC_LEX_SCALE_FACTOR,
197 #endif // DC_ENABLED
198 
199 } BcLexType;
200 
201 struct BcLex;
202 typedef void (*BcLexNext)(struct BcLex*);
203 
204 typedef struct BcLex {
205 
206 	const char *buf;
207 	size_t i;
208 	size_t line;
209 	size_t len;
210 
211 	BcLexType t;
212 	BcLexType last;
213 	BcVec str;
214 
215 } BcLex;
216 
217 void bc_lex_init(BcLex *l);
218 void bc_lex_free(BcLex *l);
219 void bc_lex_file(BcLex *l, const char *file);
220 void bc_lex_text(BcLex *l, const char *text);
221 void bc_lex_next(BcLex *l);
222 
223 void bc_lex_lineComment(BcLex *l);
224 void bc_lex_comment(BcLex *l);
225 void bc_lex_whitespace(BcLex *l);
226 void bc_lex_number(BcLex *l, char start);
227 void bc_lex_name(BcLex *l);
228 void bc_lex_commonTokens(BcLex *l, char c);
229 
230 void bc_lex_invalidChar(BcLex *l, char c);
231 
232 #endif // BC_LEX_H
233