blob: 457854298881dc97a7fa2a736de971ad585ea84c [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 Howard8f4b2072018-08-02 22:41:29 -060023#include <bc.h>
Gavin Howard29493062018-03-20 19:57:37 -060024#include <status.h>
Gavin Howardf456d372018-03-10 20:11:41 -070025#include <lex.h>
26#include <parse.h>
27
Gavin Howardf6e3fb32018-08-09 13:48:59 -060028const char bc_header[] =
Gavin Howardfb4d4d02018-07-05 18:36:21 -060029 "bc 1.0\n"
Gavin Howard9d8285d2018-03-12 11:56:15 -060030 "bc copyright (c) 2018 Gavin D. Howard and contributors\n"
Gavin Howarda280bde2018-03-13 13:49:12 -060031 "Report bugs at: https://github.com/gavinhoward/bc\n\n"
32 "This is free software with ABSOLUTELY NO WARRANTY.\n\n";
Gavin Howardf456d372018-03-10 20:11:41 -070033
Gavin Howard79ce08b2018-06-21 16:21:55 -060034const char bc_err_fmt[] = "\n%s error: %s\n\n";
35
36const char *bc_errs[] = {
Gavin Howardf456d372018-03-10 20:11:41 -070037 "bc",
Gavin Howardf456d372018-03-10 20:11:41 -070038 "Lex",
Gavin Howard9a65a4e2018-03-15 18:26:57 -060039 "Parse",
40 "Math",
41 "Runtime",
42 "POSIX",
Gavin Howard9a65a4e2018-03-15 18:26:57 -060043};
Gavin Howardf456d372018-03-10 20:11:41 -070044
Gavin Howard79ce08b2018-06-21 16:21:55 -060045const uint8_t bc_err_indices[] = {
Gavin Howard45ff3572018-05-15 16:33:58 -060046 BC_ERR_IDX_BC, BC_ERR_IDX_BC, BC_ERR_IDX_BC, BC_ERR_IDX_BC,
47 BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX,
48 BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
49 BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
50 BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
51 BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
52 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
53 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
54 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
Gavin Howarda0492142018-08-29 15:28:35 -060055 BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
Gavin Howard45ff3572018-05-15 16:33:58 -060056 BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
57 BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
58 BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
Gavin Howarda0492142018-08-29 15:28:35 -060059 BC_ERR_IDX_VEC, BC_ERR_IDX_VEC,
60 BC_ERR_IDX_BC, BC_ERR_IDX_BC, BC_ERR_IDX_BC,
Gavin Howardf456d372018-03-10 20:11:41 -070061};
62
63const char *bc_err_descs[] = {
Gavin Howardf456d372018-03-10 20:11:41 -070064 NULL,
Gavin Howardf456d372018-03-10 20:11:41 -070065 "memory allocation error",
66 "I/O error",
Gavin Howardddaa4c12018-03-24 14:50:12 -060067 "file is not text",
Gavin Howarde77b83d2018-03-29 14:24:26 -060068
69 "bad character",
Gavin Howardf456d372018-03-10 20:11:41 -070070 "string end could not be found",
71 "comment end could not be found",
72 "end of file",
73
Gavin Howardbdb2f922018-03-15 09:25:18 -060074 "bad token",
75 "bad expression",
76 "bad print statement",
77 "bad function definition",
78 "bad assignment: left must be scale, ibase, "
79 "obase, last, var, or array element",
Gavin Howardf456d372018-03-10 20:11:41 -070080 "no auto variable found",
Gavin Howardf456d372018-03-10 20:11:41 -070081 "function parameter or auto var has the same name as another",
Gavin Howardf456d372018-03-10 20:11:41 -070082
83 "negative number",
84 "non integer number",
85 "overflow",
86 "divide by zero",
87 "negative square root",
Gavin Howardbdb2f922018-03-15 09:25:18 -060088 "bad number string",
Gavin Howardf456d372018-03-10 20:11:41 -070089
Gavin Howard27fdfb92018-03-21 07:56:59 -060090 "could not open file",
Gavin Howardf456d372018-03-10 20:11:41 -070091 "mismatched parameters",
92 "undefined function",
Gavin Howardf456d372018-03-10 20:11:41 -070093 "file is not executable",
94 "could not install signal handler",
Gavin Howard293aec92018-03-13 12:29:18 -060095 "bad scale; must be [0, BC_SCALE_MAX]",
96 "bad ibase; must be [2, 16]",
97 "bad obase; must be [2, BC_BASE_MAX]",
Gavin Howardbdb2f922018-03-15 09:25:18 -060098 "string too long: must be [1, BC_STRING_MAX]",
99 "array too long; must be [1, BC_DIM_MAX]",
100 "bad read() expression",
Gavin Howardf456d372018-03-10 20:11:41 -0700101 "read() call inside of a read() call",
Gavin Howardf456d372018-03-10 20:11:41 -0700102 "variable is wrong type",
Gavin Howarda0492142018-08-29 15:28:35 -0600103 "signal caught",
Gavin Howardf456d372018-03-10 20:11:41 -0700104
Gavin Howardbdb2f922018-03-15 09:25:18 -0600105 "POSIX only allows one character names; the following is bad:",
Gavin Howardf456d372018-03-10 20:11:41 -0700106 "POSIX does not allow '#' script comments",
107 "POSIX does not allow the following keyword:",
108 "POSIX does not allow a period ('.') as a shortcut for the last result",
109 "POSIX requires parentheses around return expressions",
Gavin Howardbdb2f922018-03-15 09:25:18 -0600110 "POSIX does not allow boolean operators; the following is bad:",
Gavin Howardf456d372018-03-10 20:11:41 -0700111 "POSIX does not allow comparison operators outside if or loops",
Gavin Howard5aff5042018-03-23 08:08:19 -0600112 "POSIX requires exactly one comparison operator per condition",
Gavin Howardf456d372018-03-10 20:11:41 -0700113 "POSIX does not allow an empty init expression in a for loop",
114 "POSIX does not allow an empty condition expression in a for loop",
115 "POSIX does not allow an empty update expression in a for loop",
116 "POSIX requires the left brace be on the same line as the function header",
Gavin Howarda0492142018-08-29 15:28:35 -0600117
118 "index is out of bounds",
119 "item already exists",
Gavin Howard5f0cf2c2018-08-31 20:22:34 -0600120#ifndef NDEBUG
Gavin Howarda0492142018-08-29 15:28:35 -0600121 "quit request not honored",
122 "limits request not honored",
Gavin Howard5f0cf2c2018-08-31 20:22:34 -0600123#endif
Gavin Howardf456d372018-03-10 20:11:41 -0700124};
125
Gavin Howard67598a72018-06-21 15:04:07 -0600126const char bc_sig_msg[34] = "\ninterrupt (type \"quit\" to exit)\n";
Gavin Howardf456d372018-03-10 20:11:41 -0700127
Gavin Howardff66e292018-03-28 12:47:58 -0600128const char bc_lang_func_main[7] = "(main)";
129const char bc_lang_func_read[7] = "(read)";
130
Gavin Howarde0eec662018-03-29 17:53:20 -0600131#ifndef NDEBUG
Gavin Howardff66e292018-03-28 12:47:58 -0600132const char bc_lang_inst_chars[] =
Gavin Howard375263e2018-09-04 15:10:18 -0600133 "edED_^*/%+-=;?~<>!|&`{}@[],NVMACaI.LlrOqpQsSJjPR$H";
Gavin Howarde0eec662018-03-29 17:53:20 -0600134#endif // NDEBUG
Gavin Howard101b5e62018-03-26 07:46:27 -0600135
Gavin Howardf456d372018-03-10 20:11:41 -0700136const BcLexKeyword bc_lex_keywords[20] = {
Gavin Howard665a9932018-03-26 13:04:58 -0600137 BC_LEX_KW_ENTRY("auto", 4, true),
138 BC_LEX_KW_ENTRY("break", 5, true),
139 BC_LEX_KW_ENTRY("continue", 8, false),
140 BC_LEX_KW_ENTRY("define", 6, true),
141 BC_LEX_KW_ENTRY("else", 4, false),
142 BC_LEX_KW_ENTRY("for", 3, true),
143 BC_LEX_KW_ENTRY("halt", 4, false),
144 BC_LEX_KW_ENTRY("ibase", 5, true),
145 BC_LEX_KW_ENTRY("if", 2, true),
146 BC_LEX_KW_ENTRY("last", 4, false),
147 BC_LEX_KW_ENTRY("length", 6, true),
148 BC_LEX_KW_ENTRY("limits", 6, false),
149 BC_LEX_KW_ENTRY("obase", 5, true),
150 BC_LEX_KW_ENTRY("print", 5, false),
151 BC_LEX_KW_ENTRY("quit", 4, true),
152 BC_LEX_KW_ENTRY("read", 4, false),
153 BC_LEX_KW_ENTRY("return", 6, true),
154 BC_LEX_KW_ENTRY("scale", 5, true),
155 BC_LEX_KW_ENTRY("sqrt", 4, true),
156 BC_LEX_KW_ENTRY("while", 5, true),
Gavin Howardf456d372018-03-10 20:11:41 -0700157};
158
159const char bc_num_hex_digits[] = "0123456789ABCDEF";
160
161// This is an array that corresponds to token types. An entry is
162// true if the token is valid in an expression, false otherwise.
163const bool bc_parse_token_exprs[] = {
Gavin Howard45ff3572018-05-15 16:33:58 -0600164 true, true, true, true, true, true, true, true, true, true, true, true, true,
Gavin Howard5cc65812018-06-21 15:08:45 -0600165 true, true, true, true, true, true, true, true, true, true, true, true, false,
166 false, true, true, false, false, false, false, false, false, false, true,
167 true, false, false, false, false, false, false, false, true, false, true,
Gavin Howard45ff3572018-05-15 16:33:58 -0600168 true, true, true, false, false, true, false, true, true, false, false, false,
Gavin Howardf456d372018-03-10 20:11:41 -0700169};
170
171// This is an array of data for operators that correspond to token types.
Gavin Howardf456d372018-03-10 20:11:41 -0700172const BcOp bc_parse_ops[] = {
Gavin Howard45ff3572018-05-15 16:33:58 -0600173 { 0, false }, { 0, false },
Gavin Howardf456d372018-03-10 20:11:41 -0700174 { 1, false },
Gavin Howardf456d372018-03-10 20:11:41 -0700175 { 2, false },
Gavin Howard45ff3572018-05-15 16:33:58 -0600176 { 3, true }, { 3, true }, { 3, true },
177 { 4, true }, { 4, true },
178 { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true },
Gavin Howardf456d372018-03-10 20:11:41 -0700179 { 7, false },
Gavin Howard45ff3572018-05-15 16:33:58 -0600180 { 8, true }, { 8, true },
Gavin Howard39b64082018-09-02 00:10:18 -0600181 { 5, false }, { 5, false }, { 5, false }, { 5, false }, { 5, false },
182 { 5, false }, { 5, false },
Gavin Howardf456d372018-03-10 20:11:41 -0700183};
184
Gavin Howardce8fb792018-09-04 15:08:36 -0600185const BcNumBinaryOp bc_program_ops[] = {
Gavin Howard45ff3572018-05-15 16:33:58 -0600186 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 -0700187};
188
Gavin Howardff66e292018-03-28 12:47:58 -0600189const char bc_program_stdin_name[] = "<stdin>";
Gavin Howard67598a72018-06-21 15:04:07 -0600190const char bc_program_ready_prompt[] = "ready for more input\n";