1/*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * * Redistributions of source code must retain the above copyright notice, this
12 *   list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright notice,
15 *   this list of conditions and the following disclaimer in the documentation
16 *   and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 * *****************************************************************************
31 *
32 * The parser for bc.
33 *
34 */
35
36#if BC_ENABLED
37
38#include <assert.h>
39#include <stdbool.h>
40#include <stdlib.h>
41#include <string.h>
42
43#include <setjmp.h>
44
45#include <bc.h>
46#include <num.h>
47#include <vm.h>
48
49static void bc_parse_else(BcParse *p);
50static void bc_parse_stmt(BcParse *p);
51static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags,
52                                       BcParseNext next);
53
54static bool bc_parse_inst_isLeaf(BcInst t) {
55	return (t >= BC_INST_NUM && t <= BC_INST_MAXSCALE) ||
56#if BC_ENABLE_EXTRA_MATH
57	        t == BC_INST_TRUNC ||
58#endif // BC_ENABLE_EXTRA_MATH
59	        t <= BC_INST_DEC;
60}
61
62static bool bc_parse_isDelimiter(const BcParse *p) {
63
64	BcLexType t = p->l.t;
65	bool good = false;
66
67	if (BC_PARSE_DELIMITER(t)) return true;
68
69	if (t == BC_LEX_KW_ELSE) {
70
71		size_t i;
72		uint16_t *fptr = NULL, flags = BC_PARSE_FLAG_ELSE;
73
74		for (i = 0; i < p->flags.len && BC_PARSE_BLOCK_STMT(flags); ++i) {
75
76			fptr = bc_vec_item_rev(&p->flags, i);
77			flags = *fptr;
78
79			if ((flags & BC_PARSE_FLAG_BRACE) && p->l.last != BC_LEX_RBRACE)
80				return false;
81		}
82
83		good = ((flags & BC_PARSE_FLAG_IF) != 0);
84	}
85	else if (t == BC_LEX_RBRACE) {
86
87		size_t i;
88
89		for (i = 0; !good && i < p->flags.len; ++i) {
90			uint16_t *fptr = bc_vec_item_rev(&p->flags, i);
91			good = (((*fptr) & BC_PARSE_FLAG_BRACE) != 0);
92		}
93	}
94
95	return good;
96}
97
98static void bc_parse_setLabel(BcParse *p) {
99
100	BcFunc *func = p->func;
101	BcInstPtr *ip = bc_vec_top(&p->exits);
102	size_t *label;
103
104	assert(func == bc_vec_item(&p->prog->fns, p->fidx));
105
106	label = bc_vec_item(&func->labels, ip->idx);
107	*label = func->code.len;
108
109	bc_vec_pop(&p->exits);
110}
111
112static void bc_parse_createLabel(BcParse *p, size_t idx) {
113	bc_vec_push(&p->func->labels, &idx);
114}
115
116static void bc_parse_createCondLabel(BcParse *p, size_t idx) {
117	bc_parse_createLabel(p, p->func->code.len);
118	bc_vec_push(&p->conds, &idx);
119}
120
121static void bc_parse_createExitLabel(BcParse *p, size_t idx, bool loop) {
122
123	BcInstPtr ip;
124
125	assert(p->func == bc_vec_item(&p->prog->fns, p->fidx));
126
127	ip.func = loop;
128	ip.idx = idx;
129	ip.len = 0;
130
131	bc_vec_push(&p->exits, &ip);
132	bc_parse_createLabel(p, SIZE_MAX);
133}
134
135static void bc_parse_operator(BcParse *p, BcLexType type,
136                              size_t start, size_t *nexprs)
137{
138	BcLexType t;
139	uchar l, r = BC_PARSE_OP_PREC(type);
140	uchar left = BC_PARSE_OP_LEFT(type);
141
142	while (p->ops.len > start) {
143
144		t = BC_PARSE_TOP_OP(p);
145		if (t == BC_LEX_LPAREN) break;
146
147		l = BC_PARSE_OP_PREC(t);
148		if (l >= r && (l != r || !left)) break;
149
150		bc_parse_push(p, BC_PARSE_TOKEN_INST(t));
151		bc_vec_pop(&p->ops);
152		*nexprs -= !BC_PARSE_OP_PREFIX(t);
153	}
154
155	bc_vec_push(&p->ops, &type);
156}
157
158static void bc_parse_rightParen(BcParse *p, size_t *nexs) {
159
160	BcLexType top;
161
162	while ((top = BC_PARSE_TOP_OP(p)) != BC_LEX_LPAREN) {
163		bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
164		bc_vec_pop(&p->ops);
165		*nexs -= !BC_PARSE_OP_PREFIX(top);
166	}
167
168	bc_vec_pop(&p->ops);
169
170	bc_lex_next(&p->l);
171}
172
173static void bc_parse_params(BcParse *p, uint8_t flags) {
174
175	bool comma = false;
176	size_t nparams;
177
178	bc_lex_next(&p->l);
179
180	flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
181	flags |= (BC_PARSE_ARRAY | BC_PARSE_NEEDVAL);
182
183	for (nparams = 0; p->l.t != BC_LEX_RPAREN; ++nparams) {
184
185		bc_parse_expr_status(p, flags, bc_parse_next_param);
186
187		comma = (p->l.t == BC_LEX_COMMA);
188		if (comma) bc_lex_next(&p->l);
189	}
190
191	if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
192	bc_parse_push(p, BC_INST_CALL);
193	bc_parse_pushIndex(p, nparams);
194}
195
196static void bc_parse_call(BcParse *p, const char *name, uint8_t flags) {
197
198	size_t idx;
199
200	bc_parse_params(p, flags);
201
202	// We just assert this because bc_parse_params() should
203	// ensure that the next token is what it should be.
204	assert(p->l.t == BC_LEX_RPAREN);
205
206	// We cannot use bc_program_insertFunc() here
207	// because it will overwrite an existing function.
208	idx = bc_map_index(&p->prog->fn_map, name);
209
210	if (idx == BC_VEC_INVALID_IDX) {
211
212		BC_SIG_LOCK;
213
214		idx = bc_program_insertFunc(p->prog, name);
215
216		BC_SIG_UNLOCK;
217
218		assert(idx != BC_VEC_INVALID_IDX);
219
220		// Make sure that this pointer was not invalidated.
221		p->func = bc_vec_item(&p->prog->fns, p->fidx);
222	}
223	else idx = ((BcId*) bc_vec_item(&p->prog->fn_map, idx))->idx;
224
225	bc_parse_pushIndex(p, idx);
226
227	bc_lex_next(&p->l);
228}
229
230static void bc_parse_name(BcParse *p, BcInst *type,
231                          bool *can_assign, uint8_t flags)
232{
233	char *name;
234
235	BC_SIG_LOCK;
236
237	name = bc_vm_strdup(p->l.str.v);
238
239	BC_SETJMP_LOCKED(err);
240
241	BC_SIG_UNLOCK;
242
243	bc_lex_next(&p->l);
244
245	if (p->l.t == BC_LEX_LBRACKET) {
246
247		bc_lex_next(&p->l);
248
249		if (p->l.t == BC_LEX_RBRACKET) {
250
251			if (BC_ERR(!(flags & BC_PARSE_ARRAY)))
252				bc_parse_err(p, BC_ERR_PARSE_EXPR);
253
254			*type = BC_INST_ARRAY;
255			*can_assign = false;
256		}
257		else {
258
259			uint8_t flags2 = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) |
260			    BC_PARSE_NEEDVAL;
261
262			bc_parse_expr_status(p, flags2, bc_parse_next_elem);
263
264			if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
265				bc_parse_err(p, BC_ERR_PARSE_TOKEN);
266
267			*type = BC_INST_ARRAY_ELEM;
268			*can_assign = true;
269		}
270
271		bc_lex_next(&p->l);
272
273		bc_parse_push(p, *type);
274		bc_parse_pushName(p, name, false);
275	}
276	else if (p->l.t == BC_LEX_LPAREN) {
277
278		if (BC_ERR(flags & BC_PARSE_NOCALL))
279			bc_parse_err(p, BC_ERR_PARSE_TOKEN);
280
281		*type = BC_INST_CALL;
282		*can_assign = false;
283
284		bc_parse_call(p, name, flags);
285	}
286	else {
287		*type = BC_INST_VAR;
288		*can_assign = true;
289		bc_parse_push(p, BC_INST_VAR);
290		bc_parse_pushName(p, name, true);
291	}
292
293err:
294	BC_SIG_MAYLOCK;
295	free(name);
296	BC_LONGJMP_CONT;
297}
298
299static void bc_parse_noArgBuiltin(BcParse *p, BcInst inst) {
300
301	bc_lex_next(&p->l);
302	if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
303
304	bc_lex_next(&p->l);
305	if ((p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
306
307	bc_parse_push(p, inst);
308
309	bc_lex_next(&p->l);
310}
311
312static void bc_parse_builtin(BcParse *p, BcLexType type,
313                             uint8_t flags, BcInst *prev)
314{
315	bc_lex_next(&p->l);
316	if (BC_ERR(p->l.t != BC_LEX_LPAREN))
317		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
318
319	bc_lex_next(&p->l);
320
321	flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
322	flags |= BC_PARSE_NEEDVAL;
323	if (type == BC_LEX_KW_LENGTH) flags |= BC_PARSE_ARRAY;
324
325	bc_parse_expr_status(p, flags, bc_parse_next_rel);
326
327	if (BC_ERR(p->l.t != BC_LEX_RPAREN))
328		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
329
330	*prev = type - BC_LEX_KW_LENGTH + BC_INST_LENGTH;
331	bc_parse_push(p, *prev);
332
333	bc_lex_next(&p->l);
334}
335
336static void bc_parse_scale(BcParse *p, BcInst *type,
337                               bool *can_assign, uint8_t flags)
338{
339	bc_lex_next(&p->l);
340
341	if (p->l.t != BC_LEX_LPAREN) {
342		*type = BC_INST_SCALE;
343		*can_assign = true;
344		bc_parse_push(p, BC_INST_SCALE);
345		return;
346	}
347
348	*type = BC_INST_SCALE_FUNC;
349	*can_assign = false;
350	flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
351	flags |= BC_PARSE_NEEDVAL;
352
353	bc_lex_next(&p->l);
354
355	bc_parse_expr_status(p, flags, bc_parse_next_rel);
356	if (BC_ERR(p->l.t != BC_LEX_RPAREN))
357		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
358
359	bc_parse_push(p, BC_INST_SCALE_FUNC);
360
361	bc_lex_next(&p->l);
362}
363
364static void bc_parse_incdec(BcParse *p, BcInst *prev, bool *can_assign,
365                            size_t *nexs, uint8_t flags)
366{
367	BcLexType type;
368	uchar inst;
369	BcInst etype = *prev;
370	BcLexType last = p->l.last;
371
372	assert(prev != NULL && can_assign != NULL);
373
374	if (BC_ERR(last == BC_LEX_OP_INC || last == BC_LEX_OP_DEC ||
375	           last == BC_LEX_RPAREN))
376	{
377		bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
378	}
379
380	if (BC_PARSE_INST_VAR(etype)) {
381
382		if (!*can_assign) bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
383
384		*prev = inst = BC_INST_INC + (p->l.t != BC_LEX_OP_INC);
385		bc_parse_push(p, inst);
386		bc_lex_next(&p->l);
387		*can_assign = false;
388	}
389	else {
390
391		*prev = inst = BC_INST_ASSIGN_PLUS + (p->l.t != BC_LEX_OP_INC);
392
393		bc_lex_next(&p->l);
394		type = p->l.t;
395
396		// Because we parse the next part of the expression
397		// right here, we need to increment this.
398		*nexs = *nexs + 1;
399
400		if (type == BC_LEX_NAME) {
401			uint8_t flags2 = flags & ~BC_PARSE_ARRAY;
402			bc_parse_name(p, prev, can_assign, flags2 | BC_PARSE_NOCALL);
403		}
404		else if (type >= BC_LEX_KW_LAST && type <= BC_LEX_KW_OBASE) {
405			bc_parse_push(p, type - BC_LEX_KW_LAST + BC_INST_LAST);
406			bc_lex_next(&p->l);
407		}
408		else if (BC_NO_ERR(type == BC_LEX_KW_SCALE)) {
409
410			bc_lex_next(&p->l);
411
412			if (BC_ERR(p->l.t == BC_LEX_LPAREN))
413				bc_parse_err(p, BC_ERR_PARSE_TOKEN);
414			else bc_parse_push(p, BC_INST_SCALE);
415		}
416		else bc_parse_err(p, BC_ERR_PARSE_TOKEN);
417
418		*can_assign = false;
419
420		bc_parse_push(p, BC_INST_ONE);
421		bc_parse_push(p, inst);
422	}
423}
424
425static void bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn,
426                           bool rparen, bool binlast, size_t *nexprs)
427{
428	BcLexType type;
429
430	bc_lex_next(&p->l);
431
432	type = BC_PARSE_LEAF(*prev, binlast, rparen) ? BC_LEX_OP_MINUS : BC_LEX_NEG;
433	*prev = BC_PARSE_TOKEN_INST(type);
434
435	// We can just push onto the op stack because this is the largest
436	// precedence operator that gets pushed. Inc/dec does not.
437	if (type != BC_LEX_OP_MINUS) bc_vec_push(&p->ops, &type);
438	else bc_parse_operator(p, type, ops_bgn, nexprs);
439}
440
441static void bc_parse_str(BcParse *p, char inst) {
442	bc_parse_addString(p);
443	bc_parse_push(p, inst);
444	bc_lex_next(&p->l);
445}
446
447static void bc_parse_print(BcParse *p) {
448
449	BcLexType t;
450	bool comma = false;
451
452	bc_lex_next(&p->l);
453
454	t = p->l.t;
455
456	if (bc_parse_isDelimiter(p)) bc_parse_err(p, BC_ERR_PARSE_PRINT);
457
458	do {
459		if (t == BC_LEX_STR) bc_parse_str(p, BC_INST_PRINT_POP);
460		else {
461			bc_parse_expr_status(p, BC_PARSE_NEEDVAL, bc_parse_next_print);
462			bc_parse_push(p, BC_INST_PRINT_POP);
463		}
464
465		comma = (p->l.t == BC_LEX_COMMA);
466
467		if (comma) bc_lex_next(&p->l);
468		else {
469			if (!bc_parse_isDelimiter(p))
470				bc_parse_err(p, BC_ERR_PARSE_TOKEN);
471			else break;
472		}
473
474		t = p->l.t;
475	} while (true);
476
477	if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
478}
479
480static void bc_parse_return(BcParse *p) {
481
482	BcLexType t;
483	bool paren;
484	uchar inst = BC_INST_RET0;
485
486	if (BC_ERR(!BC_PARSE_FUNC(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
487
488	if (p->func->voidfn) inst = BC_INST_RET_VOID;
489
490	bc_lex_next(&p->l);
491
492	t = p->l.t;
493	paren = t == BC_LEX_LPAREN;
494
495	if (bc_parse_isDelimiter(p)) bc_parse_push(p, inst);
496	else {
497
498		BcParseStatus s;
499
500		s = bc_parse_expr_err(p, BC_PARSE_NEEDVAL, bc_parse_next_expr);
501
502		if (s == BC_PARSE_STATUS_EMPTY_EXPR) {
503			bc_parse_push(p, inst);
504			bc_lex_next(&p->l);
505		}
506
507		if (!paren || p->l.last != BC_LEX_RPAREN) {
508			bc_parse_err(p, BC_ERR_POSIX_RET);
509		}
510		else if (BC_ERR(p->func->voidfn))
511			bc_parse_verr(p, BC_ERR_PARSE_RET_VOID, p->func->name);
512
513		bc_parse_push(p, BC_INST_RET);
514	}
515}
516
517static void bc_parse_noElse(BcParse *p) {
518	uint16_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
519	*flag_ptr = (*flag_ptr & ~(BC_PARSE_FLAG_IF_END));
520	bc_parse_setLabel(p);
521}
522
523static void bc_parse_endBody(BcParse *p, bool brace) {
524
525	bool has_brace, new_else = false;
526
527	if (BC_ERR(p->flags.len <= 1)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
528
529	if (brace) {
530
531		assert(p->l.t == BC_LEX_RBRACE);
532
533		bc_lex_next(&p->l);
534		if (BC_ERR(!bc_parse_isDelimiter(p)))
535			bc_parse_err(p, BC_ERR_PARSE_TOKEN);
536	}
537
538	has_brace = (BC_PARSE_BRACE(p) != 0);
539
540	do {
541		size_t len = p->flags.len;
542		bool loop;
543
544		if (has_brace && !brace) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
545
546		loop = (BC_PARSE_LOOP_INNER(p) != 0);
547
548		if (loop || BC_PARSE_ELSE(p)) {
549
550			if (loop) {
551
552				size_t *label = bc_vec_top(&p->conds);
553
554				bc_parse_push(p, BC_INST_JUMP);
555				bc_parse_pushIndex(p, *label);
556
557				bc_vec_pop(&p->conds);
558			}
559
560			bc_parse_setLabel(p);
561			bc_vec_pop(&p->flags);
562		}
563		else if (BC_PARSE_FUNC_INNER(p)) {
564			BcInst inst = (p->func->voidfn ? BC_INST_RET_VOID : BC_INST_RET0);
565			bc_parse_push(p, inst);
566			bc_parse_updateFunc(p, BC_PROG_MAIN);
567			bc_vec_pop(&p->flags);
568		}
569		else if (BC_PARSE_BRACE(p) && !BC_PARSE_IF(p)) bc_vec_pop(&p->flags);
570
571		// This needs to be last to parse nested if's properly.
572		if (BC_PARSE_IF(p) && (len == p->flags.len || !BC_PARSE_BRACE(p))) {
573
574			while (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
575
576			bc_vec_pop(&p->flags);
577
578			if (!BC_S) {
579
580				*(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_IF_END;
581				new_else = (p->l.t == BC_LEX_KW_ELSE);
582
583				if (new_else) bc_parse_else(p);
584				else if (!has_brace && (!BC_PARSE_IF_END(p) || brace))
585					bc_parse_noElse(p);
586			}
587			else bc_parse_noElse(p);
588		}
589
590		if (brace && has_brace) brace = false;
591
592	} while (p->flags.len > 1 && !new_else && (!BC_PARSE_IF_END(p) || brace) &&
593	         !(has_brace = (BC_PARSE_BRACE(p) != 0)));
594
595	if (BC_ERR(p->flags.len == 1 && brace))
596		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
597	else if (brace && BC_PARSE_BRACE(p)) {
598
599		uint16_t flags = BC_PARSE_TOP_FLAG(p);
600
601		if (!(flags & (BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_LOOP_INNER)) &&
602		    !(flags & (BC_PARSE_FLAG_IF | BC_PARSE_FLAG_ELSE)) &&
603		    !(flags & (BC_PARSE_FLAG_IF_END)))
604		{
605			bc_vec_pop(&p->flags);
606		}
607	}
608}
609
610static void bc_parse_startBody(BcParse *p, uint16_t flags) {
611	assert(flags);
612	flags |= (BC_PARSE_TOP_FLAG(p) & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP));
613	flags |= BC_PARSE_FLAG_BODY;
614	bc_vec_push(&p->flags, &flags);
615}
616
617static void bc_parse_if(BcParse *p) {
618
619	size_t idx;
620	uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
621
622	bc_lex_next(&p->l);
623	if (BC_ERR(p->l.t != BC_LEX_LPAREN))
624		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
625
626	bc_lex_next(&p->l);
627	bc_parse_expr_status(p, flags, bc_parse_next_rel);
628	if (BC_ERR(p->l.t != BC_LEX_RPAREN))
629		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
630
631	bc_lex_next(&p->l);
632	bc_parse_push(p, BC_INST_JUMP_ZERO);
633
634	idx = p->func->labels.len;
635
636	bc_parse_pushIndex(p, idx);
637	bc_parse_createExitLabel(p, idx, false);
638	bc_parse_startBody(p, BC_PARSE_FLAG_IF);
639}
640
641static void bc_parse_else(BcParse *p) {
642
643	size_t idx = p->func->labels.len;
644
645	if (BC_ERR(!BC_PARSE_IF_END(p)))
646		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
647
648	bc_parse_push(p, BC_INST_JUMP);
649	bc_parse_pushIndex(p, idx);
650
651	bc_parse_noElse(p);
652
653	bc_parse_createExitLabel(p, idx, false);
654	bc_parse_startBody(p, BC_PARSE_FLAG_ELSE);
655
656	bc_lex_next(&p->l);
657}
658
659static void bc_parse_while(BcParse *p) {
660
661	size_t idx;
662	uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
663
664	bc_lex_next(&p->l);
665	if (BC_ERR(p->l.t != BC_LEX_LPAREN))
666		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
667	bc_lex_next(&p->l);
668
669	bc_parse_createCondLabel(p, p->func->labels.len);
670	idx = p->func->labels.len;
671	bc_parse_createExitLabel(p, idx, true);
672
673	bc_parse_expr_status(p, flags, bc_parse_next_rel);
674	if (BC_ERR(p->l.t != BC_LEX_RPAREN))
675		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
676	bc_lex_next(&p->l);
677
678	bc_parse_push(p, BC_INST_JUMP_ZERO);
679	bc_parse_pushIndex(p, idx);
680	bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
681}
682
683static void bc_parse_for(BcParse *p) {
684
685	size_t cond_idx, exit_idx, body_idx, update_idx;
686
687	bc_lex_next(&p->l);
688	if (BC_ERR(p->l.t != BC_LEX_LPAREN))
689		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
690	bc_lex_next(&p->l);
691
692	if (p->l.t != BC_LEX_SCOLON)
693		bc_parse_expr_status(p, 0, bc_parse_next_for);
694	else bc_parse_err(p, BC_ERR_POSIX_FOR);
695
696	if (BC_ERR(p->l.t != BC_LEX_SCOLON))
697		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
698	bc_lex_next(&p->l);
699
700	cond_idx = p->func->labels.len;
701	update_idx = cond_idx + 1;
702	body_idx = update_idx + 1;
703	exit_idx = body_idx + 1;
704
705	bc_parse_createLabel(p, p->func->code.len);
706
707	if (p->l.t != BC_LEX_SCOLON) {
708		uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
709		bc_parse_expr_status(p, flags, bc_parse_next_for);
710	}
711	else {
712
713		// Set this for the next call to bc_parse_number.
714		// This is safe to set because the current token
715		// is a semicolon, which has no string requirement.
716		bc_vec_string(&p->l.str, sizeof(bc_parse_one) - 1, bc_parse_one);
717		bc_parse_number(p);
718
719		bc_parse_err(p, BC_ERR_POSIX_FOR);
720	}
721
722	if (BC_ERR(p->l.t != BC_LEX_SCOLON))
723		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
724
725	bc_lex_next(&p->l);
726
727	bc_parse_push(p, BC_INST_JUMP_ZERO);
728	bc_parse_pushIndex(p, exit_idx);
729	bc_parse_push(p, BC_INST_JUMP);
730	bc_parse_pushIndex(p, body_idx);
731
732	bc_parse_createCondLabel(p, update_idx);
733
734	if (p->l.t != BC_LEX_RPAREN)
735		bc_parse_expr_status(p, 0, bc_parse_next_rel);
736	else bc_parse_err(p, BC_ERR_POSIX_FOR);
737
738	if (BC_ERR(p->l.t != BC_LEX_RPAREN))
739		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
740	bc_parse_push(p, BC_INST_JUMP);
741	bc_parse_pushIndex(p, cond_idx);
742	bc_parse_createLabel(p, p->func->code.len);
743
744	bc_parse_createExitLabel(p, exit_idx, true);
745	bc_lex_next(&p->l);
746	bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
747}
748
749static void bc_parse_loopExit(BcParse *p, BcLexType type) {
750
751	size_t i;
752	BcInstPtr *ip;
753
754	if (BC_ERR(!BC_PARSE_LOOP(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
755
756	if (type == BC_LEX_KW_BREAK) {
757
758		if (BC_ERR(!p->exits.len)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
759
760		i = p->exits.len - 1;
761		ip = bc_vec_item(&p->exits, i);
762
763		while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--);
764		assert(ip != NULL && (i < p->exits.len || ip->func));
765		i = ip->idx;
766	}
767	else i = *((size_t*) bc_vec_top(&p->conds));
768
769	bc_parse_push(p, BC_INST_JUMP);
770	bc_parse_pushIndex(p, i);
771
772	bc_lex_next(&p->l);
773}
774
775static void bc_parse_func(BcParse *p) {
776
777	bool comma = false, voidfn;
778	uint16_t flags;
779	size_t idx;
780
781	bc_lex_next(&p->l);
782
783	if (BC_ERR(p->l.t != BC_LEX_NAME))
784		bc_parse_err(p, BC_ERR_PARSE_FUNC);
785
786	voidfn = (!BC_IS_POSIX && p->l.t == BC_LEX_NAME &&
787	          !strcmp(p->l.str.v, "void"));
788
789	bc_lex_next(&p->l);
790
791	voidfn = (voidfn && p->l.t == BC_LEX_NAME);
792
793	if (voidfn) {
794		bc_parse_err(p, BC_ERR_POSIX_VOID);
795		bc_lex_next(&p->l);
796	}
797
798	if (BC_ERR(p->l.t != BC_LEX_LPAREN))
799		bc_parse_err(p, BC_ERR_PARSE_FUNC);
800
801	assert(p->prog->fns.len == p->prog->fn_map.len);
802
803	BC_SIG_LOCK;
804
805	idx = bc_program_insertFunc(p->prog, p->l.str.v);
806
807	BC_SIG_UNLOCK;
808
809	assert(idx);
810	bc_parse_updateFunc(p, idx);
811	p->func->voidfn = voidfn;
812
813	bc_lex_next(&p->l);
814
815	while (p->l.t != BC_LEX_RPAREN) {
816
817		BcType t = BC_TYPE_VAR;
818
819		if (p->l.t == BC_LEX_OP_MULTIPLY) {
820			t = BC_TYPE_REF;
821			bc_lex_next(&p->l);
822			bc_parse_err(p, BC_ERR_POSIX_REF);
823		}
824
825		if (BC_ERR(p->l.t != BC_LEX_NAME))
826			bc_parse_err(p, BC_ERR_PARSE_FUNC);
827
828		p->func->nparams += 1;
829
830		bc_vec_string(&p->buf, p->l.str.len, p->l.str.v);
831
832		bc_lex_next(&p->l);
833
834		if (p->l.t == BC_LEX_LBRACKET) {
835
836			if (t == BC_TYPE_VAR) t = BC_TYPE_ARRAY;
837
838			bc_lex_next(&p->l);
839
840			if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
841				bc_parse_err(p, BC_ERR_PARSE_FUNC);
842
843			bc_lex_next(&p->l);
844		}
845		else if (BC_ERR(t == BC_TYPE_REF))
846			bc_parse_verr(p, BC_ERR_PARSE_REF_VAR, p->buf.v);
847
848		comma = (p->l.t == BC_LEX_COMMA);
849		if (comma) {
850			bc_lex_next(&p->l);
851		}
852
853		bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line);
854	}
855
856	if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
857
858	flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER;
859	bc_parse_startBody(p, flags);
860
861	bc_lex_next(&p->l);
862
863	if (p->l.t != BC_LEX_LBRACE) bc_parse_err(p, BC_ERR_POSIX_BRACE);
864}
865
866static void bc_parse_auto(BcParse *p) {
867
868	bool comma, one;
869
870	if (BC_ERR(!p->auto_part)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
871	bc_lex_next(&p->l);
872
873	p->auto_part = comma = false;
874	one = p->l.t == BC_LEX_NAME;
875
876	while (p->l.t == BC_LEX_NAME) {
877
878		BcType t;
879
880		bc_vec_string(&p->buf, p->l.str.len - 1, p->l.str.v);
881
882		bc_lex_next(&p->l);
883
884		if (p->l.t == BC_LEX_LBRACKET) {
885
886			t = BC_TYPE_ARRAY;
887
888			bc_lex_next(&p->l);
889
890			if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
891				bc_parse_err(p, BC_ERR_PARSE_FUNC);
892
893			bc_lex_next(&p->l);
894		}
895		else t = BC_TYPE_VAR;
896
897		comma = (p->l.t == BC_LEX_COMMA);
898		if (comma) bc_lex_next(&p->l);
899
900		bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line);
901	}
902
903	if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
904	if (BC_ERR(!one)) bc_parse_err(p, BC_ERR_PARSE_NO_AUTO);
905	if (BC_ERR(!bc_parse_isDelimiter(p)))
906		bc_parse_err(p, BC_ERR_PARSE_TOKEN);
907}
908
909static void bc_parse_body(BcParse *p, bool brace) {
910
911	uint16_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
912
913	assert(flag_ptr != NULL);
914	assert(p->flags.len >= 2);
915
916	*flag_ptr &= ~(BC_PARSE_FLAG_BODY);
917
918	if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) {
919
920		if (BC_ERR(!brace)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
921
922		p->auto_part = (p->l.t != BC_LEX_KW_AUTO);
923
924		if (!p->auto_part) {
925
926			// Make sure this is true to not get a parse error.
927			p->auto_part = true;
928
929			bc_parse_auto(p);
930		}
931
932		if (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
933	}
934	else {
935
936		size_t len = p->flags.len;
937
938		assert(*flag_ptr);
939
940		bc_parse_stmt(p);
941
942		if (!brace && !BC_PARSE_BODY(p) && len <= p->flags.len)
943			bc_parse_endBody(p, false);
944	}
945}
946
947static void bc_parse_stmt(BcParse *p) {
948
949	size_t len;
950	uint16_t flags;
951	BcLexType type = p->l.t;
952
953	if (type == BC_LEX_NLINE) {
954		bc_lex_next(&p->l);
955		return;
956	}
957	if (type == BC_LEX_KW_AUTO) {
958		bc_parse_auto(p);
959		return;
960	}
961
962	p->auto_part = false;
963
964	if (type != BC_LEX_KW_ELSE) {
965
966		if (BC_PARSE_IF_END(p)) {
967			bc_parse_noElse(p);
968			if (p->flags.len > 1 && !BC_PARSE_BRACE(p))
969				bc_parse_endBody(p, false);
970			return;
971		}
972		else if (type == BC_LEX_LBRACE) {
973
974			if (!BC_PARSE_BODY(p)) {
975				bc_parse_startBody(p, BC_PARSE_FLAG_BRACE);
976				bc_lex_next(&p->l);
977			}
978			else {
979				*(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_BRACE;
980				bc_lex_next(&p->l);
981				bc_parse_body(p, true);
982			}
983
984			return;
985		}
986		else if (BC_PARSE_BODY(p) && !BC_PARSE_BRACE(p)) {
987			bc_parse_body(p, false);
988			return;
989		}
990	}
991
992	len = p->flags.len;
993	flags = BC_PARSE_TOP_FLAG(p);
994
995	switch (type) {
996
997		case BC_LEX_OP_INC:
998		case BC_LEX_OP_DEC:
999		case BC_LEX_OP_MINUS:
1000		case BC_LEX_OP_BOOL_NOT:
1001		case BC_LEX_LPAREN:
1002		case BC_LEX_NAME:
1003		case BC_LEX_NUMBER:
1004		case BC_LEX_KW_IBASE:
1005		case BC_LEX_KW_LAST:
1006		case BC_LEX_KW_LENGTH:
1007		case BC_LEX_KW_OBASE:
1008		case BC_LEX_KW_SCALE:
1009#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1010		case BC_LEX_KW_SEED:
1011#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1012		case BC_LEX_KW_SQRT:
1013		case BC_LEX_KW_ABS:
1014#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1015		case BC_LEX_KW_IRAND:
1016#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1017		case BC_LEX_KW_READ:
1018#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1019		case BC_LEX_KW_RAND:
1020#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1021		case BC_LEX_KW_MAXIBASE:
1022		case BC_LEX_KW_MAXOBASE:
1023		case BC_LEX_KW_MAXSCALE:
1024#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1025		case BC_LEX_KW_MAXRAND:
1026#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1027		{
1028			bc_parse_expr_status(p, BC_PARSE_PRINT, bc_parse_next_expr);
1029			break;
1030		}
1031
1032		case BC_LEX_KW_ELSE:
1033		{
1034			bc_parse_else(p);
1035			break;
1036		}
1037
1038		case BC_LEX_SCOLON:
1039		{
1040			// Do nothing.
1041			break;
1042		}
1043
1044		case BC_LEX_RBRACE:
1045		{
1046			bc_parse_endBody(p, true);
1047			break;
1048		}
1049
1050		case BC_LEX_STR:
1051		{
1052			bc_parse_str(p, BC_INST_PRINT_STR);
1053			break;
1054		}
1055
1056		case BC_LEX_KW_BREAK:
1057		case BC_LEX_KW_CONTINUE:
1058		{
1059			bc_parse_loopExit(p, p->l.t);
1060			break;
1061		}
1062
1063		case BC_LEX_KW_FOR:
1064		{
1065			bc_parse_for(p);
1066			break;
1067		}
1068
1069		case BC_LEX_KW_HALT:
1070		{
1071			bc_parse_push(p, BC_INST_HALT);
1072			bc_lex_next(&p->l);
1073			break;
1074		}
1075
1076		case BC_LEX_KW_IF:
1077		{
1078			bc_parse_if(p);
1079			break;
1080		}
1081
1082		case BC_LEX_KW_LIMITS:
1083		{
1084			bc_vm_printf("BC_LONG_BIT      = %lu\n", (ulong) BC_LONG_BIT);
1085			bc_vm_printf("BC_BASE_DIGS     = %lu\n", (ulong) BC_BASE_DIGS);
1086			bc_vm_printf("BC_BASE_POW      = %lu\n", (ulong) BC_BASE_POW);
1087			bc_vm_printf("BC_OVERFLOW_MAX  = %lu\n", (ulong) BC_NUM_BIGDIG_MAX);
1088			bc_vm_printf("\n");
1089			bc_vm_printf("BC_BASE_MAX      = %lu\n", BC_MAX_OBASE);
1090			bc_vm_printf("BC_DIM_MAX       = %lu\n", BC_MAX_DIM);
1091			bc_vm_printf("BC_SCALE_MAX     = %lu\n", BC_MAX_SCALE);
1092			bc_vm_printf("BC_STRING_MAX    = %lu\n", BC_MAX_STRING);
1093			bc_vm_printf("BC_NAME_MAX      = %lu\n", BC_MAX_NAME);
1094			bc_vm_printf("BC_NUM_MAX       = %lu\n", BC_MAX_NUM);
1095#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1096			bc_vm_printf("BC_RAND_MAX      = %lu\n", BC_MAX_RAND);
1097#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1098			bc_vm_printf("MAX Exponent     = %lu\n", BC_MAX_EXP);
1099			bc_vm_printf("Number of vars   = %lu\n", BC_MAX_VARS);
1100
1101			bc_lex_next(&p->l);
1102
1103			break;
1104		}
1105
1106		case BC_LEX_KW_PRINT:
1107		{
1108			bc_parse_print(p);
1109			break;
1110		}
1111
1112		case BC_LEX_KW_QUIT:
1113		{
1114			// Quit is a compile-time command. We don't exit directly,
1115			// so the vm can clean up. Limits do the same thing.
1116			vm.status = BC_STATUS_QUIT;
1117			BC_VM_JMP;
1118			break;
1119		}
1120
1121		case BC_LEX_KW_RETURN:
1122		{
1123			bc_parse_return(p);
1124			break;
1125		}
1126
1127		case BC_LEX_KW_WHILE:
1128		{
1129			bc_parse_while(p);
1130			break;
1131		}
1132
1133		default:
1134		{
1135			bc_parse_err(p, BC_ERR_PARSE_TOKEN);
1136		}
1137	}
1138
1139	if (len == p->flags.len && flags == BC_PARSE_TOP_FLAG(p)) {
1140		if (BC_ERR(!bc_parse_isDelimiter(p)))
1141			bc_parse_err(p, BC_ERR_PARSE_TOKEN);
1142	}
1143
1144	// Make sure semicolons are eaten.
1145	while (p->l.t == BC_LEX_SCOLON) bc_lex_next(&p->l);
1146}
1147
1148void bc_parse_parse(BcParse *p) {
1149
1150	assert(p);
1151
1152	BC_SETJMP(exit);
1153
1154	if (BC_ERR(p->l.t == BC_LEX_EOF)) bc_parse_err(p, BC_ERR_PARSE_EOF);
1155	else if (p->l.t == BC_LEX_KW_DEFINE) {
1156		if (BC_ERR(BC_PARSE_NO_EXEC(p)))
1157			bc_parse_err(p, BC_ERR_PARSE_TOKEN);
1158		bc_parse_func(p);
1159	}
1160	else bc_parse_stmt(p);
1161
1162exit:
1163	BC_SIG_MAYLOCK;
1164	if (BC_ERR(((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig)))
1165		bc_parse_reset(p);
1166	BC_LONGJMP_CONT;
1167}
1168
1169static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags,
1170                                       BcParseNext next)
1171{
1172	BcInst prev = BC_INST_PRINT;
1173	uchar inst = BC_INST_INVALID;
1174	BcLexType top, t = p->l.t;
1175	size_t nexprs = 0, ops_bgn = p->ops.len;
1176	uint32_t i, nparens, nrelops;
1177	bool pfirst, rprn, done, get_token, assign, bin_last, incdec, can_assign;
1178
1179	assert(!(flags & BC_PARSE_PRINT) || !(flags & BC_PARSE_NEEDVAL));
1180
1181	pfirst = (p->l.t == BC_LEX_LPAREN);
1182	nparens = nrelops = 0;
1183	rprn = done = get_token = assign = incdec = can_assign = false;
1184	bin_last = true;
1185
1186	// We want to eat newlines if newlines are not a valid ending token.
1187	// This is for spacing in things like for loop headers.
1188	if (!(flags & BC_PARSE_NOREAD)) {
1189		while ((t = p->l.t) == BC_LEX_NLINE) bc_lex_next(&p->l);
1190	}
1191
1192	for (; !done && BC_PARSE_EXPR(t); t = p->l.t)
1193	{
1194		switch (t) {
1195
1196			case BC_LEX_OP_INC:
1197			case BC_LEX_OP_DEC:
1198			{
1199				if (BC_ERR(incdec)) bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
1200				bc_parse_incdec(p, &prev, &can_assign, &nexprs, flags);
1201				rprn = get_token = bin_last = false;
1202				incdec = true;
1203				flags &= ~(BC_PARSE_ARRAY);
1204				break;
1205			}
1206
1207#if BC_ENABLE_EXTRA_MATH
1208			case BC_LEX_OP_TRUNC:
1209			{
1210				if (BC_ERR(!BC_PARSE_LEAF(prev, bin_last, rprn)))
1211					bc_parse_err(p, BC_ERR_PARSE_TOKEN);
1212
1213				// I can just add the instruction because
1214				// negative will already be taken care of.
1215				bc_parse_push(p, BC_INST_TRUNC);
1216				rprn = can_assign = incdec = false;
1217				get_token = true;
1218				flags &= ~(BC_PARSE_ARRAY);
1219				break;
1220			}
1221#endif // BC_ENABLE_EXTRA_MATH
1222
1223			case BC_LEX_OP_MINUS:
1224			{
1225				bc_parse_minus(p, &prev, ops_bgn, rprn, bin_last, &nexprs);
1226				rprn = get_token = can_assign = false;
1227				bin_last = (prev == BC_INST_MINUS);
1228				if (bin_last) incdec = false;
1229				flags &= ~(BC_PARSE_ARRAY);
1230				break;
1231			}
1232
1233			case BC_LEX_OP_ASSIGN_POWER:
1234			case BC_LEX_OP_ASSIGN_MULTIPLY:
1235			case BC_LEX_OP_ASSIGN_DIVIDE:
1236			case BC_LEX_OP_ASSIGN_MODULUS:
1237			case BC_LEX_OP_ASSIGN_PLUS:
1238			case BC_LEX_OP_ASSIGN_MINUS:
1239#if BC_ENABLE_EXTRA_MATH
1240			case BC_LEX_OP_ASSIGN_PLACES:
1241			case BC_LEX_OP_ASSIGN_LSHIFT:
1242			case BC_LEX_OP_ASSIGN_RSHIFT:
1243#endif // BC_ENABLE_EXTRA_MATH
1244			case BC_LEX_OP_ASSIGN:
1245			{
1246				if (!BC_PARSE_INST_VAR(prev))
1247					bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
1248			}
1249			// Fallthrough.
1250			BC_FALLTHROUGH
1251
1252			case BC_LEX_OP_POWER:
1253			case BC_LEX_OP_MULTIPLY:
1254			case BC_LEX_OP_DIVIDE:
1255			case BC_LEX_OP_MODULUS:
1256			case BC_LEX_OP_PLUS:
1257#if BC_ENABLE_EXTRA_MATH
1258			case BC_LEX_OP_PLACES:
1259			case BC_LEX_OP_LSHIFT:
1260			case BC_LEX_OP_RSHIFT:
1261#endif // BC_ENABLE_EXTRA_MATH
1262			case BC_LEX_OP_REL_EQ:
1263			case BC_LEX_OP_REL_LE:
1264			case BC_LEX_OP_REL_GE:
1265			case BC_LEX_OP_REL_NE:
1266			case BC_LEX_OP_REL_LT:
1267			case BC_LEX_OP_REL_GT:
1268			case BC_LEX_OP_BOOL_NOT:
1269			case BC_LEX_OP_BOOL_OR:
1270			case BC_LEX_OP_BOOL_AND:
1271			{
1272				if (BC_PARSE_OP_PREFIX(t)) {
1273					if (BC_ERR(!bin_last && !BC_PARSE_OP_PREFIX(p->l.last)))
1274						bc_parse_err(p, BC_ERR_PARSE_EXPR);
1275				}
1276				else if (BC_ERR(BC_PARSE_PREV_PREFIX(prev) || bin_last))
1277					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1278
1279				nrelops += (t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT);
1280				prev = BC_PARSE_TOKEN_INST(t);
1281				bc_parse_operator(p, t, ops_bgn, &nexprs);
1282				rprn = incdec = can_assign = false;
1283				get_token = true;
1284				bin_last = !BC_PARSE_OP_PREFIX(t);
1285				flags &= ~(BC_PARSE_ARRAY);
1286
1287				break;
1288			}
1289
1290			case BC_LEX_LPAREN:
1291			{
1292				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1293					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1294
1295				nparens += 1;
1296				rprn = incdec = can_assign = false;
1297				get_token = true;
1298				bc_vec_push(&p->ops, &t);
1299
1300				break;
1301			}
1302
1303			case BC_LEX_RPAREN:
1304			{
1305				// This needs to be a status. The error
1306				// is handled in bc_parse_expr_status().
1307				if (BC_ERR(p->l.last == BC_LEX_LPAREN))
1308					return BC_PARSE_STATUS_EMPTY_EXPR;
1309
1310				if (BC_ERR(bin_last || BC_PARSE_PREV_PREFIX(prev)))
1311					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1312
1313				if (!nparens) {
1314					done = true;
1315					get_token = false;
1316					break;
1317				}
1318
1319				nparens -= 1;
1320				rprn = true;
1321				get_token = bin_last = incdec = false;
1322
1323				bc_parse_rightParen(p, &nexprs);
1324
1325				break;
1326			}
1327
1328			case BC_LEX_NAME:
1329			{
1330				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1331					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1332
1333				get_token = bin_last = false;
1334				bc_parse_name(p, &prev, &can_assign,
1335				                  flags & ~BC_PARSE_NOCALL);
1336				rprn = (prev == BC_INST_CALL);
1337				nexprs += 1;
1338				flags &= ~(BC_PARSE_ARRAY);
1339
1340				break;
1341			}
1342
1343			case BC_LEX_NUMBER:
1344			{
1345				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1346					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1347
1348				bc_parse_number(p);
1349				nexprs += 1;
1350				prev = BC_INST_NUM;
1351				get_token = true;
1352				rprn = bin_last = can_assign = false;
1353				flags &= ~(BC_PARSE_ARRAY);
1354
1355				break;
1356			}
1357
1358			case BC_LEX_KW_IBASE:
1359			case BC_LEX_KW_LAST:
1360			case BC_LEX_KW_OBASE:
1361#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1362			case BC_LEX_KW_SEED:
1363#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1364			{
1365				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1366					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1367
1368				prev = t - BC_LEX_KW_LAST + BC_INST_LAST;
1369				bc_parse_push(p, prev);
1370
1371				get_token = can_assign = true;
1372				rprn = bin_last = false;
1373				nexprs += 1;
1374				flags &= ~(BC_PARSE_ARRAY);
1375
1376				break;
1377			}
1378
1379			case BC_LEX_KW_LENGTH:
1380			case BC_LEX_KW_SQRT:
1381			case BC_LEX_KW_ABS:
1382#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1383			case BC_LEX_KW_IRAND:
1384#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1385			{
1386				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1387					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1388
1389				bc_parse_builtin(p, t, flags, &prev);
1390				rprn = get_token = bin_last = incdec = can_assign = false;
1391				nexprs += 1;
1392				flags &= ~(BC_PARSE_ARRAY);
1393
1394				break;
1395			}
1396
1397			case BC_LEX_KW_READ:
1398#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1399			case BC_LEX_KW_RAND:
1400#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1401			case BC_LEX_KW_MAXIBASE:
1402			case BC_LEX_KW_MAXOBASE:
1403			case BC_LEX_KW_MAXSCALE:
1404#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1405			case BC_LEX_KW_MAXRAND:
1406#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
1407			{
1408				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1409					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1410				else if (t == BC_LEX_KW_READ && BC_ERR(flags & BC_PARSE_NOREAD))
1411					bc_parse_err(p, BC_ERR_EXEC_REC_READ);
1412				else {
1413					prev = t - BC_LEX_KW_READ + BC_INST_READ;
1414					bc_parse_noArgBuiltin(p, prev);
1415				}
1416
1417				rprn = get_token = bin_last = incdec = can_assign = false;
1418				nexprs += 1;
1419				flags &= ~(BC_PARSE_ARRAY);
1420
1421				break;
1422			}
1423
1424			case BC_LEX_KW_SCALE:
1425			{
1426				if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
1427					bc_parse_err(p, BC_ERR_PARSE_EXPR);
1428
1429				bc_parse_scale(p, &prev, &can_assign, flags);
1430				rprn = get_token = bin_last = false;
1431				nexprs += 1;
1432				flags &= ~(BC_PARSE_ARRAY);
1433
1434				break;
1435			}
1436
1437			default:
1438			{
1439#ifndef NDEBUG
1440				bc_parse_err(p, BC_ERR_PARSE_TOKEN);
1441				break;
1442#endif // NDEBUG
1443			}
1444		}
1445
1446		if (get_token) bc_lex_next(&p->l);
1447	}
1448
1449	while (p->ops.len > ops_bgn) {
1450
1451		top = BC_PARSE_TOP_OP(p);
1452		assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN;
1453
1454		if (BC_ERR(top == BC_LEX_LPAREN || top == BC_LEX_RPAREN))
1455			bc_parse_err(p, BC_ERR_PARSE_EXPR);
1456
1457		bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
1458
1459		nexprs -= !BC_PARSE_OP_PREFIX(top);
1460		bc_vec_pop(&p->ops);
1461
1462		incdec = false;
1463	}
1464
1465	if (BC_ERR(nexprs != 1)) bc_parse_err(p, BC_ERR_PARSE_EXPR);
1466
1467	for (i = 0; i < next.len && t != next.tokens[i]; ++i);
1468	if (BC_ERR(i == next.len && !bc_parse_isDelimiter(p)))
1469		bc_parse_err(p, BC_ERR_PARSE_EXPR);
1470
1471	if (!(flags & BC_PARSE_REL) && nrelops)
1472		bc_parse_err(p, BC_ERR_POSIX_REL_POS);
1473	else if ((flags & BC_PARSE_REL) && nrelops > 1)
1474		bc_parse_err(p, BC_ERR_POSIX_MULTIREL);
1475
1476	if (!(flags & BC_PARSE_NEEDVAL) && !pfirst) {
1477
1478		if (assign) {
1479			inst = *((uchar*) bc_vec_top(&p->func->code));
1480			inst += (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER);
1481			incdec = false;
1482		}
1483		else if (incdec && !(flags & BC_PARSE_PRINT)) {
1484			inst = *((uchar*) bc_vec_top(&p->func->code));
1485			incdec = (inst <= BC_INST_DEC);
1486			inst = BC_INST_ASSIGN_PLUS_NO_VAL + (inst != BC_INST_INC &&
1487			                                     inst != BC_INST_ASSIGN_PLUS);
1488		}
1489
1490		if (inst >= BC_INST_ASSIGN_POWER_NO_VAL &&
1491		    inst <= BC_INST_ASSIGN_NO_VAL)
1492		{
1493			bc_vec_pop(&p->func->code);
1494			if (incdec) bc_parse_push(p, BC_INST_ONE);
1495			bc_parse_push(p, inst);
1496		}
1497	}
1498
1499	if ((flags & BC_PARSE_PRINT)) {
1500		if (pfirst || !assign) bc_parse_push(p, BC_INST_PRINT);
1501	}
1502	else if (!(flags & BC_PARSE_NEEDVAL) &&
1503	         (inst < BC_INST_ASSIGN_POWER_NO_VAL ||
1504	          inst > BC_INST_ASSIGN_NO_VAL))
1505	{
1506		bc_parse_push(p, BC_INST_POP);
1507	}
1508
1509	// We want to eat newlines if newlines are not a valid ending token.
1510	// This is for spacing in things like for loop headers.
1511	for (incdec = true, i = 0; i < next.len && incdec; ++i)
1512		incdec = (next.tokens[i] != BC_LEX_NLINE);
1513	if (incdec) {
1514		while (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
1515	}
1516
1517	return BC_PARSE_STATUS_SUCCESS;
1518}
1519
1520void bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next) {
1521
1522	BcParseStatus s = bc_parse_expr_err(p, flags, next);
1523
1524	if (BC_ERR(s == BC_PARSE_STATUS_EMPTY_EXPR))
1525		bc_parse_err(p, BC_ERR_PARSE_EMPTY_EXPR);
1526}
1527
1528void bc_parse_expr(BcParse *p, uint8_t flags) {
1529	assert(p);
1530	bc_parse_expr_status(p, flags, bc_parse_next_read);
1531}
1532#endif // BC_ENABLED
1533