xref: /aosp_15_r20/external/bc/include/lang.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 program data.
33*5a6e8488SAndroid Build Coastguard Worker  *
34*5a6e8488SAndroid Build Coastguard Worker  */
35*5a6e8488SAndroid Build Coastguard Worker 
36*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_LANG_H
37*5a6e8488SAndroid Build Coastguard Worker #define BC_LANG_H
38*5a6e8488SAndroid Build Coastguard Worker 
39*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h>
40*5a6e8488SAndroid Build Coastguard Worker 
41*5a6e8488SAndroid Build Coastguard Worker // These have to come first to silence a warning on BC_C11 below.
42*5a6e8488SAndroid Build Coastguard Worker #include <status.h>
43*5a6e8488SAndroid Build Coastguard Worker #include <vector.h>
44*5a6e8488SAndroid Build Coastguard Worker #include <num.h>
45*5a6e8488SAndroid Build Coastguard Worker 
46*5a6e8488SAndroid Build Coastguard Worker #if BC_C11
47*5a6e8488SAndroid Build Coastguard Worker #include <assert.h>
48*5a6e8488SAndroid Build Coastguard Worker #endif // BC_C11
49*5a6e8488SAndroid Build Coastguard Worker 
50*5a6e8488SAndroid Build Coastguard Worker /// The instructions for bytecode.
51*5a6e8488SAndroid Build Coastguard Worker typedef enum BcInst
52*5a6e8488SAndroid Build Coastguard Worker {
53*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
54*5a6e8488SAndroid Build Coastguard Worker 	/// Postfix increment and decrement. Prefix are translated into
55*5a6e8488SAndroid Build Coastguard Worker 	/// BC_INST_ONE with either BC_INST_ASSIGN_PLUS or BC_INST_ASSIGN_MINUS.
56*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_INC = 0,
57*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_DEC,
58*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
59*5a6e8488SAndroid Build Coastguard Worker 
60*5a6e8488SAndroid Build Coastguard Worker 	/// Unary negation.
61*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_NEG,
62*5a6e8488SAndroid Build Coastguard Worker 
63*5a6e8488SAndroid Build Coastguard Worker 	/// Boolean not.
64*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_BOOL_NOT,
65*5a6e8488SAndroid Build Coastguard Worker 
66*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
67*5a6e8488SAndroid Build Coastguard Worker 	/// Truncation operator.
68*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_TRUNC,
69*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
70*5a6e8488SAndroid Build Coastguard Worker 
71*5a6e8488SAndroid Build Coastguard Worker 	/// These should be self-explanatory.
72*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_POWER,
73*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MULTIPLY,
74*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_DIVIDE,
75*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MODULUS,
76*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PLUS,
77*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MINUS,
78*5a6e8488SAndroid Build Coastguard Worker 
79*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
80*5a6e8488SAndroid Build Coastguard Worker 	/// Places operator.
81*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PLACES,
82*5a6e8488SAndroid Build Coastguard Worker 
83*5a6e8488SAndroid Build Coastguard Worker 	/// Shift operators.
84*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_LSHIFT,
85*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_RSHIFT,
86*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
87*5a6e8488SAndroid Build Coastguard Worker 
88*5a6e8488SAndroid Build Coastguard Worker 	/// Comparison operators.
89*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REL_EQ,
90*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REL_LE,
91*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REL_GE,
92*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REL_NE,
93*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REL_LT,
94*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REL_GT,
95*5a6e8488SAndroid Build Coastguard Worker 
96*5a6e8488SAndroid Build Coastguard Worker 	/// Boolean or and and.
97*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_BOOL_OR,
98*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_BOOL_AND,
99*5a6e8488SAndroid Build Coastguard Worker 
100*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
101*5a6e8488SAndroid Build Coastguard Worker 	/// Same as the normal operators, but assigment. So ^=, *=, /=, etc.
102*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_POWER,
103*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_MULTIPLY,
104*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_DIVIDE,
105*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_MODULUS,
106*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_PLUS,
107*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_MINUS,
108*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
109*5a6e8488SAndroid Build Coastguard Worker 	/// Places and shift assignment operators.
110*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_PLACES,
111*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_LSHIFT,
112*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_RSHIFT,
113*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
114*5a6e8488SAndroid Build Coastguard Worker 
115*5a6e8488SAndroid Build Coastguard Worker 	/// Normal assignment.
116*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN,
117*5a6e8488SAndroid Build Coastguard Worker 
118*5a6e8488SAndroid Build Coastguard Worker 	/// bc and dc detect when the value from an assignment is not necessary.
119*5a6e8488SAndroid Build Coastguard Worker 	/// For example, a plain assignment statement means the value is never used.
120*5a6e8488SAndroid Build Coastguard Worker 	/// In those cases, we can get lots of performance back by not even creating
121*5a6e8488SAndroid Build Coastguard Worker 	/// a copy at all. In fact, it saves a copy, a push onto the results stack,
122*5a6e8488SAndroid Build Coastguard Worker 	/// a pop from the results stack, and a free. Definitely worth it to detect.
123*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_POWER_NO_VAL,
124*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_MULTIPLY_NO_VAL,
125*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_DIVIDE_NO_VAL,
126*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_MODULUS_NO_VAL,
127*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_PLUS_NO_VAL,
128*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_MINUS_NO_VAL,
129*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
130*5a6e8488SAndroid Build Coastguard Worker 	/// Same as above.
131*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_PLACES_NO_VAL,
132*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_LSHIFT_NO_VAL,
133*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_RSHIFT_NO_VAL,
134*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
135*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
136*5a6e8488SAndroid Build Coastguard Worker 
137*5a6e8488SAndroid Build Coastguard Worker 	/// Normal assignment that pushes no value on the stack.
138*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASSIGN_NO_VAL,
139*5a6e8488SAndroid Build Coastguard Worker 
140*5a6e8488SAndroid Build Coastguard Worker 	/// Push a constant onto the results stack.
141*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_NUM,
142*5a6e8488SAndroid Build Coastguard Worker 
143*5a6e8488SAndroid Build Coastguard Worker 	/// Push a variable onto the results stack.
144*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_VAR,
145*5a6e8488SAndroid Build Coastguard Worker 
146*5a6e8488SAndroid Build Coastguard Worker 	/// Push an array element onto the results stack.
147*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ARRAY_ELEM,
148*5a6e8488SAndroid Build Coastguard Worker 
149*5a6e8488SAndroid Build Coastguard Worker 	/// Push an array onto the results stack. This is different from pushing an
150*5a6e8488SAndroid Build Coastguard Worker 	/// array *element* onto the results stack; it pushes a reference to the
151*5a6e8488SAndroid Build Coastguard Worker 	/// whole array. This is needed in bc for function arguments that are
152*5a6e8488SAndroid Build Coastguard Worker 	/// arrays. It is also needed for returning the length of an array.
153*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ARRAY,
154*5a6e8488SAndroid Build Coastguard Worker 
155*5a6e8488SAndroid Build Coastguard Worker 	/// Push a zero or a one onto the stack. These are special cased because it
156*5a6e8488SAndroid Build Coastguard Worker 	/// does help performance, particularly for one since inc/dec operators
157*5a6e8488SAndroid Build Coastguard Worker 	/// use it.
158*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ZERO,
159*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ONE,
160*5a6e8488SAndroid Build Coastguard Worker 
161*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
162*5a6e8488SAndroid Build Coastguard Worker 	/// Push the last printed value onto the stack.
163*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_LAST,
164*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
165*5a6e8488SAndroid Build Coastguard Worker 
166*5a6e8488SAndroid Build Coastguard Worker 	/// Push the value of any of the globals onto the stack.
167*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_IBASE,
168*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_OBASE,
169*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_SCALE,
170*5a6e8488SAndroid Build Coastguard Worker 
171*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
172*5a6e8488SAndroid Build Coastguard Worker 	/// Push the value of the seed global onto the stack.
173*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_SEED,
174*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
175*5a6e8488SAndroid Build Coastguard Worker 
176*5a6e8488SAndroid Build Coastguard Worker 	/// These are builtin functions.
177*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_LENGTH,
178*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_SCALE_FUNC,
179*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_SQRT,
180*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ABS,
181*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_IS_NUMBER,
182*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_IS_STRING,
183*5a6e8488SAndroid Build Coastguard Worker 
184*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
185*5a6e8488SAndroid Build Coastguard Worker 	/// Another builtin function.
186*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_IRAND,
187*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
188*5a6e8488SAndroid Build Coastguard Worker 
189*5a6e8488SAndroid Build Coastguard Worker 	/// Asciify.
190*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_ASCIIFY,
191*5a6e8488SAndroid Build Coastguard Worker 
192*5a6e8488SAndroid Build Coastguard Worker 	/// Another builtin function.
193*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_READ,
194*5a6e8488SAndroid Build Coastguard Worker 
195*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
196*5a6e8488SAndroid Build Coastguard Worker 	/// Another builtin function.
197*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_RAND,
198*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
199*5a6e8488SAndroid Build Coastguard Worker 
200*5a6e8488SAndroid Build Coastguard Worker 	/// Return the max for the various globals.
201*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MAXIBASE,
202*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MAXOBASE,
203*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MAXSCALE,
204*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
205*5a6e8488SAndroid Build Coastguard Worker 	/// Return the max value returned by rand().
206*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MAXRAND,
207*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
208*5a6e8488SAndroid Build Coastguard Worker 
209*5a6e8488SAndroid Build Coastguard Worker 	/// bc line_length() builtin function.
210*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_LINE_LENGTH,
211*5a6e8488SAndroid Build Coastguard Worker 
212*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
213*5a6e8488SAndroid Build Coastguard Worker 
214*5a6e8488SAndroid Build Coastguard Worker 	/// bc global_stacks() builtin function.
215*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_GLOBAL_STACKS,
216*5a6e8488SAndroid Build Coastguard Worker 
217*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
218*5a6e8488SAndroid Build Coastguard Worker 
219*5a6e8488SAndroid Build Coastguard Worker 	/// bc leading_zero() builtin function.
220*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_LEADING_ZERO,
221*5a6e8488SAndroid Build Coastguard Worker 
222*5a6e8488SAndroid Build Coastguard Worker 	/// This is slightly misnamed versus BC_INST_PRINT_POP. Well, it is in bc.
223*5a6e8488SAndroid Build Coastguard Worker 	/// dc uses this instruction to print, but not pop. That's valid in dc.
224*5a6e8488SAndroid Build Coastguard Worker 	/// However, in bc, it is *never* valid to print without popping. In bc,
225*5a6e8488SAndroid Build Coastguard Worker 	/// BC_INST_PRINT_POP is used to indicate when a string should be printed
226*5a6e8488SAndroid Build Coastguard Worker 	/// because of a print statement or whether it should be printed raw. The
227*5a6e8488SAndroid Build Coastguard Worker 	/// reason for this is because a print statement handles escaped characters.
228*5a6e8488SAndroid Build Coastguard Worker 	/// So BC_INST_PRINT_POP is for printing a string from a print statement,
229*5a6e8488SAndroid Build Coastguard Worker 	/// BC_INST_PRINT_STR is for printing a string by itself.
230*5a6e8488SAndroid Build Coastguard Worker 	///
231*5a6e8488SAndroid Build Coastguard Worker 	/// In dc, BC_INST_PRINT_POP prints and pops, and BC_INST_PRINT just prints.
232*5a6e8488SAndroid Build Coastguard Worker 	///
233*5a6e8488SAndroid Build Coastguard Worker 	/// Oh, and BC_INST_STR pushes a string onto the results stack.
234*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PRINT,
235*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PRINT_POP,
236*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_STR,
237*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
238*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PRINT_STR,
239*5a6e8488SAndroid Build Coastguard Worker 
240*5a6e8488SAndroid Build Coastguard Worker 	/// Jumps unconditionally.
241*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_JUMP,
242*5a6e8488SAndroid Build Coastguard Worker 
243*5a6e8488SAndroid Build Coastguard Worker 	/// Jumps if the top of the results stack is zero (condition failed). It
244*5a6e8488SAndroid Build Coastguard Worker 	/// turns out that we only want to jump when conditions fail to "skip" code.
245*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_JUMP_ZERO,
246*5a6e8488SAndroid Build Coastguard Worker 
247*5a6e8488SAndroid Build Coastguard Worker 	/// Call a function.
248*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_CALL,
249*5a6e8488SAndroid Build Coastguard Worker 
250*5a6e8488SAndroid Build Coastguard Worker 	/// Return the top of the stack to the caller.
251*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_RET,
252*5a6e8488SAndroid Build Coastguard Worker 
253*5a6e8488SAndroid Build Coastguard Worker 	/// Return 0 to the caller.
254*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_RET0,
255*5a6e8488SAndroid Build Coastguard Worker 
256*5a6e8488SAndroid Build Coastguard Worker 	/// Special return instruction for void functions.
257*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_RET_VOID,
258*5a6e8488SAndroid Build Coastguard Worker 
259*5a6e8488SAndroid Build Coastguard Worker 	/// Special halt instruction.
260*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_HALT,
261*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
262*5a6e8488SAndroid Build Coastguard Worker 
263*5a6e8488SAndroid Build Coastguard Worker 	/// Pop an item off of the results stack.
264*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_POP,
265*5a6e8488SAndroid Build Coastguard Worker 
266*5a6e8488SAndroid Build Coastguard Worker 	/// Swaps the top two items on the results stack.
267*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_SWAP,
268*5a6e8488SAndroid Build Coastguard Worker 
269*5a6e8488SAndroid Build Coastguard Worker 	/// Modular exponentiation.
270*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_MODEXP,
271*5a6e8488SAndroid Build Coastguard Worker 
272*5a6e8488SAndroid Build Coastguard Worker 	/// Do divide and modulus at the same time.
273*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_DIVMOD,
274*5a6e8488SAndroid Build Coastguard Worker 
275*5a6e8488SAndroid Build Coastguard Worker 	/// Turns a number into a string and prints it.
276*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PRINT_STREAM,
277*5a6e8488SAndroid Build Coastguard Worker 
278*5a6e8488SAndroid Build Coastguard Worker #if DC_ENABLED
279*5a6e8488SAndroid Build Coastguard Worker 
280*5a6e8488SAndroid Build Coastguard Worker 	/// dc extended registers command.
281*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_EXTENDED_REGISTERS,
282*5a6e8488SAndroid Build Coastguard Worker 
283*5a6e8488SAndroid Build Coastguard Worker 	/// dc's return; it pops an executing string off of the stack.
284*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_POP_EXEC,
285*5a6e8488SAndroid Build Coastguard Worker 
286*5a6e8488SAndroid Build Coastguard Worker 	/// Unconditionally execute a string.
287*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_EXECUTE,
288*5a6e8488SAndroid Build Coastguard Worker 
289*5a6e8488SAndroid Build Coastguard Worker 	/// Conditionally execute a string.
290*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_EXEC_COND,
291*5a6e8488SAndroid Build Coastguard Worker 
292*5a6e8488SAndroid Build Coastguard Worker 	/// Prints each item on the results stack, separated by newlines.
293*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PRINT_STACK,
294*5a6e8488SAndroid Build Coastguard Worker 
295*5a6e8488SAndroid Build Coastguard Worker 	/// Pops everything off of the results stack.
296*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_CLEAR_STACK,
297*5a6e8488SAndroid Build Coastguard Worker 
298*5a6e8488SAndroid Build Coastguard Worker 	/// Pushes the current length of a register stack onto the results stack.
299*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_REG_STACK_LEN,
300*5a6e8488SAndroid Build Coastguard Worker 
301*5a6e8488SAndroid Build Coastguard Worker 	/// Pushes the current length of the results stack onto the results stack.
302*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_STACK_LEN,
303*5a6e8488SAndroid Build Coastguard Worker 
304*5a6e8488SAndroid Build Coastguard Worker 	/// Pushes a copy of the item on the top of the results stack onto the
305*5a6e8488SAndroid Build Coastguard Worker 	/// results stack.
306*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_DUPLICATE,
307*5a6e8488SAndroid Build Coastguard Worker 
308*5a6e8488SAndroid Build Coastguard Worker 	/// Copies the value in a register and pushes the copy onto the results
309*5a6e8488SAndroid Build Coastguard Worker 	/// stack.
310*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_LOAD,
311*5a6e8488SAndroid Build Coastguard Worker 
312*5a6e8488SAndroid Build Coastguard Worker 	/// Pops an item off of a register stack and pushes it onto the results
313*5a6e8488SAndroid Build Coastguard Worker 	/// stack.
314*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PUSH_VAR,
315*5a6e8488SAndroid Build Coastguard Worker 
316*5a6e8488SAndroid Build Coastguard Worker 	/// Pops an item off of the results stack and pushes it onto a register's
317*5a6e8488SAndroid Build Coastguard Worker 	/// stack.
318*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_PUSH_TO_VAR,
319*5a6e8488SAndroid Build Coastguard Worker 
320*5a6e8488SAndroid Build Coastguard Worker 	/// Quit.
321*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_QUIT,
322*5a6e8488SAndroid Build Coastguard Worker 
323*5a6e8488SAndroid Build Coastguard Worker 	/// Quit executing some number of strings.
324*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_NQUIT,
325*5a6e8488SAndroid Build Coastguard Worker 
326*5a6e8488SAndroid Build Coastguard Worker 	/// Push the depth of the execution stack onto the stack.
327*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_EXEC_STACK_LEN,
328*5a6e8488SAndroid Build Coastguard Worker 
329*5a6e8488SAndroid Build Coastguard Worker #endif // DC_ENABLED
330*5a6e8488SAndroid Build Coastguard Worker 
331*5a6e8488SAndroid Build Coastguard Worker 	/// Invalid instruction.
332*5a6e8488SAndroid Build Coastguard Worker 	BC_INST_INVALID,
333*5a6e8488SAndroid Build Coastguard Worker 
334*5a6e8488SAndroid Build Coastguard Worker } BcInst;
335*5a6e8488SAndroid Build Coastguard Worker 
336*5a6e8488SAndroid Build Coastguard Worker #if BC_C11
337*5a6e8488SAndroid Build Coastguard Worker _Static_assert(BC_INST_INVALID <= UCHAR_MAX,
338*5a6e8488SAndroid Build Coastguard Worker                "Too many instructions to fit into an unsigned char");
339*5a6e8488SAndroid Build Coastguard Worker #endif // BC_C11
340*5a6e8488SAndroid Build Coastguard Worker 
341*5a6e8488SAndroid Build Coastguard Worker /// Used by maps to identify where items are in the array.
342*5a6e8488SAndroid Build Coastguard Worker typedef struct BcId
343*5a6e8488SAndroid Build Coastguard Worker {
344*5a6e8488SAndroid Build Coastguard Worker 	/// The name of the item.
345*5a6e8488SAndroid Build Coastguard Worker 	char* name;
346*5a6e8488SAndroid Build Coastguard Worker 
347*5a6e8488SAndroid Build Coastguard Worker 	/// The index into the array where the item is.
348*5a6e8488SAndroid Build Coastguard Worker 	size_t idx;
349*5a6e8488SAndroid Build Coastguard Worker 
350*5a6e8488SAndroid Build Coastguard Worker } BcId;
351*5a6e8488SAndroid Build Coastguard Worker 
352*5a6e8488SAndroid Build Coastguard Worker /// The location of a var, array, or array element.
353*5a6e8488SAndroid Build Coastguard Worker typedef struct BcLoc
354*5a6e8488SAndroid Build Coastguard Worker {
355*5a6e8488SAndroid Build Coastguard Worker 	/// The index of the var or array.
356*5a6e8488SAndroid Build Coastguard Worker 	size_t loc;
357*5a6e8488SAndroid Build Coastguard Worker 
358*5a6e8488SAndroid Build Coastguard Worker 	/// The index of the array or variable in the array stack. This is to
359*5a6e8488SAndroid Build Coastguard Worker 	/// prevent a bug with getting the wrong array element or variable after a
360*5a6e8488SAndroid Build Coastguard Worker 	/// function call. See the tests/bc/scripts/array.bc test for the array
361*5a6e8488SAndroid Build Coastguard Worker 	/// case; the variable case is in various variable tests.
362*5a6e8488SAndroid Build Coastguard Worker 	size_t stack_idx;
363*5a6e8488SAndroid Build Coastguard Worker 
364*5a6e8488SAndroid Build Coastguard Worker 	/// The index of the array element. Only used for array elements.
365*5a6e8488SAndroid Build Coastguard Worker 	size_t idx;
366*5a6e8488SAndroid Build Coastguard Worker 
367*5a6e8488SAndroid Build Coastguard Worker } BcLoc;
368*5a6e8488SAndroid Build Coastguard Worker 
369*5a6e8488SAndroid Build Coastguard Worker /// An entry for a constant.
370*5a6e8488SAndroid Build Coastguard Worker typedef struct BcConst
371*5a6e8488SAndroid Build Coastguard Worker {
372*5a6e8488SAndroid Build Coastguard Worker 	/// The original string as parsed from the source code.
373*5a6e8488SAndroid Build Coastguard Worker 	char* val;
374*5a6e8488SAndroid Build Coastguard Worker 
375*5a6e8488SAndroid Build Coastguard Worker 	/// The last base that the constant was parsed in.
376*5a6e8488SAndroid Build Coastguard Worker 	BcBigDig base;
377*5a6e8488SAndroid Build Coastguard Worker 
378*5a6e8488SAndroid Build Coastguard Worker 	/// The parsed constant.
379*5a6e8488SAndroid Build Coastguard Worker 	BcNum num;
380*5a6e8488SAndroid Build Coastguard Worker 
381*5a6e8488SAndroid Build Coastguard Worker } BcConst;
382*5a6e8488SAndroid Build Coastguard Worker 
383*5a6e8488SAndroid Build Coastguard Worker /// A function. This is also used in dc, not just bc. The reason is that strings
384*5a6e8488SAndroid Build Coastguard Worker /// are executed in dc, and they are converted to functions in order to be
385*5a6e8488SAndroid Build Coastguard Worker /// executed.
386*5a6e8488SAndroid Build Coastguard Worker typedef struct BcFunc
387*5a6e8488SAndroid Build Coastguard Worker {
388*5a6e8488SAndroid Build Coastguard Worker 	/// The bytecode instructions.
389*5a6e8488SAndroid Build Coastguard Worker 	BcVec code;
390*5a6e8488SAndroid Build Coastguard Worker 
391*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
392*5a6e8488SAndroid Build Coastguard Worker 
393*5a6e8488SAndroid Build Coastguard Worker 	/// The labels. This is a vector of indices. The index is the index into
394*5a6e8488SAndroid Build Coastguard Worker 	/// the bytecode vector where the label is.
395*5a6e8488SAndroid Build Coastguard Worker 	BcVec labels;
396*5a6e8488SAndroid Build Coastguard Worker 
397*5a6e8488SAndroid Build Coastguard Worker 	/// The autos for the function. The first items are the parameters, and the
398*5a6e8488SAndroid Build Coastguard Worker 	/// arguments to the parameters must match the types in this vector.
399*5a6e8488SAndroid Build Coastguard Worker 	BcVec autos;
400*5a6e8488SAndroid Build Coastguard Worker 
401*5a6e8488SAndroid Build Coastguard Worker 	/// The number of parameters the function takes.
402*5a6e8488SAndroid Build Coastguard Worker 	size_t nparams;
403*5a6e8488SAndroid Build Coastguard Worker 
404*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
405*5a6e8488SAndroid Build Coastguard Worker 
406*5a6e8488SAndroid Build Coastguard Worker 	/// The function's name.
407*5a6e8488SAndroid Build Coastguard Worker 	const char* name;
408*5a6e8488SAndroid Build Coastguard Worker 
409*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
410*5a6e8488SAndroid Build Coastguard Worker 	/// True if the function is a void function.
411*5a6e8488SAndroid Build Coastguard Worker 	bool voidfn;
412*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
413*5a6e8488SAndroid Build Coastguard Worker 
414*5a6e8488SAndroid Build Coastguard Worker } BcFunc;
415*5a6e8488SAndroid Build Coastguard Worker 
416*5a6e8488SAndroid Build Coastguard Worker /// Types of results that can be pushed onto the results stack.
417*5a6e8488SAndroid Build Coastguard Worker typedef enum BcResultType
418*5a6e8488SAndroid Build Coastguard Worker {
419*5a6e8488SAndroid Build Coastguard Worker 	/// Result is a variable.
420*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_VAR,
421*5a6e8488SAndroid Build Coastguard Worker 
422*5a6e8488SAndroid Build Coastguard Worker 	/// Result is an array element.
423*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_ARRAY_ELEM,
424*5a6e8488SAndroid Build Coastguard Worker 
425*5a6e8488SAndroid Build Coastguard Worker 	/// Result is an array. This is only allowed for function arguments or
426*5a6e8488SAndroid Build Coastguard Worker 	/// returning the length of the array.
427*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_ARRAY,
428*5a6e8488SAndroid Build Coastguard Worker 
429*5a6e8488SAndroid Build Coastguard Worker 	/// Result is a string.
430*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_STR,
431*5a6e8488SAndroid Build Coastguard Worker 
432*5a6e8488SAndroid Build Coastguard Worker 	/// Result is a temporary. This is used for the result of almost all
433*5a6e8488SAndroid Build Coastguard Worker 	/// expressions.
434*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_TEMP,
435*5a6e8488SAndroid Build Coastguard Worker 
436*5a6e8488SAndroid Build Coastguard Worker 	/// Special casing the two below gave performance improvements.
437*5a6e8488SAndroid Build Coastguard Worker 
438*5a6e8488SAndroid Build Coastguard Worker 	/// Result is a 0.
439*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_ZERO,
440*5a6e8488SAndroid Build Coastguard Worker 
441*5a6e8488SAndroid Build Coastguard Worker 	/// Result is a 1. Useful for inc/dec operators.
442*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_ONE,
443*5a6e8488SAndroid Build Coastguard Worker 
444*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
445*5a6e8488SAndroid Build Coastguard Worker 
446*5a6e8488SAndroid Build Coastguard Worker 	/// Result is the special "last" variable.
447*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_LAST,
448*5a6e8488SAndroid Build Coastguard Worker 
449*5a6e8488SAndroid Build Coastguard Worker 	/// Result is the return value of a void function.
450*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_VOID,
451*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
452*5a6e8488SAndroid Build Coastguard Worker 
453*5a6e8488SAndroid Build Coastguard Worker 	/// Result is the value of ibase.
454*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_IBASE,
455*5a6e8488SAndroid Build Coastguard Worker 
456*5a6e8488SAndroid Build Coastguard Worker 	/// Result is the value of obase.
457*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_OBASE,
458*5a6e8488SAndroid Build Coastguard Worker 
459*5a6e8488SAndroid Build Coastguard Worker 	/// Result is the value of scale.
460*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_SCALE,
461*5a6e8488SAndroid Build Coastguard Worker 
462*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
463*5a6e8488SAndroid Build Coastguard Worker 
464*5a6e8488SAndroid Build Coastguard Worker 	/// Result is the value of seed.
465*5a6e8488SAndroid Build Coastguard Worker 	BC_RESULT_SEED,
466*5a6e8488SAndroid Build Coastguard Worker 
467*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
468*5a6e8488SAndroid Build Coastguard Worker 
469*5a6e8488SAndroid Build Coastguard Worker } BcResultType;
470*5a6e8488SAndroid Build Coastguard Worker 
471*5a6e8488SAndroid Build Coastguard Worker /// A union to store data for various result types.
472*5a6e8488SAndroid Build Coastguard Worker typedef union BcResultData
473*5a6e8488SAndroid Build Coastguard Worker {
474*5a6e8488SAndroid Build Coastguard Worker 	/// A number. Strings are stored here too; they are numbers with
475*5a6e8488SAndroid Build Coastguard Worker 	/// cap == 0 && num == NULL. The string's index into the strings vector is
476*5a6e8488SAndroid Build Coastguard Worker 	/// stored in the scale field. But this is only used for strings stored in
477*5a6e8488SAndroid Build Coastguard Worker 	/// variables.
478*5a6e8488SAndroid Build Coastguard Worker 	BcNum n;
479*5a6e8488SAndroid Build Coastguard Worker 
480*5a6e8488SAndroid Build Coastguard Worker 	/// A vector.
481*5a6e8488SAndroid Build Coastguard Worker 	BcVec v;
482*5a6e8488SAndroid Build Coastguard Worker 
483*5a6e8488SAndroid Build Coastguard Worker 	/// A variable, array, or array element reference. This could also be a
484*5a6e8488SAndroid Build Coastguard Worker 	/// string if a string is not stored in a variable (dc only).
485*5a6e8488SAndroid Build Coastguard Worker 	BcLoc loc;
486*5a6e8488SAndroid Build Coastguard Worker 
487*5a6e8488SAndroid Build Coastguard Worker } BcResultData;
488*5a6e8488SAndroid Build Coastguard Worker 
489*5a6e8488SAndroid Build Coastguard Worker /// A tagged union for results.
490*5a6e8488SAndroid Build Coastguard Worker typedef struct BcResult
491*5a6e8488SAndroid Build Coastguard Worker {
492*5a6e8488SAndroid Build Coastguard Worker 	/// The tag. The type of the result.
493*5a6e8488SAndroid Build Coastguard Worker 	BcResultType t;
494*5a6e8488SAndroid Build Coastguard Worker 
495*5a6e8488SAndroid Build Coastguard Worker 	/// The data. The data for the result.
496*5a6e8488SAndroid Build Coastguard Worker 	BcResultData d;
497*5a6e8488SAndroid Build Coastguard Worker 
498*5a6e8488SAndroid Build Coastguard Worker } BcResult;
499*5a6e8488SAndroid Build Coastguard Worker 
500*5a6e8488SAndroid Build Coastguard Worker /// An instruction pointer. This is how bc knows where in the bytecode vector,
501*5a6e8488SAndroid Build Coastguard Worker /// and which function, the current execution is.
502*5a6e8488SAndroid Build Coastguard Worker typedef struct BcInstPtr
503*5a6e8488SAndroid Build Coastguard Worker {
504*5a6e8488SAndroid Build Coastguard Worker 	/// The index of the currently executing function in the fns vector.
505*5a6e8488SAndroid Build Coastguard Worker 	size_t func;
506*5a6e8488SAndroid Build Coastguard Worker 
507*5a6e8488SAndroid Build Coastguard Worker 	/// The index into the bytecode vector of the *next* instruction.
508*5a6e8488SAndroid Build Coastguard Worker 	size_t idx;
509*5a6e8488SAndroid Build Coastguard Worker 
510*5a6e8488SAndroid Build Coastguard Worker 	/// The length of the results vector when this function started executing.
511*5a6e8488SAndroid Build Coastguard Worker 	/// This is mostly used for bc where functions should not affect the results
512*5a6e8488SAndroid Build Coastguard Worker 	/// of their callers.
513*5a6e8488SAndroid Build Coastguard Worker 	size_t len;
514*5a6e8488SAndroid Build Coastguard Worker 
515*5a6e8488SAndroid Build Coastguard Worker } BcInstPtr;
516*5a6e8488SAndroid Build Coastguard Worker 
517*5a6e8488SAndroid Build Coastguard Worker /// Types of identifiers.
518*5a6e8488SAndroid Build Coastguard Worker typedef enum BcType
519*5a6e8488SAndroid Build Coastguard Worker {
520*5a6e8488SAndroid Build Coastguard Worker 	/// Variable.
521*5a6e8488SAndroid Build Coastguard Worker 	BC_TYPE_VAR,
522*5a6e8488SAndroid Build Coastguard Worker 
523*5a6e8488SAndroid Build Coastguard Worker 	/// Array.
524*5a6e8488SAndroid Build Coastguard Worker 	BC_TYPE_ARRAY,
525*5a6e8488SAndroid Build Coastguard Worker 
526*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
527*5a6e8488SAndroid Build Coastguard Worker 
528*5a6e8488SAndroid Build Coastguard Worker 	/// Array reference.
529*5a6e8488SAndroid Build Coastguard Worker 	BC_TYPE_REF,
530*5a6e8488SAndroid Build Coastguard Worker 
531*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
532*5a6e8488SAndroid Build Coastguard Worker 
533*5a6e8488SAndroid Build Coastguard Worker } BcType;
534*5a6e8488SAndroid Build Coastguard Worker 
535*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
536*5a6e8488SAndroid Build Coastguard Worker /// An auto variable in bc.
537*5a6e8488SAndroid Build Coastguard Worker typedef struct BcAuto
538*5a6e8488SAndroid Build Coastguard Worker {
539*5a6e8488SAndroid Build Coastguard Worker 	/// The index of the variable in the vars or arrs vectors.
540*5a6e8488SAndroid Build Coastguard Worker 	size_t idx;
541*5a6e8488SAndroid Build Coastguard Worker 
542*5a6e8488SAndroid Build Coastguard Worker 	/// The type of the variable.
543*5a6e8488SAndroid Build Coastguard Worker 	BcType type;
544*5a6e8488SAndroid Build Coastguard Worker 
545*5a6e8488SAndroid Build Coastguard Worker } BcAuto;
546*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
547*5a6e8488SAndroid Build Coastguard Worker 
548*5a6e8488SAndroid Build Coastguard Worker /// Forward declaration.
549*5a6e8488SAndroid Build Coastguard Worker struct BcProgram;
550*5a6e8488SAndroid Build Coastguard Worker 
551*5a6e8488SAndroid Build Coastguard Worker /**
552*5a6e8488SAndroid Build Coastguard Worker  * Initializes a function.
553*5a6e8488SAndroid Build Coastguard Worker  * @param f     The function to initialize.
554*5a6e8488SAndroid Build Coastguard Worker  * @param name  The name of the function. The string is assumed to be owned by
555*5a6e8488SAndroid Build Coastguard Worker  *              some other entity.
556*5a6e8488SAndroid Build Coastguard Worker  */
557*5a6e8488SAndroid Build Coastguard Worker void
558*5a6e8488SAndroid Build Coastguard Worker bc_func_init(BcFunc* f, const char* name);
559*5a6e8488SAndroid Build Coastguard Worker 
560*5a6e8488SAndroid Build Coastguard Worker /**
561*5a6e8488SAndroid Build Coastguard Worker  * Inserts an auto into the function.
562*5a6e8488SAndroid Build Coastguard Worker  * @param f     The function to insert into.
563*5a6e8488SAndroid Build Coastguard Worker  * @param p     The program. This is to search for the variable or array name.
564*5a6e8488SAndroid Build Coastguard Worker  * @param name  The name of the auto to insert.
565*5a6e8488SAndroid Build Coastguard Worker  * @param type  The type of the auto.
566*5a6e8488SAndroid Build Coastguard Worker  * @param line  The line in the source code where the insert happened. This is
567*5a6e8488SAndroid Build Coastguard Worker  *              solely for error reporting.
568*5a6e8488SAndroid Build Coastguard Worker  */
569*5a6e8488SAndroid Build Coastguard Worker void
570*5a6e8488SAndroid Build Coastguard Worker bc_func_insert(BcFunc* f, struct BcProgram* p, char* name, BcType type,
571*5a6e8488SAndroid Build Coastguard Worker                size_t line);
572*5a6e8488SAndroid Build Coastguard Worker 
573*5a6e8488SAndroid Build Coastguard Worker /**
574*5a6e8488SAndroid Build Coastguard Worker  * Resets a function in preparation for it to be reused. This can happen in bc
575*5a6e8488SAndroid Build Coastguard Worker  * because it is a dynamic language and functions can be redefined.
576*5a6e8488SAndroid Build Coastguard Worker  * @param f  The functio to reset.
577*5a6e8488SAndroid Build Coastguard Worker  */
578*5a6e8488SAndroid Build Coastguard Worker void
579*5a6e8488SAndroid Build Coastguard Worker bc_func_reset(BcFunc* f);
580*5a6e8488SAndroid Build Coastguard Worker 
581*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG
582*5a6e8488SAndroid Build Coastguard Worker /**
583*5a6e8488SAndroid Build Coastguard Worker  * Frees a function. This is a destructor. This is only used in debug builds
584*5a6e8488SAndroid Build Coastguard Worker  * because all functions are freed at exit. We free them in debug builds to
585*5a6e8488SAndroid Build Coastguard Worker  * check for memory leaks.
586*5a6e8488SAndroid Build Coastguard Worker  * @param func  The function to free as a void pointer.
587*5a6e8488SAndroid Build Coastguard Worker  */
588*5a6e8488SAndroid Build Coastguard Worker void
589*5a6e8488SAndroid Build Coastguard Worker bc_func_free(void* func);
590*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG
591*5a6e8488SAndroid Build Coastguard Worker 
592*5a6e8488SAndroid Build Coastguard Worker /**
593*5a6e8488SAndroid Build Coastguard Worker  * Initializes an array, which is the array type in bc and dc source code. Since
594*5a6e8488SAndroid Build Coastguard Worker  * variables and arrays are both arrays (see the development manual,
595*5a6e8488SAndroid Build Coastguard Worker  * manuals/development.md#execution, for more information), the @a nums
596*5a6e8488SAndroid Build Coastguard Worker  * parameter tells bc whether to initialize an array of numbers or an array of
597*5a6e8488SAndroid Build Coastguard Worker  * arrays of numbers. If the latter, it does a recursive call with nums set to
598*5a6e8488SAndroid Build Coastguard Worker  * true.
599*5a6e8488SAndroid Build Coastguard Worker  * @param a     The array to initialize.
600*5a6e8488SAndroid Build Coastguard Worker  * @param nums  True if the array should be for numbers, false if it should be
601*5a6e8488SAndroid Build Coastguard Worker  *              for vectors.
602*5a6e8488SAndroid Build Coastguard Worker  */
603*5a6e8488SAndroid Build Coastguard Worker void
604*5a6e8488SAndroid Build Coastguard Worker bc_array_init(BcVec* a, bool nums);
605*5a6e8488SAndroid Build Coastguard Worker 
606*5a6e8488SAndroid Build Coastguard Worker /**
607*5a6e8488SAndroid Build Coastguard Worker  * Copies an array to another array. This is used to do pass arrays to functions
608*5a6e8488SAndroid Build Coastguard Worker  * that do not take references to arrays. The arrays are passed entirely by
609*5a6e8488SAndroid Build Coastguard Worker  * value, which means that they need to be copied.
610*5a6e8488SAndroid Build Coastguard Worker  * @param d  The destination array.
611*5a6e8488SAndroid Build Coastguard Worker  * @param s  The source array.
612*5a6e8488SAndroid Build Coastguard Worker  */
613*5a6e8488SAndroid Build Coastguard Worker void
614*5a6e8488SAndroid Build Coastguard Worker bc_array_copy(BcVec* d, const BcVec* s);
615*5a6e8488SAndroid Build Coastguard Worker 
616*5a6e8488SAndroid Build Coastguard Worker /**
617*5a6e8488SAndroid Build Coastguard Worker  * Frees a string stored in a function. This is a destructor.
618*5a6e8488SAndroid Build Coastguard Worker  * @param string  The string to free as a void pointer.
619*5a6e8488SAndroid Build Coastguard Worker  */
620*5a6e8488SAndroid Build Coastguard Worker void
621*5a6e8488SAndroid Build Coastguard Worker bc_string_free(void* string);
622*5a6e8488SAndroid Build Coastguard Worker 
623*5a6e8488SAndroid Build Coastguard Worker /**
624*5a6e8488SAndroid Build Coastguard Worker  * Frees a constant stored in a function. This is a destructor.
625*5a6e8488SAndroid Build Coastguard Worker  * @param constant  The constant to free as a void pointer.
626*5a6e8488SAndroid Build Coastguard Worker  */
627*5a6e8488SAndroid Build Coastguard Worker void
628*5a6e8488SAndroid Build Coastguard Worker bc_const_free(void* constant);
629*5a6e8488SAndroid Build Coastguard Worker 
630*5a6e8488SAndroid Build Coastguard Worker /**
631*5a6e8488SAndroid Build Coastguard Worker  * Clears a result. It sets the type to BC_RESULT_TEMP and clears the union by
632*5a6e8488SAndroid Build Coastguard Worker  * clearing the BcNum in the union. This is to ensure that bc does not use
633*5a6e8488SAndroid Build Coastguard Worker  * uninitialized data.
634*5a6e8488SAndroid Build Coastguard Worker  * @param r  The result to clear.
635*5a6e8488SAndroid Build Coastguard Worker  */
636*5a6e8488SAndroid Build Coastguard Worker void
637*5a6e8488SAndroid Build Coastguard Worker bc_result_clear(BcResult* r);
638*5a6e8488SAndroid Build Coastguard Worker 
639*5a6e8488SAndroid Build Coastguard Worker /**
640*5a6e8488SAndroid Build Coastguard Worker  * Copies a result into another. This is done for things like duplicating the
641*5a6e8488SAndroid Build Coastguard Worker  * top of the results stack or copying the result of an assignment to put back
642*5a6e8488SAndroid Build Coastguard Worker  * on the results stack.
643*5a6e8488SAndroid Build Coastguard Worker  * @param d    The destination result.
644*5a6e8488SAndroid Build Coastguard Worker  * @param src  The source result.
645*5a6e8488SAndroid Build Coastguard Worker  */
646*5a6e8488SAndroid Build Coastguard Worker void
647*5a6e8488SAndroid Build Coastguard Worker bc_result_copy(BcResult* d, BcResult* src);
648*5a6e8488SAndroid Build Coastguard Worker 
649*5a6e8488SAndroid Build Coastguard Worker /**
650*5a6e8488SAndroid Build Coastguard Worker  * Frees a result. This is a destructor.
651*5a6e8488SAndroid Build Coastguard Worker  * @param result  The result to free as a void pointer.
652*5a6e8488SAndroid Build Coastguard Worker  */
653*5a6e8488SAndroid Build Coastguard Worker void
654*5a6e8488SAndroid Build Coastguard Worker bc_result_free(void* result);
655*5a6e8488SAndroid Build Coastguard Worker 
656*5a6e8488SAndroid Build Coastguard Worker /**
657*5a6e8488SAndroid Build Coastguard Worker  * Expands an array to @a len. This can happen because in bc, you do not have to
658*5a6e8488SAndroid Build Coastguard Worker  * explicitly initialize elements of an array. If you access an element that is
659*5a6e8488SAndroid Build Coastguard Worker  * not initialized, the array is expanded to fit it, and all missing elements
660*5a6e8488SAndroid Build Coastguard Worker  * are initialized to 0 if they are numbers, or arrays with one element of 0.
661*5a6e8488SAndroid Build Coastguard Worker  * This function does that expansion.
662*5a6e8488SAndroid Build Coastguard Worker  * @param a    The array to expand.
663*5a6e8488SAndroid Build Coastguard Worker  * @param len  The length to expand to.
664*5a6e8488SAndroid Build Coastguard Worker  */
665*5a6e8488SAndroid Build Coastguard Worker void
666*5a6e8488SAndroid Build Coastguard Worker bc_array_expand(BcVec* a, size_t len);
667*5a6e8488SAndroid Build Coastguard Worker 
668*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
669*5a6e8488SAndroid Build Coastguard Worker 
670*5a6e8488SAndroid Build Coastguard Worker /**
671*5a6e8488SAndroid Build Coastguard Worker  * Returns non-zero if the bytecode instruction i is an assignment instruction.
672*5a6e8488SAndroid Build Coastguard Worker  * @param i  The instruction to test.
673*5a6e8488SAndroid Build Coastguard Worker  * @return   Non-zero if i is an assignment instruction, zero otherwise.
674*5a6e8488SAndroid Build Coastguard Worker  */
675*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_IS_ASSIGN(i) \
676*5a6e8488SAndroid Build Coastguard Worker 	((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL)
677*5a6e8488SAndroid Build Coastguard Worker 
678*5a6e8488SAndroid Build Coastguard Worker /**
679*5a6e8488SAndroid Build Coastguard Worker  * Returns true if the bytecode instruction @a i requires the value to be
680*5a6e8488SAndroid Build Coastguard Worker  * returned for use.
681*5a6e8488SAndroid Build Coastguard Worker  * @param i  The instruction to test.
682*5a6e8488SAndroid Build Coastguard Worker  * @return   True if @a i requires the value to be returned for use, false
683*5a6e8488SAndroid Build Coastguard Worker  *           otherwise.
684*5a6e8488SAndroid Build Coastguard Worker  */
685*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN)
686*5a6e8488SAndroid Build Coastguard Worker 
687*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLED
688*5a6e8488SAndroid Build Coastguard Worker 
689*5a6e8488SAndroid Build Coastguard Worker /**
690*5a6e8488SAndroid Build Coastguard Worker  * Returns non-zero if the bytecode instruction i is an assignment instruction.
691*5a6e8488SAndroid Build Coastguard Worker  * @param i  The instruction to test.
692*5a6e8488SAndroid Build Coastguard Worker  * @return   Non-zero if i is an assignment instruction, zero otherwise.
693*5a6e8488SAndroid Build Coastguard Worker  */
694*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL)
695*5a6e8488SAndroid Build Coastguard Worker 
696*5a6e8488SAndroid Build Coastguard Worker /**
697*5a6e8488SAndroid Build Coastguard Worker  * Returns true if the bytecode instruction @a i requires the value to be
698*5a6e8488SAndroid Build Coastguard Worker  * returned for use.
699*5a6e8488SAndroid Build Coastguard Worker  * @param i  The instruction to test.
700*5a6e8488SAndroid Build Coastguard Worker  * @return   True if @a i requires the value to be returned for use, false
701*5a6e8488SAndroid Build Coastguard Worker  *           otherwise.
702*5a6e8488SAndroid Build Coastguard Worker  */
703*5a6e8488SAndroid Build Coastguard Worker #define BC_INST_USE_VAL(i) (false)
704*5a6e8488SAndroid Build Coastguard Worker 
705*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
706*5a6e8488SAndroid Build Coastguard Worker 
707*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG_CODE
708*5a6e8488SAndroid Build Coastguard Worker /// Reference to string names for all of the instructions. For debugging.
709*5a6e8488SAndroid Build Coastguard Worker extern const char* bc_inst_names[];
710*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE
711*5a6e8488SAndroid Build Coastguard Worker 
712*5a6e8488SAndroid Build Coastguard Worker /// References to the names of the main and read functions.
713*5a6e8488SAndroid Build Coastguard Worker extern const char bc_func_main[];
714*5a6e8488SAndroid Build Coastguard Worker extern const char bc_func_read[];
715*5a6e8488SAndroid Build Coastguard Worker 
716*5a6e8488SAndroid Build Coastguard Worker #endif // BC_LANG_H
717