blob: 330cca25f248c4a8387dedde75e1278e56f7f0a7 [file] [log] [blame]
Gavin Howardf456d372018-03-10 20:11:41 -07001/*
2 * *****************************************************************************
3 *
4 * Copyright 2018 Gavin D. Howard
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 *
17 * *****************************************************************************
18 *
19 * Constant data for bc.
20 *
21 */
22
Gavin Howard29493062018-03-20 19:57:37 -060023#include <status.h>
Gavin Howardf456d372018-03-10 20:11:41 -070024#include <lex.h>
25#include <parse.h>
26
Gavin Howarda280bde2018-03-13 13:49:12 -060027const char *bc_header =
Gavin Howard8495fe22018-03-24 15:09:59 -060028 "bc 0.5\n"
Gavin Howard9d8285d2018-03-12 11:56:15 -060029 "bc copyright (c) 2018 Gavin D. Howard and contributors\n"
Gavin Howarda280bde2018-03-13 13:49:12 -060030 "Report bugs at: https://github.com/gavinhoward/bc\n\n"
31 "This is free software with ABSOLUTELY NO WARRANTY.\n\n";
Gavin Howardf456d372018-03-10 20:11:41 -070032
33const char *bc_err_types[] = {
Gavin Howardf456d372018-03-10 20:11:41 -070034 "bc",
Gavin Howardf456d372018-03-10 20:11:41 -070035 "Lex",
Gavin Howard9a65a4e2018-03-15 18:26:57 -060036 "Parse",
37 "Math",
38 "Runtime",
39 "POSIX",
Gavin Howard9a65a4e2018-03-15 18:26:57 -060040};
Gavin Howardf456d372018-03-10 20:11:41 -070041
Gavin Howard431435b2018-03-17 08:08:54 -060042const uint8_t bc_err_type_indices[] = {
Gavin Howardf456d372018-03-10 20:11:41 -070043
Gavin Howard9a65a4e2018-03-15 18:26:57 -060044 BC_ERR_IDX_BC,
Gavin Howard9a65a4e2018-03-15 18:26:57 -060045 BC_ERR_IDX_BC,
46 BC_ERR_IDX_BC,
Gavin Howarde77b83d2018-03-29 14:24:26 -060047 BC_ERR_IDX_BC,
Gavin Howard9a65a4e2018-03-15 18:26:57 -060048
Gavin Howard9a65a4e2018-03-15 18:26:57 -060049 BC_ERR_IDX_LEX,
50 BC_ERR_IDX_LEX,
51 BC_ERR_IDX_LEX,
52 BC_ERR_IDX_LEX,
53
54 BC_ERR_IDX_PARSE,
55 BC_ERR_IDX_PARSE,
56 BC_ERR_IDX_PARSE,
57 BC_ERR_IDX_PARSE,
58 BC_ERR_IDX_PARSE,
59 BC_ERR_IDX_PARSE,
60 BC_ERR_IDX_PARSE,
Gavin Howard9a65a4e2018-03-15 18:26:57 -060061
62 BC_ERR_IDX_MATH,
63 BC_ERR_IDX_MATH,
64 BC_ERR_IDX_MATH,
65 BC_ERR_IDX_MATH,
66 BC_ERR_IDX_MATH,
67 BC_ERR_IDX_MATH,
Gavin Howard9a65a4e2018-03-15 18:26:57 -060068
69 BC_ERR_IDX_EXEC,
70 BC_ERR_IDX_EXEC,
71 BC_ERR_IDX_EXEC,
72 BC_ERR_IDX_EXEC,
73 BC_ERR_IDX_EXEC,
74 BC_ERR_IDX_EXEC,
75 BC_ERR_IDX_EXEC,
76 BC_ERR_IDX_EXEC,
77 BC_ERR_IDX_EXEC,
78 BC_ERR_IDX_EXEC,
79 BC_ERR_IDX_EXEC,
80 BC_ERR_IDX_EXEC,
81 BC_ERR_IDX_EXEC,
Gavin Howard9a65a4e2018-03-15 18:26:57 -060082
83 BC_ERR_IDX_POSIX,
84 BC_ERR_IDX_POSIX,
85 BC_ERR_IDX_POSIX,
86 BC_ERR_IDX_POSIX,
87 BC_ERR_IDX_POSIX,
88 BC_ERR_IDX_POSIX,
89 BC_ERR_IDX_POSIX,
90 BC_ERR_IDX_POSIX,
91 BC_ERR_IDX_POSIX,
92 BC_ERR_IDX_POSIX,
93 BC_ERR_IDX_POSIX,
94 BC_ERR_IDX_POSIX,
Gavin Howardf456d372018-03-10 20:11:41 -070095
96};
97
98const char *bc_err_descs[] = {
99
100 NULL,
Gavin Howardf456d372018-03-10 20:11:41 -0700101 "memory allocation error",
102 "I/O error",
Gavin Howardddaa4c12018-03-24 14:50:12 -0600103 "file is not text",
Gavin Howarde77b83d2018-03-29 14:24:26 -0600104
105 "bad character",
Gavin Howardf456d372018-03-10 20:11:41 -0700106 "string end could not be found",
107 "comment end could not be found",
108 "end of file",
109
Gavin Howardbdb2f922018-03-15 09:25:18 -0600110 "bad token",
111 "bad expression",
112 "bad print statement",
113 "bad function definition",
114 "bad assignment: left must be scale, ibase, "
115 "obase, last, var, or array element",
Gavin Howardf456d372018-03-10 20:11:41 -0700116 "no auto variable found",
Gavin Howardf456d372018-03-10 20:11:41 -0700117 "function parameter or auto var has the same name as another",
Gavin Howardf456d372018-03-10 20:11:41 -0700118
119 "negative number",
120 "non integer number",
121 "overflow",
122 "divide by zero",
123 "negative square root",
Gavin Howardbdb2f922018-03-15 09:25:18 -0600124 "bad number string",
Gavin Howardf456d372018-03-10 20:11:41 -0700125
Gavin Howard27fdfb92018-03-21 07:56:59 -0600126 "could not open file",
Gavin Howardf456d372018-03-10 20:11:41 -0700127 "mismatched parameters",
128 "undefined function",
Gavin Howardf456d372018-03-10 20:11:41 -0700129 "file is not executable",
130 "could not install signal handler",
Gavin Howard293aec92018-03-13 12:29:18 -0600131 "bad scale; must be [0, BC_SCALE_MAX]",
132 "bad ibase; must be [2, 16]",
133 "bad obase; must be [2, BC_BASE_MAX]",
Gavin Howardbdb2f922018-03-15 09:25:18 -0600134 "string too long: must be [1, BC_STRING_MAX]",
135 "array too long; must be [1, BC_DIM_MAX]",
136 "bad read() expression",
Gavin Howardf456d372018-03-10 20:11:41 -0700137 "read() call inside of a read() call",
Gavin Howardf456d372018-03-10 20:11:41 -0700138 "variable is wrong type",
Gavin Howardf456d372018-03-10 20:11:41 -0700139
Gavin Howardbdb2f922018-03-15 09:25:18 -0600140 "POSIX only allows one character names; the following is bad:",
Gavin Howardf456d372018-03-10 20:11:41 -0700141 "POSIX does not allow '#' script comments",
142 "POSIX does not allow the following keyword:",
143 "POSIX does not allow a period ('.') as a shortcut for the last result",
144 "POSIX requires parentheses around return expressions",
Gavin Howardbdb2f922018-03-15 09:25:18 -0600145 "POSIX does not allow boolean operators; the following is bad:",
Gavin Howardf456d372018-03-10 20:11:41 -0700146 "POSIX does not allow comparison operators outside if or loops",
Gavin Howard5aff5042018-03-23 08:08:19 -0600147 "POSIX requires exactly one comparison operator per condition",
Gavin Howardf456d372018-03-10 20:11:41 -0700148 "POSIX does not allow an empty init expression in a for loop",
149 "POSIX does not allow an empty condition expression in a for loop",
150 "POSIX does not allow an empty update expression in a for loop",
151 "POSIX requires the left brace be on the same line as the function header",
152
153};
154
Gavin Howardff66e292018-03-28 12:47:58 -0600155const char bc_sig_msg[36] = "\n\ninterrupt (type \"quit\" to exit)\n\n";
Gavin Howardf456d372018-03-10 20:11:41 -0700156
Gavin Howardff66e292018-03-28 12:47:58 -0600157const char bc_lang_func_main[7] = "(main)";
158const char bc_lang_func_read[7] = "(read)";
159
Gavin Howarde0eec662018-03-29 17:53:20 -0600160#ifndef NDEBUG
Gavin Howardff66e292018-03-28 12:47:58 -0600161const char bc_lang_inst_chars[] =
Gavin Howarde0eec662018-03-29 17:53:20 -0600162 "edED_^*/%+-=;?~<>!|&`{}@[],NVACaI.LlrOqpQsSJjPR$H";
163#endif // NDEBUG
Gavin Howard101b5e62018-03-26 07:46:27 -0600164
Gavin Howardf456d372018-03-10 20:11:41 -0700165const BcLexKeyword bc_lex_keywords[20] = {
Gavin Howard665a9932018-03-26 13:04:58 -0600166 BC_LEX_KW_ENTRY("auto", 4, true),
167 BC_LEX_KW_ENTRY("break", 5, true),
168 BC_LEX_KW_ENTRY("continue", 8, false),
169 BC_LEX_KW_ENTRY("define", 6, true),
170 BC_LEX_KW_ENTRY("else", 4, false),
171 BC_LEX_KW_ENTRY("for", 3, true),
172 BC_LEX_KW_ENTRY("halt", 4, false),
173 BC_LEX_KW_ENTRY("ibase", 5, true),
174 BC_LEX_KW_ENTRY("if", 2, true),
175 BC_LEX_KW_ENTRY("last", 4, false),
176 BC_LEX_KW_ENTRY("length", 6, true),
177 BC_LEX_KW_ENTRY("limits", 6, false),
178 BC_LEX_KW_ENTRY("obase", 5, true),
179 BC_LEX_KW_ENTRY("print", 5, false),
180 BC_LEX_KW_ENTRY("quit", 4, true),
181 BC_LEX_KW_ENTRY("read", 4, false),
182 BC_LEX_KW_ENTRY("return", 6, true),
183 BC_LEX_KW_ENTRY("scale", 5, true),
184 BC_LEX_KW_ENTRY("sqrt", 4, true),
185 BC_LEX_KW_ENTRY("while", 5, true),
Gavin Howardf456d372018-03-10 20:11:41 -0700186};
187
188const char bc_num_hex_digits[] = "0123456789ABCDEF";
189
190// This is an array that corresponds to token types. An entry is
191// true if the token is valid in an expression, false otherwise.
192const bool bc_parse_token_exprs[] = {
193
194 true,
195 true,
196
197 true,
198
199 true,
200 true,
201 true,
202
203 true,
204 true,
205
206 true,
207 true,
208 true,
209 true,
210 true,
211 true,
212 true,
213
214 true,
215 true,
216 true,
217 true,
218 true,
219 true,
220
221 true,
222
223 true,
224 true,
225
226 true,
227
228 false,
229
230 false,
231
232 true,
233 true,
234
235 false,
236 false,
237
238 false,
239 false,
240
241 false,
242 false,
243
244 false,
245 true,
246 true,
247
248 false,
249 false,
250 false,
251 false,
252 false,
253 false,
254 false,
255 true,
256 false,
257 true,
258 true,
259 true,
260 true,
261 false,
262 false,
263 true,
264 false,
265 true,
266 true,
267 false,
268
269 false,
270
271 false,
272};
273
274// This is an array of data for operators that correspond to token types.
275// The last corresponds to BC_PARSE_OP_NEGATE_IDX since it doesn't have
276// its own token type (it is the same token at the binary minus operator).
277const BcOp bc_parse_ops[] = {
278
279 { 0, false },
280 { 0, false },
281
282 { 1, false },
283
284 { 2, false },
285
286 { 3, true },
287 { 3, true },
288 { 3, true },
289
290 { 4, true },
291 { 4, true },
292
293 { 6, true },
294 { 6, true },
295 { 6, true },
296 { 6, true },
297 { 6, true },
298 { 6, true },
299
300 { 7, false },
301
302 { 8, true },
303 { 8, true },
304
305 { 5, false },
306 { 5, false },
307 { 5, false },
308 { 5, false },
309 { 5, false },
310 { 5, false },
311 { 5, false },
312
313};
314
Gavin Howardff66e292018-03-28 12:47:58 -0600315const char bc_program_byte_fmt[] = "%02x";
Gavin Howardf456d372018-03-10 20:11:41 -0700316
317const BcNumBinaryFunc bc_program_math_ops[] = {
318
Gavin Howard101b5e62018-03-26 07:46:27 -0600319 bc_num_pow,
Gavin Howardf456d372018-03-10 20:11:41 -0700320 bc_num_mul,
Gavin Howardf456d372018-03-10 20:11:41 -0700321 bc_num_div,
Gavin Howard101b5e62018-03-26 07:46:27 -0600322 bc_num_mod,
323 bc_num_add,
324 bc_num_sub,
Gavin Howardf456d372018-03-10 20:11:41 -0700325
326};
327
Gavin Howardff66e292018-03-28 12:47:58 -0600328const char bc_program_stdin_name[] = "<stdin>";
329const char bc_program_ready_prompt[] = "ready for more input\n\n";