Lines Matching +full:- +full:p
4 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
59 bc_parse_else(BcParse* p);
62 bc_parse_stmt(BcParse* p);
65 bc_parse_expr_err(BcParse* p, uint8_t flags, BcParseNext next);
68 bc_parse_expr_status(BcParse* p, uint8_t flags, BcParseNext next);
90 * @param p The parser.
94 bc_parse_isDelimiter(const BcParse* p) in bc_parse_isDelimiter() argument
96 BcLexType t = p->l.t; in bc_parse_isDelimiter()
105 // to check for a "dangling" else, where there was no brace-delimited block in bc_parse_isDelimiter()
113 for (i = 0; i < p->flags.len && BC_PARSE_BLOCK_STMT(flags); ++i) in bc_parse_isDelimiter()
115 fptr = bc_vec_item_rev(&p->flags, i); in bc_parse_isDelimiter()
120 if ((flags & BC_PARSE_FLAG_BRACE) && p->l.last != BC_LEX_RBRACE) in bc_parse_isDelimiter()
134 for (i = 0; !good && i < p->flags.len; ++i) in bc_parse_isDelimiter()
136 uint16_t* fptr = bc_vec_item_rev(&p->flags, i); in bc_parse_isDelimiter()
148 * @param p The parser.
152 bc_parse_TopFunc(const BcParse* p) in bc_parse_TopFunc() argument
154 bool good = p->flags.len == 2; in bc_parse_TopFunc()
159 return good && BC_PARSE_TOP_FLAG(p) == val; in bc_parse_TopFunc()
165 * @param p The parser.
168 bc_parse_setLabel(BcParse* p) in bc_parse_setLabel() argument
170 BcFunc* func = p->func; in bc_parse_setLabel()
171 BcInstPtr* ip = bc_vec_top(&p->exits); in bc_parse_setLabel()
174 assert(func == bc_vec_item(&p->prog->fns, p->fidx)); in bc_parse_setLabel()
177 label = bc_vec_item(&func->labels, ip->idx); in bc_parse_setLabel()
178 *label = func->code.len; in bc_parse_setLabel()
181 bc_vec_pop(&p->exits); in bc_parse_setLabel()
188 * @param p The parser.
192 bc_parse_createLabel(BcParse* p, size_t idx) in bc_parse_createLabel() argument
194 bc_vec_push(&p->func->labels, &idx); in bc_parse_createLabel()
200 * @param p The parser.
204 bc_parse_createCondLabel(BcParse* p, size_t idx) in bc_parse_createCondLabel() argument
206 bc_parse_createLabel(p, p->func->code.len); in bc_parse_createCondLabel()
207 bc_vec_push(&p->conds, &idx); in bc_parse_createCondLabel()
220 * @param p The parser.
225 bc_parse_createExitLabel(BcParse* p, size_t idx, bool loop) in bc_parse_createExitLabel() argument
229 assert(p->func == bc_vec_item(&p->prog->fns, p->fidx)); in bc_parse_createExitLabel()
235 bc_vec_push(&p->exits, &ip); in bc_parse_createExitLabel()
236 bc_parse_createLabel(p, SIZE_MAX); in bc_parse_createExitLabel()
241 * operator. This is because of the Shunting-Yard algorithm. Lower prec means
243 * @param p The parser.
252 bc_parse_operator(BcParse* p, BcLexType type, size_t start, size_t* nexprs) in bc_parse_operator() argument
259 while (p->ops.len > start) in bc_parse_operator()
262 t = BC_PARSE_TOP_OP(p); in bc_parse_operator()
282 bc_parse_push(p, BC_PARSE_TOKEN_INST(t)); in bc_parse_operator()
283 bc_vec_pop(&p->ops); in bc_parse_operator()
284 *nexprs -= !BC_PARSE_OP_PREFIX(t); in bc_parse_operator()
287 bc_vec_push(&p->ops, &type); in bc_parse_operator()
291 * Parses a right paren. In the Shunting-Yard algorithm, it needs to be put on
294 * @param p The parser.
299 bc_parse_rightParen(BcParse* p, size_t* nexprs) in bc_parse_rightParen() argument
304 while ((top = BC_PARSE_TOP_OP(p)) != BC_LEX_LPAREN) in bc_parse_rightParen()
306 bc_parse_push(p, BC_PARSE_TOKEN_INST(top)); in bc_parse_rightParen()
307 bc_vec_pop(&p->ops); in bc_parse_rightParen()
308 *nexprs -= !BC_PARSE_OP_PREFIX(top); in bc_parse_rightParen()
312 bc_vec_pop(&p->ops); in bc_parse_rightParen()
315 bc_lex_next(&p->l); in bc_parse_rightParen()
320 * @param p The parser.
325 bc_parse_args(BcParse* p, uint8_t flags) in bc_parse_args() argument
330 bc_lex_next(&p->l); in bc_parse_args()
338 for (nargs = 0; p->l.t != BC_LEX_RPAREN; ++nargs) in bc_parse_args()
340 bc_parse_expr_status(p, flags, bc_parse_next_arg); in bc_parse_args()
342 comma = (p->l.t == BC_LEX_COMMA); in bc_parse_args()
343 if (comma) bc_lex_next(&p->l); in bc_parse_args()
347 if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_args()
350 bc_parse_push(p, BC_INST_CALL); in bc_parse_args()
351 bc_parse_pushIndex(p, nargs); in bc_parse_args()
356 * @param p The parser.
361 bc_parse_call(BcParse* p, const char* name, uint8_t flags) in bc_parse_call() argument
365 bc_parse_args(p, flags); in bc_parse_call()
369 assert(p->l.t == BC_LEX_RPAREN); in bc_parse_call()
373 idx = bc_map_index(&p->prog->fn_map, name); in bc_parse_call()
379 idx = bc_program_insertFunc(p->prog, name); in bc_parse_call()
384 p->func = bc_vec_item(&p->prog->fns, p->fidx); in bc_parse_call()
387 else idx = ((BcId*) bc_vec_item(&p->prog->fn_map, idx))->idx; in bc_parse_call()
389 bc_parse_pushIndex(p, idx); in bc_parse_call()
392 bc_lex_next(&p->l); in bc_parse_call()
396 * Parses a name/identifier-based expression. It could be a variable, an array
398 * @param p The parser.
405 bc_parse_name(BcParse* p, BcInst* type, bool* can_assign, uint8_t flags) in bc_parse_name() argument
412 name = bc_vm_strdup(p->l.str.v); in bc_parse_name()
417 bc_lex_next(&p->l); in bc_parse_name()
420 if (p->l.t == BC_LEX_LBRACKET) in bc_parse_name()
422 bc_lex_next(&p->l); in bc_parse_name()
425 if (p->l.t == BC_LEX_RBRACKET) in bc_parse_name()
430 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_name()
443 bc_parse_expr_status(p, flags2, bc_parse_next_elem); in bc_parse_name()
446 if (BC_ERR(p->l.t != BC_LEX_RBRACKET)) in bc_parse_name()
448 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_name()
456 bc_lex_next(&p->l); in bc_parse_name()
459 bc_parse_push(p, *type); in bc_parse_name()
460 bc_parse_pushName(p, name, false); in bc_parse_name()
462 else if (p->l.t == BC_LEX_LPAREN) in bc_parse_name()
467 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_name()
473 bc_parse_call(p, name, flags); in bc_parse_name()
480 bc_parse_push(p, BC_INST_VAR); in bc_parse_name()
481 bc_parse_pushName(p, name, true); in bc_parse_name()
494 * @param p The parser.
498 bc_parse_noArgBuiltin(BcParse* p, BcInst inst) in bc_parse_noArgBuiltin() argument
501 bc_lex_next(&p->l); in bc_parse_noArgBuiltin()
502 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_noArgBuiltin()
505 bc_lex_next(&p->l); in bc_parse_noArgBuiltin()
506 if ((p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_noArgBuiltin()
508 bc_parse_push(p, inst); in bc_parse_noArgBuiltin()
510 bc_lex_next(&p->l); in bc_parse_noArgBuiltin()
516 * @param p The parser.
522 bc_parse_builtin(BcParse* p, BcLexType type, uint8_t flags, BcInst* prev) in bc_parse_builtin() argument
525 bc_lex_next(&p->l); in bc_parse_builtin()
526 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin()
528 bc_lex_next(&p->l); in bc_parse_builtin()
543 bc_parse_expr_status(p, flags, bc_parse_next_rel); in bc_parse_builtin()
546 if (BC_ERR(p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin()
549 *prev = type - BC_LEX_KW_LENGTH + BC_INST_LENGTH; in bc_parse_builtin()
550 bc_parse_push(p, *prev); in bc_parse_builtin()
552 bc_lex_next(&p->l); in bc_parse_builtin()
558 * @param p The parser.
564 bc_parse_builtin3(BcParse* p, BcLexType type, uint8_t flags, BcInst* prev) in bc_parse_builtin3() argument
569 bc_lex_next(&p->l); in bc_parse_builtin3()
570 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
572 bc_lex_next(&p->l); in bc_parse_builtin3()
578 bc_parse_expr_status(p, flags, bc_parse_next_builtin); in bc_parse_builtin3()
581 if (BC_ERR(p->l.t != BC_LEX_COMMA)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
583 bc_lex_next(&p->l); in bc_parse_builtin3()
585 bc_parse_expr_status(p, flags, bc_parse_next_builtin); in bc_parse_builtin3()
588 if (BC_ERR(p->l.t != BC_LEX_COMMA)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
590 bc_lex_next(&p->l); in bc_parse_builtin3()
597 if (BC_ERR(p->l.t != BC_LEX_NAME)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
600 bc_lex_next(&p->l); in bc_parse_builtin3()
603 if (BC_ERR(p->l.t != BC_LEX_LBRACKET)) in bc_parse_builtin3()
605 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
609 bc_lex_next(&p->l); in bc_parse_builtin3()
612 if (BC_ERR(p->l.t != BC_LEX_RBRACKET)) in bc_parse_builtin3()
614 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
618 bc_lex_next(&p->l); in bc_parse_builtin3()
620 else bc_parse_expr_status(p, flags, bc_parse_next_rel); in bc_parse_builtin3()
623 if (BC_ERR(p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_builtin3()
626 *prev = type - BC_LEX_KW_MODEXP + BC_INST_MODEXP; in bc_parse_builtin3()
627 bc_parse_push(p, *prev); in bc_parse_builtin3()
634 bc_parse_push(p, BC_INST_ZERO); in bc_parse_builtin3()
635 bc_parse_push(p, BC_INST_ARRAY_ELEM); in bc_parse_builtin3()
638 bc_parse_pushName(p, p->l.str.v, false); in bc_parse_builtin3()
642 bc_parse_push(p, BC_INST_SWAP); in bc_parse_builtin3()
643 bc_parse_push(p, BC_INST_ASSIGN_NO_VAL); in bc_parse_builtin3()
646 bc_lex_next(&p->l); in bc_parse_builtin3()
652 * @param p The parser.
659 bc_parse_scale(BcParse* p, BcInst* type, bool* can_assign, uint8_t flags) in bc_parse_scale() argument
661 bc_lex_next(&p->l); in bc_parse_scale()
664 if (p->l.t != BC_LEX_LPAREN) in bc_parse_scale()
669 bc_parse_push(p, BC_INST_SCALE); in bc_parse_scale()
681 bc_lex_next(&p->l); in bc_parse_scale()
683 bc_parse_expr_status(p, flags, bc_parse_next_rel); in bc_parse_scale()
686 if (BC_ERR(p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_scale()
688 bc_parse_push(p, BC_INST_SCALE_FUNC); in bc_parse_scale()
690 bc_lex_next(&p->l); in bc_parse_scale()
695 * @param p The parser.
704 bc_parse_incdec(BcParse* p, BcInst* prev, bool* can_assign, size_t* nexs, in bc_parse_incdec() argument
710 BcLexType last = p->l.last; in bc_parse_incdec()
718 bc_parse_err(p, BC_ERR_PARSE_ASSIGN); in bc_parse_incdec()
725 if (!*can_assign) bc_parse_err(p, BC_ERR_PARSE_ASSIGN); in bc_parse_incdec()
728 *prev = inst = BC_INST_INC + (p->l.t != BC_LEX_OP_INC); in bc_parse_incdec()
729 bc_parse_push(p, inst); in bc_parse_incdec()
730 bc_lex_next(&p->l); in bc_parse_incdec()
737 *prev = inst = BC_INST_ASSIGN_PLUS + (p->l.t != BC_LEX_OP_INC); in bc_parse_incdec()
739 bc_lex_next(&p->l); in bc_parse_incdec()
740 type = p->l.t; in bc_parse_incdec()
751 bc_parse_name(p, prev, can_assign, flags2 | BC_PARSE_NOCALL); in bc_parse_incdec()
756 bc_parse_push(p, type - BC_LEX_KW_LAST + BC_INST_LAST); in bc_parse_incdec()
757 bc_lex_next(&p->l); in bc_parse_incdec()
762 bc_lex_next(&p->l); in bc_parse_incdec()
765 if (BC_ERR(p->l.t == BC_LEX_LPAREN)) in bc_parse_incdec()
767 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_incdec()
769 else bc_parse_push(p, BC_INST_SCALE); in bc_parse_incdec()
772 else bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_incdec()
776 bc_parse_push(p, BC_INST_ONE); in bc_parse_incdec()
777 bc_parse_push(p, inst); in bc_parse_incdec()
784 * @param p The parser.
792 bc_parse_minus(BcParse* p, BcInst* prev, size_t ops_bgn, bool rparen, in bc_parse_minus() argument
797 bc_lex_next(&p->l); in bc_parse_minus()
805 if (type != BC_LEX_OP_MINUS) bc_vec_push(&p->ops, &type); in bc_parse_minus()
806 else bc_parse_operator(p, type, ops_bgn, nexprs); in bc_parse_minus()
811 * @param p The parser.
816 bc_parse_str(BcParse* p, BcInst inst) in bc_parse_str() argument
818 bc_parse_addString(p); in bc_parse_str()
819 bc_parse_push(p, inst); in bc_parse_str()
820 bc_lex_next(&p->l); in bc_parse_str()
825 * @param p The parser.
828 bc_parse_print(BcParse* p, BcLexType type) in bc_parse_print() argument
835 bc_lex_next(&p->l); in bc_parse_print()
837 t = p->l.t; in bc_parse_print()
840 if (bc_parse_isDelimiter(p)) bc_parse_err(p, BC_ERR_PARSE_PRINT); in bc_parse_print()
846 if (t == BC_LEX_STR) bc_parse_str(p, inst); in bc_parse_print()
850 bc_parse_expr_status(p, BC_PARSE_NEEDVAL, bc_parse_next_print); in bc_parse_print()
851 bc_parse_push(p, inst); in bc_parse_print()
855 comma = (p->l.t == BC_LEX_COMMA); in bc_parse_print()
858 if (comma) bc_lex_next(&p->l); in bc_parse_print()
862 if (!bc_parse_isDelimiter(p)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_print()
866 t = p->l.t; in bc_parse_print()
871 if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_print()
876 * @param p The parser.
879 bc_parse_return(BcParse* p) in bc_parse_return() argument
886 if (BC_ERR(!BC_PARSE_FUNC(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_return()
889 if (p->func->voidfn) inst = BC_INST_RET_VOID; in bc_parse_return()
891 bc_lex_next(&p->l); in bc_parse_return()
893 t = p->l.t; in bc_parse_return()
897 if (bc_parse_isDelimiter(p)) bc_parse_push(p, inst); in bc_parse_return()
903 s = bc_parse_expr_err(p, BC_PARSE_NEEDVAL, bc_parse_next_expr); in bc_parse_return()
908 bc_parse_push(p, inst); in bc_parse_return()
909 bc_lex_next(&p->l); in bc_parse_return()
913 if (!paren || p->l.last != BC_LEX_RPAREN) in bc_parse_return()
915 bc_parse_err(p, BC_ERR_POSIX_RET); in bc_parse_return()
919 if (BC_ERR(p->func->voidfn)) in bc_parse_return()
923 bc_parse_verr(p, BC_ERR_PARSE_RET_VOID, p->func->name); in bc_parse_return()
928 else bc_parse_push(p, BC_INST_RET); in bc_parse_return()
935 * @param p The parser.
938 bc_parse_noElse(BcParse* p) in bc_parse_noElse() argument
940 uint16_t* flag_ptr = BC_PARSE_TOP_FLAG_PTR(p); in bc_parse_noElse()
942 bc_parse_setLabel(p); in bc_parse_noElse()
947 * @param p The parser.
951 bc_parse_endBody(BcParse* p, bool brace) in bc_parse_endBody() argument
956 if (BC_ERR(p->flags.len <= 1)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_endBody()
962 assert(p->l.t == BC_LEX_RBRACE); in bc_parse_endBody()
964 bc_lex_next(&p->l); in bc_parse_endBody()
967 if (BC_ERR(!bc_parse_isDelimiter(p) && !bc_parse_TopFunc(p))) in bc_parse_endBody()
969 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_endBody()
974 has_brace = (BC_PARSE_BRACE(p) != 0); in bc_parse_endBody()
978 size_t len = p->flags.len; in bc_parse_endBody()
982 if (has_brace && !brace) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_endBody()
985 loop = (BC_PARSE_LOOP_INNER(p) != 0); in bc_parse_endBody()
988 if (loop || BC_PARSE_ELSE(p)) in bc_parse_endBody()
993 size_t* label = bc_vec_top(&p->conds); in bc_parse_endBody()
995 bc_parse_push(p, BC_INST_JUMP); in bc_parse_endBody()
996 bc_parse_pushIndex(p, *label); in bc_parse_endBody()
998 bc_vec_pop(&p->conds); in bc_parse_endBody()
1001 bc_parse_setLabel(p); in bc_parse_endBody()
1002 bc_vec_pop(&p->flags); in bc_parse_endBody()
1005 else if (BC_PARSE_FUNC_INNER(p)) in bc_parse_endBody()
1007 BcInst inst = (p->func->voidfn ? BC_INST_RET_VOID : BC_INST_RET0); in bc_parse_endBody()
1008 bc_parse_push(p, inst); in bc_parse_endBody()
1009 bc_parse_updateFunc(p, BC_PROG_MAIN); in bc_parse_endBody()
1010 bc_vec_pop(&p->flags); in bc_parse_endBody()
1014 else if (has_brace && !BC_PARSE_IF(p)) bc_vec_pop(&p->flags); in bc_parse_endBody()
1017 if (BC_PARSE_IF(p) && (len == p->flags.len || !BC_PARSE_BRACE(p))) in bc_parse_endBody()
1020 while (p->l.t == BC_LEX_NLINE) in bc_parse_endBody()
1022 bc_lex_next(&p->l); in bc_parse_endBody()
1026 bc_vec_pop(&p->flags); in bc_parse_endBody()
1028 // If we are allowed non-POSIX stuff... in bc_parse_endBody()
1032 *(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_IF_END; in bc_parse_endBody()
1033 new_else = (p->l.t == BC_LEX_KW_ELSE); in bc_parse_endBody()
1036 if (new_else) bc_parse_else(p); in bc_parse_endBody()
1037 else if (!has_brace && (!BC_PARSE_IF_END(p) || brace)) in bc_parse_endBody()
1039 bc_parse_noElse(p); in bc_parse_endBody()
1043 else bc_parse_noElse(p); in bc_parse_endBody()
1054 while (p->flags.len > 1 && !new_else && (!BC_PARSE_IF_END(p) || brace) && in bc_parse_endBody()
1055 !(has_brace = (BC_PARSE_BRACE(p) != 0))); in bc_parse_endBody()
1058 if (BC_ERR(p->flags.len == 1 && brace)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_endBody()
1059 else if (brace && BC_PARSE_BRACE(p)) in bc_parse_endBody()
1062 uint16_t flags = BC_PARSE_TOP_FLAG(p); in bc_parse_endBody()
1070 bc_vec_pop(&p->flags); in bc_parse_endBody()
1077 * @param p The parser.
1081 bc_parse_startBody(BcParse* p, uint16_t flags) in bc_parse_startBody() argument
1084 flags |= (BC_PARSE_TOP_FLAG(p) & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP)); in bc_parse_startBody()
1086 bc_vec_push(&p->flags, &flags); in bc_parse_startBody()
1090 bc_parse_endif(BcParse* p) in bc_parse_endif() argument
1096 if (BC_NO_ERR(!BC_PARSE_NO_EXEC(p))) return; in bc_parse_endif()
1102 for (i = 0; good && i < p->flags.len; ++i) in bc_parse_endif()
1104 uint16_t flag = *((uint16_t*) bc_vec_item(&p->flags, i)); in bc_parse_endif()
1113 BcMode mode = vm->mode; in bc_parse_endif()
1115 vm->mode = BC_MODE_FILE; in bc_parse_endif()
1118 while (p->flags.len > 1 || BC_PARSE_IF_END(p)) in bc_parse_endif()
1120 if (BC_PARSE_IF_END(p)) bc_parse_noElse(p); in bc_parse_endif()
1121 if (p->flags.len > 1) bc_parse_endBody(p, false); in bc_parse_endif()
1124 vm->mode = (uchar) mode; in bc_parse_endif()
1127 else bc_parse_err(&vm->prs, BC_ERR_PARSE_BLOCK); in bc_parse_endif()
1132 * @param p The parser.
1135 bc_parse_if(BcParse* p) in bc_parse_if() argument
1142 bc_lex_next(&p->l); in bc_parse_if()
1143 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_if()
1146 bc_lex_next(&p->l); in bc_parse_if()
1147 bc_parse_expr_status(p, flags, bc_parse_next_rel); in bc_parse_if()
1150 if (BC_ERR(p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_if()
1152 bc_lex_next(&p->l); in bc_parse_if()
1155 bc_parse_push(p, BC_INST_JUMP_ZERO); in bc_parse_if()
1157 idx = p->func->labels.len; in bc_parse_if()
1161 bc_parse_pushIndex(p, idx); in bc_parse_if()
1162 bc_parse_createExitLabel(p, idx, false); in bc_parse_if()
1164 bc_parse_startBody(p, BC_PARSE_FLAG_IF); in bc_parse_if()
1169 * @param p The parser.
1172 bc_parse_else(BcParse* p) in bc_parse_else() argument
1174 size_t idx = p->func->labels.len; in bc_parse_else()
1177 if (BC_ERR(!BC_PARSE_IF_END(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_else()
1181 bc_parse_push(p, BC_INST_JUMP); in bc_parse_else()
1182 bc_parse_pushIndex(p, idx); in bc_parse_else()
1186 bc_parse_noElse(p); in bc_parse_else()
1189 bc_parse_createExitLabel(p, idx, false); in bc_parse_else()
1190 bc_parse_startBody(p, BC_PARSE_FLAG_ELSE); in bc_parse_else()
1192 bc_lex_next(&p->l); in bc_parse_else()
1197 * @param p The parser.
1200 bc_parse_while(BcParse* p) in bc_parse_while() argument
1207 bc_lex_next(&p->l); in bc_parse_while()
1208 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_while()
1209 bc_lex_next(&p->l); in bc_parse_while()
1212 bc_parse_createCondLabel(p, p->func->labels.len); in bc_parse_while()
1213 idx = p->func->labels.len; in bc_parse_while()
1214 bc_parse_createExitLabel(p, idx, true); in bc_parse_while()
1216 // Parse the actual condition and barf on non-right paren. in bc_parse_while()
1217 bc_parse_expr_status(p, flags, bc_parse_next_rel); in bc_parse_while()
1218 if (BC_ERR(p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_while()
1219 bc_lex_next(&p->l); in bc_parse_while()
1222 bc_parse_push(p, BC_INST_JUMP_ZERO); in bc_parse_while()
1223 bc_parse_pushIndex(p, idx); in bc_parse_while()
1224 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); in bc_parse_while()
1229 * @param p The parser.
1232 bc_parse_for(BcParse* p) in bc_parse_for() argument
1237 bc_lex_next(&p->l); in bc_parse_for()
1238 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_for()
1239 bc_lex_next(&p->l); in bc_parse_for()
1243 if (p->l.t != BC_LEX_SCOLON) bc_parse_expr_status(p, 0, bc_parse_next_for); in bc_parse_for()
1244 else bc_parse_err(p, BC_ERR_POSIX_FOR); in bc_parse_for()
1247 if (BC_ERR(p->l.t != BC_LEX_SCOLON)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_for()
1248 bc_lex_next(&p->l); in bc_parse_for()
1254 cond_idx = p->func->labels.len; in bc_parse_for()
1260 bc_parse_createLabel(p, p->func->code.len); in bc_parse_for()
1263 if (p->l.t != BC_LEX_SCOLON) in bc_parse_for()
1266 bc_parse_expr_status(p, flags, bc_parse_next_for); in bc_parse_for()
1272 // non-zero. This is safe to set because the current token is a in bc_parse_for()
1274 bc_vec_string(&p->l.str, sizeof(bc_parse_one) - 1, bc_parse_one); in bc_parse_for()
1275 bc_parse_number(p); in bc_parse_for()
1278 bc_parse_err(p, BC_ERR_POSIX_FOR); in bc_parse_for()
1282 if (BC_ERR(p->l.t != BC_LEX_SCOLON)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_for()
1283 bc_lex_next(&p->l); in bc_parse_for()
1289 bc_parse_push(p, BC_INST_JUMP_ZERO); in bc_parse_for()
1290 bc_parse_pushIndex(p, exit_idx); in bc_parse_for()
1291 bc_parse_push(p, BC_INST_JUMP); in bc_parse_for()
1292 bc_parse_pushIndex(p, body_idx); in bc_parse_for()
1295 bc_parse_createCondLabel(p, update_idx); in bc_parse_for()
1298 if (p->l.t != BC_LEX_RPAREN) bc_parse_expr_status(p, 0, bc_parse_next_rel); in bc_parse_for()
1299 else bc_parse_err(p, BC_ERR_POSIX_FOR); in bc_parse_for()
1302 if (BC_ERR(p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_for()
1305 bc_parse_push(p, BC_INST_JUMP); in bc_parse_for()
1306 bc_parse_pushIndex(p, cond_idx); in bc_parse_for()
1307 bc_parse_createLabel(p, p->func->code.len); in bc_parse_for()
1310 bc_parse_createExitLabel(p, exit_idx, true); in bc_parse_for()
1311 bc_lex_next(&p->l); in bc_parse_for()
1312 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); in bc_parse_for()
1318 * @param p The parser.
1322 bc_parse_loopExit(BcParse* p, BcLexType type) in bc_parse_loopExit() argument
1328 if (BC_ERR(!BC_PARSE_LOOP(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_loopExit()
1334 if (BC_ERR(!p->exits.len)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_loopExit()
1337 i = p->exits.len - 1; in bc_parse_loopExit()
1338 ip = bc_vec_item(&p->exits, i); in bc_parse_loopExit()
1340 // The condition !ip->func is true if the exit is not for a loop, so we in bc_parse_loopExit()
1342 while (!ip->func && i < p->exits.len) in bc_parse_loopExit()
1344 ip = bc_vec_item(&p->exits, i); in bc_parse_loopExit()
1345 i -= 1; in bc_parse_loopExit()
1349 assert(ip != NULL && (i < p->exits.len || ip->func)); in bc_parse_loopExit()
1352 i = ip->idx; in bc_parse_loopExit()
1356 else i = *((size_t*) bc_vec_top(&p->conds)); in bc_parse_loopExit()
1359 bc_parse_push(p, BC_INST_JUMP); in bc_parse_loopExit()
1360 bc_parse_pushIndex(p, i); in bc_parse_loopExit()
1362 bc_lex_next(&p->l); in bc_parse_loopExit()
1367 * @param p The parser.
1370 bc_parse_func(BcParse* p) in bc_parse_func() argument
1376 bc_lex_next(&p->l); in bc_parse_func()
1379 if (BC_ERR(p->l.t != BC_LEX_NAME)) bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_func()
1382 voidfn = (!BC_IS_POSIX && p->l.t == BC_LEX_NAME && in bc_parse_func()
1383 !strcmp(p->l.str.v, "void")); in bc_parse_func()
1387 bc_lex_next(&p->l); in bc_parse_func()
1390 voidfn = (voidfn && p->l.t == BC_LEX_NAME); in bc_parse_func()
1395 bc_parse_err(p, BC_ERR_POSIX_VOID); in bc_parse_func()
1399 bc_lex_next(&p->l); in bc_parse_func()
1403 if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_func()
1406 assert(p->prog->fns.len == p->prog->fn_map.len); in bc_parse_func()
1409 idx = bc_program_insertFunc(p->prog, p->l.str.v); in bc_parse_func()
1415 bc_parse_updateFunc(p, idx); in bc_parse_func()
1416 p->func->voidfn = voidfn; in bc_parse_func()
1418 bc_lex_next(&p->l); in bc_parse_func()
1421 while (p->l.t != BC_LEX_RPAREN) in bc_parse_func()
1426 if (p->l.t == BC_LEX_OP_MULTIPLY) in bc_parse_func()
1429 bc_lex_next(&p->l); in bc_parse_func()
1432 bc_parse_err(p, BC_ERR_POSIX_REF); in bc_parse_func()
1436 if (BC_ERR(p->l.t != BC_LEX_NAME)) bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_func()
1439 p->func->nparams += 1; in bc_parse_func()
1442 bc_vec_string(&p->buf, p->l.str.len, p->l.str.v); in bc_parse_func()
1444 bc_lex_next(&p->l); in bc_parse_func()
1447 if (p->l.t == BC_LEX_LBRACKET) in bc_parse_func()
1452 bc_lex_next(&p->l); in bc_parse_func()
1455 if (BC_ERR(p->l.t != BC_LEX_RBRACKET)) in bc_parse_func()
1457 bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_func()
1460 bc_lex_next(&p->l); in bc_parse_func()
1466 bc_parse_verr(p, BC_ERR_PARSE_REF_VAR, p->buf.v); in bc_parse_func()
1470 comma = (p->l.t == BC_LEX_COMMA); in bc_parse_func()
1471 if (comma) bc_lex_next(&p->l); in bc_parse_func()
1474 bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line); in bc_parse_func()
1478 if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_func()
1482 bc_parse_startBody(p, flags); in bc_parse_func()
1484 bc_lex_next(&p->l); in bc_parse_func()
1488 if (p->l.t != BC_LEX_LBRACE) bc_parse_err(p, BC_ERR_POSIX_BRACE); in bc_parse_func()
1493 * @param p The parser.
1496 bc_parse_auto(BcParse* p) in bc_parse_auto() argument
1501 if (BC_ERR(!p->auto_part)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_auto()
1502 bc_lex_next(&p->l); in bc_parse_auto()
1504 p->auto_part = comma = false; in bc_parse_auto()
1507 one = (p->l.t == BC_LEX_NAME); in bc_parse_auto()
1510 while (p->l.t == BC_LEX_NAME) in bc_parse_auto()
1515 bc_vec_string(&p->buf, p->l.str.len - 1, p->l.str.v); in bc_parse_auto()
1517 bc_lex_next(&p->l); in bc_parse_auto()
1520 if (p->l.t == BC_LEX_LBRACKET) in bc_parse_auto()
1524 bc_lex_next(&p->l); in bc_parse_auto()
1527 if (BC_ERR(p->l.t != BC_LEX_RBRACKET)) in bc_parse_auto()
1529 bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_auto()
1532 bc_lex_next(&p->l); in bc_parse_auto()
1537 comma = (p->l.t == BC_LEX_COMMA); in bc_parse_auto()
1538 if (comma) bc_lex_next(&p->l); in bc_parse_auto()
1541 bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line); in bc_parse_auto()
1545 if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC); in bc_parse_auto()
1548 if (BC_ERR(!one)) bc_parse_err(p, BC_ERR_PARSE_NO_AUTO); in bc_parse_auto()
1551 if (BC_ERR(!bc_parse_isDelimiter(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_auto()
1556 * @param p The parser.
1560 bc_parse_body(BcParse* p, bool brace) in bc_parse_body() argument
1562 uint16_t* flag_ptr = BC_PARSE_TOP_FLAG_PTR(p); in bc_parse_body()
1565 assert(p->flags.len >= 2); in bc_parse_body()
1576 if (BC_ERR(!brace)) bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_body()
1578 p->auto_part = (p->l.t != BC_LEX_KW_AUTO); in bc_parse_body()
1580 if (!p->auto_part) in bc_parse_body()
1583 p->auto_part = true; in bc_parse_body()
1586 bc_parse_auto(p); in bc_parse_body()
1590 if (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l); in bc_parse_body()
1595 size_t len = p->flags.len; in bc_parse_body()
1600 bc_parse_stmt(p); in bc_parse_body()
1606 if (!brace && !BC_PARSE_BODY(p) && len <= p->flags.len) in bc_parse_body()
1608 bc_parse_endBody(p, false); in bc_parse_body()
1616 * @param p The parser.
1619 bc_parse_stmt(BcParse* p) in bc_parse_stmt() argument
1623 BcLexType type = p->l.t; in bc_parse_stmt()
1628 bc_lex_next(&p->l); in bc_parse_stmt()
1635 bc_parse_auto(p); in bc_parse_stmt()
1640 p->auto_part = false; in bc_parse_stmt()
1647 if (BC_PARSE_IF_END(p)) in bc_parse_stmt()
1651 bc_parse_noElse(p); in bc_parse_stmt()
1652 if (p->flags.len > 1 && !BC_PARSE_BRACE(p)) in bc_parse_stmt()
1654 bc_parse_endBody(p, false); in bc_parse_stmt()
1663 if (!BC_PARSE_BODY(p)) in bc_parse_stmt()
1665 bc_parse_startBody(p, BC_PARSE_FLAG_BRACE); in bc_parse_stmt()
1666 bc_lex_next(&p->l); in bc_parse_stmt()
1673 *(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_BRACE; in bc_parse_stmt()
1674 bc_lex_next(&p->l); in bc_parse_stmt()
1675 bc_parse_body(p, true); in bc_parse_stmt()
1685 else if (BC_PARSE_BODY(p) && !BC_PARSE_BRACE(p)) in bc_parse_stmt()
1687 bc_parse_body(p, false); in bc_parse_stmt()
1692 len = p->flags.len; in bc_parse_stmt()
1693 flags = BC_PARSE_TOP_FLAG(p); in bc_parse_stmt()
1737 bc_parse_expr_status(p, BC_PARSE_PRINT, bc_parse_next_expr); in bc_parse_stmt()
1743 bc_parse_else(p); in bc_parse_stmt()
1756 bc_parse_endBody(p, true); in bc_parse_stmt()
1762 bc_parse_str(p, BC_INST_PRINT_STR); in bc_parse_stmt()
1769 bc_parse_loopExit(p, p->l.t); in bc_parse_stmt()
1775 bc_parse_for(p); in bc_parse_stmt()
1781 bc_parse_push(p, BC_INST_HALT); in bc_parse_stmt()
1782 bc_lex_next(&p->l); in bc_parse_stmt()
1788 bc_parse_if(p); in bc_parse_stmt()
1794 // `limits` is a compile-time command, so execute it right away. in bc_parse_stmt()
1812 bc_lex_next(&p->l); in bc_parse_stmt()
1820 bc_parse_print(p, type); in bc_parse_stmt()
1826 // Quit is a compile-time command. We don't exit directly, so the vm in bc_parse_stmt()
1828 vm->status = BC_STATUS_QUIT; in bc_parse_stmt()
1835 bc_parse_return(p); in bc_parse_stmt()
1841 bc_parse_while(p); in bc_parse_stmt()
1918 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_stmt()
1923 if (len == p->flags.len && flags == BC_PARSE_TOP_FLAG(p)) in bc_parse_stmt()
1925 if (BC_ERR(!bc_parse_isDelimiter(p))) in bc_parse_stmt()
1927 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_stmt()
1932 while (p->l.t == BC_LEX_SCOLON || p->l.t == BC_LEX_NLINE) in bc_parse_stmt()
1934 bc_lex_next(&p->l); in bc_parse_stmt()
1940 if (p->l.last == BC_LEX_SCOLON && p->l.t == BC_LEX_KW_DEFINE && BC_IS_POSIX) in bc_parse_stmt()
1942 bc_parse_err(p, BC_ERR_POSIX_FUNC_AFTER_SEMICOLON); in bc_parse_stmt()
1947 bc_parse_parse(BcParse* p) in bc_parse_parse() argument
1949 assert(p); in bc_parse_parse()
1955 if (BC_ERR(p->l.t == BC_LEX_EOF)) bc_parse_err(p, BC_ERR_PARSE_EOF); in bc_parse_parse()
1958 else if (p->l.t == BC_LEX_KW_DEFINE) in bc_parse_parse()
1960 if (BC_ERR(BC_PARSE_NO_EXEC(p))) in bc_parse_parse()
1962 bc_parse_endif(p); in bc_parse_parse()
1963 if (BC_ERR(BC_PARSE_NO_EXEC(p))) in bc_parse_parse()
1965 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_parse()
1968 bc_parse_func(p); in bc_parse_parse()
1972 else bc_parse_stmt(p); in bc_parse_parse()
1977 if (BC_ERR(((vm->status && vm->status != BC_STATUS_QUIT) || vm->sig != 0))) in bc_parse_parse()
1979 bc_parse_reset(p); in bc_parse_parse()
1987 * Parse an expression. This is the actual implementation of the Shunting-Yard
1989 * @param p The parser.
1998 bc_parse_expr_err(BcParse* p, uint8_t flags, BcParseNext next) in bc_parse_expr_err() argument
2015 // recursive (the Shunting-Yard Algorithm is most easily expressed in bc_parse_expr_err()
2019 // - nparens is the number of left parens without matches. in bc_parse_expr_err()
2020 // - nrelops is the number of relational operators that appear in the expr. in bc_parse_expr_err()
2021 // - nexprs is the number of unused expressions. in bc_parse_expr_err()
2022 // - rprn is a right paren encountered last. in bc_parse_expr_err()
2023 // - array_last is an array item encountered last. in bc_parse_expr_err()
2024 // - done means the expression has been fully parsed. in bc_parse_expr_err()
2025 // - get_token is true when a token is needed at the end of an iteration. in bc_parse_expr_err()
2026 // - assign is true when an assignment statement was parsed last. in bc_parse_expr_err()
2027 // - incdec is true when the previous operator was an inc or dec operator. in bc_parse_expr_err()
2028 // - can_assign is true when an assignemnt is valid. in bc_parse_expr_err()
2029 // - bin_last is true when the previous instruction was a binary operator. in bc_parse_expr_err()
2030 t = p->l.t; in bc_parse_expr_err()
2031 pfirst = (p->l.t == BC_LEX_LPAREN); in bc_parse_expr_err()
2034 ops_bgn = p->ops.len; in bc_parse_expr_err()
2042 while ((t = p->l.t) == BC_LEX_NLINE) in bc_parse_expr_err()
2044 bc_lex_next(&p->l); in bc_parse_expr_err()
2048 // This is the Shunting-Yard algorithm loop. in bc_parse_expr_err()
2049 for (; !done && BC_PARSE_EXPR(t); t = p->l.t) in bc_parse_expr_err()
2056 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2066 if (BC_ERR(incdec)) bc_parse_err(p, BC_ERR_PARSE_ASSIGN); in bc_parse_expr_err()
2068 bc_parse_incdec(p, &prev, &can_assign, &nexprs, flags); in bc_parse_expr_err()
2084 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_expr_err()
2089 bc_parse_push(p, BC_INST_TRUNC); in bc_parse_expr_err()
2101 bc_parse_minus(p, &prev, ops_bgn, rprn, bin_last, &nexprs); in bc_parse_expr_err()
2132 bc_parse_err(p, BC_ERR_PARSE_ASSIGN); in bc_parse_expr_err()
2165 if (BC_ERR(!bin_last && !BC_PARSE_OP_PREFIX(p->l.last))) in bc_parse_expr_err()
2167 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2175 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2181 bc_parse_operator(p, t, ops_bgn, &nexprs); in bc_parse_expr_err()
2196 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2204 bc_vec_push(&p->ops, &t); in bc_parse_expr_err()
2213 if (BC_ERR(p->l.last == BC_LEX_LPAREN)) in bc_parse_expr_err()
2222 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2239 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2242 nparens -= 1; in bc_parse_expr_err()
2246 bc_parse_rightParen(p, &nexprs); in bc_parse_expr_err()
2254 if (BC_IS_POSIX) bc_parse_err(p, BC_ERR_POSIX_EXPR_STRING); in bc_parse_expr_err()
2259 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2262 bc_parse_addString(p); in bc_parse_expr_err()
2276 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2281 bc_parse_name(p, &prev, &can_assign, flags & ~BC_PARSE_NOCALL); in bc_parse_expr_err()
2296 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2300 bc_parse_number(p); in bc_parse_expr_err()
2321 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2324 prev = t - BC_LEX_KW_LAST + BC_INST_LAST; in bc_parse_expr_err()
2325 bc_parse_push(p, prev); in bc_parse_expr_err()
2348 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2351 bc_parse_builtin(p, t, flags, &prev); in bc_parse_expr_err()
2377 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2383 bc_parse_err(p, BC_ERR_EXEC_REC_READ); in bc_parse_expr_err()
2386 prev = t - BC_LEX_KW_READ + BC_INST_READ; in bc_parse_expr_err()
2387 bc_parse_noArgBuiltin(p, prev); in bc_parse_expr_err()
2401 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2406 bc_parse_scale(p, &prev, &can_assign, flags); in bc_parse_expr_err()
2421 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2424 bc_parse_builtin3(p, t, flags, &prev); in bc_parse_expr_err()
2488 bc_parse_err(p, BC_ERR_PARSE_TOKEN); in bc_parse_expr_err()
2494 if (get_token) bc_lex_next(&p->l); in bc_parse_expr_err()
2499 while (p->ops.len > ops_bgn) in bc_parse_expr_err()
2501 top = BC_PARSE_TOP_OP(p); in bc_parse_expr_err()
2507 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2510 bc_parse_push(p, BC_PARSE_TOKEN_INST(top)); in bc_parse_expr_err()
2513 nexprs -= !BC_PARSE_OP_PREFIX(top); in bc_parse_expr_err()
2514 bc_vec_pop(&p->ops); in bc_parse_expr_err()
2520 if (BC_ERR(nexprs != 1)) bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2527 if (BC_ERR(i == next.len && !bc_parse_isDelimiter(p))) in bc_parse_expr_err()
2529 bc_parse_err(p, BC_ERR_PARSE_EXPR); in bc_parse_expr_err()
2535 bc_parse_err(p, BC_ERR_POSIX_REL_POS); in bc_parse_expr_err()
2539 bc_parse_err(p, BC_ERR_POSIX_MULTIREL); in bc_parse_expr_err()
2551 inst = *((uchar*) bc_vec_top(&p->func->code)); in bc_parse_expr_err()
2552 inst += (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER); in bc_parse_expr_err()
2559 inst = *((uchar*) bc_vec_top(&p->func->code)); in bc_parse_expr_err()
2575 bc_vec_pop(&p->func->code); in bc_parse_expr_err()
2576 if (incdec) bc_parse_push(p, BC_INST_ONE); in bc_parse_expr_err()
2577 bc_parse_push(p, inst); in bc_parse_expr_err()
2586 if (pfirst || !assign) bc_parse_push(p, BC_INST_PRINT); in bc_parse_expr_err()
2594 bc_parse_push(p, BC_INST_POP); in bc_parse_expr_err()
2608 while (p->l.t == BC_LEX_NLINE) in bc_parse_expr_err()
2610 bc_lex_next(&p->l); in bc_parse_expr_err()
2620 * @param p The parser.
2625 bc_parse_expr_status(BcParse* p, uint8_t flags, BcParseNext next) in bc_parse_expr_status() argument
2627 BcParseStatus s = bc_parse_expr_err(p, flags, next); in bc_parse_expr_status()
2631 bc_parse_err(p, BC_ERR_PARSE_EMPTY_EXPR); in bc_parse_expr_status()
2636 bc_parse_expr(BcParse* p, uint8_t flags) in bc_parse_expr() argument
2638 assert(p); in bc_parse_expr()
2639 bc_parse_expr_status(p, flags, bc_parse_next_read); in bc_parse_expr()