blob: dc71860285abf449d307572619e92ae336966d31 [file] [log] [blame]
Gavin Howard5715b042018-02-12 16:11:42 -07001/*
Gavin Howardb5904bf2018-02-20 13:28:18 -07002 * *****************************************************************************
Gavin Howard5715b042018-02-12 16:11:42 -07003 *
Gavin Howardb5904bf2018-02-20 13:28:18 -07004 * Copyright 2018 Gavin D. Howard
Gavin Howard5715b042018-02-12 16:11:42 -07005 *
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 *
Gavin Howardb5904bf2018-02-20 13:28:18 -070017 * *****************************************************************************
Gavin Howard5715b042018-02-12 16:11:42 -070018 *
Gavin Howard4ffe5a92018-09-26 20:58:31 -060019 * Definitions for bc.
Gavin Howard5715b042018-02-12 16:11:42 -070020 *
21 */
22
Gavin Howard4ffe5a92018-09-26 20:58:31 -060023#ifndef BC_BC_H
24#define BC_BC_H
Gavin Howard8a596d42018-01-15 15:46:01 -070025
Gavin Howard1545ffe2018-12-24 11:26:46 -070026#if BC_ENABLED
27
Gavin Howardc1902aa2018-12-20 15:54:28 -070028#include <limits.h>
Gavin Howard707a4e32018-10-03 16:36:41 -060029#include <stdbool.h>
30
Gavin Howard29493062018-03-20 19:57:37 -060031#include <status.h>
Gavin Howard707a4e32018-10-03 16:36:41 -060032#include <lex.h>
33#include <parse.h>
Gavin Howard6839e4d2018-03-20 21:24:52 -060034
Gavin Howardeb9a8222018-03-13 09:25:56 -060035// ** Exclude start. **
Gavin Howard773c86b2018-11-02 14:07:19 -060036// ** Busybox exclude start. **
Gavin Howarda84ad992018-12-03 19:11:06 -070037int bc_main(int argc, char **argv);
38
Gavin Howardd5551672018-09-22 19:52:42 -060039extern const char bc_help[];
Gavin Howard1cbfe242019-01-09 17:13:11 -070040extern const char bc_lib[];
41extern const char* bc_lib_name;
42extern const char bc_lib2[];
43extern const char* bc_lib2_name;
Gavin Howard773c86b2018-11-02 14:07:19 -060044// ** Busybox exclude end. **
Gavin Howard707a4e32018-10-03 16:36:41 -060045// ** Exclude end. **
46
47typedef struct BcLexKeyword {
Gavin Howardc1902aa2018-12-20 15:54:28 -070048 uchar data;
Gavin Howard707a4e32018-10-03 16:36:41 -060049 const char name[9];
Gavin Howard707a4e32018-10-03 16:36:41 -060050} BcLexKeyword;
51
Gavin Howard4662d6c2018-12-20 16:31:31 -070052#define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1))
53
Gavin Howardfbd2b4a2018-12-27 12:11:41 -070054#define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1)))
55#define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1))))
Gavin Howard4662d6c2018-12-20 16:31:31 -070056
Gavin Howardc1902aa2018-12-20 15:54:28 -070057#define BC_LEX_KW_ENTRY(a, b, c) \
Gavin Howarded38e942018-12-21 15:09:13 -070058 { .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c),.name = a }
Gavin Howard707a4e32018-10-03 16:36:41 -060059
Gavin Howard76d79422018-12-31 14:18:49 -070060#define bc_lex_posixErr(l, e) (bc_vm_posixError((e), (l)->line))
61#define bc_lex_vposixErr(l, e, ...) \
62 (bc_vm_posixError((e), (l)->line, __VA_ARGS__))
63
Gavin Howardc70bd502018-12-31 17:28:32 -070064extern const BcLexKeyword bc_lex_kws[];
65extern const size_t bc_lex_kws_len;
Gavin Howard707a4e32018-10-03 16:36:41 -060066
67BcStatus bc_lex_token(BcLex *l);
68
Gavin Howardb15fa032019-01-02 14:42:36 -070069#define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags))
70#define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p)))
71
72#define BC_PARSE_FLAG_BRACE (1<<0)
73#define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE)
74
75#define BC_PARSE_FLAG_FUNC_INNER (1<<1)
76#define BC_PARSE_FUNC_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC_INNER)
77
78#define BC_PARSE_FLAG_FUNC (1<<2)
79#define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC)
80
81#define BC_PARSE_FLAG_BODY (1<<3)
82#define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY)
83
84#define BC_PARSE_FLAG_LOOP (1<<4)
85#define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP)
86
87#define BC_PARSE_FLAG_LOOP_INNER (1<<5)
88#define BC_PARSE_LOOP_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP_INNER)
89
90#define BC_PARSE_FLAG_IF (1<<6)
91#define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF)
92
93#define BC_PARSE_FLAG_ELSE (1<<7)
94#define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE)
95
96#define BC_PARSE_FLAG_IF_END (1<<8)
97#define BC_PARSE_IF_END(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF_END)
98
99#define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0)
100
Gavin Howard7ed50c72019-01-14 11:20:12 -0700101#define BC_PARSE_DELIMITER(t) \
102 ((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF)
Gavin Howardb15fa032019-01-02 14:42:36 -0700103
Gavin Howard63fdbfa2019-01-16 09:47:04 -0700104#define BC_PARSE_BLOCK_STMT(f) \
105 ((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER))
106
Gavin Howard2b4fde92018-12-24 16:02:24 -0700107#define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l)))
Gavin Howard4662d6c2018-12-20 16:31:31 -0700108
Gavin Howard1c6cfb82019-01-21 11:42:34 -0700109#define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)]
110#define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1))
111#define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1)))
Gavin Howard4662d6c2018-12-20 16:31:31 -0700112
Gavin Howard675b5cc2018-12-20 16:55:36 -0700113#define BC_PARSE_EXPR_ENTRY(e1, e2, e3, e4, e5, e6, e7, e8) \
114 (((e1) << 7) | ((e2) << 6) | ((e3) << 5) | ((e4) << 4) | \
115 ((e5) << 3) | ((e6) << 2) | ((e7) << 1) | ((e8) << 0))
116
117#define BC_PARSE_EXPR(i) \
Gavin Howard1cbfe242019-01-09 17:13:11 -0700118 (bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07))))
Gavin Howard675b5cc2018-12-20 16:55:36 -0700119
Gavin Howard890d0c02018-10-30 16:34:50 -0600120#define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops)))
Gavin Howardb6e5a172018-12-28 17:41:15 -0700121#define BC_PARSE_LEAF(prev, bin_last, rparen) \
122 (!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev)))
Gavin Howardf81f9042018-12-27 14:19:53 -0700123#define BC_PARSE_INST_VAR(t) \
124 ((t) == BC_INST_VAR || (t) == BC_INST_ARRAY_ELEM || (t) == BC_INST_LAST || \
125 (t) == BC_INST_SCALE || (t) == BC_INST_IBASE || (t) == BC_INST_OBASE)
Gavin Howard707a4e32018-10-03 16:36:41 -0600126
Gavin Howarde5228882019-01-10 16:08:04 -0700127#define BC_PARSE_PREV_PREFIX(p) \
128 ((p) >= BC_INST_INC_PRE && (p) <= BC_INST_BOOL_NOT)
129#define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG)
Gavin Howardac7a3c92019-01-10 13:26:29 -0700130
Gavin Howard707a4e32018-10-03 16:36:41 -0600131// We can calculate the conversion between tokens and exprs by subtracting the
Gavin Howard954f9b62018-12-19 15:22:20 -0700132// position of the first operator in the lex enum and adding the position of
133// the first in the expr enum. Note: This only works for binary operators.
134#define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG))
Gavin Howard707a4e32018-10-03 16:36:41 -0600135
Gavin Howard76d79422018-12-31 14:18:49 -0700136#define bc_parse_posixErr(p, e) (bc_vm_posixError((e), (p)->l.line))
137
Gavin Howard707a4e32018-10-03 16:36:41 -0600138// ** Exclude start. **
Gavin Howard773c86b2018-11-02 14:07:19 -0600139// ** Busybox exclude start. **
Gavin Howard7536dcf2018-12-15 19:27:09 -0700140BcStatus bc_parse_expr(BcParse *p, uint8_t flags);
Gavin Howard773c86b2018-11-02 14:07:19 -0600141// ** Busybox exclude end. **
Gavin Howard707a4e32018-10-03 16:36:41 -0600142// ** Exclude end. **
143
Gavin Howard9d2497d2018-10-29 16:10:21 -0600144BcStatus bc_parse_parse(BcParse *p);
Gavin Howard7536dcf2018-12-15 19:27:09 -0700145BcStatus bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next);
Gavin Howardff66e292018-03-28 12:47:58 -0600146
Gavin Howard10667092018-12-20 11:52:55 -0700147#if BC_ENABLE_SIGNALS
148extern const char bc_sig_msg[];
Gavin Howard10667092018-12-20 11:52:55 -0700149#endif // BC_ENABLE_SIGNALS
150
Gavin Howarda73c11b2018-12-17 11:30:39 -0700151extern const char* const bc_parse_const1;
Gavin Howard675b5cc2018-12-20 16:55:36 -0700152extern const uint8_t bc_parse_exprs[];
Gavin Howardc1902aa2018-12-20 15:54:28 -0700153extern const uchar bc_parse_ops[];
Gavin Howardf89006a2018-10-29 13:01:51 -0600154extern const BcParseNext bc_parse_next_expr;
155extern const BcParseNext bc_parse_next_param;
156extern const BcParseNext bc_parse_next_print;
157extern const BcParseNext bc_parse_next_rel;
158extern const BcParseNext bc_parse_next_elem;
159extern const BcParseNext bc_parse_next_for;
160extern const BcParseNext bc_parse_next_read;
161
Gavin Howarddf4fe792018-10-03 16:48:30 -0600162#endif // BC_ENABLED
163
Gavin Howard4ffe5a92018-09-26 20:58:31 -0600164#endif // BC_BC_H