xref: /aosp_15_r20/external/bc/include/bc.h (revision 5a6e848804d15c18a0125914844ee4eb0bda4fcf)
1*5a6e8488SAndroid Build Coastguard Worker /*
2*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
3*5a6e8488SAndroid Build Coastguard Worker  *
4*5a6e8488SAndroid Build Coastguard Worker  * SPDX-License-Identifier: BSD-2-Clause
5*5a6e8488SAndroid Build Coastguard Worker  *
6*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
7*5a6e8488SAndroid Build Coastguard Worker  *
8*5a6e8488SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
9*5a6e8488SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
10*5a6e8488SAndroid Build Coastguard Worker  *
11*5a6e8488SAndroid Build Coastguard Worker  * * Redistributions of source code must retain the above copyright notice, this
12*5a6e8488SAndroid Build Coastguard Worker  *   list of conditions and the following disclaimer.
13*5a6e8488SAndroid Build Coastguard Worker  *
14*5a6e8488SAndroid Build Coastguard Worker  * * Redistributions in binary form must reproduce the above copyright notice,
15*5a6e8488SAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer in the documentation
16*5a6e8488SAndroid Build Coastguard Worker  *   and/or other materials provided with the distribution.
17*5a6e8488SAndroid Build Coastguard Worker  *
18*5a6e8488SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*5a6e8488SAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*5a6e8488SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*5a6e8488SAndroid Build Coastguard Worker  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*5a6e8488SAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*5a6e8488SAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*5a6e8488SAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*5a6e8488SAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*5a6e8488SAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*5a6e8488SAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*5a6e8488SAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
29*5a6e8488SAndroid Build Coastguard Worker  *
30*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
31*5a6e8488SAndroid Build Coastguard Worker  *
32*5a6e8488SAndroid Build Coastguard Worker  * Definitions for bc only.
33*5a6e8488SAndroid Build Coastguard Worker  *
34*5a6e8488SAndroid Build Coastguard Worker  */
35*5a6e8488SAndroid Build Coastguard Worker 
36*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_BC_H
37*5a6e8488SAndroid Build Coastguard Worker #define BC_BC_H
38*5a6e8488SAndroid Build Coastguard Worker 
39*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
40*5a6e8488SAndroid Build Coastguard Worker 
41*5a6e8488SAndroid Build Coastguard Worker #include <limits.h>
42*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h>
43*5a6e8488SAndroid Build Coastguard Worker 
44*5a6e8488SAndroid Build Coastguard Worker #include <status.h>
45*5a6e8488SAndroid Build Coastguard Worker #include <lex.h>
46*5a6e8488SAndroid Build Coastguard Worker #include <parse.h>
47*5a6e8488SAndroid Build Coastguard Worker 
48*5a6e8488SAndroid Build Coastguard Worker /**
49*5a6e8488SAndroid Build Coastguard Worker  * The main function for bc. It just sets variables and passes its arguments
50*5a6e8488SAndroid Build Coastguard Worker  * through to @a bc_vm_boot().
51*5a6e8488SAndroid Build Coastguard Worker  * @return  A status.
52*5a6e8488SAndroid Build Coastguard Worker  */
53*5a6e8488SAndroid Build Coastguard Worker BcStatus
54*5a6e8488SAndroid Build Coastguard Worker bc_main(int argc, const char* argv[]);
55*5a6e8488SAndroid Build Coastguard Worker 
56*5a6e8488SAndroid Build Coastguard Worker // These are references to the help text, the library text, and the "filename"
57*5a6e8488SAndroid Build Coastguard Worker // for the library.
58*5a6e8488SAndroid Build Coastguard Worker extern const char bc_help[];
59*5a6e8488SAndroid Build Coastguard Worker extern const char bc_lib[];
60*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_lib_name;
61*5a6e8488SAndroid Build Coastguard Worker 
62*5a6e8488SAndroid Build Coastguard Worker // These are references to the second math library and its "filename."
63*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
64*5a6e8488SAndroid Build Coastguard Worker extern const char bc_lib2[];
65*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_lib2_name;
66*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
67*5a6e8488SAndroid Build Coastguard Worker 
68*5a6e8488SAndroid Build Coastguard Worker /**
69*5a6e8488SAndroid Build Coastguard Worker  * A struct containing information about a bc keyword.
70*5a6e8488SAndroid Build Coastguard Worker  */
71*5a6e8488SAndroid Build Coastguard Worker typedef struct BcLexKeyword
72*5a6e8488SAndroid Build Coastguard Worker {
73*5a6e8488SAndroid Build Coastguard Worker 	/// Holds the length of the keyword along with a bit that, if set, means the
74*5a6e8488SAndroid Build Coastguard Worker 	/// keyword is used in POSIX bc.
75*5a6e8488SAndroid Build Coastguard Worker 	uchar data;
76*5a6e8488SAndroid Build Coastguard Worker 
77*5a6e8488SAndroid Build Coastguard Worker 	/// The keyword text.
78*5a6e8488SAndroid Build Coastguard Worker 	const char name[14];
79*5a6e8488SAndroid Build Coastguard Worker } BcLexKeyword;
80*5a6e8488SAndroid Build Coastguard Worker 
81*5a6e8488SAndroid Build Coastguard Worker /// Sets the most significant bit. Used for setting the POSIX bit in
82*5a6e8488SAndroid Build Coastguard Worker /// BcLexKeyword's data field.
83*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1))
84*5a6e8488SAndroid Build Coastguard Worker 
85*5a6e8488SAndroid Build Coastguard Worker /// Returns non-zero if the keyword is POSIX, zero otherwise.
86*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1)))
87*5a6e8488SAndroid Build Coastguard Worker 
88*5a6e8488SAndroid Build Coastguard Worker /// Returns the length of the keyword.
89*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1))))
90*5a6e8488SAndroid Build Coastguard Worker 
91*5a6e8488SAndroid Build Coastguard Worker /// A macro to easily build a keyword entry. See bc_lex_kws in src/data.c.
92*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_KW_ENTRY(a, b, c) \
93*5a6e8488SAndroid Build Coastguard Worker 	{ .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c), .name = a }
94*5a6e8488SAndroid Build Coastguard Worker 
95*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
96*5a6e8488SAndroid Build Coastguard Worker 
97*5a6e8488SAndroid Build Coastguard Worker /// A macro for the number of keywords bc has. This has to be updated if any are
98*5a6e8488SAndroid Build Coastguard Worker /// added. This is for the redefined_kws field of the BcVm struct.
99*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_NKWS (37)
100*5a6e8488SAndroid Build Coastguard Worker 
101*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_EXTRA_MATH
102*5a6e8488SAndroid Build Coastguard Worker 
103*5a6e8488SAndroid Build Coastguard Worker /// A macro for the number of keywords bc has. This has to be updated if any are
104*5a6e8488SAndroid Build Coastguard Worker /// added. This is for the redefined_kws field of the BcVm struct.
105*5a6e8488SAndroid Build Coastguard Worker #define BC_LEX_NKWS (33)
106*5a6e8488SAndroid Build Coastguard Worker 
107*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
108*5a6e8488SAndroid Build Coastguard Worker 
109*5a6e8488SAndroid Build Coastguard Worker // The array of keywords and its length.
110*5a6e8488SAndroid Build Coastguard Worker extern const BcLexKeyword bc_lex_kws[];
111*5a6e8488SAndroid Build Coastguard Worker extern const size_t bc_lex_kws_len;
112*5a6e8488SAndroid Build Coastguard Worker 
113*5a6e8488SAndroid Build Coastguard Worker /**
114*5a6e8488SAndroid Build Coastguard Worker  * The @a BcLexNext function for bc. (See include/lex.h for a definition of
115*5a6e8488SAndroid Build Coastguard Worker  * @a BcLexNext.)
116*5a6e8488SAndroid Build Coastguard Worker  * @param l  The lexer.
117*5a6e8488SAndroid Build Coastguard Worker  */
118*5a6e8488SAndroid Build Coastguard Worker void
119*5a6e8488SAndroid Build Coastguard Worker bc_lex_token(BcLex* l);
120*5a6e8488SAndroid Build Coastguard Worker 
121*5a6e8488SAndroid Build Coastguard Worker // The following section is for flags needed when parsing bc code. These flags
122*5a6e8488SAndroid Build Coastguard Worker // are complicated, but necessary. Why you ask? Because bc's standard is awful.
123*5a6e8488SAndroid Build Coastguard Worker //
124*5a6e8488SAndroid Build Coastguard Worker // If you don't believe me, go read the bc Parsing section of the Development
125*5a6e8488SAndroid Build Coastguard Worker // manual (manuals/development.md). Then come back.
126*5a6e8488SAndroid Build Coastguard Worker //
127*5a6e8488SAndroid Build Coastguard Worker // In other words, these flags are the sign declaring, "Here be dragons."
128*5a6e8488SAndroid Build Coastguard Worker 
129*5a6e8488SAndroid Build Coastguard Worker /**
130*5a6e8488SAndroid Build Coastguard Worker  * This returns a pointer to the set of flags at the top of the flag stack.
131*5a6e8488SAndroid Build Coastguard Worker  * @a p is expected to be a BcParse pointer.
132*5a6e8488SAndroid Build Coastguard Worker  * @param p  The parser.
133*5a6e8488SAndroid Build Coastguard Worker  * @return   A pointer to the top flag set.
134*5a6e8488SAndroid Build Coastguard Worker  */
135*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags))
136*5a6e8488SAndroid Build Coastguard Worker 
137*5a6e8488SAndroid Build Coastguard Worker /**
138*5a6e8488SAndroid Build Coastguard Worker  * This returns the flag set at the top of the flag stack. @a p is expected to
139*5a6e8488SAndroid Build Coastguard Worker  * be a BcParse pointer.
140*5a6e8488SAndroid Build Coastguard Worker  * @param p  The parser.
141*5a6e8488SAndroid Build Coastguard Worker  * @return   The top flag set.
142*5a6e8488SAndroid Build Coastguard Worker  */
143*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p)))
144*5a6e8488SAndroid Build Coastguard Worker 
145*5a6e8488SAndroid Build Coastguard Worker // After this point, all flag #defines are in sets of 2: one to define the flag,
146*5a6e8488SAndroid Build Coastguard Worker // and one to define a way to grab the flag from the flag set at the top of the
147*5a6e8488SAndroid Build Coastguard Worker // flag stack. All `p` arguments are pointers to a BcParse.
148*5a6e8488SAndroid Build Coastguard Worker 
149*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser has seen a left brace.
150*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_BRACE (UINTMAX_C(1) << 0)
151*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE)
152*5a6e8488SAndroid Build Coastguard Worker 
153*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser is parsing inside of the braces of a function
154*5a6e8488SAndroid Build Coastguard Worker // body.
155*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_FUNC_INNER (UINTMAX_C(1) << 1)
156*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FUNC_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC_INNER)
157*5a6e8488SAndroid Build Coastguard Worker 
158*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser is parsing a function. It is different from
159*5a6e8488SAndroid Build Coastguard Worker // the one above because it is set if it is parsing a function body *or* header,
160*5a6e8488SAndroid Build Coastguard Worker // not just if it's parsing a function body.
161*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_FUNC (UINTMAX_C(1) << 2)
162*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC)
163*5a6e8488SAndroid Build Coastguard Worker 
164*5a6e8488SAndroid Build Coastguard Worker // This flag is set if the parser is expecting to parse a body, whether of a
165*5a6e8488SAndroid Build Coastguard Worker // function, an if statement, or a loop.
166*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_BODY (UINTMAX_C(1) << 3)
167*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY)
168*5a6e8488SAndroid Build Coastguard Worker 
169*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing a loop. This is important because the break
170*5a6e8488SAndroid Build Coastguard Worker // and continue keywords are only valid inside of a loop.
171*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_LOOP (UINTMAX_C(1) << 4)
172*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP)
173*5a6e8488SAndroid Build Coastguard Worker 
174*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing the body of a loop. It is different from
175*5a6e8488SAndroid Build Coastguard Worker // the one above the same way @a BC_PARSE_FLAG_FUNC_INNER is different from
176*5a6e8488SAndroid Build Coastguard Worker // @a BC_PARSE_FLAG_FUNC.
177*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_LOOP_INNER (UINTMAX_C(1) << 5)
178*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_LOOP_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP_INNER)
179*5a6e8488SAndroid Build Coastguard Worker 
180*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing an if statement.
181*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_IF (UINTMAX_C(1) << 6)
182*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF)
183*5a6e8488SAndroid Build Coastguard Worker 
184*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc is parsing an else statement. This is important
185*5a6e8488SAndroid Build Coastguard Worker // because of "else if" constructions, among other things.
186*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_ELSE (UINTMAX_C(1) << 7)
187*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE)
188*5a6e8488SAndroid Build Coastguard Worker 
189*5a6e8488SAndroid Build Coastguard Worker // This flag is set if bc just finished parsing an if statement and its body.
190*5a6e8488SAndroid Build Coastguard Worker // It tells the parser that it can probably expect an else statement next. This
191*5a6e8488SAndroid Build Coastguard Worker // flag is, thus, one of the most subtle.
192*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_FLAG_IF_END (UINTMAX_C(1) << 8)
193*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_IF_END(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF_END)
194*5a6e8488SAndroid Build Coastguard Worker 
195*5a6e8488SAndroid Build Coastguard Worker /**
196*5a6e8488SAndroid Build Coastguard Worker  * This returns true if bc is in a state where it should not execute any code
197*5a6e8488SAndroid Build Coastguard Worker  * at all.
198*5a6e8488SAndroid Build Coastguard Worker  * @param p  The parser.
199*5a6e8488SAndroid Build Coastguard Worker  * @return   True if execution cannot proceed, false otherwise.
200*5a6e8488SAndroid Build Coastguard Worker  */
201*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0)
202*5a6e8488SAndroid Build Coastguard Worker 
203*5a6e8488SAndroid Build Coastguard Worker /**
204*5a6e8488SAndroid Build Coastguard Worker  * This returns true if the token @a t is a statement delimiter, which is
205*5a6e8488SAndroid Build Coastguard Worker  * either a newline or a semicolon.
206*5a6e8488SAndroid Build Coastguard Worker  * @param t  The token to check.
207*5a6e8488SAndroid Build Coastguard Worker  * @return   True if t is a statement delimiter token; false otherwise.
208*5a6e8488SAndroid Build Coastguard Worker  */
209*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_DELIMITER(t) \
210*5a6e8488SAndroid Build Coastguard Worker 	((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF)
211*5a6e8488SAndroid Build Coastguard Worker 
212*5a6e8488SAndroid Build Coastguard Worker /**
213*5a6e8488SAndroid Build Coastguard Worker  * This is poorly named, but it basically returns whether or not the current
214*5a6e8488SAndroid Build Coastguard Worker  * state is valid for the end of an else statement.
215*5a6e8488SAndroid Build Coastguard Worker  * @param f  The flag set to be checked.
216*5a6e8488SAndroid Build Coastguard Worker  * @return   True if the state is valid for the end of an else statement.
217*5a6e8488SAndroid Build Coastguard Worker  */
218*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_BLOCK_STMT(f) \
219*5a6e8488SAndroid Build Coastguard Worker 	((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER))
220*5a6e8488SAndroid Build Coastguard Worker 
221*5a6e8488SAndroid Build Coastguard Worker /**
222*5a6e8488SAndroid Build Coastguard Worker  * This returns the value of the data for an operator with precedence @a p and
223*5a6e8488SAndroid Build Coastguard Worker  * associativity @a l (true if left associative, false otherwise). This is used
224*5a6e8488SAndroid Build Coastguard Worker  * to construct an array of operators, bc_parse_ops, in src/data.c.
225*5a6e8488SAndroid Build Coastguard Worker  * @param p  The precedence.
226*5a6e8488SAndroid Build Coastguard Worker  * @param l  True if the operator is left associative, false otherwise.
227*5a6e8488SAndroid Build Coastguard Worker  * @return   The data for the operator.
228*5a6e8488SAndroid Build Coastguard Worker  */
229*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l)))
230*5a6e8488SAndroid Build Coastguard Worker 
231*5a6e8488SAndroid Build Coastguard Worker /**
232*5a6e8488SAndroid Build Coastguard Worker  * Returns the operator data for the lex token @a t.
233*5a6e8488SAndroid Build Coastguard Worker  * @param t  The token to return operator data for.
234*5a6e8488SAndroid Build Coastguard Worker  * @return   The operator data for @a t.
235*5a6e8488SAndroid Build Coastguard Worker  */
236*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)]
237*5a6e8488SAndroid Build Coastguard Worker 
238*5a6e8488SAndroid Build Coastguard Worker /**
239*5a6e8488SAndroid Build Coastguard Worker  * Returns non-zero if operator @a op is left associative, zero otherwise.
240*5a6e8488SAndroid Build Coastguard Worker  * @param op  The operator to test for associativity.
241*5a6e8488SAndroid Build Coastguard Worker  * @return    Non-zero if the operator is left associative, zero otherwise.
242*5a6e8488SAndroid Build Coastguard Worker  */
243*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1))
244*5a6e8488SAndroid Build Coastguard Worker 
245*5a6e8488SAndroid Build Coastguard Worker /**
246*5a6e8488SAndroid Build Coastguard Worker  * Returns the precedence of operator @a op. Lower number means higher
247*5a6e8488SAndroid Build Coastguard Worker  * precedence.
248*5a6e8488SAndroid Build Coastguard Worker  * @param op  The operator to return the precedence of.
249*5a6e8488SAndroid Build Coastguard Worker  * @return    The precedence of @a op.
250*5a6e8488SAndroid Build Coastguard Worker  */
251*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1)))
252*5a6e8488SAndroid Build Coastguard Worker 
253*5a6e8488SAndroid Build Coastguard Worker /**
254*5a6e8488SAndroid Build Coastguard Worker  * A macro to easily define a series of bits for whether a lex token is an
255*5a6e8488SAndroid Build Coastguard Worker  * expression token or not. It takes 8 expression bits, corresponding to the 8
256*5a6e8488SAndroid Build Coastguard Worker  * bits in a uint8_t. You can see this in use for bc_parse_exprs in src/data.c.
257*5a6e8488SAndroid Build Coastguard Worker  * @param e1  The first bit.
258*5a6e8488SAndroid Build Coastguard Worker  * @param e2  The second bit.
259*5a6e8488SAndroid Build Coastguard Worker  * @param e3  The third bit.
260*5a6e8488SAndroid Build Coastguard Worker  * @param e4  The fourth bit.
261*5a6e8488SAndroid Build Coastguard Worker  * @param e5  The fifth bit.
262*5a6e8488SAndroid Build Coastguard Worker  * @param e6  The sixth bit.
263*5a6e8488SAndroid Build Coastguard Worker  * @param e7  The seventh bit.
264*5a6e8488SAndroid Build Coastguard Worker  * @param e8  The eighth bit.
265*5a6e8488SAndroid Build Coastguard Worker  * @return    An expression entry for bc_parse_exprs[].
266*5a6e8488SAndroid Build Coastguard Worker  */
267*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_EXPR_ENTRY(e1, e2, e3, e4, e5, e6, e7, e8)               \
268*5a6e8488SAndroid Build Coastguard Worker 	((UINTMAX_C(e1) << 7) | (UINTMAX_C(e2) << 6) | (UINTMAX_C(e3) << 5) | \
269*5a6e8488SAndroid Build Coastguard Worker 	 (UINTMAX_C(e4) << 4) | (UINTMAX_C(e5) << 3) | (UINTMAX_C(e6) << 2) | \
270*5a6e8488SAndroid Build Coastguard Worker 	 (UINTMAX_C(e7) << 1) | (UINTMAX_C(e8) << 0))
271*5a6e8488SAndroid Build Coastguard Worker 
272*5a6e8488SAndroid Build Coastguard Worker /**
273*5a6e8488SAndroid Build Coastguard Worker  * Returns true if token @a i is a token that belongs in an expression.
274*5a6e8488SAndroid Build Coastguard Worker  * @param i  The token to test.
275*5a6e8488SAndroid Build Coastguard Worker  * @return   True if i is an expression token, false otherwise.
276*5a6e8488SAndroid Build Coastguard Worker  */
277*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_EXPR(i) \
278*5a6e8488SAndroid Build Coastguard Worker 	(bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07))))
279*5a6e8488SAndroid Build Coastguard Worker 
280*5a6e8488SAndroid Build Coastguard Worker /**
281*5a6e8488SAndroid Build Coastguard Worker  * Returns the operator (by lex token) that is at the top of the operator
282*5a6e8488SAndroid Build Coastguard Worker  * stack.
283*5a6e8488SAndroid Build Coastguard Worker  * @param p  The parser.
284*5a6e8488SAndroid Build Coastguard Worker  * @return   The operator that is at the top of the operator stack, as a lex
285*5a6e8488SAndroid Build Coastguard Worker  *           token.
286*5a6e8488SAndroid Build Coastguard Worker  */
287*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops)))
288*5a6e8488SAndroid Build Coastguard Worker 
289*5a6e8488SAndroid Build Coastguard Worker /**
290*5a6e8488SAndroid Build Coastguard Worker  * Returns true if bc has a "leaf" token. A "leaf" token is one that can stand
291*5a6e8488SAndroid Build Coastguard Worker  * alone in an expression. For example, a number by itself can be an expression,
292*5a6e8488SAndroid Build Coastguard Worker  * but a binary operator, while valid for an expression, cannot be alone in the
293*5a6e8488SAndroid Build Coastguard Worker  * expression. It must have an expression to the left and right of itself. See
294*5a6e8488SAndroid Build Coastguard Worker  * the documentation for @a bc_parse_expr_err() in src/bc_parse.c.
295*5a6e8488SAndroid Build Coastguard Worker  * @param prev      The previous token as an instruction.
296*5a6e8488SAndroid Build Coastguard Worker  * @param bin_last  True if that last operator was a binary operator, false
297*5a6e8488SAndroid Build Coastguard Worker  *                  otherwise.
298*5a6e8488SAndroid Build Coastguard Worker  * @param rparen    True if the last operator was a right paren.
299*5a6e8488SAndroid Build Coastguard Worker  * return           True if the last token was a leaf token, false otherwise.
300*5a6e8488SAndroid Build Coastguard Worker  */
301*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_LEAF(prev, bin_last, rparen) \
302*5a6e8488SAndroid Build Coastguard Worker 	(!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev)))
303*5a6e8488SAndroid Build Coastguard Worker 
304*5a6e8488SAndroid Build Coastguard Worker /**
305*5a6e8488SAndroid Build Coastguard Worker  * This returns true if the token @a t should be treated as though it's a
306*5a6e8488SAndroid Build Coastguard Worker  * variable. This goes for actual variables, array elements, and globals.
307*5a6e8488SAndroid Build Coastguard Worker  * @param t  The token to test.
308*5a6e8488SAndroid Build Coastguard Worker  * @return   True if @a t should be treated as though it's a variable, false
309*5a6e8488SAndroid Build Coastguard Worker  *           otherwise.
310*5a6e8488SAndroid Build Coastguard Worker  */
311*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
312*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_INST_VAR(t) \
313*5a6e8488SAndroid Build Coastguard Worker 	((t) >= BC_INST_VAR && (t) <= BC_INST_SEED && (t) != BC_INST_ARRAY)
314*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_EXTRA_MATH
315*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_INST_VAR(t) \
316*5a6e8488SAndroid Build Coastguard Worker 	((t) >= BC_INST_VAR && (t) <= BC_INST_SCALE && (t) != BC_INST_ARRAY)
317*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
318*5a6e8488SAndroid Build Coastguard Worker 
319*5a6e8488SAndroid Build Coastguard Worker /**
320*5a6e8488SAndroid Build Coastguard Worker  * Returns true if the previous token @a p (in the form of a bytecode
321*5a6e8488SAndroid Build Coastguard Worker  * instruction) is a prefix operator. The fact that it is for bytecode
322*5a6e8488SAndroid Build Coastguard Worker  * instructions is what makes it different from @a BC_PARSE_OP_PREFIX below.
323*5a6e8488SAndroid Build Coastguard Worker  * @param p  The previous token.
324*5a6e8488SAndroid Build Coastguard Worker  * @return   True if @a p is a prefix operator.
325*5a6e8488SAndroid Build Coastguard Worker  */
326*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_PREV_PREFIX(p) ((p) >= BC_INST_NEG && (p) <= BC_INST_BOOL_NOT)
327*5a6e8488SAndroid Build Coastguard Worker 
328*5a6e8488SAndroid Build Coastguard Worker /**
329*5a6e8488SAndroid Build Coastguard Worker  * Returns true if token @a t is a prefix operator.
330*5a6e8488SAndroid Build Coastguard Worker  * @param t  The token to test.
331*5a6e8488SAndroid Build Coastguard Worker  * @return   True if @a t is a prefix operator, false otherwise.
332*5a6e8488SAndroid Build Coastguard Worker  */
333*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG)
334*5a6e8488SAndroid Build Coastguard Worker 
335*5a6e8488SAndroid Build Coastguard Worker /**
336*5a6e8488SAndroid Build Coastguard Worker  * We can calculate the conversion between tokens and bytecode instructions by
337*5a6e8488SAndroid Build Coastguard Worker  * subtracting the position of the first operator in the lex enum and adding the
338*5a6e8488SAndroid Build Coastguard Worker  * position of the first in the instruction enum. Note: This only works for
339*5a6e8488SAndroid Build Coastguard Worker  * binary operators.
340*5a6e8488SAndroid Build Coastguard Worker  * @param t  The token to turn into an instruction.
341*5a6e8488SAndroid Build Coastguard Worker  * @return   The token as an instruction.
342*5a6e8488SAndroid Build Coastguard Worker  */
343*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG))
344*5a6e8488SAndroid Build Coastguard Worker 
345*5a6e8488SAndroid Build Coastguard Worker /**
346*5a6e8488SAndroid Build Coastguard Worker  * Returns true if the token is a bc keyword.
347*5a6e8488SAndroid Build Coastguard Worker  * @param t  The token to check.
348*5a6e8488SAndroid Build Coastguard Worker  * @return   True if @a t is a bc keyword, false otherwise.
349*5a6e8488SAndroid Build Coastguard Worker  */
350*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_IS_KEYWORD(t) ((t) >= BC_LEX_KW_AUTO && (t) <= BC_LEX_KW_ELSE)
351*5a6e8488SAndroid Build Coastguard Worker 
352*5a6e8488SAndroid Build Coastguard Worker /// A struct that holds data about what tokens should be expected next. There
353*5a6e8488SAndroid Build Coastguard Worker /// are a few instances of these, all named because they are used in specific
354*5a6e8488SAndroid Build Coastguard Worker /// cases. Basically, in certain situations, it's useful to use the same code,
355*5a6e8488SAndroid Build Coastguard Worker /// but have a list of valid tokens.
356*5a6e8488SAndroid Build Coastguard Worker ///
357*5a6e8488SAndroid Build Coastguard Worker /// Obviously, @a len is the number of tokens in the @a tokens array. If more
358*5a6e8488SAndroid Build Coastguard Worker /// than 4 is needed in the future, @a tokens will have to be changed.
359*5a6e8488SAndroid Build Coastguard Worker typedef struct BcParseNext
360*5a6e8488SAndroid Build Coastguard Worker {
361*5a6e8488SAndroid Build Coastguard Worker 	/// The number of tokens in the tokens array.
362*5a6e8488SAndroid Build Coastguard Worker 	uchar len;
363*5a6e8488SAndroid Build Coastguard Worker 
364*5a6e8488SAndroid Build Coastguard Worker 	/// The tokens that can be expected next.
365*5a6e8488SAndroid Build Coastguard Worker 	uchar tokens[4];
366*5a6e8488SAndroid Build Coastguard Worker 
367*5a6e8488SAndroid Build Coastguard Worker } BcParseNext;
368*5a6e8488SAndroid Build Coastguard Worker 
369*5a6e8488SAndroid Build Coastguard Worker /// A macro to construct an array literal of tokens from a parameter list.
370*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ }
371*5a6e8488SAndroid Build Coastguard Worker 
372*5a6e8488SAndroid Build Coastguard Worker /// A macro to generate a BcParseNext literal from BcParseNext data. See
373*5a6e8488SAndroid Build Coastguard Worker /// src/data.c for examples.
374*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NEXT(a, ...) \
375*5a6e8488SAndroid Build Coastguard Worker 	{ .len = (uchar) (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) }
376*5a6e8488SAndroid Build Coastguard Worker 
377*5a6e8488SAndroid Build Coastguard Worker /// A status returned by @a bc_parse_expr_err(). It can either return success or
378*5a6e8488SAndroid Build Coastguard Worker /// an error indicating an empty expression.
379*5a6e8488SAndroid Build Coastguard Worker typedef enum BcParseStatus
380*5a6e8488SAndroid Build Coastguard Worker {
381*5a6e8488SAndroid Build Coastguard Worker 	BC_PARSE_STATUS_SUCCESS,
382*5a6e8488SAndroid Build Coastguard Worker 	BC_PARSE_STATUS_EMPTY_EXPR,
383*5a6e8488SAndroid Build Coastguard Worker 
384*5a6e8488SAndroid Build Coastguard Worker } BcParseStatus;
385*5a6e8488SAndroid Build Coastguard Worker 
386*5a6e8488SAndroid Build Coastguard Worker /**
387*5a6e8488SAndroid Build Coastguard Worker  * The @a BcParseExpr function for bc. (See include/parse.h for a definition of
388*5a6e8488SAndroid Build Coastguard Worker  * @a BcParseExpr.)
389*5a6e8488SAndroid Build Coastguard Worker  * @param p      The parser.
390*5a6e8488SAndroid Build Coastguard Worker  * @param flags  Flags that define the requirements that the parsed code must
391*5a6e8488SAndroid Build Coastguard Worker  *               meet or an error will result. See @a BcParseExpr for more info.
392*5a6e8488SAndroid Build Coastguard Worker  */
393*5a6e8488SAndroid Build Coastguard Worker void
394*5a6e8488SAndroid Build Coastguard Worker bc_parse_expr(BcParse* p, uint8_t flags);
395*5a6e8488SAndroid Build Coastguard Worker 
396*5a6e8488SAndroid Build Coastguard Worker /**
397*5a6e8488SAndroid Build Coastguard Worker  * The @a BcParseParse function for bc. (See include/parse.h for a definition of
398*5a6e8488SAndroid Build Coastguard Worker  * @a BcParseParse.)
399*5a6e8488SAndroid Build Coastguard Worker  * @param p  The parser.
400*5a6e8488SAndroid Build Coastguard Worker  */
401*5a6e8488SAndroid Build Coastguard Worker void
402*5a6e8488SAndroid Build Coastguard Worker bc_parse_parse(BcParse* p);
403*5a6e8488SAndroid Build Coastguard Worker 
404*5a6e8488SAndroid Build Coastguard Worker /**
405*5a6e8488SAndroid Build Coastguard Worker  * Ends a series of if statements. This is to ensure that full parses happen
406*5a6e8488SAndroid Build Coastguard Worker  * when a file finishes or before defining a function. Without this, bc thinks
407*5a6e8488SAndroid Build Coastguard Worker  * that it cannot parse any further. But if we reach the end of a file or a
408*5a6e8488SAndroid Build Coastguard Worker  * function definition, we know we can add an empty else clause.
409*5a6e8488SAndroid Build Coastguard Worker  * @param p  The parser.
410*5a6e8488SAndroid Build Coastguard Worker  */
411*5a6e8488SAndroid Build Coastguard Worker void
412*5a6e8488SAndroid Build Coastguard Worker bc_parse_endif(BcParse* p);
413*5a6e8488SAndroid Build Coastguard Worker 
414*5a6e8488SAndroid Build Coastguard Worker /// References to the signal message and its length.
415*5a6e8488SAndroid Build Coastguard Worker extern const char bc_sig_msg[];
416*5a6e8488SAndroid Build Coastguard Worker extern const uchar bc_sig_msg_len;
417*5a6e8488SAndroid Build Coastguard Worker 
418*5a6e8488SAndroid Build Coastguard Worker /// A reference to an array of bits that are set if the corresponding lex token
419*5a6e8488SAndroid Build Coastguard Worker /// is valid in an expression.
420*5a6e8488SAndroid Build Coastguard Worker extern const uint8_t bc_parse_exprs[];
421*5a6e8488SAndroid Build Coastguard Worker 
422*5a6e8488SAndroid Build Coastguard Worker /// A reference to an array of bc operators.
423*5a6e8488SAndroid Build Coastguard Worker extern const uchar bc_parse_ops[];
424*5a6e8488SAndroid Build Coastguard Worker 
425*5a6e8488SAndroid Build Coastguard Worker // References to the various instances of BcParseNext's.
426*5a6e8488SAndroid Build Coastguard Worker 
427*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing normal
428*5a6e8488SAndroid Build Coastguard Worker /// expressions. More accurately. these are the tokens that are valid for
429*5a6e8488SAndroid Build Coastguard Worker /// *ending* the expression.
430*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_expr;
431*5a6e8488SAndroid Build Coastguard Worker 
432*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing function
433*5a6e8488SAndroid Build Coastguard Worker /// parameters (well, actually arguments).
434*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_arg;
435*5a6e8488SAndroid Build Coastguard Worker 
436*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing a print
437*5a6e8488SAndroid Build Coastguard Worker /// statement.
438*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_print;
439*5a6e8488SAndroid Build Coastguard Worker 
440*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing things like
441*5a6e8488SAndroid Build Coastguard Worker /// loop headers and builtin functions where the only thing expected is a right
442*5a6e8488SAndroid Build Coastguard Worker /// paren.
443*5a6e8488SAndroid Build Coastguard Worker ///
444*5a6e8488SAndroid Build Coastguard Worker /// The name is an artifact of history, and is related to @a BC_PARSE_REL (see
445*5a6e8488SAndroid Build Coastguard Worker /// include/parse.h). It refers to how POSIX only allows some operators as part
446*5a6e8488SAndroid Build Coastguard Worker /// of the conditional of for loops, while loops, and if statements.
447*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_rel;
448*5a6e8488SAndroid Build Coastguard Worker 
449*5a6e8488SAndroid Build Coastguard Worker // What tokens are valid as next tokens when parsing an array element
450*5a6e8488SAndroid Build Coastguard Worker // expression.
451*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_elem;
452*5a6e8488SAndroid Build Coastguard Worker 
453*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing the first
454*5a6e8488SAndroid Build Coastguard Worker /// two parts of a for loop header.
455*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_for;
456*5a6e8488SAndroid Build Coastguard Worker 
457*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing a read
458*5a6e8488SAndroid Build Coastguard Worker /// expression.
459*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_read;
460*5a6e8488SAndroid Build Coastguard Worker 
461*5a6e8488SAndroid Build Coastguard Worker /// A reference to what tokens are valid as next tokens when parsing a builtin
462*5a6e8488SAndroid Build Coastguard Worker /// function with multiple arguments.
463*5a6e8488SAndroid Build Coastguard Worker extern const BcParseNext bc_parse_next_builtin;
464*5a6e8488SAndroid Build Coastguard Worker 
465*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLED
466*5a6e8488SAndroid Build Coastguard Worker 
467*5a6e8488SAndroid Build Coastguard Worker // If bc is not enabled, execution is always possible because dc has strict
468*5a6e8488SAndroid Build Coastguard Worker // rules that ensure execution can always proceed safely.
469*5a6e8488SAndroid Build Coastguard Worker #define BC_PARSE_NO_EXEC(p) (0)
470*5a6e8488SAndroid Build Coastguard Worker 
471*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
472*5a6e8488SAndroid Build Coastguard Worker 
473*5a6e8488SAndroid Build Coastguard Worker #endif // BC_BC_H
474