blob: dcb278b930ce5da911c10f73d59c76b9f3c9d719 [file] [log] [blame]
/*
* *****************************************************************************
*
* Copyright 2018 Gavin D. Howard
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* *****************************************************************************
*
* Constant data for bc.
*
*/
#include <bc.h>
#include <status.h>
#include <lex.h>
#include <parse.h>
const char bc_header[] =
"bc 1.0\n"
"bc copyright (c) 2018 Gavin D. Howard and contributors\n"
"Report bugs at: https://github.com/gavinhoward/bc\n\n"
"This is free software with ABSOLUTELY NO WARRANTY.\n\n";
const char bc_err_fmt[] = "\n%s error: %s\n\n";
const char bc_err_line[] = ":%d\n\n";
const char *bc_errs[] = {
"bc",
"Lex",
"Parse",
"Math",
"Runtime",
"POSIX",
};
const uint8_t bc_err_indices[] = {
BC_ERR_IDX_BC, BC_ERR_IDX_BC, BC_ERR_IDX_BC, BC_ERR_IDX_BC,
BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX,
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
BC_ERR_IDX_VEC, BC_ERR_IDX_VEC,
BC_ERR_IDX_BC, BC_ERR_IDX_BC, BC_ERR_IDX_BC,
};
const char *bc_err_descs[] = {
NULL,
"memory allocation error",
"I/O error",
"file is not text:",
"bad character",
"string end could not be found",
"comment end could not be found",
"end of file",
"bad token",
"bad expression",
"bad print statement",
"bad function definition",
"bad assignment: left must be scale, ibase, "
"obase, last, var, or array element",
"no auto variable found",
"function parameter or auto var has the same name as another",
"block end could not be found",
"negative number",
"non integer number",
"overflow",
"divide by zero",
"negative square root",
"bad number string",
"could not open file:",
"mismatched parameters",
"undefined function",
"file is not executable:",
"could not install signal handler",
"bad scale; must be [0, BC_SCALE_MAX]",
"bad ibase; must be [2, 16]",
"bad obase; must be [2, BC_BASE_MAX]",
"number too long: must be [1, BC_NUM_MAX]",
"name too long: must be [1, BC_NAME_MAX]",
"string too long: must be [1, BC_STRING_MAX]",
"array too long; must be [1, BC_DIM_MAX]",
"bad read() expression",
"read() call inside of a read() call",
"variable is wrong type",
"signal caught",
"POSIX only allows one character names; the following is bad:",
"POSIX does not allow '#' script comments",
"POSIX does not allow the following keyword:",
"POSIX does not allow a period ('.') as a shortcut for the last result",
"POSIX requires parentheses around return expressions",
"POSIX does not allow boolean operators; the following is bad:",
"POSIX does not allow comparison operators outside if or loops",
"POSIX requires exactly one comparison operator per condition",
"POSIX does not allow an empty init expression in a for loop",
"POSIX does not allow an empty condition expression in a for loop",
"POSIX does not allow an empty update expression in a for loop",
"POSIX requires the left brace be on the same line as the function header",
"index is out of bounds",
"item already exists",
#ifndef NDEBUG
"quit request not honored",
"limits request not honored",
#endif // NDEBUG
};
const char bc_sig_msg[34] = "\ninterrupt (type \"quit\" to exit)\n";
const char bc_lang_func_main[7] = "(main)";
const char bc_lang_func_read[7] = "(read)";
#ifndef NDEBUG
const char bc_lang_inst_chars[] =
"edED_^*/%+-=;?~<>!|&`{}@[],NVMACaI.LlrOqpQsSJjPR$H";
#endif // NDEBUG
const BcLexKeyword bc_lex_keywords[20] = {
BC_LEX_KW_ENTRY("auto", 4, true),
BC_LEX_KW_ENTRY("break", 5, true),
BC_LEX_KW_ENTRY("continue", 8, false),
BC_LEX_KW_ENTRY("define", 6, true),
BC_LEX_KW_ENTRY("else", 4, false),
BC_LEX_KW_ENTRY("for", 3, true),
BC_LEX_KW_ENTRY("halt", 4, false),
BC_LEX_KW_ENTRY("ibase", 5, true),
BC_LEX_KW_ENTRY("if", 2, true),
BC_LEX_KW_ENTRY("last", 4, false),
BC_LEX_KW_ENTRY("length", 6, true),
BC_LEX_KW_ENTRY("limits", 6, false),
BC_LEX_KW_ENTRY("obase", 5, true),
BC_LEX_KW_ENTRY("print", 5, false),
BC_LEX_KW_ENTRY("quit", 4, true),
BC_LEX_KW_ENTRY("read", 4, false),
BC_LEX_KW_ENTRY("return", 6, true),
BC_LEX_KW_ENTRY("scale", 5, true),
BC_LEX_KW_ENTRY("sqrt", 4, true),
BC_LEX_KW_ENTRY("while", 5, true),
};
const char bc_num_hex_digits[] = "0123456789ABCDEF";
// This is an array that corresponds to token types. An entry is
// true if the token is valid in an expression, false otherwise.
const bool bc_parse_token_exprs[] = {
true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, false,
false, true, true, false, false, false, false, false, false, false, true,
true, false, false, false, false, false, false, false, true, false, true,
true, true, true, false, false, true, false, true, true, false, false, false,
};
// These are to identify what tokens can
// come after expressions in certain cases.
const BcNext bc_parse_next_expr =
BC_PARSE_NEXT(3, BC_LEX_NEWLINE, BC_LEX_SEMICOLON, BC_LEX_RIGHT_BRACE);
const BcNext bc_parse_next_param =
BC_PARSE_NEXT(2, BC_LEX_RIGHT_PAREN, BC_LEX_COMMA);
const BcNext bc_parse_next_print =
BC_PARSE_NEXT(3, BC_LEX_COMMA, BC_LEX_NEWLINE, BC_LEX_SEMICOLON);
const BcNext bc_parse_next_cond = BC_PARSE_NEXT(1, BC_LEX_RIGHT_PAREN);
const BcNext bc_parse_next_elem = BC_PARSE_NEXT(1, BC_LEX_RIGHT_BRACKET);
const BcNext bc_parse_next_for = BC_PARSE_NEXT(1, BC_LEX_SEMICOLON);
const BcNext bc_parse_next_read = BC_PARSE_NEXT(1, BC_LEX_NEWLINE);
// This is an array of data for operators that correspond to token types.
const BcOp bc_parse_ops[] = {
{ 0, false }, { 0, false },
{ 1, false },
{ 2, false },
{ 3, true }, { 3, true }, { 3, true },
{ 4, true }, { 4, true },
{ 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true }, { 6, true },
{ 1, false },
{ 7, true }, { 7, true },
{ 5, false }, { 5, false }, { 5, false }, { 5, false }, { 5, false },
{ 5, false }, { 5, false },
};
const BcNumBinaryOp bc_program_ops[] = {
bc_num_pow, bc_num_mul, bc_num_div, bc_num_mod, bc_num_add, bc_num_sub,
};
const char bc_program_stdin_name[] = "<stdin>";
const char bc_program_ready_prompt[] = "ready for more input\n";