1 /*
2  * *****************************************************************************
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * Copyright (c) 2018-2021 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 program data.
33  *
34  */
35 
36 #ifndef BC_LANG_H
37 #define BC_LANG_H
38 
39 #include <stdbool.h>
40 
41 #include <status.h>
42 #include <vector.h>
43 #include <num.h>
44 
45 #if BC_ENABLED
46 #define BC_INST_IS_ASSIGN(i) \
47 	((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL)
48 #define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN)
49 #else // BC_ENABLED
50 #define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL)
51 #define BC_INST_USE_VAL(i) (false)
52 #endif // BC_ENABLED
53 
54 #ifndef NDEBUG
55 #define BC_ENABLE_FUNC_FREE (1)
56 #else // NDEBUG
57 #define BC_ENABLE_FUNC_FREE DC_ENABLED
58 #endif // NDEBUG
59 
60 typedef enum BcInst {
61 
62 #if BC_ENABLED
63 	BC_INST_INC = 0,
64 	BC_INST_DEC,
65 #endif // BC_ENABLED
66 
67 	BC_INST_NEG,
68 	BC_INST_BOOL_NOT,
69 #if BC_ENABLE_EXTRA_MATH
70 	BC_INST_TRUNC,
71 #endif // BC_ENABLE_EXTRA_MATH
72 
73 	BC_INST_POWER,
74 	BC_INST_MULTIPLY,
75 	BC_INST_DIVIDE,
76 	BC_INST_MODULUS,
77 	BC_INST_PLUS,
78 	BC_INST_MINUS,
79 
80 #if BC_ENABLE_EXTRA_MATH
81 	BC_INST_PLACES,
82 
83 	BC_INST_LSHIFT,
84 	BC_INST_RSHIFT,
85 #endif // BC_ENABLE_EXTRA_MATH
86 
87 	BC_INST_REL_EQ,
88 	BC_INST_REL_LE,
89 	BC_INST_REL_GE,
90 	BC_INST_REL_NE,
91 	BC_INST_REL_LT,
92 	BC_INST_REL_GT,
93 
94 	BC_INST_BOOL_OR,
95 	BC_INST_BOOL_AND,
96 
97 #if BC_ENABLED
98 	BC_INST_ASSIGN_POWER,
99 	BC_INST_ASSIGN_MULTIPLY,
100 	BC_INST_ASSIGN_DIVIDE,
101 	BC_INST_ASSIGN_MODULUS,
102 	BC_INST_ASSIGN_PLUS,
103 	BC_INST_ASSIGN_MINUS,
104 #if BC_ENABLE_EXTRA_MATH
105 	BC_INST_ASSIGN_PLACES,
106 	BC_INST_ASSIGN_LSHIFT,
107 	BC_INST_ASSIGN_RSHIFT,
108 #endif // BC_ENABLE_EXTRA_MATH
109 	BC_INST_ASSIGN,
110 
111 	BC_INST_ASSIGN_POWER_NO_VAL,
112 	BC_INST_ASSIGN_MULTIPLY_NO_VAL,
113 	BC_INST_ASSIGN_DIVIDE_NO_VAL,
114 	BC_INST_ASSIGN_MODULUS_NO_VAL,
115 	BC_INST_ASSIGN_PLUS_NO_VAL,
116 	BC_INST_ASSIGN_MINUS_NO_VAL,
117 #if BC_ENABLE_EXTRA_MATH
118 	BC_INST_ASSIGN_PLACES_NO_VAL,
119 	BC_INST_ASSIGN_LSHIFT_NO_VAL,
120 	BC_INST_ASSIGN_RSHIFT_NO_VAL,
121 #endif // BC_ENABLE_EXTRA_MATH
122 #endif // BC_ENABLED
123 	BC_INST_ASSIGN_NO_VAL,
124 
125 	BC_INST_NUM,
126 	BC_INST_VAR,
127 	BC_INST_ARRAY_ELEM,
128 #if BC_ENABLED
129 	BC_INST_ARRAY,
130 #endif // BC_ENABLED
131 
132 	BC_INST_ZERO,
133 	BC_INST_ONE,
134 
135 #if BC_ENABLED
136 	BC_INST_LAST,
137 #endif // BC_ENABLED
138 	BC_INST_IBASE,
139 	BC_INST_OBASE,
140 	BC_INST_SCALE,
141 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
142 	BC_INST_SEED,
143 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
144 	BC_INST_LENGTH,
145 	BC_INST_SCALE_FUNC,
146 	BC_INST_SQRT,
147 	BC_INST_ABS,
148 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
149 	BC_INST_IRAND,
150 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
151 	BC_INST_READ,
152 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
153 	BC_INST_RAND,
154 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
155 	BC_INST_MAXIBASE,
156 	BC_INST_MAXOBASE,
157 	BC_INST_MAXSCALE,
158 #if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
159 	BC_INST_MAXRAND,
160 #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
161 
162 	BC_INST_PRINT,
163 	BC_INST_PRINT_POP,
164 	BC_INST_STR,
165 	BC_INST_PRINT_STR,
166 
167 #if BC_ENABLED
168 	BC_INST_JUMP,
169 	BC_INST_JUMP_ZERO,
170 
171 	BC_INST_CALL,
172 
173 	BC_INST_RET,
174 	BC_INST_RET0,
175 	BC_INST_RET_VOID,
176 
177 	BC_INST_HALT,
178 #endif // BC_ENABLED
179 
180 	BC_INST_POP,
181 
182 #if DC_ENABLED
183 	BC_INST_POP_EXEC,
184 	BC_INST_MODEXP,
185 	BC_INST_DIVMOD,
186 
187 	BC_INST_EXECUTE,
188 	BC_INST_EXEC_COND,
189 
190 	BC_INST_ASCIIFY,
191 	BC_INST_PRINT_STREAM,
192 
193 	BC_INST_PRINT_STACK,
194 	BC_INST_CLEAR_STACK,
195 	BC_INST_STACK_LEN,
196 	BC_INST_DUPLICATE,
197 	BC_INST_SWAP,
198 
199 	BC_INST_LOAD,
200 	BC_INST_PUSH_VAR,
201 	BC_INST_PUSH_TO_VAR,
202 
203 	BC_INST_QUIT,
204 	BC_INST_NQUIT,
205 #endif // DC_ENABLED
206 
207 	BC_INST_INVALID = UCHAR_MAX,
208 
209 } BcInst;
210 
211 typedef struct BcId {
212 	char *name;
213 	size_t idx;
214 } BcId;
215 
216 typedef struct BcLoc {
217 	size_t loc;
218 	size_t idx;
219 } BcLoc;
220 
221 typedef struct BcConst {
222 	char *val;
223 	BcBigDig base;
224 	BcNum num;
225 } BcConst;
226 
227 typedef struct BcFunc {
228 
229 	BcVec code;
230 #if BC_ENABLED
231 	BcVec labels;
232 	BcVec autos;
233 	size_t nparams;
234 #endif // BC_ENABLED
235 
236 	BcVec strs;
237 	BcVec consts;
238 
239 	const char *name;
240 #if BC_ENABLED
241 	bool voidfn;
242 #endif // BC_ENABLED
243 
244 } BcFunc;
245 
246 typedef enum BcResultType {
247 
248 	BC_RESULT_VAR,
249 	BC_RESULT_ARRAY_ELEM,
250 #if BC_ENABLED
251 	BC_RESULT_ARRAY,
252 #endif // BC_ENABLED
253 
254 	BC_RESULT_STR,
255 
256 	BC_RESULT_TEMP,
257 
258 	BC_RESULT_ZERO,
259 	BC_RESULT_ONE,
260 
261 #if BC_ENABLED
262 	BC_RESULT_LAST,
263 	BC_RESULT_VOID,
264 #endif // BC_ENABLED
265 	BC_RESULT_IBASE,
266 	BC_RESULT_OBASE,
267 	BC_RESULT_SCALE,
268 #if BC_ENABLE_EXTRA_MATH
269 	BC_RESULT_SEED,
270 #endif // BC_ENABLE_EXTRA_MATH
271 
272 } BcResultType;
273 
274 typedef union BcResultData {
275 	BcNum n;
276 	BcVec v;
277 	BcLoc loc;
278 } BcResultData;
279 
280 typedef struct BcResult {
281 	BcResultType t;
282 	BcResultData d;
283 } BcResult;
284 
285 typedef struct BcInstPtr {
286 	size_t func;
287 	size_t idx;
288 	size_t len;
289 } BcInstPtr;
290 
291 typedef enum BcType {
292 	BC_TYPE_VAR,
293 	BC_TYPE_ARRAY,
294 #if BC_ENABLED
295 	BC_TYPE_REF,
296 #endif // BC_ENABLED
297 } BcType;
298 
299 struct BcProgram;
300 
301 void bc_func_init(BcFunc *f, const char* name);
302 void bc_func_insert(BcFunc *f, struct BcProgram* p, char* name,
303                     BcType type, size_t line);
304 void bc_func_reset(BcFunc *f);
305 void bc_func_free(void *func);
306 
307 void bc_array_init(BcVec *a, bool nums);
308 void bc_array_copy(BcVec *d, const BcVec *s);
309 
310 void bc_string_free(void *string);
311 void bc_const_free(void *constant);
312 void bc_id_free(void *id);
313 void bc_result_clear(BcResult *r);
314 void bc_result_copy(BcResult *d, BcResult *src);
315 void bc_result_free(void *result);
316 
317 void bc_array_expand(BcVec *a, size_t len);
318 int bc_id_cmp(const BcId *e1, const BcId *e2);
319 
320 #if BC_DEBUG_CODE
321 extern const char* bc_inst_names[];
322 #endif // BC_DEBUG_CODE
323 
324 extern const char bc_func_main[];
325 extern const char bc_func_read[];
326 
327 #endif // BC_LANG_H
328