aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c269
1 files changed, 121 insertions, 148 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 3815b7f09..f942d42ac 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -3584,9 +3584,14 @@ static void bc_parse_create(BcParse *p, size_t func,
3584#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))
3585 3585
3586static BC_STATUS zbc_parse_else(BcParse *p); 3586static BC_STATUS zbc_parse_else(BcParse *p);
3587static BcStatus bc_parse_stmt(BcParse *p); 3587static BC_STATUS zbc_parse_stmt(BcParse *p);
3588static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next); 3588static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next);
3589static 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);
3590#if ERRORS_ARE_FATAL
3591# define zbc_parse_else(...) (zbc_parse_else(__VA_ARGS__), BC_STATUS_SUCCESS)
3592# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS)
3593# define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
3594#endif
3590 3595
3591static BC_STATUS zbc_parse_operator(BcParse *p, BcLexType type, size_t start, 3596static BC_STATUS zbc_parse_operator(BcParse *p, BcLexType type, size_t start,
3592 size_t *nexprs, bool next) 3597 size_t *nexprs, bool next)
@@ -3657,7 +3662,7 @@ static BcStatus bc_parse_params(BcParse *p, uint8_t flags)
3657 for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) { 3662 for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) {
3658 3663
3659 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3664 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3660 s = bc_parse_expr(p, flags, bc_parse_next_param); 3665 s = zbc_parse_expr(p, flags, bc_parse_next_param);
3661 if (s) return s; 3666 if (s) return s;
3662 3667
3663 comma = p->l.t.t == BC_LEX_COMMA; 3668 comma = p->l.t.t == BC_LEX_COMMA;
@@ -3739,7 +3744,7 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3739 *type = BC_INST_ARRAY_ELEM; 3744 *type = BC_INST_ARRAY_ELEM;
3740 3745
3741 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL); 3746 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
3742 s = bc_parse_expr(p, flags, bc_parse_next_elem); 3747 s = zbc_parse_expr(p, flags, bc_parse_next_elem);
3743 if (s) goto err; 3748 if (s) goto err;
3744 } 3749 }
3745 3750
@@ -3805,7 +3810,7 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
3805 s = zbc_lex_next(&p->l); 3810 s = zbc_lex_next(&p->l);
3806 if (s) return s; 3811 if (s) return s;
3807 3812
3808 s = bc_parse_expr(p, flags, bc_parse_next_rel); 3813 s = zbc_parse_expr(p, flags, bc_parse_next_rel);
3809 if (s) return s; 3814 if (s) return s;
3810 3815
3811 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 3816 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
@@ -3835,7 +3840,7 @@ static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags)
3835 s = zbc_lex_next(&p->l); 3840 s = zbc_lex_next(&p->l);
3836 if (s) return s; 3841 if (s) return s;
3837 3842
3838 s = bc_parse_expr(p, flags, bc_parse_next_rel); 3843 s = zbc_parse_expr(p, flags, bc_parse_next_rel);
3839 if (s) return s; 3844 if (s) return s;
3840 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 3845 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
3841 bc_parse_push(p, BC_INST_SCALE_FUNC); 3846 bc_parse_push(p, BC_INST_SCALE_FUNC);
@@ -3957,55 +3962,57 @@ static BC_STATUS zbc_parse_string(BcParse *p, char inst)
3957# define zbc_parse_string(...) (zbc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS) 3962# define zbc_parse_string(...) (zbc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS)
3958#endif 3963#endif
3959 3964
3960static BcStatus bc_parse_print(BcParse *p) 3965static BC_STATUS zbc_parse_print(BcParse *p)
3961{ 3966{
3962 BcStatus s; 3967 BcStatus s;
3963 BcLexType type; 3968 BcLexType type;
3964 bool comma; 3969 bool comma;
3965 3970
3966 s = zbc_lex_next(&p->l); 3971 s = zbc_lex_next(&p->l);
3967 if (s) return s; 3972 if (s) RETURN_STATUS(s);
3968 3973
3969 type = p->l.t.t; 3974 type = p->l.t.t;
3970 3975
3971 if (type == BC_LEX_SCOLON || type == BC_LEX_NLINE) 3976 if (type == BC_LEX_SCOLON || type == BC_LEX_NLINE)
3972 return bc_error("bad print statement"); 3977 RETURN_STATUS(bc_error("bad print statement"));
3973 3978
3974 comma = false; 3979 comma = false;
3975 while (type != BC_LEX_SCOLON && type != BC_LEX_NLINE) { 3980 while (type != BC_LEX_SCOLON && type != BC_LEX_NLINE) {
3976
3977 if (type == BC_LEX_STR) { 3981 if (type == BC_LEX_STR) {
3978 s = zbc_parse_string(p, BC_INST_PRINT_POP); 3982 s = zbc_parse_string(p, BC_INST_PRINT_POP);
3979 if (s) return s; 3983 if (s) RETURN_STATUS(s);
3980 } else { 3984 } else {
3981 s = bc_parse_expr(p, 0, bc_parse_next_print); 3985 s = zbc_parse_expr(p, 0, bc_parse_next_print);
3982 if (s) return s; 3986 if (s) RETURN_STATUS(s);
3983 bc_parse_push(p, BC_INST_PRINT_POP); 3987 bc_parse_push(p, BC_INST_PRINT_POP);
3984 } 3988 }
3985 3989
3986 comma = p->l.t.t == BC_LEX_COMMA; 3990 comma = p->l.t.t == BC_LEX_COMMA;
3987 if (comma) { 3991 if (comma) {
3988 s = zbc_lex_next(&p->l); 3992 s = zbc_lex_next(&p->l);
3989 if (s) return s; 3993 if (s) RETURN_STATUS(s);
3990 } 3994 }
3991 type = p->l.t.t; 3995 type = p->l.t.t;
3992 } 3996 }
3993 3997
3994 if (comma) return bc_error_bad_token(); 3998 if (comma) RETURN_STATUS(bc_error_bad_token());
3995 3999
3996 return zbc_lex_next(&p->l); 4000 RETURN_STATUS(zbc_lex_next(&p->l));
3997} 4001}
4002#if ERRORS_ARE_FATAL
4003# define zbc_parse_print(...) (zbc_parse_print(__VA_ARGS__), BC_STATUS_SUCCESS)
4004#endif
3998 4005
3999static BcStatus bc_parse_return(BcParse *p) 4006static BC_STATUS zbc_parse_return(BcParse *p)
4000{ 4007{
4001 BcStatus s; 4008 BcStatus s;
4002 BcLexType t; 4009 BcLexType t;
4003 bool paren; 4010 bool paren;
4004 4011
4005 if (!BC_PARSE_FUNC(p)) return bc_error_bad_token(); 4012 if (!BC_PARSE_FUNC(p)) RETURN_STATUS(bc_error_bad_token());
4006 4013
4007 s = zbc_lex_next(&p->l); 4014 s = zbc_lex_next(&p->l);
4008 if (s) return s; 4015 if (s) RETURN_STATUS(s);
4009 4016
4010 t = p->l.t.t; 4017 t = p->l.t.t;
4011 paren = t == BC_LEX_LPAREN; 4018 paren = t == BC_LEX_LPAREN;
@@ -4013,24 +4020,26 @@ static BcStatus bc_parse_return(BcParse *p)
4013 if (t == BC_LEX_NLINE || t == BC_LEX_SCOLON) 4020 if (t == BC_LEX_NLINE || t == BC_LEX_SCOLON)
4014 bc_parse_push(p, BC_INST_RET0); 4021 bc_parse_push(p, BC_INST_RET0);
4015 else { 4022 else {
4016
4017 s = bc_parse_expr_empty_ok(p, 0, bc_parse_next_expr); 4023 s = bc_parse_expr_empty_ok(p, 0, bc_parse_next_expr);
4018 if (s == BC_STATUS_PARSE_EMPTY_EXP) { 4024 if (s == BC_STATUS_PARSE_EMPTY_EXP) {
4019 bc_parse_push(p, BC_INST_RET0); 4025 bc_parse_push(p, BC_INST_RET0);
4020 s = zbc_lex_next(&p->l); 4026 s = zbc_lex_next(&p->l);
4021 } 4027 }
4022 if (s) return s; 4028 if (s) RETURN_STATUS(s);
4023 4029
4024 if (!paren || p->l.t.last != BC_LEX_RPAREN) { 4030 if (!paren || p->l.t.last != BC_LEX_RPAREN) {
4025 s = bc_POSIX_requires("parentheses around return expressions"); 4031 s = bc_POSIX_requires("parentheses around return expressions");
4026 ERROR_RETURN(if (s) return s;) 4032 ERROR_RETURN(if (s) RETURN_STATUS(s);)
4027 } 4033 }
4028 4034
4029 bc_parse_push(p, BC_INST_RET); 4035 bc_parse_push(p, BC_INST_RET);
4030 } 4036 }
4031 4037
4032 return s; 4038 RETURN_STATUS(s);
4033} 4039}
4040#if ERRORS_ARE_FATAL
4041# define zbc_parse_return(...) (zbc_parse_return(__VA_ARGS__), BC_STATUS_SUCCESS)
4042#endif
4034 4043
4035static BC_STATUS zbc_parse_endBody(BcParse *p, bool brace) 4044static BC_STATUS zbc_parse_endBody(BcParse *p, bool brace)
4036{ 4045{
@@ -4063,7 +4072,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p, bool brace)
4063 *flag_ptr = (*flag_ptr | BC_PARSE_FLAG_IF_END); 4072 *flag_ptr = (*flag_ptr | BC_PARSE_FLAG_IF_END);
4064 4073
4065 if (p->l.t.t == BC_LEX_KEY_ELSE) 4074 if (p->l.t.t == BC_LEX_KEY_ELSE)
4066 ERROR_RETURN(s =) zbc_parse_else(p); 4075 s = zbc_parse_else(p);
4067 } 4076 }
4068 else if (BC_PARSE_ELSE(p)) { 4077 else if (BC_PARSE_ELSE(p)) {
4069 BcInstPtr *ip; 4078 BcInstPtr *ip;
@@ -4126,23 +4135,23 @@ static void bc_parse_noElse(BcParse *p)
4126 bc_vec_pop(&p->exits); 4135 bc_vec_pop(&p->exits);
4127} 4136}
4128 4137
4129static BcStatus bc_parse_if(BcParse *p) 4138static BC_STATUS zbc_parse_if(BcParse *p)
4130{ 4139{
4131 BcStatus s; 4140 BcStatus s;
4132 BcInstPtr ip; 4141 BcInstPtr ip;
4133 4142
4134 s = zbc_lex_next(&p->l); 4143 s = zbc_lex_next(&p->l);
4135 if (s) return s; 4144 if (s) RETURN_STATUS(s);
4136 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 4145 if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4137 4146
4138 s = zbc_lex_next(&p->l); 4147 s = zbc_lex_next(&p->l);
4139 if (s) return s; 4148 if (s) RETURN_STATUS(s);
4140 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); 4149 s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
4141 if (s) return s; 4150 if (s) RETURN_STATUS(s);
4142 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 4151 if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4143 4152
4144 s = zbc_lex_next(&p->l); 4153 s = zbc_lex_next(&p->l);
4145 if (s) return s; 4154 if (s) RETURN_STATUS(s);
4146 bc_parse_push(p, BC_INST_JUMP_ZERO); 4155 bc_parse_push(p, BC_INST_JUMP_ZERO);
4147 4156
4148 ip.idx = p->func->labels.len; 4157 ip.idx = p->func->labels.len;
@@ -4153,9 +4162,13 @@ static BcStatus bc_parse_if(BcParse *p)
4153 bc_vec_push(&p->func->labels, &ip.idx); 4162 bc_vec_push(&p->func->labels, &ip.idx);
4154 bc_parse_startBody(p, BC_PARSE_FLAG_IF); 4163 bc_parse_startBody(p, BC_PARSE_FLAG_IF);
4155 4164
4156 return BC_STATUS_SUCCESS; 4165 RETURN_STATUS(BC_STATUS_SUCCESS);
4157} 4166}
4167#if ERRORS_ARE_FATAL
4168# define zbc_parse_if(...) (zbc_parse_if(__VA_ARGS__), BC_STATUS_SUCCESS)
4169#endif
4158 4170
4171#undef zbc_parse_else
4159static BC_STATUS zbc_parse_else(BcParse *p) 4172static BC_STATUS zbc_parse_else(BcParse *p)
4160{ 4173{
4161 BcInstPtr ip; 4174 BcInstPtr ip;
@@ -4180,16 +4193,16 @@ static BC_STATUS zbc_parse_else(BcParse *p)
4180# define zbc_parse_else(...) (zbc_parse_else(__VA_ARGS__), BC_STATUS_SUCCESS) 4193# define zbc_parse_else(...) (zbc_parse_else(__VA_ARGS__), BC_STATUS_SUCCESS)
4181#endif 4194#endif
4182 4195
4183static BcStatus bc_parse_while(BcParse *p) 4196static BC_STATUS zbc_parse_while(BcParse *p)
4184{ 4197{
4185 BcStatus s; 4198 BcStatus s;
4186 BcInstPtr ip; 4199 BcInstPtr ip;
4187 4200
4188 s = zbc_lex_next(&p->l); 4201 s = zbc_lex_next(&p->l);
4189 if (s) return s; 4202 if (s) RETURN_STATUS(s);
4190 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 4203 if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4191 s = zbc_lex_next(&p->l); 4204 s = zbc_lex_next(&p->l);
4192 if (s) return s; 4205 if (s) RETURN_STATUS(s);
4193 4206
4194 ip.idx = p->func->labels.len; 4207 ip.idx = p->func->labels.len;
4195 4208
@@ -4203,40 +4216,43 @@ static BcStatus bc_parse_while(BcParse *p)
4203 bc_vec_push(&p->exits, &ip); 4216 bc_vec_push(&p->exits, &ip);
4204 bc_vec_push(&p->func->labels, &ip.idx); 4217 bc_vec_push(&p->func->labels, &ip.idx);
4205 4218
4206 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); 4219 s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
4207 if (s) return s; 4220 if (s) RETURN_STATUS(s);
4208 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 4221 if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4209 s = zbc_lex_next(&p->l); 4222 s = zbc_lex_next(&p->l);
4210 if (s) return s; 4223 if (s) RETURN_STATUS(s);
4211 4224
4212 bc_parse_push(p, BC_INST_JUMP_ZERO); 4225 bc_parse_push(p, BC_INST_JUMP_ZERO);
4213 bc_parse_pushIndex(p, ip.idx); 4226 bc_parse_pushIndex(p, ip.idx);
4214 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); 4227 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
4215 4228
4216 return BC_STATUS_SUCCESS; 4229 RETURN_STATUS(BC_STATUS_SUCCESS);
4217} 4230}
4231#if ERRORS_ARE_FATAL
4232# define zbc_parse_while(...) (zbc_parse_while(__VA_ARGS__), BC_STATUS_SUCCESS)
4233#endif
4218 4234
4219static BcStatus bc_parse_for(BcParse *p) 4235static BC_STATUS zbc_parse_for(BcParse *p)
4220{ 4236{
4221 BcStatus s; 4237 BcStatus s;
4222 BcInstPtr ip; 4238 BcInstPtr ip;
4223 size_t cond_idx, exit_idx, body_idx, update_idx; 4239 size_t cond_idx, exit_idx, body_idx, update_idx;
4224 4240
4225 s = zbc_lex_next(&p->l); 4241 s = zbc_lex_next(&p->l);
4226 if (s) return s; 4242 if (s) RETURN_STATUS(s);
4227 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 4243 if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
4228 s = zbc_lex_next(&p->l); 4244 s = zbc_lex_next(&p->l);
4229 if (s) return s; 4245 if (s) RETURN_STATUS(s);
4230 4246
4231 if (p->l.t.t != BC_LEX_SCOLON) 4247 if (p->l.t.t != BC_LEX_SCOLON)
4232 s = bc_parse_expr(p, 0, bc_parse_next_for); 4248 s = zbc_parse_expr(p, 0, bc_parse_next_for);
4233 else 4249 else
4234 s = bc_POSIX_does_not_allow_empty_X_expression_in_for("init"); 4250 s = bc_POSIX_does_not_allow_empty_X_expression_in_for("init");
4235 4251
4236 if (s) return s; 4252 if (s) RETURN_STATUS(s);
4237 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token(); 4253 if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
4238 s = zbc_lex_next(&p->l); 4254 s = zbc_lex_next(&p->l);
4239 if (s) return s; 4255 if (s) RETURN_STATUS(s);
4240 4256
4241 cond_idx = p->func->labels.len; 4257 cond_idx = p->func->labels.len;
4242 update_idx = cond_idx + 1; 4258 update_idx = cond_idx + 1;
@@ -4246,15 +4262,15 @@ static BcStatus bc_parse_for(BcParse *p)
4246 bc_vec_push(&p->func->labels, &p->func->code.len); 4262 bc_vec_push(&p->func->labels, &p->func->code.len);
4247 4263
4248 if (p->l.t.t != BC_LEX_SCOLON) 4264 if (p->l.t.t != BC_LEX_SCOLON)
4249 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_for); 4265 s = zbc_parse_expr(p, BC_PARSE_REL, bc_parse_next_for);
4250 else 4266 else
4251 s = bc_POSIX_does_not_allow_empty_X_expression_in_for("condition"); 4267 s = bc_POSIX_does_not_allow_empty_X_expression_in_for("condition");
4252 4268
4253 if (s) return s; 4269 if (s) RETURN_STATUS(s);
4254 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token(); 4270 if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token());
4255 4271
4256 s = zbc_lex_next(&p->l); 4272 s = zbc_lex_next(&p->l);
4257 if (s) return s; 4273 if (s) RETURN_STATUS(s);
4258 4274
4259 bc_parse_push(p, BC_INST_JUMP_ZERO); 4275 bc_parse_push(p, BC_INST_JUMP_ZERO);
4260 bc_parse_pushIndex(p, exit_idx); 4276 bc_parse_pushIndex(p, exit_idx);
@@ -4267,13 +4283,13 @@ static BcStatus bc_parse_for(BcParse *p)
4267 bc_vec_push(&p->func->labels, &p->func->code.len); 4283 bc_vec_push(&p->func->labels, &p->func->code.len);
4268 4284
4269 if (p->l.t.t != BC_LEX_RPAREN) 4285 if (p->l.t.t != BC_LEX_RPAREN)
4270 s = bc_parse_expr(p, 0, bc_parse_next_rel); 4286 s = zbc_parse_expr(p, 0, bc_parse_next_rel);
4271 else 4287 else
4272 s = bc_POSIX_does_not_allow_empty_X_expression_in_for("update"); 4288 s = bc_POSIX_does_not_allow_empty_X_expression_in_for("update");
4273 4289
4274 if (s) return s; 4290 if (s) RETURN_STATUS(s);
4275 4291
4276 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 4292 if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
4277 bc_parse_push(p, BC_INST_JUMP); 4293 bc_parse_push(p, BC_INST_JUMP);
4278 bc_parse_pushIndex(p, cond_idx); 4294 bc_parse_pushIndex(p, cond_idx);
4279 bc_vec_push(&p->func->labels, &p->func->code.len); 4295 bc_vec_push(&p->func->labels, &p->func->code.len);
@@ -4285,11 +4301,14 @@ static BcStatus bc_parse_for(BcParse *p)
4285 bc_vec_push(&p->exits, &ip); 4301 bc_vec_push(&p->exits, &ip);
4286 bc_vec_push(&p->func->labels, &ip.idx); 4302 bc_vec_push(&p->func->labels, &ip.idx);
4287 s = zbc_lex_next(&p->l); 4303 s = zbc_lex_next(&p->l);
4288 if (s) return s; 4304 if (s) RETURN_STATUS(s);
4289 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); 4305 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
4290 4306
4291 return BC_STATUS_SUCCESS; 4307 RETURN_STATUS(BC_STATUS_SUCCESS);
4292} 4308}
4309#if ERRORS_ARE_FATAL
4310# define zbc_parse_for(...) (zbc_parse_for(__VA_ARGS__), BC_STATUS_SUCCESS)
4311#endif
4293 4312
4294static BC_STATUS zbc_parse_loopExit(BcParse *p, BcLexType type) 4313static BC_STATUS zbc_parse_loopExit(BcParse *p, BcLexType type)
4295{ 4314{
@@ -4487,7 +4506,7 @@ static BC_STATUS zbc_parse_body(BcParse *p, bool brace)
4487 if (p->l.t.t == BC_LEX_NLINE) s = zbc_lex_next(&p->l); 4506 if (p->l.t.t == BC_LEX_NLINE) s = zbc_lex_next(&p->l);
4488 } 4507 }
4489 else { 4508 else {
4490 s = bc_parse_stmt(p); 4509 s = zbc_parse_stmt(p);
4491 if (!s && !brace) s = zbc_parse_endBody(p, false); 4510 if (!s && !brace) s = zbc_parse_endBody(p, false);
4492 } 4511 }
4493 4512
@@ -4497,56 +4516,41 @@ static BC_STATUS zbc_parse_body(BcParse *p, bool brace)
4497# define zbc_parse_body(...) (zbc_parse_body(__VA_ARGS__), BC_STATUS_SUCCESS) 4516# define zbc_parse_body(...) (zbc_parse_body(__VA_ARGS__), BC_STATUS_SUCCESS)
4498#endif 4517#endif
4499 4518
4500static BcStatus bc_parse_stmt(BcParse *p) 4519#undef zbc_parse_stmt
4520static BC_STATUS zbc_parse_stmt(BcParse *p)
4501{ 4521{
4502 BcStatus s = BC_STATUS_SUCCESS; 4522 BcStatus s = BC_STATUS_SUCCESS;
4503 4523
4504 switch (p->l.t.t) { 4524 switch (p->l.t.t) {
4505
4506 case BC_LEX_NLINE: 4525 case BC_LEX_NLINE:
4507 { 4526 RETURN_STATUS(zbc_lex_next(&p->l));
4508 return zbc_lex_next(&p->l);
4509 }
4510 4527
4511 case BC_LEX_KEY_ELSE: 4528 case BC_LEX_KEY_ELSE:
4512 {
4513 p->auto_part = false; 4529 p->auto_part = false;
4514 break; 4530 break;
4515 }
4516 4531
4517 case BC_LEX_LBRACE: 4532 case BC_LEX_LBRACE:
4518 { 4533 if (!BC_PARSE_BODY(p)) RETURN_STATUS(bc_error_bad_token());
4519 if (!BC_PARSE_BODY(p)) return bc_error_bad_token();
4520
4521 ++p->nbraces; 4534 ++p->nbraces;
4522 s = zbc_lex_next(&p->l); 4535 s = zbc_lex_next(&p->l);
4523 if (s) return s; 4536 if (s) RETURN_STATUS(s);
4524 4537 RETURN_STATUS(zbc_parse_body(p, true));
4525 return zbc_parse_body(p, true);
4526 }
4527 4538
4528 case BC_LEX_KEY_AUTO: 4539 case BC_LEX_KEY_AUTO:
4529 { 4540 RETURN_STATUS(zbc_parse_auto(p));
4530 return zbc_parse_auto(p);
4531 }
4532 4541
4533 default: 4542 default:
4534 {
4535 p->auto_part = false; 4543 p->auto_part = false;
4536
4537 if (BC_PARSE_IF_END(p)) { 4544 if (BC_PARSE_IF_END(p)) {
4538 bc_parse_noElse(p); 4545 bc_parse_noElse(p);
4539 return BC_STATUS_SUCCESS; 4546 RETURN_STATUS(BC_STATUS_SUCCESS);
4540 } 4547 }
4541 else if (BC_PARSE_BODY(p)) 4548 if (BC_PARSE_BODY(p))
4542 return zbc_parse_body(p, false); 4549 RETURN_STATUS(zbc_parse_body(p, false));
4543
4544 break; 4550 break;
4545 }
4546 } 4551 }
4547 4552
4548 switch (p->l.t.t) { 4553 switch (p->l.t.t) {
4549
4550 case BC_LEX_OP_INC: 4554 case BC_LEX_OP_INC:
4551 case BC_LEX_OP_DEC: 4555 case BC_LEX_OP_DEC:
4552 case BC_LEX_OP_MINUS: 4556 case BC_LEX_OP_MINUS:
@@ -4561,67 +4565,39 @@ static BcStatus bc_parse_stmt(BcParse *p)
4561 case BC_LEX_KEY_READ: 4565 case BC_LEX_KEY_READ:
4562 case BC_LEX_KEY_SCALE: 4566 case BC_LEX_KEY_SCALE:
4563 case BC_LEX_KEY_SQRT: 4567 case BC_LEX_KEY_SQRT:
4564 { 4568 s = zbc_parse_expr(p, BC_PARSE_PRINT, bc_parse_next_expr);
4565 s = bc_parse_expr(p, BC_PARSE_PRINT, bc_parse_next_expr);
4566 break; 4569 break;
4567 }
4568
4569 case BC_LEX_KEY_ELSE: 4570 case BC_LEX_KEY_ELSE:
4570 {
4571 s = zbc_parse_else(p); 4571 s = zbc_parse_else(p);
4572 break; 4572 break;
4573 }
4574
4575 case BC_LEX_SCOLON: 4573 case BC_LEX_SCOLON:
4576 {
4577 while (!s && p->l.t.t == BC_LEX_SCOLON) s = zbc_lex_next(&p->l); 4574 while (!s && p->l.t.t == BC_LEX_SCOLON) s = zbc_lex_next(&p->l);
4578 break; 4575 break;
4579 }
4580
4581 case BC_LEX_RBRACE: 4576 case BC_LEX_RBRACE:
4582 {
4583 s = zbc_parse_endBody(p, true); 4577 s = zbc_parse_endBody(p, true);
4584 break; 4578 break;
4585 }
4586
4587 case BC_LEX_STR: 4579 case BC_LEX_STR:
4588 {
4589 s = zbc_parse_string(p, BC_INST_PRINT_STR); 4580 s = zbc_parse_string(p, BC_INST_PRINT_STR);
4590 break; 4581 break;
4591 }
4592
4593 case BC_LEX_KEY_BREAK: 4582 case BC_LEX_KEY_BREAK:
4594 case BC_LEX_KEY_CONTINUE: 4583 case BC_LEX_KEY_CONTINUE:
4595 {
4596 s = zbc_parse_loopExit(p, p->l.t.t); 4584 s = zbc_parse_loopExit(p, p->l.t.t);
4597 break; 4585 break;
4598 }
4599
4600 case BC_LEX_KEY_FOR: 4586 case BC_LEX_KEY_FOR:
4601 { 4587 s = zbc_parse_for(p);
4602 s = bc_parse_for(p);
4603 break; 4588 break;
4604 }
4605
4606 case BC_LEX_KEY_HALT: 4589 case BC_LEX_KEY_HALT:
4607 {
4608 bc_parse_push(p, BC_INST_HALT); 4590 bc_parse_push(p, BC_INST_HALT);
4609 s = zbc_lex_next(&p->l); 4591 s = zbc_lex_next(&p->l);
4610 break; 4592 break;
4611 }
4612
4613 case BC_LEX_KEY_IF: 4593 case BC_LEX_KEY_IF:
4614 { 4594 s = zbc_parse_if(p);
4615 s = bc_parse_if(p);
4616 break; 4595 break;
4617 }
4618
4619 case BC_LEX_KEY_LIMITS: 4596 case BC_LEX_KEY_LIMITS:
4620 {
4621 // "limits" is a compile-time command, 4597 // "limits" is a compile-time command,
4622 // the output is produced at _parse time_. 4598 // the output is produced at _parse time_.
4623 s = zbc_lex_next(&p->l); 4599 s = zbc_lex_next(&p->l);
4624 if (s) return s; 4600 if (s) RETURN_STATUS(s);
4625 printf( 4601 printf(
4626 "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n" 4602 "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n"
4627 "BC_DIM_MAX = "BC_MAX_DIM_STR "\n" 4603 "BC_DIM_MAX = "BC_MAX_DIM_STR "\n"
@@ -4633,43 +4609,30 @@ static BcStatus bc_parse_stmt(BcParse *p)
4633 "Number of vars = "BC_MAX_VARS_STR "\n" 4609 "Number of vars = "BC_MAX_VARS_STR "\n"
4634 ); 4610 );
4635 break; 4611 break;
4636 }
4637
4638 case BC_LEX_KEY_PRINT: 4612 case BC_LEX_KEY_PRINT:
4639 { 4613 s = zbc_parse_print(p);
4640 s = bc_parse_print(p);
4641 break; 4614 break;
4642 }
4643
4644 case BC_LEX_KEY_QUIT: 4615 case BC_LEX_KEY_QUIT:
4645 {
4646 // "quit" is a compile-time command. For example, 4616 // "quit" is a compile-time command. For example,
4647 // "if (0 == 1) quit" terminates when parsing the statement, 4617 // "if (0 == 1) quit" terminates when parsing the statement,
4648 // not when it is executed 4618 // not when it is executed
4649 QUIT_OR_RETURN_TO_MAIN; 4619 QUIT_OR_RETURN_TO_MAIN;
4650 }
4651
4652 case BC_LEX_KEY_RETURN: 4620 case BC_LEX_KEY_RETURN:
4653 { 4621 s = zbc_parse_return(p);
4654 s = bc_parse_return(p);
4655 break; 4622 break;
4656 }
4657
4658 case BC_LEX_KEY_WHILE: 4623 case BC_LEX_KEY_WHILE:
4659 { 4624 s = zbc_parse_while(p);
4660 s = bc_parse_while(p);
4661 break; 4625 break;
4662 }
4663
4664 default: 4626 default:
4665 {
4666 s = bc_error_bad_token(); 4627 s = bc_error_bad_token();
4667 break; 4628 break;
4668 }
4669 } 4629 }
4670 4630
4671 return s; 4631 RETURN_STATUS(s);
4672} 4632}
4633#if ERRORS_ARE_FATAL
4634# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS)
4635#endif
4673 4636
4674static FAST_FUNC BcStatus bc_parse_parse(BcParse *p) 4637static FAST_FUNC BcStatus bc_parse_parse(BcParse *p)
4675{ 4638{
@@ -4682,7 +4645,7 @@ static FAST_FUNC BcStatus bc_parse_parse(BcParse *p)
4682 s = zbc_parse_func(p); 4645 s = zbc_parse_func(p);
4683 } 4646 }
4684 else 4647 else
4685 s = bc_parse_stmt(p); 4648 s = zbc_parse_stmt(p);
4686 4649
4687 if (s || G_interrupt) { 4650 if (s || G_interrupt) {
4688 bc_parse_reset(p); 4651 bc_parse_reset(p);
@@ -4952,25 +4915,32 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4952 return s; 4915 return s;
4953} 4916}
4954 4917
4955static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) 4918#undef zbc_parse_expr
4919static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4956{ 4920{
4957 BcStatus s; 4921 BcStatus s;
4958 4922
4959 s = bc_parse_expr_empty_ok(p, flags, next); 4923 s = bc_parse_expr_empty_ok(p, flags, next);
4960 if (s == BC_STATUS_PARSE_EMPTY_EXP) 4924 if (s == BC_STATUS_PARSE_EMPTY_EXP)
4961 return bc_error("empty expression"); 4925 RETURN_STATUS(bc_error("empty expression"));
4962 return s; 4926 RETURN_STATUS(s);
4963} 4927}
4928#if ERRORS_ARE_FATAL
4929# define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
4930#endif
4964 4931
4965static void bc_parse_init(BcParse *p, size_t func) 4932static void bc_parse_init(BcParse *p, size_t func)
4966{ 4933{
4967 bc_parse_create(p, func, bc_parse_parse, zbc_lex_token); 4934 bc_parse_create(p, func, bc_parse_parse, zbc_lex_token);
4968} 4935}
4969 4936
4970static BcStatus bc_parse_expression(BcParse *p, uint8_t flags) 4937static BC_STATUS zbc_parse_expression(BcParse *p, uint8_t flags)
4971{ 4938{
4972 return bc_parse_expr(p, flags, bc_parse_next_read); 4939 RETURN_STATUS(zbc_parse_expr(p, flags, bc_parse_next_read));
4973} 4940}
4941#if ERRORS_ARE_FATAL
4942# define zbc_parse_expression(...) (zbc_parse_expression(__VA_ARGS__), BC_STATUS_SUCCESS)
4943#endif
4974 4944
4975#endif // ENABLE_BC 4945#endif // ENABLE_BC
4976 4946
@@ -5198,14 +5168,17 @@ static void common_parse_init(BcParse *p, size_t func)
5198 } 5168 }
5199} 5169}
5200 5170
5201static BcStatus common_parse_expr(BcParse *p, uint8_t flags) 5171static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags)
5202{ 5172{
5203 if (IS_BC) { 5173 if (IS_BC) {
5204 IF_BC(return bc_parse_expression(p, flags);) 5174 IF_BC(RETURN_STATUS(zbc_parse_expression(p, flags));)
5205 } else { 5175 } else {
5206 IF_DC(return zdc_parse_expr(p, flags);) 5176 IF_DC(RETURN_STATUS(zdc_parse_expr(p, flags));)
5207 } 5177 }
5208} 5178}
5179#if ERRORS_ARE_FATAL
5180# define zcommon_parse_expr(...) (zcommon_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
5181#endif
5209 5182
5210static BcVec* bc_program_search(char *id, bool var) 5183static BcVec* bc_program_search(char *id, bool var)
5211{ 5184{
@@ -5440,7 +5413,7 @@ static BcStatus bc_program_read(void)
5440 5413
5441 s = bc_parse_text(&parse, buf.v); 5414 s = bc_parse_text(&parse, buf.v);
5442 if (s) goto exec_err; 5415 if (s) goto exec_err;
5443 s = common_parse_expr(&parse, BC_PARSE_NOREAD); 5416 s = zcommon_parse_expr(&parse, BC_PARSE_NOREAD);
5444 if (s) goto exec_err; 5417 if (s) goto exec_err;
5445 5418
5446 if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) { 5419 if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) {
@@ -6639,7 +6612,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
6639 common_parse_init(&prs, fidx); 6612 common_parse_init(&prs, fidx);
6640 s = bc_parse_text(&prs, *str); 6613 s = bc_parse_text(&prs, *str);
6641 if (s) goto err; 6614 if (s) goto err;
6642 s = common_parse_expr(&prs, BC_PARSE_NOCALL); 6615 s = zcommon_parse_expr(&prs, BC_PARSE_NOCALL);
6643 if (s) goto err; 6616 if (s) goto err;
6644 6617
6645 if (prs.l.t.t != BC_LEX_EOF) { 6618 if (prs.l.t.t != BC_LEX_EOF) {