diff options
-rw-r--r-- | miscutils/bc.c | 274 |
1 files changed, 137 insertions, 137 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index eae5063a8..3815b7f09 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -3771,22 +3771,25 @@ err: | |||
3771 | return s; | 3771 | return s; |
3772 | } | 3772 | } |
3773 | 3773 | ||
3774 | static BcStatus bc_parse_read(BcParse *p) | 3774 | static BC_STATUS zbc_parse_read(BcParse *p) |
3775 | { | 3775 | { |
3776 | BcStatus s; | 3776 | BcStatus s; |
3777 | 3777 | ||
3778 | s = zbc_lex_next(&p->l); | 3778 | s = zbc_lex_next(&p->l); |
3779 | if (s) return s; | 3779 | if (s) RETURN_STATUS(s); |
3780 | if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); | 3780 | if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token()); |
3781 | 3781 | ||
3782 | s = zbc_lex_next(&p->l); | 3782 | s = zbc_lex_next(&p->l); |
3783 | if (s) return s; | 3783 | if (s) RETURN_STATUS(s); |
3784 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); | 3784 | if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); |
3785 | 3785 | ||
3786 | bc_parse_push(p, BC_INST_READ); | 3786 | bc_parse_push(p, BC_INST_READ); |
3787 | 3787 | ||
3788 | return zbc_lex_next(&p->l); | 3788 | RETURN_STATUS(zbc_lex_next(&p->l)); |
3789 | } | 3789 | } |
3790 | #if ERRORS_ARE_FATAL | ||
3791 | # define zbc_parse_read(...) (zbc_parse_read(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
3792 | #endif | ||
3790 | 3793 | ||
3791 | static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, | 3794 | static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, |
3792 | BcInst *prev) | 3795 | BcInst *prev) |
@@ -3910,7 +3913,7 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, | |||
3910 | return s; | 3913 | return s; |
3911 | } | 3914 | } |
3912 | 3915 | ||
3913 | static BcStatus bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, | 3916 | static BC_STATUS zbc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, |
3914 | bool rparen, size_t *nexprs) | 3917 | bool rparen, size_t *nexprs) |
3915 | { | 3918 | { |
3916 | BcStatus s; | 3919 | BcStatus s; |
@@ -3918,7 +3921,7 @@ static BcStatus bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, | |||
3918 | BcInst etype = *prev; | 3921 | BcInst etype = *prev; |
3919 | 3922 | ||
3920 | s = zbc_lex_next(&p->l); | 3923 | s = zbc_lex_next(&p->l); |
3921 | if (s) return s; | 3924 | if (s) RETURN_STATUS(s); |
3922 | 3925 | ||
3923 | type = rparen || etype == BC_INST_INC_POST || etype == BC_INST_DEC_POST || | 3926 | type = rparen || etype == BC_INST_INC_POST || etype == BC_INST_DEC_POST || |
3924 | (etype >= BC_INST_NUM && etype <= BC_INST_SQRT) ? | 3927 | (etype >= BC_INST_NUM && etype <= BC_INST_SQRT) ? |
@@ -3933,10 +3936,13 @@ static BcStatus bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, | |||
3933 | else | 3936 | else |
3934 | s = zbc_parse_operator(p, type, ops_bgn, nexprs, false); | 3937 | s = zbc_parse_operator(p, type, ops_bgn, nexprs, false); |
3935 | 3938 | ||
3936 | return s; | 3939 | RETURN_STATUS(s); |
3937 | } | 3940 | } |
3941 | #if ERRORS_ARE_FATAL | ||
3942 | # define zbc_parse_minus(...) (zbc_parse_minus(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
3943 | #endif | ||
3938 | 3944 | ||
3939 | static BcStatus bc_parse_string(BcParse *p, char inst) | 3945 | static BC_STATUS zbc_parse_string(BcParse *p, char inst) |
3940 | { | 3946 | { |
3941 | char *str = xstrdup(p->l.t.v.v); | 3947 | char *str = xstrdup(p->l.t.v.v); |
3942 | 3948 | ||
@@ -3945,8 +3951,11 @@ static BcStatus bc_parse_string(BcParse *p, char inst) | |||
3945 | bc_vec_push(&G.prog.strs, &str); | 3951 | bc_vec_push(&G.prog.strs, &str); |
3946 | bc_parse_push(p, inst); | 3952 | bc_parse_push(p, inst); |
3947 | 3953 | ||
3948 | return zbc_lex_next(&p->l); | 3954 | RETURN_STATUS(zbc_lex_next(&p->l)); |
3949 | } | 3955 | } |
3956 | #if ERRORS_ARE_FATAL | ||
3957 | # define zbc_parse_string(...) (zbc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
3958 | #endif | ||
3950 | 3959 | ||
3951 | static BcStatus bc_parse_print(BcParse *p) | 3960 | static BcStatus bc_parse_print(BcParse *p) |
3952 | { | 3961 | { |
@@ -3966,7 +3975,7 @@ static BcStatus bc_parse_print(BcParse *p) | |||
3966 | while (type != BC_LEX_SCOLON && type != BC_LEX_NLINE) { | 3975 | while (type != BC_LEX_SCOLON && type != BC_LEX_NLINE) { |
3967 | 3976 | ||
3968 | if (type == BC_LEX_STR) { | 3977 | if (type == BC_LEX_STR) { |
3969 | s = bc_parse_string(p, BC_INST_PRINT_POP); | 3978 | s = zbc_parse_string(p, BC_INST_PRINT_POP); |
3970 | if (s) return s; | 3979 | if (s) return s; |
3971 | } else { | 3980 | } else { |
3972 | s = bc_parse_expr(p, 0, bc_parse_next_print); | 3981 | s = bc_parse_expr(p, 0, bc_parse_next_print); |
@@ -4023,32 +4032,29 @@ static BcStatus bc_parse_return(BcParse *p) | |||
4023 | return s; | 4032 | return s; |
4024 | } | 4033 | } |
4025 | 4034 | ||
4026 | static BcStatus bc_parse_endBody(BcParse *p, bool brace) | 4035 | static BC_STATUS zbc_parse_endBody(BcParse *p, bool brace) |
4027 | { | 4036 | { |
4028 | BcStatus s = BC_STATUS_SUCCESS; | 4037 | BcStatus s = BC_STATUS_SUCCESS; |
4029 | 4038 | ||
4030 | if (p->flags.len <= 1 || (brace && p->nbraces == 0)) | 4039 | if (p->flags.len <= 1 || (brace && p->nbraces == 0)) |
4031 | return bc_error_bad_token(); | 4040 | RETURN_STATUS(bc_error_bad_token()); |
4032 | 4041 | ||
4033 | if (brace) { | 4042 | if (brace) { |
4034 | 4043 | if (p->l.t.t != BC_LEX_RBRACE) | |
4035 | if (p->l.t.t == BC_LEX_RBRACE) { | 4044 | RETURN_STATUS(bc_error_bad_token()); |
4036 | if (!p->nbraces) return bc_error_bad_token(); | 4045 | if (!p->nbraces) |
4037 | --p->nbraces; | 4046 | RETURN_STATUS(bc_error_bad_token()); |
4038 | s = zbc_lex_next(&p->l); | 4047 | --p->nbraces; |
4039 | if (s) return s; | 4048 | s = zbc_lex_next(&p->l); |
4040 | } | 4049 | if (s) RETURN_STATUS(s); |
4041 | else | ||
4042 | return bc_error_bad_token(); | ||
4043 | } | 4050 | } |
4044 | 4051 | ||
4045 | if (BC_PARSE_IF(p)) { | 4052 | if (BC_PARSE_IF(p)) { |
4046 | |||
4047 | uint8_t *flag_ptr; | 4053 | uint8_t *flag_ptr; |
4048 | 4054 | ||
4049 | while (p->l.t.t == BC_LEX_NLINE) { | 4055 | while (p->l.t.t == BC_LEX_NLINE) { |
4050 | s = zbc_lex_next(&p->l); | 4056 | s = zbc_lex_next(&p->l); |
4051 | if (s) return s; | 4057 | if (s) RETURN_STATUS(s); |
4052 | } | 4058 | } |
4053 | 4059 | ||
4054 | bc_vec_pop(&p->flags); | 4060 | bc_vec_pop(&p->flags); |
@@ -4060,7 +4066,6 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace) | |||
4060 | ERROR_RETURN(s =) zbc_parse_else(p); | 4066 | ERROR_RETURN(s =) zbc_parse_else(p); |
4061 | } | 4067 | } |
4062 | else if (BC_PARSE_ELSE(p)) { | 4068 | else if (BC_PARSE_ELSE(p)) { |
4063 | |||
4064 | BcInstPtr *ip; | 4069 | BcInstPtr *ip; |
4065 | size_t *label; | 4070 | size_t *label; |
4066 | 4071 | ||
@@ -4078,7 +4083,6 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace) | |||
4078 | bc_vec_pop(&p->flags); | 4083 | bc_vec_pop(&p->flags); |
4079 | } | 4084 | } |
4080 | else { | 4085 | else { |
4081 | |||
4082 | BcInstPtr *ip = bc_vec_top(&p->exits); | 4086 | BcInstPtr *ip = bc_vec_top(&p->exits); |
4083 | size_t *label = bc_vec_top(&p->conds); | 4087 | size_t *label = bc_vec_top(&p->conds); |
4084 | 4088 | ||
@@ -4093,8 +4097,11 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace) | |||
4093 | bc_vec_pop(&p->conds); | 4097 | bc_vec_pop(&p->conds); |
4094 | } | 4098 | } |
4095 | 4099 | ||
4096 | return s; | 4100 | RETURN_STATUS(s); |
4097 | } | 4101 | } |
4102 | #if ERRORS_ARE_FATAL | ||
4103 | # define zbc_parse_endBody(...) (zbc_parse_endBody(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
4104 | #endif | ||
4098 | 4105 | ||
4099 | static void bc_parse_startBody(BcParse *p, uint8_t flags) | 4106 | static void bc_parse_startBody(BcParse *p, uint8_t flags) |
4100 | { | 4107 | { |
@@ -4284,23 +4291,24 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4284 | return BC_STATUS_SUCCESS; | 4291 | return BC_STATUS_SUCCESS; |
4285 | } | 4292 | } |
4286 | 4293 | ||
4287 | static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type) | 4294 | static BC_STATUS zbc_parse_loopExit(BcParse *p, BcLexType type) |
4288 | { | 4295 | { |
4289 | BcStatus s; | 4296 | BcStatus s; |
4290 | size_t i; | 4297 | size_t i; |
4291 | BcInstPtr *ip; | 4298 | BcInstPtr *ip; |
4292 | 4299 | ||
4293 | if (!BC_PARSE_LOOP(p)) return bc_error_bad_token(); | 4300 | if (!BC_PARSE_LOOP(p)) RETURN_STATUS(bc_error_bad_token()); |
4294 | 4301 | ||
4295 | if (type == BC_LEX_KEY_BREAK) { | 4302 | if (type == BC_LEX_KEY_BREAK) { |
4296 | 4303 | if (p->exits.len == 0) RETURN_STATUS(bc_error_bad_token()); | |
4297 | if (p->exits.len == 0) return bc_error_bad_token(); | ||
4298 | 4304 | ||
4299 | i = p->exits.len - 1; | 4305 | i = p->exits.len - 1; |
4300 | ip = bc_vec_item(&p->exits, i); | 4306 | ip = bc_vec_item(&p->exits, i); |
4301 | 4307 | ||
4302 | while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--); | 4308 | while (!ip->func && i < p->exits.len) |
4303 | if (i >= p->exits.len && !ip->func) return bc_error_bad_token(); | 4309 | ip = bc_vec_item(&p->exits, i--); |
4310 | if (i >= p->exits.len && !ip->func) | ||
4311 | RETURN_STATUS(bc_error_bad_token()); | ||
4304 | 4312 | ||
4305 | i = ip->idx; | 4313 | i = ip->idx; |
4306 | } | 4314 | } |
@@ -4311,15 +4319,18 @@ static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type) | |||
4311 | bc_parse_pushIndex(p, i); | 4319 | bc_parse_pushIndex(p, i); |
4312 | 4320 | ||
4313 | s = zbc_lex_next(&p->l); | 4321 | s = zbc_lex_next(&p->l); |
4314 | if (s) return s; | 4322 | if (s) RETURN_STATUS(s); |
4315 | 4323 | ||
4316 | if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE) | 4324 | if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE) |
4317 | return bc_error_bad_token(); | 4325 | RETURN_STATUS(bc_error_bad_token()); |
4318 | 4326 | ||
4319 | return zbc_lex_next(&p->l); | 4327 | RETURN_STATUS(zbc_lex_next(&p->l)); |
4320 | } | 4328 | } |
4329 | #if ERRORS_ARE_FATAL | ||
4330 | # define zbc_parse_loopExit(...) (zbc_parse_loopExit(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
4331 | #endif | ||
4321 | 4332 | ||
4322 | static BcStatus bc_parse_func(BcParse *p) | 4333 | static BC_STATUS zbc_parse_func(BcParse *p) |
4323 | { | 4334 | { |
4324 | BcStatus s; | 4335 | BcStatus s; |
4325 | bool var, comma = false; | 4336 | bool var, comma = false; |
@@ -4327,24 +4338,23 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4327 | char *name; | 4338 | char *name; |
4328 | 4339 | ||
4329 | s = zbc_lex_next(&p->l); | 4340 | s = zbc_lex_next(&p->l); |
4330 | if (s) return s; | 4341 | if (s) RETURN_STATUS(s); |
4331 | if (p->l.t.t != BC_LEX_NAME) | 4342 | if (p->l.t.t != BC_LEX_NAME) |
4332 | return bc_error("bad function definition"); | 4343 | RETURN_STATUS(bc_error("bad function definition")); |
4333 | 4344 | ||
4334 | name = xstrdup(p->l.t.v.v); | 4345 | name = xstrdup(p->l.t.v.v); |
4335 | bc_parse_addFunc(p, name, &p->fidx); | 4346 | bc_parse_addFunc(p, name, &p->fidx); |
4336 | 4347 | ||
4337 | s = zbc_lex_next(&p->l); | 4348 | s = zbc_lex_next(&p->l); |
4338 | if (s) return s; | 4349 | if (s) RETURN_STATUS(s); |
4339 | if (p->l.t.t != BC_LEX_LPAREN) | 4350 | if (p->l.t.t != BC_LEX_LPAREN) |
4340 | return bc_error("bad function definition"); | 4351 | RETURN_STATUS(bc_error("bad function definition")); |
4341 | s = zbc_lex_next(&p->l); | 4352 | s = zbc_lex_next(&p->l); |
4342 | if (s) return s; | 4353 | if (s) RETURN_STATUS(s); |
4343 | 4354 | ||
4344 | while (p->l.t.t != BC_LEX_RPAREN) { | 4355 | while (p->l.t.t != BC_LEX_RPAREN) { |
4345 | |||
4346 | if (p->l.t.t != BC_LEX_NAME) | 4356 | if (p->l.t.t != BC_LEX_NAME) |
4347 | return bc_error("bad function definition"); | 4357 | RETURN_STATUS(bc_error("bad function definition")); |
4348 | 4358 | ||
4349 | ++p->func->nparams; | 4359 | ++p->func->nparams; |
4350 | 4360 | ||
@@ -4355,7 +4365,6 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4355 | var = p->l.t.t != BC_LEX_LBRACKET; | 4365 | var = p->l.t.t != BC_LEX_LBRACKET; |
4356 | 4366 | ||
4357 | if (!var) { | 4367 | if (!var) { |
4358 | |||
4359 | s = zbc_lex_next(&p->l); | 4368 | s = zbc_lex_next(&p->l); |
4360 | if (s) goto err; | 4369 | if (s) goto err; |
4361 | 4370 | ||
@@ -4378,46 +4387,48 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4378 | if (s) goto err; | 4387 | if (s) goto err; |
4379 | } | 4388 | } |
4380 | 4389 | ||
4381 | if (comma) return bc_error("bad function definition"); | 4390 | if (comma) RETURN_STATUS(bc_error("bad function definition")); |
4382 | 4391 | ||
4383 | flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY; | 4392 | flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY; |
4384 | bc_parse_startBody(p, flags); | 4393 | bc_parse_startBody(p, flags); |
4385 | 4394 | ||
4386 | s = zbc_lex_next(&p->l); | 4395 | s = zbc_lex_next(&p->l); |
4387 | if (s) return s; | 4396 | if (s) RETURN_STATUS(s); |
4388 | 4397 | ||
4389 | if (p->l.t.t != BC_LEX_LBRACE) | 4398 | if (p->l.t.t != BC_LEX_LBRACE) |
4390 | s = bc_POSIX_requires("the left brace be on the same line as the function header"); | 4399 | s = bc_POSIX_requires("the left brace be on the same line as the function header"); |
4391 | 4400 | ||
4392 | return s; | 4401 | RETURN_STATUS(s); |
4393 | 4402 | ||
4394 | err: | 4403 | err: |
4395 | free(name); | 4404 | free(name); |
4396 | return s; | 4405 | RETURN_STATUS(s); |
4397 | } | 4406 | } |
4407 | #if ERRORS_ARE_FATAL | ||
4408 | # define zbc_parse_func(...) (zbc_parse_func(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
4409 | #endif | ||
4398 | 4410 | ||
4399 | static BcStatus bc_parse_auto(BcParse *p) | 4411 | static BC_STATUS zbc_parse_auto(BcParse *p) |
4400 | { | 4412 | { |
4401 | BcStatus s; | 4413 | BcStatus s; |
4402 | bool comma, var, one; | 4414 | bool comma, var, one; |
4403 | char *name; | 4415 | char *name; |
4404 | 4416 | ||
4405 | if (!p->auto_part) return bc_error_bad_token(); | 4417 | if (!p->auto_part) RETURN_STATUS(bc_error_bad_token()); |
4418 | |||
4406 | s = zbc_lex_next(&p->l); | 4419 | s = zbc_lex_next(&p->l); |
4407 | if (s) return s; | 4420 | if (s) RETURN_STATUS(s); |
4408 | 4421 | ||
4409 | p->auto_part = comma = false; | 4422 | p->auto_part = comma = false; |
4410 | one = p->l.t.t == BC_LEX_NAME; | 4423 | one = p->l.t.t == BC_LEX_NAME; |
4411 | 4424 | ||
4412 | while (p->l.t.t == BC_LEX_NAME) { | 4425 | while (p->l.t.t == BC_LEX_NAME) { |
4413 | |||
4414 | name = xstrdup(p->l.t.v.v); | 4426 | name = xstrdup(p->l.t.v.v); |
4415 | s = zbc_lex_next(&p->l); | 4427 | s = zbc_lex_next(&p->l); |
4416 | if (s) goto err; | 4428 | if (s) goto err; |
4417 | 4429 | ||
4418 | var = p->l.t.t != BC_LEX_LBRACKET; | 4430 | var = p->l.t.t != BC_LEX_LBRACKET; |
4419 | if (!var) { | 4431 | if (!var) { |
4420 | |||
4421 | s = zbc_lex_next(&p->l); | 4432 | s = zbc_lex_next(&p->l); |
4422 | if (s) goto err; | 4433 | if (s) goto err; |
4423 | 4434 | ||
@@ -4440,20 +4451,23 @@ static BcStatus bc_parse_auto(BcParse *p) | |||
4440 | if (s) goto err; | 4451 | if (s) goto err; |
4441 | } | 4452 | } |
4442 | 4453 | ||
4443 | if (comma) return bc_error("bad function definition"); | 4454 | if (comma) RETURN_STATUS(bc_error("bad function definition")); |
4444 | if (!one) return bc_error("no auto variable found"); | 4455 | if (!one) RETURN_STATUS(bc_error("no auto variable found")); |
4445 | 4456 | ||
4446 | if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON) | 4457 | if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON) |
4447 | return bc_error_bad_token(); | 4458 | RETURN_STATUS(bc_error_bad_token()); |
4448 | 4459 | ||
4449 | return zbc_lex_next(&p->l); | 4460 | RETURN_STATUS(zbc_lex_next(&p->l)); |
4450 | 4461 | ||
4451 | err: | 4462 | err: |
4452 | free(name); | 4463 | free(name); |
4453 | return s; | 4464 | RETURN_STATUS(s); |
4454 | } | 4465 | } |
4466 | #if ERRORS_ARE_FATAL | ||
4467 | # define zbc_parse_auto(...) (zbc_parse_auto(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
4468 | #endif | ||
4455 | 4469 | ||
4456 | static BcStatus bc_parse_body(BcParse *p, bool brace) | 4470 | static BC_STATUS zbc_parse_body(BcParse *p, bool brace) |
4457 | { | 4471 | { |
4458 | BcStatus s = BC_STATUS_SUCCESS; | 4472 | BcStatus s = BC_STATUS_SUCCESS; |
4459 | uint8_t *flag_ptr = bc_vec_top(&p->flags); | 4473 | uint8_t *flag_ptr = bc_vec_top(&p->flags); |
@@ -4461,24 +4475,27 @@ static BcStatus bc_parse_body(BcParse *p, bool brace) | |||
4461 | *flag_ptr &= ~(BC_PARSE_FLAG_BODY); | 4475 | *flag_ptr &= ~(BC_PARSE_FLAG_BODY); |
4462 | 4476 | ||
4463 | if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) { | 4477 | if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) { |
4478 | if (!brace) RETURN_STATUS(bc_error_bad_token()); | ||
4464 | 4479 | ||
4465 | if (!brace) return bc_error_bad_token(); | ||
4466 | p->auto_part = p->l.t.t != BC_LEX_KEY_AUTO; | 4480 | p->auto_part = p->l.t.t != BC_LEX_KEY_AUTO; |
4467 | 4481 | ||
4468 | if (!p->auto_part) { | 4482 | if (!p->auto_part) { |
4469 | s = bc_parse_auto(p); | 4483 | s = zbc_parse_auto(p); |
4470 | if (s) return s; | 4484 | if (s) RETURN_STATUS(s); |
4471 | } | 4485 | } |
4472 | 4486 | ||
4473 | if (p->l.t.t == BC_LEX_NLINE) s = zbc_lex_next(&p->l); | 4487 | if (p->l.t.t == BC_LEX_NLINE) s = zbc_lex_next(&p->l); |
4474 | } | 4488 | } |
4475 | else { | 4489 | else { |
4476 | s = bc_parse_stmt(p); | 4490 | s = bc_parse_stmt(p); |
4477 | if (!s && !brace) s = bc_parse_endBody(p, false); | 4491 | if (!s && !brace) s = zbc_parse_endBody(p, false); |
4478 | } | 4492 | } |
4479 | 4493 | ||
4480 | return s; | 4494 | RETURN_STATUS(s); |
4481 | } | 4495 | } |
4496 | #if ERRORS_ARE_FATAL | ||
4497 | # define zbc_parse_body(...) (zbc_parse_body(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
4498 | #endif | ||
4482 | 4499 | ||
4483 | static BcStatus bc_parse_stmt(BcParse *p) | 4500 | static BcStatus bc_parse_stmt(BcParse *p) |
4484 | { | 4501 | { |
@@ -4505,12 +4522,12 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4505 | s = zbc_lex_next(&p->l); | 4522 | s = zbc_lex_next(&p->l); |
4506 | if (s) return s; | 4523 | if (s) return s; |
4507 | 4524 | ||
4508 | return bc_parse_body(p, true); | 4525 | return zbc_parse_body(p, true); |
4509 | } | 4526 | } |
4510 | 4527 | ||
4511 | case BC_LEX_KEY_AUTO: | 4528 | case BC_LEX_KEY_AUTO: |
4512 | { | 4529 | { |
4513 | return bc_parse_auto(p); | 4530 | return zbc_parse_auto(p); |
4514 | } | 4531 | } |
4515 | 4532 | ||
4516 | default: | 4533 | default: |
@@ -4522,7 +4539,7 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4522 | return BC_STATUS_SUCCESS; | 4539 | return BC_STATUS_SUCCESS; |
4523 | } | 4540 | } |
4524 | else if (BC_PARSE_BODY(p)) | 4541 | else if (BC_PARSE_BODY(p)) |
4525 | return bc_parse_body(p, false); | 4542 | return zbc_parse_body(p, false); |
4526 | 4543 | ||
4527 | break; | 4544 | break; |
4528 | } | 4545 | } |
@@ -4563,20 +4580,20 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4563 | 4580 | ||
4564 | case BC_LEX_RBRACE: | 4581 | case BC_LEX_RBRACE: |
4565 | { | 4582 | { |
4566 | s = bc_parse_endBody(p, true); | 4583 | s = zbc_parse_endBody(p, true); |
4567 | break; | 4584 | break; |
4568 | } | 4585 | } |
4569 | 4586 | ||
4570 | case BC_LEX_STR: | 4587 | case BC_LEX_STR: |
4571 | { | 4588 | { |
4572 | s = bc_parse_string(p, BC_INST_PRINT_STR); | 4589 | s = zbc_parse_string(p, BC_INST_PRINT_STR); |
4573 | break; | 4590 | break; |
4574 | } | 4591 | } |
4575 | 4592 | ||
4576 | case BC_LEX_KEY_BREAK: | 4593 | case BC_LEX_KEY_BREAK: |
4577 | case BC_LEX_KEY_CONTINUE: | 4594 | case BC_LEX_KEY_CONTINUE: |
4578 | { | 4595 | { |
4579 | s = bc_parse_loopExit(p, p->l.t.t); | 4596 | s = zbc_parse_loopExit(p, p->l.t.t); |
4580 | break; | 4597 | break; |
4581 | } | 4598 | } |
4582 | 4599 | ||
@@ -4662,7 +4679,7 @@ static FAST_FUNC BcStatus bc_parse_parse(BcParse *p) | |||
4662 | s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file"); | 4679 | s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file"); |
4663 | else if (p->l.t.t == BC_LEX_KEY_DEFINE) { | 4680 | else if (p->l.t.t == BC_LEX_KEY_DEFINE) { |
4664 | if (!BC_PARSE_CAN_EXEC(p)) return bc_error_bad_token(); | 4681 | if (!BC_PARSE_CAN_EXEC(p)) return bc_error_bad_token(); |
4665 | s = bc_parse_func(p); | 4682 | s = zbc_parse_func(p); |
4666 | } | 4683 | } |
4667 | else | 4684 | else |
4668 | s = bc_parse_stmt(p); | 4685 | s = bc_parse_stmt(p); |
@@ -4703,7 +4720,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne | |||
4703 | 4720 | ||
4704 | case BC_LEX_OP_MINUS: | 4721 | case BC_LEX_OP_MINUS: |
4705 | { | 4722 | { |
4706 | s = bc_parse_minus(p, &prev, ops_bgn, rprn, &nexprs); | 4723 | s = zbc_parse_minus(p, &prev, ops_bgn, rprn, &nexprs); |
4707 | rprn = get_token = false; | 4724 | rprn = get_token = false; |
4708 | bin_last = prev == BC_INST_MINUS; | 4725 | bin_last = prev == BC_INST_MINUS; |
4709 | break; | 4726 | break; |
@@ -4854,7 +4871,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne | |||
4854 | else if (flags & BC_PARSE_NOREAD) | 4871 | else if (flags & BC_PARSE_NOREAD) |
4855 | s = bc_error_nested_read_call(); | 4872 | s = bc_error_nested_read_call(); |
4856 | else | 4873 | else |
4857 | s = bc_parse_read(p); | 4874 | s = zbc_parse_read(p); |
4858 | 4875 | ||
4859 | paren_expr = true; | 4876 | paren_expr = true; |
4860 | rprn = get_token = bin_last = false; | 4877 | rprn = get_token = bin_last = false; |
@@ -4961,20 +4978,23 @@ static BcStatus bc_parse_expression(BcParse *p, uint8_t flags) | |||
4961 | 4978 | ||
4962 | #define DC_PARSE_BUF_LEN ((int) (sizeof(uint32_t) * CHAR_BIT)) | 4979 | #define DC_PARSE_BUF_LEN ((int) (sizeof(uint32_t) * CHAR_BIT)) |
4963 | 4980 | ||
4964 | static BcStatus dc_parse_register(BcParse *p) | 4981 | static BC_STATUS zdc_parse_register(BcParse *p) |
4965 | { | 4982 | { |
4966 | BcStatus s; | 4983 | BcStatus s; |
4967 | char *name; | 4984 | char *name; |
4968 | 4985 | ||
4969 | s = zbc_lex_next(&p->l); | 4986 | s = zbc_lex_next(&p->l); |
4970 | if (s) return s; | 4987 | if (s) RETURN_STATUS(s); |
4971 | if (p->l.t.t != BC_LEX_NAME) return bc_error_bad_token(); | 4988 | if (p->l.t.t != BC_LEX_NAME) RETURN_STATUS(bc_error_bad_token()); |
4972 | 4989 | ||
4973 | name = xstrdup(p->l.t.v.v); | 4990 | name = xstrdup(p->l.t.v.v); |
4974 | bc_parse_pushName(p, name); | 4991 | bc_parse_pushName(p, name); |
4975 | 4992 | ||
4976 | return s; | 4993 | RETURN_STATUS(s); |
4977 | } | 4994 | } |
4995 | #if ERRORS_ARE_FATAL | ||
4996 | # define zdc_parse_register(...) (zdc_parse_register(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
4997 | #endif | ||
4978 | 4998 | ||
4979 | static BC_STATUS zdc_parse_string(BcParse *p) | 4999 | static BC_STATUS zdc_parse_string(BcParse *p) |
4980 | { | 5000 | { |
@@ -4996,14 +5016,14 @@ static BC_STATUS zdc_parse_string(BcParse *p) | |||
4996 | # define zdc_parse_string(...) (zdc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS) | 5016 | # define zdc_parse_string(...) (zdc_parse_string(__VA_ARGS__), BC_STATUS_SUCCESS) |
4997 | #endif | 5017 | #endif |
4998 | 5018 | ||
4999 | static BcStatus dc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store) | 5019 | static BC_STATUS zdc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store) |
5000 | { | 5020 | { |
5001 | BcStatus s; | 5021 | BcStatus s; |
5002 | 5022 | ||
5003 | bc_parse_push(p, inst); | 5023 | bc_parse_push(p, inst); |
5004 | if (name) { | 5024 | if (name) { |
5005 | s = dc_parse_register(p); | 5025 | s = zdc_parse_register(p); |
5006 | if (s) return s; | 5026 | if (s) RETURN_STATUS(s); |
5007 | } | 5027 | } |
5008 | 5028 | ||
5009 | if (store) { | 5029 | if (store) { |
@@ -5012,34 +5032,40 @@ static BcStatus dc_parse_mem(BcParse *p, uint8_t inst, bool name, bool store) | |||
5012 | bc_parse_push(p, BC_INST_POP); | 5032 | bc_parse_push(p, BC_INST_POP); |
5013 | } | 5033 | } |
5014 | 5034 | ||
5015 | return zbc_lex_next(&p->l); | 5035 | RETURN_STATUS(zbc_lex_next(&p->l)); |
5016 | } | 5036 | } |
5037 | #if ERRORS_ARE_FATAL | ||
5038 | # define zdc_parse_mem(...) (zdc_parse_mem(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
5039 | #endif | ||
5017 | 5040 | ||
5018 | static BcStatus dc_parse_cond(BcParse *p, uint8_t inst) | 5041 | static BC_STATUS zdc_parse_cond(BcParse *p, uint8_t inst) |
5019 | { | 5042 | { |
5020 | BcStatus s; | 5043 | BcStatus s; |
5021 | 5044 | ||
5022 | bc_parse_push(p, inst); | 5045 | bc_parse_push(p, inst); |
5023 | bc_parse_push(p, BC_INST_EXEC_COND); | 5046 | bc_parse_push(p, BC_INST_EXEC_COND); |
5024 | 5047 | ||
5025 | s = dc_parse_register(p); | 5048 | s = zdc_parse_register(p); |
5026 | if (s) return s; | 5049 | if (s) RETURN_STATUS(s); |
5027 | 5050 | ||
5028 | s = zbc_lex_next(&p->l); | 5051 | s = zbc_lex_next(&p->l); |
5029 | if (s) return s; | 5052 | if (s) RETURN_STATUS(s); |
5030 | 5053 | ||
5031 | if (p->l.t.t == BC_LEX_ELSE) { | 5054 | if (p->l.t.t == BC_LEX_ELSE) { |
5032 | s = dc_parse_register(p); | 5055 | s = zdc_parse_register(p); |
5033 | if (s) return s; | 5056 | if (s) RETURN_STATUS(s); |
5034 | s = zbc_lex_next(&p->l); | 5057 | s = zbc_lex_next(&p->l); |
5035 | } | 5058 | } |
5036 | else | 5059 | else |
5037 | bc_parse_push(p, BC_PARSE_STREND); | 5060 | bc_parse_push(p, BC_PARSE_STREND); |
5038 | 5061 | ||
5039 | return s; | 5062 | RETURN_STATUS(s); |
5040 | } | 5063 | } |
5064 | #if ERRORS_ARE_FATAL | ||
5065 | # define zdc_parse_cond(...) (zdc_parse_cond(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
5066 | #endif | ||
5041 | 5067 | ||
5042 | static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | 5068 | static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t, uint8_t flags) |
5043 | { | 5069 | { |
5044 | BcStatus s = BC_STATUS_SUCCESS; | 5070 | BcStatus s = BC_STATUS_SUCCESS; |
5045 | BcInst prev; | 5071 | BcInst prev; |
@@ -5047,99 +5073,72 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | |||
5047 | bool assign, get_token = false; | 5073 | bool assign, get_token = false; |
5048 | 5074 | ||
5049 | switch (t) { | 5075 | switch (t) { |
5050 | |||
5051 | case BC_LEX_OP_REL_EQ: | 5076 | case BC_LEX_OP_REL_EQ: |
5052 | case BC_LEX_OP_REL_LE: | 5077 | case BC_LEX_OP_REL_LE: |
5053 | case BC_LEX_OP_REL_GE: | 5078 | case BC_LEX_OP_REL_GE: |
5054 | case BC_LEX_OP_REL_NE: | 5079 | case BC_LEX_OP_REL_NE: |
5055 | case BC_LEX_OP_REL_LT: | 5080 | case BC_LEX_OP_REL_LT: |
5056 | case BC_LEX_OP_REL_GT: | 5081 | case BC_LEX_OP_REL_GT: |
5057 | { | 5082 | s = zdc_parse_cond(p, t - BC_LEX_OP_REL_EQ + BC_INST_REL_EQ); |
5058 | s = dc_parse_cond(p, t - BC_LEX_OP_REL_EQ + BC_INST_REL_EQ); | ||
5059 | break; | 5083 | break; |
5060 | } | ||
5061 | |||
5062 | case BC_LEX_SCOLON: | 5084 | case BC_LEX_SCOLON: |
5063 | case BC_LEX_COLON: | 5085 | case BC_LEX_COLON: |
5064 | { | 5086 | s = zdc_parse_mem(p, BC_INST_ARRAY_ELEM, true, t == BC_LEX_COLON); |
5065 | s = dc_parse_mem(p, BC_INST_ARRAY_ELEM, true, t == BC_LEX_COLON); | ||
5066 | break; | 5087 | break; |
5067 | } | ||
5068 | |||
5069 | case BC_LEX_STR: | 5088 | case BC_LEX_STR: |
5070 | { | ||
5071 | s = zdc_parse_string(p); | 5089 | s = zdc_parse_string(p); |
5072 | break; | 5090 | break; |
5073 | } | ||
5074 | |||
5075 | case BC_LEX_NEG: | 5091 | case BC_LEX_NEG: |
5076 | case BC_LEX_NUMBER: | 5092 | case BC_LEX_NUMBER: |
5077 | { | ||
5078 | if (t == BC_LEX_NEG) { | 5093 | if (t == BC_LEX_NEG) { |
5079 | s = zbc_lex_next(&p->l); | 5094 | s = zbc_lex_next(&p->l); |
5080 | if (s) return s; | 5095 | if (s) RETURN_STATUS(s); |
5081 | if (p->l.t.t != BC_LEX_NUMBER) | 5096 | if (p->l.t.t != BC_LEX_NUMBER) |
5082 | return bc_error_bad_token(); | 5097 | RETURN_STATUS(bc_error_bad_token()); |
5083 | } | 5098 | } |
5084 | |||
5085 | bc_parse_number(p, &prev, &p->nbraces); | 5099 | bc_parse_number(p, &prev, &p->nbraces); |
5086 | |||
5087 | if (t == BC_LEX_NEG) bc_parse_push(p, BC_INST_NEG); | 5100 | if (t == BC_LEX_NEG) bc_parse_push(p, BC_INST_NEG); |
5088 | get_token = true; | 5101 | get_token = true; |
5089 | |||
5090 | break; | 5102 | break; |
5091 | } | ||
5092 | |||
5093 | case BC_LEX_KEY_READ: | 5103 | case BC_LEX_KEY_READ: |
5094 | { | ||
5095 | if (flags & BC_PARSE_NOREAD) | 5104 | if (flags & BC_PARSE_NOREAD) |
5096 | s = bc_error_nested_read_call(); | 5105 | s = bc_error_nested_read_call(); |
5097 | else | 5106 | else |
5098 | bc_parse_push(p, BC_INST_READ); | 5107 | bc_parse_push(p, BC_INST_READ); |
5099 | get_token = true; | 5108 | get_token = true; |
5100 | break; | 5109 | break; |
5101 | } | ||
5102 | |||
5103 | case BC_LEX_OP_ASSIGN: | 5110 | case BC_LEX_OP_ASSIGN: |
5104 | case BC_LEX_STORE_PUSH: | 5111 | case BC_LEX_STORE_PUSH: |
5105 | { | ||
5106 | assign = t == BC_LEX_OP_ASSIGN; | 5112 | assign = t == BC_LEX_OP_ASSIGN; |
5107 | inst = assign ? BC_INST_VAR : BC_INST_PUSH_TO_VAR; | 5113 | inst = assign ? BC_INST_VAR : BC_INST_PUSH_TO_VAR; |
5108 | s = dc_parse_mem(p, inst, true, assign); | 5114 | s = zdc_parse_mem(p, inst, true, assign); |
5109 | break; | 5115 | break; |
5110 | } | ||
5111 | |||
5112 | case BC_LEX_LOAD: | 5116 | case BC_LEX_LOAD: |
5113 | case BC_LEX_LOAD_POP: | 5117 | case BC_LEX_LOAD_POP: |
5114 | { | ||
5115 | inst = t == BC_LEX_LOAD_POP ? BC_INST_PUSH_VAR : BC_INST_LOAD; | 5118 | inst = t == BC_LEX_LOAD_POP ? BC_INST_PUSH_VAR : BC_INST_LOAD; |
5116 | s = dc_parse_mem(p, inst, true, false); | 5119 | s = zdc_parse_mem(p, inst, true, false); |
5117 | break; | 5120 | break; |
5118 | } | ||
5119 | |||
5120 | case BC_LEX_STORE_IBASE: | 5121 | case BC_LEX_STORE_IBASE: |
5121 | case BC_LEX_STORE_SCALE: | 5122 | case BC_LEX_STORE_SCALE: |
5122 | case BC_LEX_STORE_OBASE: | 5123 | case BC_LEX_STORE_OBASE: |
5123 | { | ||
5124 | inst = t - BC_LEX_STORE_IBASE + BC_INST_IBASE; | 5124 | inst = t - BC_LEX_STORE_IBASE + BC_INST_IBASE; |
5125 | s = dc_parse_mem(p, inst, false, true); | 5125 | s = zdc_parse_mem(p, inst, false, true); |
5126 | break; | 5126 | break; |
5127 | } | ||
5128 | |||
5129 | default: | 5127 | default: |
5130 | { | ||
5131 | s = bc_error_bad_token(); | 5128 | s = bc_error_bad_token(); |
5132 | get_token = true; | 5129 | get_token = true; |
5133 | break; | 5130 | break; |
5134 | } | ||
5135 | } | 5131 | } |
5136 | 5132 | ||
5137 | if (!s && get_token) s = zbc_lex_next(&p->l); | 5133 | if (!s && get_token) s = zbc_lex_next(&p->l); |
5138 | 5134 | ||
5139 | return s; | 5135 | RETURN_STATUS(s); |
5140 | } | 5136 | } |
5137 | #if ERRORS_ARE_FATAL | ||
5138 | # define zdc_parse_token(...) (zdc_parse_token(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
5139 | #endif | ||
5141 | 5140 | ||
5142 | static BcStatus dc_parse_expr(BcParse *p, uint8_t flags) | 5141 | static BC_STATUS zdc_parse_expr(BcParse *p, uint8_t flags) |
5143 | { | 5142 | { |
5144 | BcStatus s = BC_STATUS_SUCCESS; | 5143 | BcStatus s = BC_STATUS_SUCCESS; |
5145 | BcInst inst; | 5144 | BcInst inst; |
@@ -5148,22 +5147,23 @@ static BcStatus dc_parse_expr(BcParse *p, uint8_t flags) | |||
5148 | if (flags & BC_PARSE_NOCALL) p->nbraces = G.prog.results.len; | 5147 | if (flags & BC_PARSE_NOCALL) p->nbraces = G.prog.results.len; |
5149 | 5148 | ||
5150 | for (t = p->l.t.t; !s && t != BC_LEX_EOF; t = p->l.t.t) { | 5149 | for (t = p->l.t.t; !s && t != BC_LEX_EOF; t = p->l.t.t) { |
5151 | |||
5152 | inst = dc_parse_insts[t]; | 5150 | inst = dc_parse_insts[t]; |
5153 | 5151 | ||
5154 | if (inst != BC_INST_INVALID) { | 5152 | if (inst != BC_INST_INVALID) { |
5155 | bc_parse_push(p, inst); | 5153 | bc_parse_push(p, inst); |
5156 | s = zbc_lex_next(&p->l); | 5154 | s = zbc_lex_next(&p->l); |
5157 | } | 5155 | } else |
5158 | else | 5156 | s = zdc_parse_token(p, t, flags); |
5159 | s = dc_parse_token(p, t, flags); | ||
5160 | } | 5157 | } |
5161 | 5158 | ||
5162 | if (!s && p->l.t.t == BC_LEX_EOF && (flags & BC_PARSE_NOCALL)) | 5159 | if (!s && p->l.t.t == BC_LEX_EOF && (flags & BC_PARSE_NOCALL)) |
5163 | bc_parse_push(p, BC_INST_POP_EXEC); | 5160 | bc_parse_push(p, BC_INST_POP_EXEC); |
5164 | 5161 | ||
5165 | return s; | 5162 | RETURN_STATUS(s); |
5166 | } | 5163 | } |
5164 | #if ERRORS_ARE_FATAL | ||
5165 | # define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS) | ||
5166 | #endif | ||
5167 | 5167 | ||
5168 | static FAST_FUNC BcStatus dc_parse_parse(BcParse *p) | 5168 | static FAST_FUNC BcStatus dc_parse_parse(BcParse *p) |
5169 | { | 5169 | { |
@@ -5172,7 +5172,7 @@ static FAST_FUNC BcStatus dc_parse_parse(BcParse *p) | |||
5172 | if (p->l.t.t == BC_LEX_EOF) | 5172 | if (p->l.t.t == BC_LEX_EOF) |
5173 | s = bc_error("end of file"); | 5173 | s = bc_error("end of file"); |
5174 | else | 5174 | else |
5175 | s = dc_parse_expr(p, 0); | 5175 | s = zdc_parse_expr(p, 0); |
5176 | 5176 | ||
5177 | if (s || G_interrupt) { | 5177 | if (s || G_interrupt) { |
5178 | bc_parse_reset(p); | 5178 | bc_parse_reset(p); |
@@ -5203,7 +5203,7 @@ static BcStatus common_parse_expr(BcParse *p, uint8_t flags) | |||
5203 | if (IS_BC) { | 5203 | if (IS_BC) { |
5204 | IF_BC(return bc_parse_expression(p, flags);) | 5204 | IF_BC(return bc_parse_expression(p, flags);) |
5205 | } else { | 5205 | } else { |
5206 | IF_DC(return dc_parse_expr(p, flags);) | 5206 | IF_DC(return zdc_parse_expr(p, flags);) |
5207 | } | 5207 | } |
5208 | } | 5208 | } |
5209 | 5209 | ||