aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorGavin Howard <gavin@yzena.com>2021-07-21 00:18:02 -0600
committerGavin Howard <gavin@yzena.com>2021-07-21 00:18:02 -0600
commitf7b06df01207fbc3e214d45e8a77abd6a047b152 (patch)
treeab56ab9a0a2a85139745b6f30831ed051dd47ba2 /src/data.c
parentf4e36d5707c0857f1761b85b4187c1c2d85c1771 (diff)
downloadplatform_external_bc-f7b06df01207fbc3e214d45e8a77abd6a047b152.tar.gz
platform_external_bc-f7b06df01207fbc3e214d45e8a77abd6a047b152.tar.bz2
platform_external_bc-f7b06df01207fbc3e214d45e8a77abd6a047b152.zip
Add modexp and divmod to bc
Might as well. Signed-off-by: Gavin Howard <gavin@yzena.com>
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/src/data.c b/src/data.c
index e2461b13..fe61a711 100644
--- a/src/data.c
+++ b/src/data.c
@@ -825,7 +825,7 @@ const char bc_parse_one[2] = "1";
#if BC_ENABLED
-/// A list of keywords for bc.
+/// A list of keywords for bc. This needs to be updated if keywords change.
const BcLexKeyword bc_lex_kws[] = {
BC_LEX_KW_ENTRY("auto", 4, true),
BC_LEX_KW_ENTRY("break", 5, true),
@@ -851,6 +851,8 @@ const BcLexKeyword bc_lex_kws[] = {
#if BC_ENABLE_EXTRA_MATH
BC_LEX_KW_ENTRY("irand", 5, false),
#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_ENTRY("modexp", 6, false),
+ BC_LEX_KW_ENTRY("divmod", 6, false),
BC_LEX_KW_ENTRY("quit", 4, true),
BC_LEX_KW_ENTRY("read", 4, false),
#if BC_ENABLE_EXTRA_MATH
@@ -880,25 +882,64 @@ static_assert(sizeof(bc_lex_kws) / sizeof(BcLexKeyword) == BC_LEX_NKWS,
#endif // BC_C11
/// An array of booleans that correspond to token types. An entry is true if the
-/// token is valid in an expression, false otherwise.
+/// token is valid in an expression, false otherwise. This will need to change
+/// if tokens change.
const uint8_t bc_parse_exprs[] = {
+
+ // Starts with BC_LEX_EOF.
BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_OP_MULTIPLY if extra math is enabled, BC_LEX_OP_DIVIDE
+ // otherwise.
BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_OP_REL_EQ if extra math is enabled, BC_LEX_OP_REL_LT
+ // otherwise.
BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
#if BC_ENABLE_EXTRA_MATH
+
+ // Starts with BC_LEX_OP_ASSIGN_POWER.
BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_OP_ASSIGN_RSHIFT.
BC_PARSE_EXPR_ENTRY(true, true, false, false, true, true, false, false),
+
+ // Starts with BC_LEX_RBRACKET.
BC_PARSE_EXPR_ENTRY(false, false, false, false, false, true, true, false),
+
+ // Starts with BC_LEX_KW_BREAK.
BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+
+ // Starts with BC_LEX_KW_HALT.
BC_PARSE_EXPR_ENTRY(false, true, true, true, true, true, true, false),
- BC_PARSE_EXPR_ENTRY(true, true, true, false, true, true, true, true),
- BC_PARSE_EXPR_ENTRY(true, true, false, 0, 0, 0, 0, 0)
+
+ // Starts with BC_LEX_KW_SQRT.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, false, true, true),
+
+ // Starts with BC_LEX_KW_MAXIBASE.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, false, 0, 0, 0)
+
#else // BC_ENABLE_EXTRA_MATH
+
+ // Starts with BC_LEX_OP_ASSIGN_PLUS.
BC_PARSE_EXPR_ENTRY(true, true, true, false, false, true, true, false),
+
+ // Starts with BC_LEX_COMMA.
BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, true, true),
+
+ // Starts with BC_LEX_KW_AUTO.
BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+
+ // Starts with BC_LEX_KW_WHILE.
BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, false),
- BC_PARSE_EXPR_ENTRY(true, true, false, true, true, true, true, false)
+
+ // Starts with BC_LEX_KW_SQRT.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, false, true, true, true),
+
+ // Starts with BC_LEX_KW_MAXSCALE,
+ BC_PARSE_EXPR_ENTRY(true, false, 0, 0, 0, 0, 0, 0)
+
#endif // BC_ENABLE_EXTRA_MATH
};
@@ -959,6 +1000,11 @@ const BcParseNext bc_parse_next_for = BC_PARSE_NEXT(1, BC_LEX_SCOLON);
/// The valid next tokens for read expressions.
const BcParseNext bc_parse_next_read =
BC_PARSE_NEXT(2, BC_LEX_NLINE, BC_LEX_EOF);
+
+/// The valid next tokens for the arguments of a builtin function with multiple
+/// arguments.
+const BcParseNext bc_parse_next_builtin = BC_PARSE_NEXT(1, BC_LEX_COMMA);
+
#endif // BC_ENABLED
#if DC_ENABLED
@@ -977,7 +1023,8 @@ const size_t dc_lex_regs_len = sizeof(dc_lex_regs) / sizeof(uint8_t);
/// A list corresponding to characters starting at double quote ("). If an entry
/// is BC_LEX_INVALID, then that character needs extra lexing in dc. If it does
/// not, the character can trivially be replaced by the entry. Positions are
-/// kept because it corresponds to the ASCII table.
+/// kept because it corresponds to the ASCII table. This may need to be changed
+/// if tokens change.
const uchar dc_lex_tokens[] = {
#if BC_ENABLE_EXTRA_MATH
BC_LEX_KW_IRAND,
@@ -1051,13 +1098,14 @@ const uchar dc_lex_tokens[] = {
BC_LEX_KW_QUIT, BC_LEX_SWAP, BC_LEX_OP_ASSIGN, BC_LEX_INVALID,
BC_LEX_INVALID, BC_LEX_KW_SQRT, BC_LEX_INVALID, BC_LEX_EXECUTE,
BC_LEX_REG_STACK_LEVEL, BC_LEX_STACK_LEVEL,
- BC_LEX_LBRACE, BC_LEX_OP_MODEXP, BC_LEX_RBRACE, BC_LEX_OP_DIVMOD,
+ BC_LEX_LBRACE, BC_LEX_KW_MODEXP, BC_LEX_RBRACE, BC_LEX_KW_DIVMOD,
BC_LEX_INVALID
};
/// A list of instructions that correspond to lex tokens. If an entry is
/// BC_INST_INVALID, that lex token needs extra parsing in the dc parser.
-/// Otherwise, the token can trivially be replaced by the entry.
+/// Otherwise, the token can trivially be replaced by the entry. This needs to
+/// be updated if the tokens change.
const uchar dc_parse_insts[] = {
BC_INST_INVALID, BC_INST_INVALID,
#if BC_ENABLED
@@ -1102,7 +1150,7 @@ const uchar dc_parse_insts[] = {
#if BC_ENABLE_EXTRA_MATH
BC_INST_IRAND,
#endif // BC_ENABLE_EXTRA_MATH
- BC_INST_QUIT, BC_INST_INVALID,
+ BC_INST_MODEXP, BC_INST_DIVMOD, BC_INST_QUIT, BC_INST_INVALID,
#if BC_ENABLE_EXTRA_MATH
BC_INST_RAND,
#endif // BC_ENABLE_EXTRA_MATH
@@ -1112,7 +1160,7 @@ const uchar dc_parse_insts[] = {
BC_INST_MAXRAND,
#endif // BC_ENABLE_EXTRA_MATH
BC_INST_INVALID,
- BC_INST_REL_EQ, BC_INST_MODEXP, BC_INST_DIVMOD, BC_INST_INVALID,
+ BC_INST_REL_EQ, BC_INST_INVALID,
BC_INST_EXECUTE, BC_INST_PRINT_STACK, BC_INST_CLEAR_STACK,
BC_INST_INVALID, BC_INST_STACK_LEN, BC_INST_DUPLICATE, BC_INST_SWAP,
BC_INST_POP, BC_INST_ASCIIFY, BC_INST_PRINT_STREAM,