aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c266
1 files changed, 148 insertions, 118 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 8f326d20e..eae5063a8 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -544,8 +544,14 @@ enum {
544#define bc_lex_kws_POSIX(i) ((1 << (i)) & POSIX_KWORD_MASK) 544#define bc_lex_kws_POSIX(i) ((1 << (i)) & POSIX_KWORD_MASK)
545#endif 545#endif
546 546
547#if ENABLE_FEATURE_BC_SIGNALS || ENABLE_FEATURE_CLEAN_UP
548# define BC_STATUS BcStatus
549#else
550# define BC_STATUS void
551#endif
552
547struct BcLex; 553struct BcLex;
548typedef BcStatus (*BcLexNext)(struct BcLex *) FAST_FUNC; 554typedef BC_STATUS (*BcLexNext)(struct BcLex *) FAST_FUNC;
549 555
550typedef struct BcLex { 556typedef struct BcLex {
551 557
@@ -933,13 +939,13 @@ dc_parse_insts[] = {
933# define ERRORS_ARE_FATAL 0 939# define ERRORS_ARE_FATAL 0
934# define ERRORFUNC /*nothing*/ 940# define ERRORFUNC /*nothing*/
935# define ERROR_RETURN(a) a 941# define ERROR_RETURN(a) a
936# define BC_STATUS BcStatus 942//moved up: # define BC_STATUS BcStatus
937# define RETURN_STATUS(v) return (v) 943# define RETURN_STATUS(v) return (v)
938#else 944#else
939# define ERRORS_ARE_FATAL 1 945# define ERRORS_ARE_FATAL 1
940# define ERRORFUNC NORETURN 946# define ERRORFUNC NORETURN
941# define ERROR_RETURN(a) /*nothing*/ 947# define ERROR_RETURN(a) /*nothing*/
942# define BC_STATUS void 948//moved up: # define BC_STATUS void
943# define RETURN_STATUS(v) do { ((void)(v)); return; } while (0) 949# define RETURN_STATUS(v) do { ((void)(v)); return; } while (0)
944#endif 950#endif
945 951
@@ -2940,40 +2946,48 @@ static void bc_lex_file(BcLex *l)
2940 l->newline = false; 2946 l->newline = false;
2941} 2947}
2942 2948
2943static BcStatus bc_lex_next(BcLex *l) 2949static BC_STATUS zbc_lex_next(BcLex *l)
2944{ 2950{
2945 BcStatus s; 2951 BcStatus s;
2946 2952
2947 l->t.last = l->t.t; 2953 l->t.last = l->t.t;
2948 if (l->t.last == BC_LEX_EOF) return bc_error("end of file"); 2954 if (l->t.last == BC_LEX_EOF) RETURN_STATUS(bc_error("end of file"));
2949 2955
2950 l->line += l->newline; 2956 l->line += l->newline;
2951 G.err_line = l->line; 2957 G.err_line = l->line;
2952 l->t.t = BC_LEX_EOF; 2958 l->t.t = BC_LEX_EOF;
2953 2959
2954 l->newline = (l->i == l->len); 2960 l->newline = (l->i == l->len);
2955 if (l->newline) return BC_STATUS_SUCCESS; 2961 if (l->newline) RETURN_STATUS(BC_STATUS_SUCCESS);
2956 2962
2957 // Loop until failure or we don't have whitespace. This 2963 // Loop until failure or we don't have whitespace. This
2958 // is so the parser doesn't get inundated with whitespace. 2964 // is so the parser doesn't get inundated with whitespace.
2965 s = BC_STATUS_SUCCESS;
2959 do { 2966 do {
2960 s = l->next(l); 2967//TODO: replace pointer with if(IS_BC)
2968 ERROR_RETURN(s =) l->next(l);
2961 } while (!s && l->t.t == BC_LEX_WHITESPACE); 2969 } while (!s && l->t.t == BC_LEX_WHITESPACE);
2962 2970
2963 return s; 2971 RETURN_STATUS(s);
2964} 2972}
2973#if ERRORS_ARE_FATAL
2974# define zbc_lex_next(...) (zbc_lex_next(__VA_ARGS__), BC_STATUS_SUCCESS)
2975#endif
2965 2976
2966static BcStatus bc_lex_text(BcLex *l, const char *text) 2977static BC_STATUS zbc_lex_text(BcLex *l, const char *text)
2967{ 2978{
2968 l->buf = text; 2979 l->buf = text;
2969 l->i = 0; 2980 l->i = 0;
2970 l->len = strlen(text); 2981 l->len = strlen(text);
2971 l->t.t = l->t.last = BC_LEX_INVALID; 2982 l->t.t = l->t.last = BC_LEX_INVALID;
2972 return bc_lex_next(l); 2983 RETURN_STATUS(zbc_lex_next(l));
2973} 2984}
2985#if ERRORS_ARE_FATAL
2986# define zbc_lex_text(...) (zbc_lex_text(__VA_ARGS__), BC_STATUS_SUCCESS)
2987#endif
2974 2988
2975#if ENABLE_BC 2989#if ENABLE_BC
2976static BcStatus bc_lex_identifier(BcLex *l) 2990static BC_STATUS zbc_lex_identifier(BcLex *l)
2977{ 2991{
2978 BcStatus s; 2992 BcStatus s;
2979 unsigned i; 2993 unsigned i;
@@ -2993,12 +3007,12 @@ static BcStatus bc_lex_identifier(BcLex *l)
2993 l->t.t = BC_LEX_KEY_1st_keyword + i; 3007 l->t.t = BC_LEX_KEY_1st_keyword + i;
2994 if (!bc_lex_kws_POSIX(i)) { 3008 if (!bc_lex_kws_POSIX(i)) {
2995 s = bc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8); 3009 s = bc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8);
2996 ERROR_RETURN(if (s) return s;) 3010 ERROR_RETURN(if (s) RETURN_STATUS(s);)
2997 } 3011 }
2998 3012
2999 // We minus 1 because the index has already been incremented. 3013 // We minus 1 because the index has already been incremented.
3000 l->i += j - 1; 3014 l->i += j - 1;
3001 return BC_STATUS_SUCCESS; 3015 RETURN_STATUS(BC_STATUS_SUCCESS);
3002 } 3016 }
3003 3017
3004 bc_lex_name(l); 3018 bc_lex_name(l);
@@ -3012,8 +3026,11 @@ static BcStatus bc_lex_identifier(BcLex *l)
3012 s = bc_posix_error_fmt("POSIX only allows one character names; the following is bad: '%.*s'", len, buf); 3026 s = bc_posix_error_fmt("POSIX only allows one character names; the following is bad: '%.*s'", len, buf);
3013 } 3027 }
3014 3028
3015 return s; 3029 RETURN_STATUS(s);
3016} 3030}
3031#if ERRORS_ARE_FATAL
3032# define zbc_lex_identifier(...) (zbc_lex_identifier(__VA_ARGS__), BC_STATUS_SUCCESS)
3033#endif
3017 3034
3018static BcStatus bc_lex_string(BcLex *l) 3035static BcStatus bc_lex_string(BcLex *l)
3019{ 3036{
@@ -3088,7 +3105,7 @@ static BC_STATUS zbc_lex_comment(BcLex *l)
3088# define zbc_lex_comment(...) (zbc_lex_comment(__VA_ARGS__), BC_STATUS_SUCCESS) 3105# define zbc_lex_comment(...) (zbc_lex_comment(__VA_ARGS__), BC_STATUS_SUCCESS)
3089#endif 3106#endif
3090 3107
3091static FAST_FUNC BcStatus bc_lex_token(BcLex *l) 3108static FAST_FUNC BC_STATUS zbc_lex_token(BcLex *l)
3092{ 3109{
3093 BcStatus s = BC_STATUS_SUCCESS; 3110 BcStatus s = BC_STATUS_SUCCESS;
3094 char c = l->buf[l->i++], c2; 3111 char c = l->buf[l->i++], c2;
@@ -3111,7 +3128,7 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3111 bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); 3128 bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT);
3112 if (l->t.t == BC_LEX_OP_BOOL_NOT) { 3129 if (l->t.t == BC_LEX_OP_BOOL_NOT) {
3113 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); 3130 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("!");
3114 ERROR_RETURN(if (s) return s;) 3131 ERROR_RETURN(if (s) RETURN_STATUS(s);)
3115 } 3132 }
3116 break; 3133 break;
3117 case '"': 3134 case '"':
@@ -3119,7 +3136,7 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3119 break; 3136 break;
3120 case '#': 3137 case '#':
3121 s = bc_POSIX_does_not_allow("'#' script comments"); 3138 s = bc_POSIX_does_not_allow("'#' script comments");
3122 ERROR_RETURN(if (s) return s;) 3139 ERROR_RETURN(if (s) RETURN_STATUS(s);)
3123 bc_lex_lineComment(l); 3140 bc_lex_lineComment(l);
3124 break; 3141 break;
3125 case '%': 3142 case '%':
@@ -3129,7 +3146,7 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3129 c2 = l->buf[l->i]; 3146 c2 = l->buf[l->i];
3130 if (c2 == '&') { 3147 if (c2 == '&') {
3131 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); 3148 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("&&");
3132 ERROR_RETURN(if (s) return s;) 3149 ERROR_RETURN(if (s) RETURN_STATUS(s);)
3133 ++l->i; 3150 ++l->i;
3134 l->t.t = BC_LEX_OP_BOOL_AND; 3151 l->t.t = BC_LEX_OP_BOOL_AND;
3135 } else { 3152 } else {
@@ -3248,7 +3265,7 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3248 case 'x': 3265 case 'x':
3249 case 'y': 3266 case 'y':
3250 case 'z': 3267 case 'z':
3251 s = bc_lex_identifier(l); 3268 s = zbc_lex_identifier(l);
3252 break; 3269 break;
3253 case '{': 3270 case '{':
3254 case '}': 3271 case '}':
@@ -3258,7 +3275,7 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3258 c2 = l->buf[l->i]; 3275 c2 = l->buf[l->i];
3259 if (c2 == '|') { 3276 if (c2 == '|') {
3260 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); 3277 s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("||");
3261 ERROR_RETURN(if (s) return s;) 3278 ERROR_RETURN(if (s) RETURN_STATUS(s);)
3262 ++l->i; 3279 ++l->i;
3263 l->t.t = BC_LEX_OP_BOOL_OR; 3280 l->t.t = BC_LEX_OP_BOOL_OR;
3264 } else { 3281 } else {
@@ -3272,7 +3289,7 @@ static FAST_FUNC BcStatus bc_lex_token(BcLex *l)
3272 break; 3289 break;
3273 } 3290 }
3274 3291
3275 return s; 3292 RETURN_STATUS(s);
3276} 3293}
3277#endif // ENABLE_BC 3294#endif // ENABLE_BC
3278 3295
@@ -3338,7 +3355,7 @@ static BC_STATUS zdc_lex_string(BcLex *l)
3338# define zdc_lex_string(...) (zdc_lex_string(__VA_ARGS__), BC_STATUS_SUCCESS) 3355# define zdc_lex_string(...) (zdc_lex_string(__VA_ARGS__), BC_STATUS_SUCCESS)
3339#endif 3356#endif
3340 3357
3341static FAST_FUNC BcStatus dc_lex_token(BcLex *l) 3358static FAST_FUNC BC_STATUS zdc_lex_token(BcLex *l)
3342{ 3359{
3343 BcStatus s = BC_STATUS_SUCCESS; 3360 BcStatus s = BC_STATUS_SUCCESS;
3344 char c = l->buf[l->i++], c2; 3361 char c = l->buf[l->i++], c2;
@@ -3346,13 +3363,13 @@ static FAST_FUNC BcStatus dc_lex_token(BcLex *l)
3346 3363
3347 for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) { 3364 for (i = 0; i < ARRAY_SIZE(dc_lex_regs); ++i) {
3348 if (l->t.last == dc_lex_regs[i]) 3365 if (l->t.last == dc_lex_regs[i])
3349 return zdc_lex_register(l); 3366 RETURN_STATUS(zdc_lex_register(l));
3350 } 3367 }
3351 3368
3352 if (c >= '%' && c <= '~' 3369 if (c >= '%' && c <= '~'
3353 && (l->t.t = dc_lex_tokens[(c - '%')]) != BC_LEX_INVALID 3370 && (l->t.t = dc_lex_tokens[(c - '%')]) != BC_LEX_INVALID
3354 ) { 3371 ) {
3355 return s; 3372 RETURN_STATUS(s);
3356 } 3373 }
3357 3374
3358 // This is the workhorse of the lexer. 3375 // This is the workhorse of the lexer.
@@ -3378,7 +3395,7 @@ static FAST_FUNC BcStatus dc_lex_token(BcLex *l)
3378 else if (c2 == '>') 3395 else if (c2 == '>')
3379 l->t.t = BC_LEX_OP_REL_GE; 3396 l->t.t = BC_LEX_OP_REL_GE;
3380 else 3397 else
3381 return bc_error_bad_character(c); 3398 RETURN_STATUS(bc_error_bad_character(c));
3382 ++l->i; 3399 ++l->i;
3383 break; 3400 break;
3384 case '#': 3401 case '#':
@@ -3417,7 +3434,7 @@ static FAST_FUNC BcStatus dc_lex_token(BcLex *l)
3417 break; 3434 break;
3418 } 3435 }
3419 3436
3420 return s; 3437 RETURN_STATUS(s);
3421} 3438}
3422#endif // ENABLE_DC 3439#endif // ENABLE_DC
3423 3440
@@ -3482,7 +3499,7 @@ static BcStatus bc_parse_text(BcParse *p, const char *text)
3482 return bc_error("file is not executable"); 3499 return bc_error("file is not executable");
3483 } 3500 }
3484 3501
3485 return bc_lex_text(&p->l, text); 3502 return zbc_lex_text(&p->l, text);
3486} 3503}
3487 3504
3488// Called when parsing or execution detects a failure, 3505// Called when parsing or execution detects a failure,
@@ -3566,12 +3583,12 @@ static void bc_parse_create(BcParse *p, size_t func,
3566// first in the expr enum. Note: This only works for binary operators. 3583// first in the expr enum. Note: This only works for binary operators.
3567#define BC_PARSE_TOKEN_INST(t) ((char) ((t) -BC_LEX_NEG + BC_INST_NEG)) 3584#define BC_PARSE_TOKEN_INST(t) ((char) ((t) -BC_LEX_NEG + BC_INST_NEG))
3568 3585
3569static BcStatus bc_parse_else(BcParse *p); 3586static BC_STATUS zbc_parse_else(BcParse *p);
3570static BcStatus bc_parse_stmt(BcParse *p); 3587static BcStatus bc_parse_stmt(BcParse *p);
3571static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next); 3588static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next);
3572static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext next); 3589static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext next);
3573 3590
3574static BcStatus bc_parse_operator(BcParse *p, BcLexType type, size_t start, 3591static BC_STATUS zbc_parse_operator(BcParse *p, BcLexType type, size_t start,
3575 size_t *nexprs, bool next) 3592 size_t *nexprs, bool next)
3576{ 3593{
3577 BcStatus s = BC_STATUS_SUCCESS; 3594 BcStatus s = BC_STATUS_SUCCESS;
@@ -3593,35 +3610,40 @@ static BcStatus bc_parse_operator(BcParse *p, BcLexType type, size_t start,
3593 } 3610 }
3594 3611
3595 bc_vec_push(&p->ops, &type); 3612 bc_vec_push(&p->ops, &type);
3596 if (next) s = bc_lex_next(&p->l); 3613 if (next) s = zbc_lex_next(&p->l);
3597 3614
3598 return s; 3615 RETURN_STATUS(s);
3599} 3616}
3617#if ERRORS_ARE_FATAL
3618# define zbc_parse_operator(...) (zbc_parse_operator(__VA_ARGS__), BC_STATUS_SUCCESS)
3619#endif
3600 3620
3601static BcStatus bc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs) 3621static BC_STATUS zbc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3602{ 3622{
3603 BcLexType top; 3623 BcLexType top;
3604 3624
3605 if (p->ops.len <= ops_bgn) 3625 if (p->ops.len <= ops_bgn)
3606 return bc_error_bad_expression(); 3626 RETURN_STATUS(bc_error_bad_expression());
3607 top = BC_PARSE_TOP_OP(p); 3627 top = BC_PARSE_TOP_OP(p);
3608 3628
3609 while (top != BC_LEX_LPAREN) { 3629 while (top != BC_LEX_LPAREN) {
3610
3611 bc_parse_push(p, BC_PARSE_TOKEN_INST(top)); 3630 bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
3612 3631
3613 bc_vec_pop(&p->ops); 3632 bc_vec_pop(&p->ops);
3614 *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG; 3633 *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG;
3615 3634
3616 if (p->ops.len <= ops_bgn) 3635 if (p->ops.len <= ops_bgn)
3617 return bc_error_bad_expression(); 3636 RETURN_STATUS(bc_error_bad_expression());
3618 top = BC_PARSE_TOP_OP(p); 3637 top = BC_PARSE_TOP_OP(p);
3619 } 3638 }
3620 3639
3621 bc_vec_pop(&p->ops); 3640 bc_vec_pop(&p->ops);
3622 3641
3623 return bc_lex_next(&p->l); 3642 RETURN_STATUS(zbc_lex_next(&p->l));
3624} 3643}
3644#if ERRORS_ARE_FATAL
3645# define zbc_parse_rightParen(...) (zbc_parse_rightParen(__VA_ARGS__), BC_STATUS_SUCCESS)
3646#endif
3625 3647
3626static BcStatus bc_parse_params(BcParse *p, uint8_t flags) 3648static BcStatus bc_parse_params(BcParse *p, uint8_t flags)
3627{ 3649{
@@ -3629,7 +3651,7 @@ static BcStatus bc_parse_params(BcParse *p, uint8_t flags)
3629 bool comma = false; 3651 bool comma = false;
3630 size_t nparams; 3652 size_t nparams;
3631 3653
3632 s = bc_lex_next(&p->l); 3654 s = zbc_lex_next(&p->l);
3633 if (s) return s; 3655 if (s) return s;
3634 3656
3635 for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) { 3657 for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) {
@@ -3640,7 +3662,7 @@ static BcStatus bc_parse_params(BcParse *p, uint8_t flags)
3640 3662
3641 comma = p->l.t.t == BC_LEX_COMMA; 3663 comma = p->l.t.t == BC_LEX_COMMA;
3642 if (comma) { 3664 if (comma) {
3643 s = bc_lex_next(&p->l); 3665 s = zbc_lex_next(&p->l);
3644 if (s) return s; 3666 if (s) return s;
3645 } 3667 }
3646 } 3668 }
@@ -3682,7 +3704,7 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags)
3682 entry_ptr = bc_vec_item(&G.prog.fn_map, idx); 3704 entry_ptr = bc_vec_item(&G.prog.fn_map, idx);
3683 bc_parse_pushIndex(p, entry_ptr->idx); 3705 bc_parse_pushIndex(p, entry_ptr->idx);
3684 3706
3685 return bc_lex_next(&p->l); 3707 return zbc_lex_next(&p->l);
3686 3708
3687err: 3709err:
3688 free(name); 3710 free(name);
@@ -3695,12 +3717,12 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3695 char *name; 3717 char *name;
3696 3718
3697 name = xstrdup(p->l.t.v.v); 3719 name = xstrdup(p->l.t.v.v);
3698 s = bc_lex_next(&p->l); 3720 s = zbc_lex_next(&p->l);
3699 if (s) goto err; 3721 if (s) goto err;
3700 3722
3701 if (p->l.t.t == BC_LEX_LBRACKET) { 3723 if (p->l.t.t == BC_LEX_LBRACKET) {
3702 3724
3703 s = bc_lex_next(&p->l); 3725 s = zbc_lex_next(&p->l);
3704 if (s) goto err; 3726 if (s) goto err;
3705 3727
3706 if (p->l.t.t == BC_LEX_RBRACKET) { 3728 if (p->l.t.t == BC_LEX_RBRACKET) {
@@ -3721,7 +3743,7 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3721 if (s) goto err; 3743 if (s) goto err;
3722 } 3744 }
3723 3745
3724 s = bc_lex_next(&p->l); 3746 s = zbc_lex_next(&p->l);
3725 if (s) goto err; 3747 if (s) goto err;
3726 bc_parse_push(p, *type); 3748 bc_parse_push(p, *type);
3727 bc_parse_pushName(p, name); 3749 bc_parse_pushName(p, name);
@@ -3753,17 +3775,17 @@ static BcStatus bc_parse_read(BcParse *p)
3753{ 3775{
3754 BcStatus s; 3776 BcStatus s;
3755 3777
3756 s = bc_lex_next(&p->l); 3778 s = zbc_lex_next(&p->l);
3757 if (s) return s; 3779 if (s) return s;
3758 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 3780 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
3759 3781
3760 s = bc_lex_next(&p->l); 3782 s = zbc_lex_next(&p->l);
3761 if (s) return s; 3783 if (s) return s;
3762 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 3784 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
3763 3785
3764 bc_parse_push(p, BC_INST_READ); 3786 bc_parse_push(p, BC_INST_READ);
3765 3787
3766 return bc_lex_next(&p->l); 3788 return zbc_lex_next(&p->l);
3767} 3789}
3768 3790
3769static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, 3791static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
@@ -3771,13 +3793,13 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
3771{ 3793{
3772 BcStatus s; 3794 BcStatus s;
3773 3795
3774 s = bc_lex_next(&p->l); 3796 s = zbc_lex_next(&p->l);
3775 if (s) return s; 3797 if (s) return s;
3776 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 3798 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
3777 3799
3778 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3800 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3779 3801
3780 s = bc_lex_next(&p->l); 3802 s = zbc_lex_next(&p->l);
3781 if (s) return s; 3803 if (s) return s;
3782 3804
3783 s = bc_parse_expr(p, flags, bc_parse_next_rel); 3805 s = bc_parse_expr(p, flags, bc_parse_next_rel);
@@ -3788,14 +3810,14 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
3788 *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT; 3810 *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT;
3789 bc_parse_push(p, *prev); 3811 bc_parse_push(p, *prev);
3790 3812
3791 return bc_lex_next(&p->l); 3813 return zbc_lex_next(&p->l);
3792} 3814}
3793 3815
3794static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags) 3816static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags)
3795{ 3817{
3796 BcStatus s; 3818 BcStatus s;
3797 3819
3798 s = bc_lex_next(&p->l); 3820 s = zbc_lex_next(&p->l);
3799 if (s) return s; 3821 if (s) return s;
3800 3822
3801 if (p->l.t.t != BC_LEX_LPAREN) { 3823 if (p->l.t.t != BC_LEX_LPAREN) {
@@ -3807,7 +3829,7 @@ static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags)
3807 *type = BC_INST_SCALE_FUNC; 3829 *type = BC_INST_SCALE_FUNC;
3808 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL); 3830 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
3809 3831
3810 s = bc_lex_next(&p->l); 3832 s = zbc_lex_next(&p->l);
3811 if (s) return s; 3833 if (s) return s;
3812 3834
3813 s = bc_parse_expr(p, flags, bc_parse_next_rel); 3835 s = bc_parse_expr(p, flags, bc_parse_next_rel);
@@ -3815,7 +3837,7 @@ static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags)
3815 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 3837 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
3816 bc_parse_push(p, BC_INST_SCALE_FUNC); 3838 bc_parse_push(p, BC_INST_SCALE_FUNC);
3817 3839
3818 return bc_lex_next(&p->l); 3840 return zbc_lex_next(&p->l);
3819} 3841}
3820 3842
3821static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, 3843static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
@@ -3832,14 +3854,14 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
3832 { 3854 {
3833 *prev = inst = BC_INST_INC_POST + (p->l.t.t != BC_LEX_OP_INC); 3855 *prev = inst = BC_INST_INC_POST + (p->l.t.t != BC_LEX_OP_INC);
3834 bc_parse_push(p, inst); 3856 bc_parse_push(p, inst);
3835 s = bc_lex_next(&p->l); 3857 s = zbc_lex_next(&p->l);
3836 } 3858 }
3837 else { 3859 else {
3838 3860
3839 *prev = inst = BC_INST_INC_PRE + (p->l.t.t != BC_LEX_OP_INC); 3861 *prev = inst = BC_INST_INC_PRE + (p->l.t.t != BC_LEX_OP_INC);
3840 *paren_expr = true; 3862 *paren_expr = true;
3841 3863
3842 s = bc_lex_next(&p->l); 3864 s = zbc_lex_next(&p->l);
3843 if (s) return s; 3865 if (s) return s;
3844 type = p->l.t.t; 3866 type = p->l.t.t;
3845 3867
@@ -3860,13 +3882,13 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
3860 case BC_LEX_KEY_OBASE: 3882 case BC_LEX_KEY_OBASE:
3861 { 3883 {
3862 bc_parse_push(p, type - BC_LEX_KEY_IBASE + BC_INST_IBASE); 3884 bc_parse_push(p, type - BC_LEX_KEY_IBASE + BC_INST_IBASE);
3863 s = bc_lex_next(&p->l); 3885 s = zbc_lex_next(&p->l);
3864 break; 3886 break;
3865 } 3887 }
3866 3888
3867 case BC_LEX_KEY_SCALE: 3889 case BC_LEX_KEY_SCALE:
3868 { 3890 {
3869 s = bc_lex_next(&p->l); 3891 s = zbc_lex_next(&p->l);
3870 if (s) return s; 3892 if (s) return s;
3871 if (p->l.t.t == BC_LEX_LPAREN) 3893 if (p->l.t.t == BC_LEX_LPAREN)
3872 s = bc_error_bad_token(); 3894 s = bc_error_bad_token();
@@ -3895,7 +3917,7 @@ static BcStatus bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn,
3895 BcLexType type; 3917 BcLexType type;
3896 BcInst etype = *prev; 3918 BcInst etype = *prev;
3897 3919
3898 s = bc_lex_next(&p->l); 3920 s = zbc_lex_next(&p->l);
3899 if (s) return s; 3921 if (s) return s;
3900 3922
3901 type = rparen || etype == BC_INST_INC_POST || etype == BC_INST_DEC_POST || 3923 type = rparen || etype == BC_INST_INC_POST || etype == BC_INST_DEC_POST ||
@@ -3909,7 +3931,7 @@ static BcStatus bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn,
3909 if (type != BC_LEX_OP_MINUS) 3931 if (type != BC_LEX_OP_MINUS)
3910 bc_vec_push(&p->ops, &type); 3932 bc_vec_push(&p->ops, &type);
3911 else 3933 else
3912 s = bc_parse_operator(p, type, ops_bgn, nexprs, false); 3934 s = zbc_parse_operator(p, type, ops_bgn, nexprs, false);
3913 3935
3914 return s; 3936 return s;
3915} 3937}
@@ -3923,7 +3945,7 @@ static BcStatus bc_parse_string(BcParse *p, char inst)
3923 bc_vec_push(&G.prog.strs, &str); 3945 bc_vec_push(&G.prog.strs, &str);
3924 bc_parse_push(p, inst); 3946 bc_parse_push(p, inst);
3925 3947
3926 return bc_lex_next(&p->l); 3948 return zbc_lex_next(&p->l);
3927} 3949}
3928 3950
3929static BcStatus bc_parse_print(BcParse *p) 3951static BcStatus bc_parse_print(BcParse *p)
@@ -3932,7 +3954,7 @@ static BcStatus bc_parse_print(BcParse *p)
3932 BcLexType type; 3954 BcLexType type;
3933 bool comma; 3955 bool comma;
3934 3956
3935 s = bc_lex_next(&p->l); 3957 s = zbc_lex_next(&p->l);
3936 if (s) return s; 3958 if (s) return s;
3937 3959
3938 type = p->l.t.t; 3960 type = p->l.t.t;
@@ -3954,7 +3976,7 @@ static BcStatus bc_parse_print(BcParse *p)
3954 3976
3955 comma = p->l.t.t == BC_LEX_COMMA; 3977 comma = p->l.t.t == BC_LEX_COMMA;
3956 if (comma) { 3978 if (comma) {
3957 s = bc_lex_next(&p->l); 3979 s = zbc_lex_next(&p->l);
3958 if (s) return s; 3980 if (s) return s;
3959 } 3981 }
3960 type = p->l.t.t; 3982 type = p->l.t.t;
@@ -3962,7 +3984,7 @@ static BcStatus bc_parse_print(BcParse *p)
3962 3984
3963 if (comma) return bc_error_bad_token(); 3985 if (comma) return bc_error_bad_token();
3964 3986
3965 return bc_lex_next(&p->l); 3987 return zbc_lex_next(&p->l);
3966} 3988}
3967 3989
3968static BcStatus bc_parse_return(BcParse *p) 3990static BcStatus bc_parse_return(BcParse *p)
@@ -3973,7 +3995,7 @@ static BcStatus bc_parse_return(BcParse *p)
3973 3995
3974 if (!BC_PARSE_FUNC(p)) return bc_error_bad_token(); 3996 if (!BC_PARSE_FUNC(p)) return bc_error_bad_token();
3975 3997
3976 s = bc_lex_next(&p->l); 3998 s = zbc_lex_next(&p->l);
3977 if (s) return s; 3999 if (s) return s;
3978 4000
3979 t = p->l.t.t; 4001 t = p->l.t.t;
@@ -3986,7 +4008,7 @@ static BcStatus bc_parse_return(BcParse *p)
3986 s = bc_parse_expr_empty_ok(p, 0, bc_parse_next_expr); 4008 s = bc_parse_expr_empty_ok(p, 0, bc_parse_next_expr);
3987 if (s == BC_STATUS_PARSE_EMPTY_EXP) { 4009 if (s == BC_STATUS_PARSE_EMPTY_EXP) {
3988 bc_parse_push(p, BC_INST_RET0); 4010 bc_parse_push(p, BC_INST_RET0);
3989 s = bc_lex_next(&p->l); 4011 s = zbc_lex_next(&p->l);
3990 } 4012 }
3991 if (s) return s; 4013 if (s) return s;
3992 4014
@@ -4013,7 +4035,7 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace)
4013 if (p->l.t.t == BC_LEX_RBRACE) { 4035 if (p->l.t.t == BC_LEX_RBRACE) {
4014 if (!p->nbraces) return bc_error_bad_token(); 4036 if (!p->nbraces) return bc_error_bad_token();
4015 --p->nbraces; 4037 --p->nbraces;
4016 s = bc_lex_next(&p->l); 4038 s = zbc_lex_next(&p->l);
4017 if (s) return s; 4039 if (s) return s;
4018 } 4040 }
4019 else 4041 else
@@ -4025,7 +4047,7 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace)
4025 uint8_t *flag_ptr; 4047 uint8_t *flag_ptr;
4026 4048
4027 while (p->l.t.t == BC_LEX_NLINE) { 4049 while (p->l.t.t == BC_LEX_NLINE) {
4028 s = bc_lex_next(&p->l); 4050 s = zbc_lex_next(&p->l);
4029 if (s) return s; 4051 if (s) return s;
4030 } 4052 }
4031 4053
@@ -4034,7 +4056,8 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace)
4034 flag_ptr = BC_PARSE_TOP_FLAG_PTR(p); 4056 flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
4035 *flag_ptr = (*flag_ptr | BC_PARSE_FLAG_IF_END); 4057 *flag_ptr = (*flag_ptr | BC_PARSE_FLAG_IF_END);
4036 4058
4037 if (p->l.t.t == BC_LEX_KEY_ELSE) s = bc_parse_else(p); 4059 if (p->l.t.t == BC_LEX_KEY_ELSE)
4060 ERROR_RETURN(s =) zbc_parse_else(p);
4038 } 4061 }
4039 else if (BC_PARSE_ELSE(p)) { 4062 else if (BC_PARSE_ELSE(p)) {
4040 4063
@@ -4101,17 +4124,17 @@ static BcStatus bc_parse_if(BcParse *p)
4101 BcStatus s; 4124 BcStatus s;
4102 BcInstPtr ip; 4125 BcInstPtr ip;
4103 4126
4104 s = bc_lex_next(&p->l); 4127 s = zbc_lex_next(&p->l);
4105 if (s) return s; 4128 if (s) return s;
4106 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 4129 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
4107 4130
4108 s = bc_lex_next(&p->l); 4131 s = zbc_lex_next(&p->l);
4109 if (s) return s; 4132 if (s) return s;
4110 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); 4133 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
4111 if (s) return s; 4134 if (s) return s;
4112 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 4135 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
4113 4136
4114 s = bc_lex_next(&p->l); 4137 s = zbc_lex_next(&p->l);
4115 if (s) return s; 4138 if (s) return s;
4116 bc_parse_push(p, BC_INST_JUMP_ZERO); 4139 bc_parse_push(p, BC_INST_JUMP_ZERO);
4117 4140
@@ -4126,11 +4149,11 @@ static BcStatus bc_parse_if(BcParse *p)
4126 return BC_STATUS_SUCCESS; 4149 return BC_STATUS_SUCCESS;
4127} 4150}
4128 4151
4129static BcStatus bc_parse_else(BcParse *p) 4152static BC_STATUS zbc_parse_else(BcParse *p)
4130{ 4153{
4131 BcInstPtr ip; 4154 BcInstPtr ip;
4132 4155
4133 if (!BC_PARSE_IF_END(p)) return bc_error_bad_token(); 4156 if (!BC_PARSE_IF_END(p)) RETURN_STATUS(bc_error_bad_token());
4134 4157
4135 ip.idx = p->func->labels.len; 4158 ip.idx = p->func->labels.len;
4136 ip.func = ip.len = 0; 4159 ip.func = ip.len = 0;
@@ -4144,18 +4167,21 @@ static BcStatus bc_parse_else(BcParse *p)
4144 bc_vec_push(&p->func->labels, &ip.idx); 4167 bc_vec_push(&p->func->labels, &ip.idx);
4145 bc_parse_startBody(p, BC_PARSE_FLAG_ELSE); 4168 bc_parse_startBody(p, BC_PARSE_FLAG_ELSE);
4146 4169
4147 return bc_lex_next(&p->l); 4170 RETURN_STATUS(zbc_lex_next(&p->l));
4148} 4171}
4172#if ERRORS_ARE_FATAL
4173# define zbc_parse_else(...) (zbc_parse_else(__VA_ARGS__), BC_STATUS_SUCCESS)
4174#endif
4149 4175
4150static BcStatus bc_parse_while(BcParse *p) 4176static BcStatus bc_parse_while(BcParse *p)
4151{ 4177{
4152 BcStatus s; 4178 BcStatus s;
4153 BcInstPtr ip; 4179 BcInstPtr ip;
4154 4180
4155 s = bc_lex_next(&p->l); 4181 s = zbc_lex_next(&p->l);
4156 if (s) return s; 4182 if (s) return s;
4157 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 4183 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
4158 s = bc_lex_next(&p->l); 4184 s = zbc_lex_next(&p->l);
4159 if (s) return s; 4185 if (s) return s;
4160 4186
4161 ip.idx = p->func->labels.len; 4187 ip.idx = p->func->labels.len;
@@ -4173,7 +4199,7 @@ static BcStatus bc_parse_while(BcParse *p)
4173 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); 4199 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
4174 if (s) return s; 4200 if (s) return s;
4175 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 4201 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
4176 s = bc_lex_next(&p->l); 4202 s = zbc_lex_next(&p->l);
4177 if (s) return s; 4203 if (s) return s;
4178 4204
4179 bc_parse_push(p, BC_INST_JUMP_ZERO); 4205 bc_parse_push(p, BC_INST_JUMP_ZERO);
@@ -4189,10 +4215,10 @@ static BcStatus bc_parse_for(BcParse *p)
4189 BcInstPtr ip; 4215 BcInstPtr ip;
4190 size_t cond_idx, exit_idx, body_idx, update_idx; 4216 size_t cond_idx, exit_idx, body_idx, update_idx;
4191 4217
4192 s = bc_lex_next(&p->l); 4218 s = zbc_lex_next(&p->l);
4193 if (s) return s; 4219 if (s) return s;
4194 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 4220 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
4195 s = bc_lex_next(&p->l); 4221 s = zbc_lex_next(&p->l);
4196 if (s) return s; 4222 if (s) return s;
4197 4223
4198 if (p->l.t.t != BC_LEX_SCOLON) 4224 if (p->l.t.t != BC_LEX_SCOLON)
@@ -4202,7 +4228,7 @@ static BcStatus bc_parse_for(BcParse *p)
4202 4228
4203 if (s) return s; 4229 if (s) return s;
4204 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token(); 4230 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token();
4205 s = bc_lex_next(&p->l); 4231 s = zbc_lex_next(&p->l);
4206 if (s) return s; 4232 if (s) return s;
4207 4233
4208 cond_idx = p->func->labels.len; 4234 cond_idx = p->func->labels.len;
@@ -4220,7 +4246,7 @@ static BcStatus bc_parse_for(BcParse *p)
4220 if (s) return s; 4246 if (s) return s;
4221 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token(); 4247 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token();
4222 4248
4223 s = bc_lex_next(&p->l); 4249 s = zbc_lex_next(&p->l);
4224 if (s) return s; 4250 if (s) return s;
4225 4251
4226 bc_parse_push(p, BC_INST_JUMP_ZERO); 4252 bc_parse_push(p, BC_INST_JUMP_ZERO);
@@ -4251,7 +4277,8 @@ static BcStatus bc_parse_for(BcParse *p)
4251 4277
4252 bc_vec_push(&p->exits, &ip); 4278 bc_vec_push(&p->exits, &ip);
4253 bc_vec_push(&p->func->labels, &ip.idx); 4279 bc_vec_push(&p->func->labels, &ip.idx);
4254 bc_lex_next(&p->l); 4280 s = zbc_lex_next(&p->l);
4281 if (s) return s;
4255 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); 4282 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
4256 4283
4257 return BC_STATUS_SUCCESS; 4284 return BC_STATUS_SUCCESS;
@@ -4283,13 +4310,13 @@ static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type)
4283 bc_parse_push(p, BC_INST_JUMP); 4310 bc_parse_push(p, BC_INST_JUMP);
4284 bc_parse_pushIndex(p, i); 4311 bc_parse_pushIndex(p, i);
4285 4312
4286 s = bc_lex_next(&p->l); 4313 s = zbc_lex_next(&p->l);
4287 if (s) return s; 4314 if (s) return s;
4288 4315
4289 if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE) 4316 if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE)
4290 return bc_error_bad_token(); 4317 return bc_error_bad_token();
4291 4318
4292 return bc_lex_next(&p->l); 4319 return zbc_lex_next(&p->l);
4293} 4320}
4294 4321
4295static BcStatus bc_parse_func(BcParse *p) 4322static BcStatus bc_parse_func(BcParse *p)
@@ -4299,7 +4326,7 @@ static BcStatus bc_parse_func(BcParse *p)
4299 uint8_t flags; 4326 uint8_t flags;
4300 char *name; 4327 char *name;
4301 4328
4302 s = bc_lex_next(&p->l); 4329 s = zbc_lex_next(&p->l);
4303 if (s) return s; 4330 if (s) return s;
4304 if (p->l.t.t != BC_LEX_NAME) 4331 if (p->l.t.t != BC_LEX_NAME)
4305 return bc_error("bad function definition"); 4332 return bc_error("bad function definition");
@@ -4307,11 +4334,11 @@ static BcStatus bc_parse_func(BcParse *p)
4307 name = xstrdup(p->l.t.v.v); 4334 name = xstrdup(p->l.t.v.v);
4308 bc_parse_addFunc(p, name, &p->fidx); 4335 bc_parse_addFunc(p, name, &p->fidx);
4309 4336
4310 s = bc_lex_next(&p->l); 4337 s = zbc_lex_next(&p->l);
4311 if (s) return s; 4338 if (s) return s;
4312 if (p->l.t.t != BC_LEX_LPAREN) 4339 if (p->l.t.t != BC_LEX_LPAREN)
4313 return bc_error("bad function definition"); 4340 return bc_error("bad function definition");
4314 s = bc_lex_next(&p->l); 4341 s = zbc_lex_next(&p->l);
4315 if (s) return s; 4342 if (s) return s;
4316 4343
4317 while (p->l.t.t != BC_LEX_RPAREN) { 4344 while (p->l.t.t != BC_LEX_RPAREN) {
@@ -4322,14 +4349,14 @@ static BcStatus bc_parse_func(BcParse *p)
4322 ++p->func->nparams; 4349 ++p->func->nparams;
4323 4350
4324 name = xstrdup(p->l.t.v.v); 4351 name = xstrdup(p->l.t.v.v);
4325 s = bc_lex_next(&p->l); 4352 s = zbc_lex_next(&p->l);
4326 if (s) goto err; 4353 if (s) goto err;
4327 4354
4328 var = p->l.t.t != BC_LEX_LBRACKET; 4355 var = p->l.t.t != BC_LEX_LBRACKET;
4329 4356
4330 if (!var) { 4357 if (!var) {
4331 4358
4332 s = bc_lex_next(&p->l); 4359 s = zbc_lex_next(&p->l);
4333 if (s) goto err; 4360 if (s) goto err;
4334 4361
4335 if (p->l.t.t != BC_LEX_RBRACKET) { 4362 if (p->l.t.t != BC_LEX_RBRACKET) {
@@ -4337,13 +4364,13 @@ static BcStatus bc_parse_func(BcParse *p)
4337 goto err; 4364 goto err;
4338 } 4365 }
4339 4366
4340 s = bc_lex_next(&p->l); 4367 s = zbc_lex_next(&p->l);
4341 if (s) goto err; 4368 if (s) goto err;
4342 } 4369 }
4343 4370
4344 comma = p->l.t.t == BC_LEX_COMMA; 4371 comma = p->l.t.t == BC_LEX_COMMA;
4345 if (comma) { 4372 if (comma) {
4346 s = bc_lex_next(&p->l); 4373 s = zbc_lex_next(&p->l);
4347 if (s) goto err; 4374 if (s) goto err;
4348 } 4375 }
4349 4376
@@ -4356,7 +4383,7 @@ static BcStatus bc_parse_func(BcParse *p)
4356 flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY; 4383 flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY;
4357 bc_parse_startBody(p, flags); 4384 bc_parse_startBody(p, flags);
4358 4385
4359 s = bc_lex_next(&p->l); 4386 s = zbc_lex_next(&p->l);
4360 if (s) return s; 4387 if (s) return s;
4361 4388
4362 if (p->l.t.t != BC_LEX_LBRACE) 4389 if (p->l.t.t != BC_LEX_LBRACE)
@@ -4376,7 +4403,7 @@ static BcStatus bc_parse_auto(BcParse *p)
4376 char *name; 4403 char *name;
4377 4404
4378 if (!p->auto_part) return bc_error_bad_token(); 4405 if (!p->auto_part) return bc_error_bad_token();
4379 s = bc_lex_next(&p->l); 4406 s = zbc_lex_next(&p->l);
4380 if (s) return s; 4407 if (s) return s;
4381 4408
4382 p->auto_part = comma = false; 4409 p->auto_part = comma = false;
@@ -4385,13 +4412,13 @@ static BcStatus bc_parse_auto(BcParse *p)
4385 while (p->l.t.t == BC_LEX_NAME) { 4412 while (p->l.t.t == BC_LEX_NAME) {
4386 4413
4387 name = xstrdup(p->l.t.v.v); 4414 name = xstrdup(p->l.t.v.v);
4388 s = bc_lex_next(&p->l); 4415 s = zbc_lex_next(&p->l);
4389 if (s) goto err; 4416 if (s) goto err;
4390 4417
4391 var = p->l.t.t != BC_LEX_LBRACKET; 4418 var = p->l.t.t != BC_LEX_LBRACKET;
4392 if (!var) { 4419 if (!var) {
4393 4420
4394 s = bc_lex_next(&p->l); 4421 s = zbc_lex_next(&p->l);
4395 if (s) goto err; 4422 if (s) goto err;
4396 4423
4397 if (p->l.t.t != BC_LEX_RBRACKET) { 4424 if (p->l.t.t != BC_LEX_RBRACKET) {
@@ -4399,13 +4426,13 @@ static BcStatus bc_parse_auto(BcParse *p)
4399 goto err; 4426 goto err;
4400 } 4427 }
4401 4428
4402 s = bc_lex_next(&p->l); 4429 s = zbc_lex_next(&p->l);
4403 if (s) goto err; 4430 if (s) goto err;
4404 } 4431 }
4405 4432
4406 comma = p->l.t.t == BC_LEX_COMMA; 4433 comma = p->l.t.t == BC_LEX_COMMA;
4407 if (comma) { 4434 if (comma) {
4408 s = bc_lex_next(&p->l); 4435 s = zbc_lex_next(&p->l);
4409 if (s) goto err; 4436 if (s) goto err;
4410 } 4437 }
4411 4438
@@ -4419,7 +4446,7 @@ static BcStatus bc_parse_auto(BcParse *p)
4419 if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON) 4446 if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON)
4420 return bc_error_bad_token(); 4447 return bc_error_bad_token();
4421 4448
4422 return bc_lex_next(&p->l); 4449 return zbc_lex_next(&p->l);
4423 4450
4424err: 4451err:
4425 free(name); 4452 free(name);
@@ -4443,7 +4470,7 @@ static BcStatus bc_parse_body(BcParse *p, bool brace)
4443 if (s) return s; 4470 if (s) return s;
4444 } 4471 }
4445 4472
4446 if (p->l.t.t == BC_LEX_NLINE) s = bc_lex_next(&p->l); 4473 if (p->l.t.t == BC_LEX_NLINE) s = zbc_lex_next(&p->l);
4447 } 4474 }
4448 else { 4475 else {
4449 s = bc_parse_stmt(p); 4476 s = bc_parse_stmt(p);
@@ -4461,7 +4488,7 @@ static BcStatus bc_parse_stmt(BcParse *p)
4461 4488
4462 case BC_LEX_NLINE: 4489 case BC_LEX_NLINE:
4463 { 4490 {
4464 return bc_lex_next(&p->l); 4491 return zbc_lex_next(&p->l);
4465 } 4492 }
4466 4493
4467 case BC_LEX_KEY_ELSE: 4494 case BC_LEX_KEY_ELSE:
@@ -4475,7 +4502,7 @@ static BcStatus bc_parse_stmt(BcParse *p)
4475 if (!BC_PARSE_BODY(p)) return bc_error_bad_token(); 4502 if (!BC_PARSE_BODY(p)) return bc_error_bad_token();
4476 4503
4477 ++p->nbraces; 4504 ++p->nbraces;
4478 s = bc_lex_next(&p->l); 4505 s = zbc_lex_next(&p->l);
4479 if (s) return s; 4506 if (s) return s;
4480 4507
4481 return bc_parse_body(p, true); 4508 return bc_parse_body(p, true);
@@ -4524,13 +4551,13 @@ static BcStatus bc_parse_stmt(BcParse *p)
4524 4551
4525 case BC_LEX_KEY_ELSE: 4552 case BC_LEX_KEY_ELSE:
4526 { 4553 {
4527 s = bc_parse_else(p); 4554 s = zbc_parse_else(p);
4528 break; 4555 break;
4529 } 4556 }
4530 4557
4531 case BC_LEX_SCOLON: 4558 case BC_LEX_SCOLON:
4532 { 4559 {
4533 while (!s && p->l.t.t == BC_LEX_SCOLON) s = bc_lex_next(&p->l); 4560 while (!s && p->l.t.t == BC_LEX_SCOLON) s = zbc_lex_next(&p->l);
4534 break; 4561 break;
4535 } 4562 }
4536 4563
@@ -4562,7 +4589,7 @@ static BcStatus bc_parse_stmt(BcParse *p)
4562 case BC_LEX_KEY_HALT: 4589 case BC_LEX_KEY_HALT:
4563 { 4590 {
4564 bc_parse_push(p, BC_INST_HALT); 4591 bc_parse_push(p, BC_INST_HALT);
4565 s = bc_lex_next(&p->l); 4592 s = zbc_lex_next(&p->l);
4566 break; 4593 break;
4567 } 4594 }
4568 4595
@@ -4576,7 +4603,7 @@ static BcStatus bc_parse_stmt(BcParse *p)
4576 { 4603 {
4577 // "limits" is a compile-time command, 4604 // "limits" is a compile-time command,
4578 // the output is produced at _parse time_. 4605 // the output is produced at _parse time_.
4579 s = bc_lex_next(&p->l); 4606 s = zbc_lex_next(&p->l);
4580 if (s) return s; 4607 if (s) return s;
4581 printf( 4608 printf(
4582 "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n" 4609 "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n"
@@ -4726,7 +4753,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4726 4753
4727 nrelops += t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT; 4754 nrelops += t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT;
4728 prev = BC_PARSE_TOKEN_INST(t); 4755 prev = BC_PARSE_TOKEN_INST(t);
4729 s = bc_parse_operator(p, t, ops_bgn, &nexprs, true); 4756 s = zbc_parse_operator(p, t, ops_bgn, &nexprs, true);
4730 rprn = get_token = false; 4757 rprn = get_token = false;
4731 bin_last = t != BC_LEX_OP_BOOL_NOT; 4758 bin_last = t != BC_LEX_OP_BOOL_NOT;
4732 4759
@@ -4763,7 +4790,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4763 paren_expr = rprn = true; 4790 paren_expr = rprn = true;
4764 get_token = bin_last = false; 4791 get_token = bin_last = false;
4765 4792
4766 s = bc_parse_rightParen(p, ops_bgn, &nexprs); 4793 s = zbc_parse_rightParen(p, ops_bgn, &nexprs);
4767 4794
4768 break; 4795 break;
4769 } 4796 }
@@ -4857,7 +4884,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4857 } 4884 }
4858 } 4885 }
4859 4886
4860 if (!s && get_token) s = bc_lex_next(&p->l); 4887 if (!s && get_token) s = zbc_lex_next(&p->l);
4861 } 4888 }
4862 4889
4863 if (s) return s; 4890 if (s) return s;
@@ -4920,7 +4947,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4920 4947
4921static void bc_parse_init(BcParse *p, size_t func) 4948static void bc_parse_init(BcParse *p, size_t func)
4922{ 4949{
4923 bc_parse_create(p, func, bc_parse_parse, bc_lex_token); 4950 bc_parse_create(p, func, bc_parse_parse, zbc_lex_token);
4924} 4951}
4925 4952
4926static BcStatus bc_parse_expression(BcParse *p, uint8_t flags) 4953static BcStatus bc_parse_expression(BcParse *p, uint8_t flags)
@@ -4939,7 +4966,7 @@ static BcStatus dc_parse_register(BcParse *p)
4939 BcStatus s; 4966 BcStatus s;
4940 char *name; 4967 char *name;
4941 4968
4942 s = bc_lex_next(&p->l); 4969 s = zbc_lex_next(&p->l);
4943 if (s) return s; 4970 if (s) return s;
4944 if (p->l.t.t != BC_LEX_NAME) return bc_error_bad_token(); 4971 if (p->l.t.t != BC_LEX_NAME) return bc_error_bad_token();
4945 4972
@@ -4949,7 +4976,7 @@ static BcStatus dc_parse_register(BcParse *p)
4949 return s; 4976 return s;
4950} 4977}
4951 4978
4952static BcStatus dc_parse_string(BcParse *p) 4979static BC_STATUS zdc_parse_string(BcParse *p)
4953{ 4980{
4954 char *str, *name, b[DC_PARSE_BUF_LEN + 1]; 4981 char *str, *name, b[DC_PARSE_BUF_LEN + 1];
4955 size_t idx, len = G.prog.strs.len; 4982 size_t idx, len = G.prog.strs.len;
@@ -4963,8 +4990,11 @@ static BcStatus dc_parse_string(BcParse *p)
4963 bc_vec_push(&G.prog.strs, &str); 4990 bc_vec_push(&G.prog.strs, &str);
4964 bc_parse_addFunc(p, name, &idx); 4991 bc_parse_addFunc(p, name, &idx);
4965 4992
4966 return bc_lex_next(&p->l); 4993 RETURN_STATUS(zbc_lex_next(&p->l));
4967} 4994}
4995#if ERRORS_ARE_FATAL
4996# define zdc_parse_string(...) (zdc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS)
4997#endif
4968 4998
4969static BcStatus dc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store) 4999static BcStatus dc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store)
4970{ 5000{
@@ -4982,7 +5012,7 @@ static BcStatus dc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store)
4982 bc_parse_push(p, BC_INST_POP); 5012 bc_parse_push(p, BC_INST_POP);
4983 } 5013 }
4984 5014
4985 return bc_lex_next(&p->l); 5015 return zbc_lex_next(&p->l);
4986} 5016}
4987 5017
4988static BcStatus dc_parse_cond(BcParse *p, uint8_t inst) 5018static BcStatus dc_parse_cond(BcParse *p, uint8_t inst)
@@ -4995,13 +5025,13 @@ static BcStatus dc_parse_cond(BcParse *p, uint8_t inst)
4995 s = dc_parse_register(p); 5025 s = dc_parse_register(p);
4996 if (s) return s; 5026 if (s) return s;
4997 5027
4998 s = bc_lex_next(&p->l); 5028 s = zbc_lex_next(&p->l);
4999 if (s) return s; 5029 if (s) return s;
5000 5030
5001 if (p->l.t.t == BC_LEX_ELSE) { 5031 if (p->l.t.t == BC_LEX_ELSE) {
5002 s = dc_parse_register(p); 5032 s = dc_parse_register(p);
5003 if (s) return s; 5033 if (s) return s;
5004 s = bc_lex_next(&p->l); 5034 s = zbc_lex_next(&p->l);
5005 } 5035 }
5006 else 5036 else
5007 bc_parse_push(p, BC_PARSE_STREND); 5037 bc_parse_push(p, BC_PARSE_STREND);
@@ -5038,7 +5068,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags)
5038 5068
5039 case BC_LEX_STR: 5069 case BC_LEX_STR:
5040 { 5070 {
5041 s = dc_parse_string(p); 5071 s = zdc_parse_string(p);
5042 break; 5072 break;
5043 } 5073 }
5044 5074
@@ -5046,7 +5076,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags)
5046 case BC_LEX_NUMBER: 5076 case BC_LEX_NUMBER:
5047 { 5077 {
5048 if (t == BC_LEX_NEG) { 5078 if (t == BC_LEX_NEG) {
5049 s = bc_lex_next(&p->l); 5079 s = zbc_lex_next(&p->l);
5050 if (s) return s; 5080 if (s) return s;
5051 if (p->l.t.t != BC_LEX_NUMBER) 5081 if (p->l.t.t != BC_LEX_NUMBER)
5052 return bc_error_bad_token(); 5082 return bc_error_bad_token();
@@ -5104,7 +5134,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags)
5104 } 5134 }
5105 } 5135 }
5106 5136
5107 if (!s && get_token) s = bc_lex_next(&p->l); 5137 if (!s && get_token) s = zbc_lex_next(&p->l);
5108 5138
5109 return s; 5139 return s;
5110} 5140}
@@ -5123,7 +5153,7 @@ static BcStatus dc_parse_expr(BcParse *p, uint8_t flags)
5123 5153
5124 if (inst != BC_INST_INVALID) { 5154 if (inst != BC_INST_INVALID) {
5125 bc_parse_push(p, inst); 5155 bc_parse_push(p, inst);
5126 s = bc_lex_next(&p->l); 5156 s = zbc_lex_next(&p->l);
5127 } 5157 }
5128 else 5158 else
5129 s = dc_parse_token(p, t, flags); 5159 s = dc_parse_token(p, t, flags);
@@ -5154,7 +5184,7 @@ static FAST_FUNC BcStatus dc_parse_parse(BcParse *p)
5154 5184
5155static void dc_parse_init(BcParse *p, size_t func) 5185static void dc_parse_init(BcParse *p, size_t func)
5156{ 5186{
5157 bc_parse_create(p, func, dc_parse_parse, dc_lex_token); 5187 bc_parse_create(p, func, dc_parse_parse, zdc_lex_token);
5158} 5188}
5159 5189
5160#endif // ENABLE_DC 5190#endif // ENABLE_DC