blob: 2ce5f9becf21446a8d09f4a560d536b69733a155 [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 Howardf456d372018-03-10 20:11:41 -070023#include <lex.h>
24#include <parse.h>
Gavin Howardd2a05252018-09-27 14:00:40 -060025#include <num.h>
Gavin Howardf456d372018-03-10 20:11:41 -070026
Gavin Howard4ffe5a92018-09-26 20:58:31 -060027const char bc_name[] = "bc";
28const char dc_name[] = "dc";
29
Gavin Howard86fb8d32018-09-25 18:00:06 -060030const char bc_header[] =
Gavin Howard73527d22018-09-25 17:43:34 -060031 "bc 1.0\n"
Gavin Howardcdcae372018-09-26 16:49:04 -060032 "Copyright (c) 2018 Gavin D. Howard and contributors\n"
Gavin Howard73527d22018-09-25 17:43:34 -060033 "Report bugs at: https://github.com/gavinhoward/bc\n\n"
Gavin Howard41044032018-09-27 10:49:51 -060034 "This is free software with ABSOLUTELY NO WARRANTY.\n";
Gavin Howardf456d372018-03-10 20:11:41 -070035
Gavin Howard79ce08b2018-06-21 16:21:55 -060036const char bc_err_fmt[] = "\n%s error: %s\n\n";
Gavin Howard60183832018-09-04 22:43:44 -060037const char bc_err_line[] = ":%d\n\n";
Gavin Howard79ce08b2018-06-21 16:21:55 -060038
39const char *bc_errs[] = {
Gavin Howard73527d22018-09-25 17:43:34 -060040 "VM",
41 "Lex",
42 "Parse",
43 "Math",
44 "Runtime",
45 "POSIX",
Gavin Howard9a65a4e2018-03-15 18:26:57 -060046};
Gavin Howardf456d372018-03-10 20:11:41 -070047
Gavin Howard79ce08b2018-06-21 16:21:55 -060048const uint8_t bc_err_indices[] = {
Gavin Howard73527d22018-09-25 17:43:34 -060049 BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM,
50 BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX,
51 BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
52 BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
53 BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
54 BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
55 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
56 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
57 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
58 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
59 BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
60 BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
61 BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
62 BC_ERR_IDX_VEC, BC_ERR_IDX_VEC,
63 BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM,
Gavin Howardf456d372018-03-10 20:11:41 -070064};
65
66const char *bc_err_descs[] = {
Gavin Howard0790bca2018-09-22 19:44:35 -060067
Gavin Howard73527d22018-09-25 17:43:34 -060068 NULL,
69 "memory allocation error",
70 "I/O error",
71 "file is not text:",
Gavin Howarde77b83d2018-03-29 14:24:26 -060072
Gavin Howard73527d22018-09-25 17:43:34 -060073 "bad character",
74 "string end could not be found",
75 "comment end could not be found",
76 "end of file",
Gavin Howardf456d372018-03-10 20:11:41 -070077
Gavin Howard73527d22018-09-25 17:43:34 -060078 "bad token",
79 "bad expression",
80 "bad print statement",
81 "bad function definition",
82 "bad assignment: left side must be scale, ibase, "
83 "obase, last, var, or array element",
84 "no auto variable found",
85 "function parameter or auto var has the same name as another",
86 "block end could not be found",
Gavin Howardf456d372018-03-10 20:11:41 -070087
Gavin Howard73527d22018-09-25 17:43:34 -060088 "negative number",
89 "non integer number",
90 "overflow",
91 "divide by zero",
92 "negative square root",
93 "bad number string",
Gavin Howardf456d372018-03-10 20:11:41 -070094
Gavin Howard73527d22018-09-25 17:43:34 -060095 "could not open file:",
96 "mismatched parameters",
97 "undefined function",
98 "file is not executable:",
99 "could not install signal handler",
100 "bad scale; must be [0, BC_SCALE_MAX]",
101 "bad ibase; must be [2, 16]",
102 "bad obase; must be [2, BC_BASE_MAX]",
103 "number too long: must be [1, BC_NUM_MAX]",
104 "name too long: must be [1, BC_NAME_MAX]",
105 "string too long: must be [1, BC_STRING_MAX]",
106 "array too long; must be [1, BC_DIM_MAX]",
107 "bad read() expression",
108 "read() call inside of a read() call",
109 "variable is wrong type",
110 "signal caught",
Gavin Howardf456d372018-03-10 20:11:41 -0700111
Gavin Howard73527d22018-09-25 17:43:34 -0600112 "POSIX only allows one character names; the following is bad:",
113 "POSIX does not allow '#' script comments",
114 "POSIX does not allow the following keyword:",
115 "POSIX does not allow a period ('.') as a shortcut for the last result",
116 "POSIX requires parentheses around return expressions",
117 "POSIX does not allow boolean operators; the following is bad:",
118 "POSIX does not allow comparison operators outside if or loops",
119 "POSIX requires exactly one comparison operator per condition",
120 "POSIX does not allow an empty init expression in a for loop",
121 "POSIX does not allow an empty condition expression in a for loop",
122 "POSIX does not allow an empty update expression in a for loop",
123 "POSIX requires the left brace be on the same line as the function header",
Gavin Howarda0492142018-08-29 15:28:35 -0600124
Gavin Howard73527d22018-09-25 17:43:34 -0600125 "index is out of bounds",
126 "item already exists",
Gavin Howard5f0cf2c2018-08-31 20:22:34 -0600127#ifndef NDEBUG
Gavin Howard73527d22018-09-25 17:43:34 -0600128 "quit request not honored",
129 "limits request not honored",
Gavin Howardc3a66802018-09-04 16:53:26 -0600130#endif // NDEBUG
Gavin Howard0790bca2018-09-22 19:44:35 -0600131
Gavin Howardf456d372018-03-10 20:11:41 -0700132};
133
Gavin Howard67598a72018-06-21 15:04:07 -0600134const char bc_sig_msg[34] = "\ninterrupt (type \"quit\" to exit)\n";
Gavin Howardf456d372018-03-10 20:11:41 -0700135
Gavin Howardf4a74ee2018-09-24 15:32:52 -0600136const char bc_lang_func_main[] = "(main)";
137const char bc_lang_func_read[] = "(read)";
Gavin Howardff66e292018-03-28 12:47:58 -0600138
Gavin Howarde0eec662018-03-29 17:53:20 -0600139#ifndef NDEBUG
Gavin Howardff66e292018-03-28 12:47:58 -0600140const char bc_lang_inst_chars[] =
Gavin Howard73527d22018-09-25 17:43:34 -0600141 "edED_^*/%+-=;?~<>!|&`{}@[],NVMACaI.LlrOqpQsSJjPR$H";
Gavin Howarde0eec662018-03-29 17:53:20 -0600142#endif // NDEBUG
Gavin Howard101b5e62018-03-26 07:46:27 -0600143
Gavin Howard63738202018-09-26 15:34:20 -0600144const BcLexKeyword bc_lex_kws[20] = {
Gavin Howard73527d22018-09-25 17:43:34 -0600145 BC_LEX_KW_ENTRY("auto", 4, true),
146 BC_LEX_KW_ENTRY("break", 5, true),
147 BC_LEX_KW_ENTRY("continue", 8, false),
148 BC_LEX_KW_ENTRY("define", 6, true),
149 BC_LEX_KW_ENTRY("else", 4, false),
150 BC_LEX_KW_ENTRY("for", 3, true),
151 BC_LEX_KW_ENTRY("halt", 4, false),
152 BC_LEX_KW_ENTRY("ibase", 5, true),
153 BC_LEX_KW_ENTRY("if", 2, true),
154 BC_LEX_KW_ENTRY("last", 4, false),
155 BC_LEX_KW_ENTRY("length", 6, true),
156 BC_LEX_KW_ENTRY("limits", 6, false),
157 BC_LEX_KW_ENTRY("obase", 5, true),
158 BC_LEX_KW_ENTRY("print", 5, false),
159 BC_LEX_KW_ENTRY("quit", 4, true),
160 BC_LEX_KW_ENTRY("read", 4, false),
161 BC_LEX_KW_ENTRY("return", 6, true),
162 BC_LEX_KW_ENTRY("scale", 5, true),
163 BC_LEX_KW_ENTRY("sqrt", 4, true),
164 BC_LEX_KW_ENTRY("while", 5, true),
Gavin Howardf456d372018-03-10 20:11:41 -0700165};
166
167const char bc_num_hex_digits[] = "0123456789ABCDEF";
168
169// This is an array that corresponds to token types. An entry is
170// true if the token is valid in an expression, false otherwise.
171const bool bc_parse_token_exprs[] = {
Gavin Howard73527d22018-09-25 17:43:34 -0600172 true, true, true, true, true, true, true, true, true, true, true, true, true,
173 true, true, true, true, true, true, true, true, true, true, true, true, false,
174 false, true, true, false, false, false, false, false, false, false, true,
175 true, false, false, false, false, false, false, false, true, false, true,
176 true, true, true, false, false, true, false, true, true, false, false, false,
Gavin Howardf456d372018-03-10 20:11:41 -0700177};
178
Gavin Howarde56e9182018-09-12 17:22:09 -0600179// These are to identify what tokens can
180// come after expressions in certain cases.
Gavin Howard4c2ec1b2018-09-24 19:57:40 -0600181const BcParseNext bc_parse_next_expr =
Gavin Howard63738202018-09-26 15:34:20 -0600182 BC_PARSE_NEXT(3, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_RBRACE);
Gavin Howard4c2ec1b2018-09-24 19:57:40 -0600183const BcParseNext bc_parse_next_param =
Gavin Howard63738202018-09-26 15:34:20 -0600184 BC_PARSE_NEXT(2, BC_LEX_RPAREN, BC_LEX_COMMA);
Gavin Howard4c2ec1b2018-09-24 19:57:40 -0600185const BcParseNext bc_parse_next_print =
Gavin Howard63738202018-09-26 15:34:20 -0600186 BC_PARSE_NEXT(3, BC_LEX_COMMA, BC_LEX_NLINE, BC_LEX_SCOLON);
187const BcParseNext bc_parse_next_cond = BC_PARSE_NEXT(1, BC_LEX_RPAREN);
188const BcParseNext bc_parse_next_elem = BC_PARSE_NEXT(1, BC_LEX_RBRACKET);
189const BcParseNext bc_parse_next_for = BC_PARSE_NEXT(1, BC_LEX_SCOLON);
190const BcParseNext bc_parse_next_read = BC_PARSE_NEXT(1, BC_LEX_NLINE);
Gavin Howard79be14a2018-09-12 16:39:27 -0600191
Gavin Howardf456d372018-03-10 20:11:41 -0700192// This is an array of data for operators that correspond to token types.
Gavin Howardf456d372018-03-10 20:11:41 -0700193const BcOp bc_parse_ops[] = {
Gavin Howard73527d22018-09-25 17:43:34 -0600194 { 0, false }, { 0, false },
195 { 1, false },
196 { 2, false },
197 { 3, true }, { 3, true }, { 3, true },
198 { 4, true }, { 4, true },
199 { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true },
200 { 1, false },
201 { 7, true }, { 7, true },
202 { 5, false }, { 5, false }, { 5, false }, { 5, false }, { 5, false },
203 { 5, false }, { 5, false },
Gavin Howardf456d372018-03-10 20:11:41 -0700204};
205
Gavin Howardce8fb792018-09-04 15:08:36 -0600206const BcNumBinaryOp bc_program_ops[] = {
Gavin Howard73527d22018-09-25 17:43:34 -0600207 bc_num_pow, bc_num_mul, bc_num_div, bc_num_mod, bc_num_add, bc_num_sub,
Gavin Howardf456d372018-03-10 20:11:41 -0700208};
209
Gavin Howardff66e292018-03-28 12:47:58 -0600210const char bc_program_stdin_name[] = "<stdin>";
Gavin Howard63738202018-09-26 15:34:20 -0600211const char bc_program_ready_msg[] = "ready for more input\n";