aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 16:03:46 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 16:03:46 +0100
commit24fb2cd62fcc2c422692df4138e0f1e333a52c42 (patch)
tree2e0abfd8cb3578409c60cb7d880a8ba2c0df31de
parentf359e004b0ce4a5ac361f553c13e876123fd4ebb (diff)
downloadbusybox-w32-24fb2cd62fcc2c422692df4138e0f1e333a52c42.tar.gz
busybox-w32-24fb2cd62fcc2c422692df4138e0f1e333a52c42.tar.bz2
busybox-w32-24fb2cd62fcc2c422692df4138e0f1e333a52c42.zip
bc: shrink error handling code by enabling tail-call optimization
function old new delta bc_posix_error_fmt - 60 +60 bc_error_fmt - 38 +38 bc_error_bad_character - 17 +17 bc_parse_auto 302 313 +11 bc_num_ulong 93 103 +10 bc_error_variable_is_wrong_type - 10 +10 bc_error_stack_has_too_few_elements - 10 +10 bc_error_nested_read_call - 10 +10 bc_error_bad_token - 10 +10 bc_error_bad_expression - 10 +10 bc_num_d 561 564 +3 bc_program_assign 484 486 +2 dc_parse_parse 60 59 -1 bc_program_num 1130 1129 -1 bc_program_call 367 366 -1 bc_parse_stmt 2277 2276 -1 bc_lex_number 299 298 -1 bc_lex_name 91 90 -1 bc_func_insert 98 97 -1 bc_num_shift 74 72 -2 bc_vm_run 1924 1921 -3 bc_parse_endBody 424 420 -4 bc_lex_next 81 77 -4 bc_program_read 343 338 -5 bc_program_asciify 469 464 -5 bc_program_pushVar 221 215 -6 bc_program_print 784 778 -6 bc_program_prep 99 93 -6 bc_program_assignStr 167 161 -6 bc_parse_else 143 137 -6 bc_parse_body 124 118 -6 dc_parse_register 61 53 -8 dc_lex_token 699 691 -8 bc_program_modexp 756 746 -10 bc_parse_name 593 581 -12 dc_parse_expr 775 762 -13 bc_program_copyToVar 336 323 -13 bc_program_binOpPrep 324 311 -13 bc_program_execStr 561 543 -18 bc_program_exec 4150 4132 -18 bc_parse_parse 483 464 -19 bc_error 38 14 -24 bc_lex_token 1266 1237 -29 bc_posix_error 60 14 -46 bc_parse_expr 2194 2146 -48 ------------------------------------------------------------------------------ (add/remove: 8/0 grow/shrink: 4/33 up/down: 191/-345) Total: -154 bytes text data bss dec hex filename 987226 485 7296 995007 f2ebf busybox_old 987072 485 7296 994853 f2e25 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c233
1 files changed, 136 insertions, 97 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index b392b05a3..6f2606c79 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -1110,7 +1110,7 @@ static void quit(void)
1110 exit(0); 1110 exit(0);
1111} 1111}
1112 1112
1113static int bc_error(const char *fmt, ...) 1113static NOINLINE int bc_error_fmt(const char *fmt, ...)
1114{ 1114{
1115 va_list p; 1115 va_list p;
1116 1116
@@ -1122,12 +1122,13 @@ static int bc_error(const char *fmt, ...)
1122 return BC_STATUS_FAILURE; 1122 return BC_STATUS_FAILURE;
1123} 1123}
1124 1124
1125static int bc_posix_error(const char *fmt, ...) 1125static NOINLINE int bc_posix_error_fmt(const char *fmt, ...)
1126{ 1126{
1127 va_list p; 1127 va_list p;
1128 1128
1129 // Are non-POSIX constructs totally ok?
1129 if (!(option_mask32 & (BC_FLAG_S|BC_FLAG_W))) 1130 if (!(option_mask32 & (BC_FLAG_S|BC_FLAG_W)))
1130 return BC_STATUS_SUCCESS; 1131 return BC_STATUS_SUCCESS; // yes
1131 1132
1132 va_start(p, fmt); 1133 va_start(p, fmt);
1133 bb_verror_msg(fmt, p, NULL); 1134 bb_verror_msg(fmt, p, NULL);
@@ -1141,6 +1142,44 @@ static int bc_posix_error(const char *fmt, ...)
1141 return BC_STATUS_FAILURE; 1142 return BC_STATUS_FAILURE;
1142} 1143}
1143 1144
1145// We use error functions with "return bc_error(FMT[, PARAMS])" idiom.
1146// This idiom begs for tail-call optimization, but for it to work,
1147// function must not have calller-cleaned parameters on stack.
1148// Unfortunately, vararg functions do exactly that on most arches.
1149// Thus, these shims for the cases when we have no PARAMS:
1150static int bc_error(const char *msg)
1151{
1152 return bc_error_fmt("%s", msg);
1153}
1154static int bc_posix_error(const char *msg)
1155{
1156 return bc_posix_error_fmt("%s", msg);
1157}
1158static int bc_error_bad_character(char c)
1159{
1160 return bc_error_fmt("bad character '%c'", c);
1161}
1162static int bc_error_bad_expression(void)
1163{
1164 return bc_error("bad expression");
1165}
1166static int bc_error_bad_token(void)
1167{
1168 return bc_error("bad token");
1169}
1170static int bc_error_stack_has_too_few_elements(void)
1171{
1172 return bc_error("stack has too few elements");
1173}
1174static int bc_error_variable_is_wrong_type(void)
1175{
1176 return bc_error("variable is wrong type");
1177}
1178static int bc_error_nested_read_call(void)
1179{
1180 return bc_error("read() call inside of a read() call");
1181}
1182
1144static void bc_vec_grow(BcVec *v, size_t n) 1183static void bc_vec_grow(BcVec *v, size_t n)
1145{ 1184{
1146 size_t cap = v->cap * 2; 1185 size_t cap = v->cap * 2;
@@ -1349,7 +1388,7 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
1349 || i > 0x7e 1388 || i > 0x7e
1350 ) { 1389 ) {
1351 // Bad chars on this line, ignore entire line 1390 // Bad chars on this line, ignore entire line
1352 bc_error("illegal character 0x%02x", i); 1391 bc_error_fmt("illegal character 0x%02x", i);
1353 bad_chars = 1; 1392 bad_chars = 1;
1354 } 1393 }
1355 c = (char) i; 1394 c = (char) i;
@@ -3214,7 +3253,7 @@ static BcStatus bc_lex_token(BcLex *l)
3214 } 3253 }
3215 else { 3254 else {
3216 l->t.t = BC_LEX_INVALID; 3255 l->t.t = BC_LEX_INVALID;
3217 s = bc_error("bad character '%c'", '&'); 3256 s = bc_error_bad_character('&');
3218 } 3257 }
3219 3258
3220 break; 3259 break;
@@ -3343,7 +3382,7 @@ static BcStatus bc_lex_token(BcLex *l)
3343 ++l->i; 3382 ++l->i;
3344 } 3383 }
3345 else 3384 else
3346 s = bc_error("bad character '%c'", c); 3385 s = bc_error_bad_character(c);
3347 break; 3386 break;
3348 } 3387 }
3349 3388
@@ -3404,7 +3443,7 @@ static BcStatus bc_lex_token(BcLex *l)
3404 } 3443 }
3405 else { 3444 else {
3406 l->t.t = BC_LEX_INVALID; 3445 l->t.t = BC_LEX_INVALID;
3407 s = bc_error("bad character '%c'", c); 3446 s = bc_error_bad_character(c);
3408 } 3447 }
3409 3448
3410 break; 3449 break;
@@ -3413,7 +3452,7 @@ static BcStatus bc_lex_token(BcLex *l)
3413 default: 3452 default:
3414 { 3453 {
3415 l->t.t = BC_LEX_INVALID; 3454 l->t.t = BC_LEX_INVALID;
3416 s = bc_error("bad character '%c'", c); 3455 s = bc_error_bad_character(c);
3417 break; 3456 break;
3418 } 3457 }
3419 } 3458 }
@@ -3526,7 +3565,7 @@ static BcStatus dc_lex_token(BcLex *l)
3526 else if (c2 == '>') 3565 else if (c2 == '>')
3527 l->t.t = BC_LEX_OP_REL_GE; 3566 l->t.t = BC_LEX_OP_REL_GE;
3528 else 3567 else
3529 return bc_error("bad character '%c'", c); 3568 return bc_error_bad_character(c);
3530 3569
3531 ++l->i; 3570 ++l->i;
3532 break; 3571 break;
@@ -3543,7 +3582,7 @@ static BcStatus dc_lex_token(BcLex *l)
3543 if (isdigit(l->buf[l->i])) 3582 if (isdigit(l->buf[l->i]))
3544 s = bc_lex_number(l, c); 3583 s = bc_lex_number(l, c);
3545 else 3584 else
3546 s = bc_error("bad character '%c'", c); 3585 s = bc_error_bad_character(c);
3547 break; 3586 break;
3548 } 3587 }
3549 3588
@@ -3577,7 +3616,7 @@ static BcStatus dc_lex_token(BcLex *l)
3577 default: 3616 default:
3578 { 3617 {
3579 l->t.t = BC_LEX_INVALID; 3618 l->t.t = BC_LEX_INVALID;
3580 s = bc_error("bad character '%c'", c); 3619 s = bc_error_bad_character(c);
3581 break; 3620 break;
3582 } 3621 }
3583 } 3622 }
@@ -3733,7 +3772,7 @@ static BcStatus bc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3733 BcLexType top; 3772 BcLexType top;
3734 3773
3735 if (p->ops.len <= ops_bgn) 3774 if (p->ops.len <= ops_bgn)
3736 return bc_error("bad expression"); 3775 return bc_error_bad_expression();
3737 top = BC_PARSE_TOP_OP(p); 3776 top = BC_PARSE_TOP_OP(p);
3738 3777
3739 while (top != BC_LEX_LPAREN) { 3778 while (top != BC_LEX_LPAREN) {
@@ -3744,7 +3783,7 @@ static BcStatus bc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3744 *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG; 3783 *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG;
3745 3784
3746 if (p->ops.len <= ops_bgn) 3785 if (p->ops.len <= ops_bgn)
3747 return bc_error("bad expression"); 3786 return bc_error_bad_expression();
3748 top = BC_PARSE_TOP_OP(p); 3787 top = BC_PARSE_TOP_OP(p);
3749 } 3788 }
3750 3789
@@ -3775,7 +3814,7 @@ static BcStatus bc_parse_params(BcParse *p, uint8_t flags)
3775 } 3814 }
3776 } 3815 }
3777 3816
3778 if (comma) return bc_error("bad token"); 3817 if (comma) return bc_error_bad_token();
3779 bc_parse_push(p, BC_INST_CALL); 3818 bc_parse_push(p, BC_INST_CALL);
3780 bc_parse_pushIndex(p, nparams); 3819 bc_parse_pushIndex(p, nparams);
3781 3820
@@ -3794,7 +3833,7 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags)
3794 if (s) goto err; 3833 if (s) goto err;
3795 3834
3796 if (p->l.t.t != BC_LEX_RPAREN) { 3835 if (p->l.t.t != BC_LEX_RPAREN) {
3797 s = bc_error("bad token"); 3836 s = bc_error_bad_token();
3798 goto err; 3837 goto err;
3799 } 3838 }
3800 3839
@@ -3836,7 +3875,7 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3836 if (p->l.t.t == BC_LEX_RBRACKET) { 3875 if (p->l.t.t == BC_LEX_RBRACKET) {
3837 3876
3838 if (!(flags & BC_PARSE_ARRAY)) { 3877 if (!(flags & BC_PARSE_ARRAY)) {
3839 s = bc_error("bad expression"); 3878 s = bc_error_bad_expression();
3840 goto err; 3879 goto err;
3841 } 3880 }
3842 3881
@@ -3859,7 +3898,7 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3859 else if (p->l.t.t == BC_LEX_LPAREN) { 3898 else if (p->l.t.t == BC_LEX_LPAREN) {
3860 3899
3861 if (flags & BC_PARSE_NOCALL) { 3900 if (flags & BC_PARSE_NOCALL) {
3862 s = bc_error("bad token"); 3901 s = bc_error_bad_token();
3863 goto err; 3902 goto err;
3864 } 3903 }
3865 3904
@@ -3885,11 +3924,11 @@ static BcStatus bc_parse_read(BcParse *p)
3885 3924
3886 s = bc_lex_next(&p->l); 3925 s = bc_lex_next(&p->l);
3887 if (s) return s; 3926 if (s) return s;
3888 if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); 3927 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
3889 3928
3890 s = bc_lex_next(&p->l); 3929 s = bc_lex_next(&p->l);
3891 if (s) return s; 3930 if (s) return s;
3892 if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); 3931 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
3893 3932
3894 bc_parse_push(p, BC_INST_READ); 3933 bc_parse_push(p, BC_INST_READ);
3895 3934
@@ -3903,7 +3942,7 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
3903 3942
3904 s = bc_lex_next(&p->l); 3943 s = bc_lex_next(&p->l);
3905 if (s) return s; 3944 if (s) return s;
3906 if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); 3945 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
3907 3946
3908 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3947 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3909 3948
@@ -3913,7 +3952,7 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
3913 s = bc_parse_expr(p, flags, bc_parse_next_rel); 3952 s = bc_parse_expr(p, flags, bc_parse_next_rel);
3914 if (s) return s; 3953 if (s) return s;
3915 3954
3916 if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); 3955 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
3917 3956
3918 *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT; 3957 *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT;
3919 bc_parse_push(p, *prev); 3958 bc_parse_push(p, *prev);
@@ -3942,7 +3981,7 @@ static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags)
3942 3981
3943 s = bc_parse_expr(p, flags, bc_parse_next_rel); 3982 s = bc_parse_expr(p, flags, bc_parse_next_rel);
3944 if (s) return s; 3983 if (s) return s;
3945 if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); 3984 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
3946 bc_parse_push(p, BC_INST_SCALE_FUNC); 3985 bc_parse_push(p, BC_INST_SCALE_FUNC);
3947 3986
3948 return bc_lex_next(&p->l); 3987 return bc_lex_next(&p->l);
@@ -3999,7 +4038,7 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
3999 s = bc_lex_next(&p->l); 4038 s = bc_lex_next(&p->l);
4000 if (s) return s; 4039 if (s) return s;
4001 if (p->l.t.t == BC_LEX_LPAREN) 4040 if (p->l.t.t == BC_LEX_LPAREN)
4002 s = bc_error("bad token"); 4041 s = bc_error_bad_token();
4003 else 4042 else
4004 bc_parse_push(p, BC_INST_SCALE); 4043 bc_parse_push(p, BC_INST_SCALE);
4005 break; 4044 break;
@@ -4007,7 +4046,7 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
4007 4046
4008 default: 4047 default:
4009 { 4048 {
4010 s = bc_error("bad token"); 4049 s = bc_error_bad_token();
4011 break; 4050 break;
4012 } 4051 }
4013 } 4052 }
@@ -4088,7 +4127,7 @@ static BcStatus bc_parse_print(BcParse *p)
4088 } 4127 }
4089 4128
4090 if (s) return s; 4129 if (s) return s;
4091 if (comma) return bc_error("bad token"); 4130 if (comma) return bc_error_bad_token();
4092 4131
4093 return bc_lex_next(&p->l); 4132 return bc_lex_next(&p->l);
4094} 4133}
@@ -4099,7 +4138,7 @@ static BcStatus bc_parse_return(BcParse *p)
4099 BcLexType t; 4138 BcLexType t;
4100 bool paren; 4139 bool paren;
4101 4140
4102 if (!BC_PARSE_FUNC(p)) return bc_error("bad token"); 4141 if (!BC_PARSE_FUNC(p)) return bc_error_bad_token();
4103 4142
4104 s = bc_lex_next(&p->l); 4143 s = bc_lex_next(&p->l);
4105 if (s) return s; 4144 if (s) return s;
@@ -4137,18 +4176,18 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace)
4137 BcStatus s = BC_STATUS_SUCCESS; 4176 BcStatus s = BC_STATUS_SUCCESS;
4138 4177
4139 if (p->flags.len <= 1 || (brace && p->nbraces == 0)) 4178 if (p->flags.len <= 1 || (brace && p->nbraces == 0))
4140 return bc_error("bad token"); 4179 return bc_error_bad_token();
4141 4180
4142 if (brace) { 4181 if (brace) {
4143 4182
4144 if (p->l.t.t == BC_LEX_RBRACE) { 4183 if (p->l.t.t == BC_LEX_RBRACE) {
4145 if (!p->nbraces) return bc_error("bad token"); 4184 if (!p->nbraces) return bc_error_bad_token();
4146 --p->nbraces; 4185 --p->nbraces;
4147 s = bc_lex_next(&p->l); 4186 s = bc_lex_next(&p->l);
4148 if (s) return s; 4187 if (s) return s;
4149 } 4188 }
4150 else 4189 else
4151 return bc_error("bad token"); 4190 return bc_error_bad_token();
4152 } 4191 }
4153 4192
4154 if (BC_PARSE_IF(p)) { 4193 if (BC_PARSE_IF(p)) {
@@ -4234,13 +4273,13 @@ static BcStatus bc_parse_if(BcParse *p)
4234 4273
4235 s = bc_lex_next(&p->l); 4274 s = bc_lex_next(&p->l);
4236 if (s) return s; 4275 if (s) return s;
4237 if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); 4276 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
4238 4277
4239 s = bc_lex_next(&p->l); 4278 s = bc_lex_next(&p->l);
4240 if (s) return s; 4279 if (s) return s;
4241 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); 4280 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
4242 if (s) return s; 4281 if (s) return s;
4243 if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); 4282 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
4244 4283
4245 s = bc_lex_next(&p->l); 4284 s = bc_lex_next(&p->l);
4246 if (s) return s; 4285 if (s) return s;
@@ -4261,7 +4300,7 @@ static BcStatus bc_parse_else(BcParse *p)
4261{ 4300{
4262 BcInstPtr ip; 4301 BcInstPtr ip;
4263 4302
4264 if (!BC_PARSE_IF_END(p)) return bc_error("bad token"); 4303 if (!BC_PARSE_IF_END(p)) return bc_error_bad_token();
4265 4304
4266 ip.idx = p->func->labels.len; 4305 ip.idx = p->func->labels.len;
4267 ip.func = ip.len = 0; 4306 ip.func = ip.len = 0;
@@ -4285,7 +4324,7 @@ static BcStatus bc_parse_while(BcParse *p)
4285 4324
4286 s = bc_lex_next(&p->l); 4325 s = bc_lex_next(&p->l);
4287 if (s) return s; 4326 if (s) return s;
4288 if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); 4327 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
4289 s = bc_lex_next(&p->l); 4328 s = bc_lex_next(&p->l);
4290 if (s) return s; 4329 if (s) return s;
4291 4330
@@ -4303,7 +4342,7 @@ static BcStatus bc_parse_while(BcParse *p)
4303 4342
4304 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); 4343 s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel);
4305 if (s) return s; 4344 if (s) return s;
4306 if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); 4345 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
4307 s = bc_lex_next(&p->l); 4346 s = bc_lex_next(&p->l);
4308 if (s) return s; 4347 if (s) return s;
4309 4348
@@ -4322,7 +4361,7 @@ static BcStatus bc_parse_for(BcParse *p)
4322 4361
4323 s = bc_lex_next(&p->l); 4362 s = bc_lex_next(&p->l);
4324 if (s) return s; 4363 if (s) return s;
4325 if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); 4364 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token();
4326 s = bc_lex_next(&p->l); 4365 s = bc_lex_next(&p->l);
4327 if (s) return s; 4366 if (s) return s;
4328 4367
@@ -4332,7 +4371,7 @@ static BcStatus bc_parse_for(BcParse *p)
4332 s = bc_posix_error("POSIX does not allow an empty init expression in a for loop"); 4371 s = bc_posix_error("POSIX does not allow an empty init expression in a for loop");
4333 4372
4334 if (s) return s; 4373 if (s) return s;
4335 if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); 4374 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token();
4336 s = bc_lex_next(&p->l); 4375 s = bc_lex_next(&p->l);
4337 if (s) return s; 4376 if (s) return s;
4338 4377
@@ -4349,7 +4388,7 @@ static BcStatus bc_parse_for(BcParse *p)
4349 s = bc_posix_error("POSIX does not allow an empty condition expression in a for loop"); 4388 s = bc_posix_error("POSIX does not allow an empty condition expression in a for loop");
4350 4389
4351 if (s) return s; 4390 if (s) return s;
4352 if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); 4391 if (p->l.t.t != BC_LEX_SCOLON) return bc_error_bad_token();
4353 4392
4354 s = bc_lex_next(&p->l); 4393 s = bc_lex_next(&p->l);
4355 if (s) return s; 4394 if (s) return s;
@@ -4371,7 +4410,7 @@ static BcStatus bc_parse_for(BcParse *p)
4371 4410
4372 if (s) return s; 4411 if (s) return s;
4373 4412
4374 if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); 4413 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token();
4375 bc_parse_push(p, BC_INST_JUMP); 4414 bc_parse_push(p, BC_INST_JUMP);
4376 bc_parse_pushIndex(p, cond_idx); 4415 bc_parse_pushIndex(p, cond_idx);
4377 bc_vec_push(&p->func->labels, &p->func->code.len); 4416 bc_vec_push(&p->func->labels, &p->func->code.len);
@@ -4394,17 +4433,17 @@ static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type)
4394 size_t i; 4433 size_t i;
4395 BcInstPtr *ip; 4434 BcInstPtr *ip;
4396 4435
4397 if (!BC_PARSE_LOOP(p)) return bc_error("bad token"); 4436 if (!BC_PARSE_LOOP(p)) return bc_error_bad_token();
4398 4437
4399 if (type == BC_LEX_KEY_BREAK) { 4438 if (type == BC_LEX_KEY_BREAK) {
4400 4439
4401 if (p->exits.len == 0) return bc_error("bad token"); 4440 if (p->exits.len == 0) return bc_error_bad_token();
4402 4441
4403 i = p->exits.len - 1; 4442 i = p->exits.len - 1;
4404 ip = bc_vec_item(&p->exits, i); 4443 ip = bc_vec_item(&p->exits, i);
4405 4444
4406 while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--); 4445 while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--);
4407 if (i >= p->exits.len && !ip->func) return bc_error("bad token"); 4446 if (i >= p->exits.len && !ip->func) return bc_error_bad_token();
4408 4447
4409 i = ip->idx; 4448 i = ip->idx;
4410 } 4449 }
@@ -4418,7 +4457,7 @@ static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type)
4418 if (s) return s; 4457 if (s) return s;
4419 4458
4420 if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE) 4459 if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE)
4421 return bc_error("bad token"); 4460 return bc_error_bad_token();
4422 4461
4423 return bc_lex_next(&p->l); 4462 return bc_lex_next(&p->l);
4424} 4463}
@@ -4506,7 +4545,7 @@ static BcStatus bc_parse_auto(BcParse *p)
4506 bool comma, var, one; 4545 bool comma, var, one;
4507 char *name; 4546 char *name;
4508 4547
4509 if (!p->auto_part) return bc_error("bad token"); 4548 if (!p->auto_part) return bc_error_bad_token();
4510 s = bc_lex_next(&p->l); 4549 s = bc_lex_next(&p->l);
4511 if (s) return s; 4550 if (s) return s;
4512 4551
@@ -4548,7 +4587,7 @@ static BcStatus bc_parse_auto(BcParse *p)
4548 if (!one) return bc_error("no auto variable found"); 4587 if (!one) return bc_error("no auto variable found");
4549 4588
4550 if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON) 4589 if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON)
4551 return bc_error("bad token"); 4590 return bc_error_bad_token();
4552 4591
4553 return bc_lex_next(&p->l); 4592 return bc_lex_next(&p->l);
4554 4593
@@ -4566,7 +4605,7 @@ static BcStatus bc_parse_body(BcParse *p, bool brace)
4566 4605
4567 if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) { 4606 if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) {
4568 4607
4569 if (!brace) return bc_error("bad token"); 4608 if (!brace) return bc_error_bad_token();
4570 p->auto_part = p->l.t.t != BC_LEX_KEY_AUTO; 4609 p->auto_part = p->l.t.t != BC_LEX_KEY_AUTO;
4571 4610
4572 if (!p->auto_part) { 4611 if (!p->auto_part) {
@@ -4603,7 +4642,7 @@ static BcStatus bc_parse_stmt(BcParse *p)
4603 4642
4604 case BC_LEX_LBRACE: 4643 case BC_LEX_LBRACE:
4605 { 4644 {
4606 if (!BC_PARSE_BODY(p)) return bc_error("bad token"); 4645 if (!BC_PARSE_BODY(p)) return bc_error_bad_token();
4607 4646
4608 ++p->nbraces; 4647 ++p->nbraces;
4609 s = bc_lex_next(&p->l); 4648 s = bc_lex_next(&p->l);
@@ -4748,7 +4787,7 @@ static BcStatus bc_parse_stmt(BcParse *p)
4748 4787
4749 default: 4788 default:
4750 { 4789 {
4751 s = bc_error("bad token"); 4790 s = bc_error_bad_token();
4752 break; 4791 break;
4753 } 4792 }
4754 } 4793 }
@@ -4763,7 +4802,7 @@ static BcStatus bc_parse_parse(BcParse *p)
4763 if (p->l.t.t == BC_LEX_EOF) 4802 if (p->l.t.t == BC_LEX_EOF)
4764 s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file"); 4803 s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file");
4765 else if (p->l.t.t == BC_LEX_KEY_DEFINE) { 4804 else if (p->l.t.t == BC_LEX_KEY_DEFINE) {
4766 if (!BC_PARSE_CAN_EXEC(p)) return bc_error("bad token"); 4805 if (!BC_PARSE_CAN_EXEC(p)) return bc_error_bad_token();
4767 s = bc_parse_func(p); 4806 s = bc_parse_func(p);
4768 } 4807 }
4769 else 4808 else
@@ -4849,7 +4888,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4849 if (((t == BC_LEX_OP_BOOL_NOT) != bin_last) 4888 if (((t == BC_LEX_OP_BOOL_NOT) != bin_last)
4850 || (t != BC_LEX_OP_BOOL_NOT && prev == BC_INST_BOOL_NOT) 4889 || (t != BC_LEX_OP_BOOL_NOT && prev == BC_INST_BOOL_NOT)
4851 ) { 4890 ) {
4852 return bc_error("bad expression"); 4891 return bc_error_bad_expression();
4853 } 4892 }
4854 4893
4855 nrelops += t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT; 4894 nrelops += t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT;
@@ -4864,7 +4903,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4864 case BC_LEX_LPAREN: 4903 case BC_LEX_LPAREN:
4865 { 4904 {
4866 if (BC_PARSE_LEAF(prev, rprn)) 4905 if (BC_PARSE_LEAF(prev, rprn))
4867 return bc_error("bad expression"); 4906 return bc_error_bad_expression();
4868 ++nparens; 4907 ++nparens;
4869 paren_expr = rprn = bin_last = false; 4908 paren_expr = rprn = bin_last = false;
4870 get_token = true; 4909 get_token = true;
@@ -4876,7 +4915,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4876 case BC_LEX_RPAREN: 4915 case BC_LEX_RPAREN:
4877 { 4916 {
4878 if (bin_last || prev == BC_INST_BOOL_NOT) 4917 if (bin_last || prev == BC_INST_BOOL_NOT)
4879 return bc_error("bad expression"); 4918 return bc_error_bad_expression();
4880 4919
4881 if (nparens == 0) { 4920 if (nparens == 0) {
4882 s = BC_STATUS_SUCCESS; 4921 s = BC_STATUS_SUCCESS;
@@ -4899,7 +4938,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4899 case BC_LEX_NAME: 4938 case BC_LEX_NAME:
4900 { 4939 {
4901 if (BC_PARSE_LEAF(prev, rprn)) 4940 if (BC_PARSE_LEAF(prev, rprn))
4902 return bc_error("bad expression"); 4941 return bc_error_bad_expression();
4903 paren_expr = true; 4942 paren_expr = true;
4904 rprn = get_token = bin_last = false; 4943 rprn = get_token = bin_last = false;
4905 s = bc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL); 4944 s = bc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL);
@@ -4911,7 +4950,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4911 case BC_LEX_NUMBER: 4950 case BC_LEX_NUMBER:
4912 { 4951 {
4913 if (BC_PARSE_LEAF(prev, rprn)) 4952 if (BC_PARSE_LEAF(prev, rprn))
4914 return bc_error("bad expression"); 4953 return bc_error_bad_expression();
4915 bc_parse_number(p, &prev, &nexprs); 4954 bc_parse_number(p, &prev, &nexprs);
4916 paren_expr = get_token = true; 4955 paren_expr = get_token = true;
4917 rprn = bin_last = false; 4956 rprn = bin_last = false;
@@ -4924,7 +4963,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4924 case BC_LEX_KEY_OBASE: 4963 case BC_LEX_KEY_OBASE:
4925 { 4964 {
4926 if (BC_PARSE_LEAF(prev, rprn)) 4965 if (BC_PARSE_LEAF(prev, rprn))
4927 return bc_error("bad expression"); 4966 return bc_error_bad_expression();
4928 prev = (char) (t - BC_LEX_KEY_IBASE + BC_INST_IBASE); 4967 prev = (char) (t - BC_LEX_KEY_IBASE + BC_INST_IBASE);
4929 bc_parse_push(p, (char) prev); 4968 bc_parse_push(p, (char) prev);
4930 4969
@@ -4939,7 +4978,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4939 case BC_LEX_KEY_SQRT: 4978 case BC_LEX_KEY_SQRT:
4940 { 4979 {
4941 if (BC_PARSE_LEAF(prev, rprn)) 4980 if (BC_PARSE_LEAF(prev, rprn))
4942 return bc_error("bad expression"); 4981 return bc_error_bad_expression();
4943 s = bc_parse_builtin(p, t, flags, &prev); 4982 s = bc_parse_builtin(p, t, flags, &prev);
4944 paren_expr = true; 4983 paren_expr = true;
4945 rprn = get_token = bin_last = false; 4984 rprn = get_token = bin_last = false;
@@ -4951,9 +4990,9 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4951 case BC_LEX_KEY_READ: 4990 case BC_LEX_KEY_READ:
4952 { 4991 {
4953 if (BC_PARSE_LEAF(prev, rprn)) 4992 if (BC_PARSE_LEAF(prev, rprn))
4954 return bc_error("bad expression"); 4993 return bc_error_bad_expression();
4955 else if (flags & BC_PARSE_NOREAD) 4994 else if (flags & BC_PARSE_NOREAD)
4956 s = bc_error("read() call inside of a read() call"); 4995 s = bc_error_nested_read_call();
4957 else 4996 else
4958 s = bc_parse_read(p); 4997 s = bc_parse_read(p);
4959 4998
@@ -4968,7 +5007,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4968 case BC_LEX_KEY_SCALE: 5007 case BC_LEX_KEY_SCALE:
4969 { 5008 {
4970 if (BC_PARSE_LEAF(prev, rprn)) 5009 if (BC_PARSE_LEAF(prev, rprn))
4971 return bc_error("bad expression"); 5010 return bc_error_bad_expression();
4972 s = bc_parse_scale(p, &prev, flags); 5011 s = bc_parse_scale(p, &prev, flags);
4973 paren_expr = true; 5012 paren_expr = true;
4974 rprn = get_token = bin_last = false; 5013 rprn = get_token = bin_last = false;
@@ -4980,7 +5019,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4980 5019
4981 default: 5020 default:
4982 { 5021 {
4983 s = bc_error("bad token"); 5022 s = bc_error_bad_token();
4984 break; 5023 break;
4985 } 5024 }
4986 } 5025 }
@@ -4997,7 +5036,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4997 assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN; 5036 assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN;
4998 5037
4999 if (top == BC_LEX_LPAREN || top == BC_LEX_RPAREN) 5038 if (top == BC_LEX_LPAREN || top == BC_LEX_RPAREN)
5000 return bc_error("bad expression"); 5039 return bc_error_bad_expression();
5001 5040
5002 bc_parse_push(p, BC_PARSE_TOKEN_INST(top)); 5041 bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
5003 5042
@@ -5006,12 +5045,12 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
5006 } 5045 }
5007 5046
5008 if (prev == BC_INST_BOOL_NOT || nexprs != 1) 5047 if (prev == BC_INST_BOOL_NOT || nexprs != 1)
5009 return bc_error("bad expression"); 5048 return bc_error_bad_expression();
5010 5049
5011 for (i = 0; i < next.len; ++i) 5050 for (i = 0; i < next.len; ++i)
5012 if (t == next.tokens[i]) 5051 if (t == next.tokens[i])
5013 goto ok; 5052 goto ok;
5014 return bc_error("bad expression"); 5053 return bc_error_bad_expression();
5015 ok: 5054 ok:
5016 5055
5017 if (!(flags & BC_PARSE_REL) && nrelops) { 5056 if (!(flags & BC_PARSE_REL) && nrelops) {
@@ -5050,7 +5089,7 @@ static BcStatus dc_parse_register(BcParse *p)
5050 5089
5051 s = bc_lex_next(&p->l); 5090 s = bc_lex_next(&p->l);
5052 if (s) return s; 5091 if (s) return s;
5053 if (p->l.t.t != BC_LEX_NAME) return bc_error("bad token"); 5092 if (p->l.t.t != BC_LEX_NAME) return bc_error_bad_token();
5054 5093
5055 name = xstrdup(p->l.t.v.v); 5094 name = xstrdup(p->l.t.v.v);
5056 bc_parse_pushName(p, name); 5095 bc_parse_pushName(p, name);
@@ -5158,7 +5197,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags)
5158 s = bc_lex_next(&p->l); 5197 s = bc_lex_next(&p->l);
5159 if (s) return s; 5198 if (s) return s;
5160 if (p->l.t.t != BC_LEX_NUMBER) 5199 if (p->l.t.t != BC_LEX_NUMBER)
5161 return bc_error("bad token"); 5200 return bc_error_bad_token();
5162 } 5201 }
5163 5202
5164 bc_parse_number(p, &prev, &p->nbraces); 5203 bc_parse_number(p, &prev, &p->nbraces);
@@ -5172,7 +5211,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags)
5172 case BC_LEX_KEY_READ: 5211 case BC_LEX_KEY_READ:
5173 { 5212 {
5174 if (flags & BC_PARSE_NOREAD) 5213 if (flags & BC_PARSE_NOREAD)
5175 s = bc_error("read() call inside of a read() call"); 5214 s = bc_error_nested_read_call();
5176 else 5215 else
5177 bc_parse_push(p, BC_INST_READ); 5216 bc_parse_push(p, BC_INST_READ);
5178 get_token = true; 5217 get_token = true;
@@ -5207,7 +5246,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags)
5207 5246
5208 default: 5247 default:
5209 { 5248 {
5210 s = bc_error("bad token"); 5249 s = bc_error_bad_token();
5211 get_token = true; 5250 get_token = true;
5212 break; 5251 break;
5213 } 5252 }
@@ -5393,7 +5432,7 @@ static BcStatus bc_program_binOpPrep(BcResult **l, BcNum **ln,
5393 BcResultType lt, rt; 5432 BcResultType lt, rt;
5394 5433
5395 if (!BC_PROG_STACK(&G.prog.results, 2)) 5434 if (!BC_PROG_STACK(&G.prog.results, 2))
5396 return bc_error("stack has too few elements"); 5435 return bc_error_stack_has_too_few_elements();
5397 5436
5398 *r = bc_vec_item_rev(&G.prog.results, 0); 5437 *r = bc_vec_item_rev(&G.prog.results, 0);
5399 *l = bc_vec_item_rev(&G.prog.results, 1); 5438 *l = bc_vec_item_rev(&G.prog.results, 1);
@@ -5415,9 +5454,9 @@ static BcStatus bc_program_binOpPrep(BcResult **l, BcNum **ln,
5415 } 5454 }
5416 5455
5417 if (!BC_PROG_NUM((*l), (*ln)) && (!assign || (*l)->t != BC_RESULT_VAR)) 5456 if (!BC_PROG_NUM((*l), (*ln)) && (!assign || (*l)->t != BC_RESULT_VAR))
5418 return bc_error("variable is wrong type"); 5457 return bc_error_variable_is_wrong_type();
5419 if (!assign && !BC_PROG_NUM((*r), (*ln))) 5458 if (!assign && !BC_PROG_NUM((*r), (*ln)))
5420 return bc_error("variable is wrong type"); 5459 return bc_error_variable_is_wrong_type();
5421 5460
5422 return s; 5461 return s;
5423} 5462}
@@ -5435,14 +5474,14 @@ static BcStatus bc_program_prep(BcResult **r, BcNum **n)
5435 BcStatus s; 5474 BcStatus s;
5436 5475
5437 if (!BC_PROG_STACK(&G.prog.results, 1)) 5476 if (!BC_PROG_STACK(&G.prog.results, 1))
5438 return bc_error("stack has too few elements"); 5477 return bc_error_stack_has_too_few_elements();
5439 *r = bc_vec_top(&G.prog.results); 5478 *r = bc_vec_top(&G.prog.results);
5440 5479
5441 s = bc_program_num(*r, n, false); 5480 s = bc_program_num(*r, n, false);
5442 if (s) return s; 5481 if (s) return s;
5443 5482
5444 if (!BC_PROG_NUM((*r), (*n))) 5483 if (!BC_PROG_NUM((*r), (*n)))
5445 return bc_error("variable is wrong type"); 5484 return bc_error_variable_is_wrong_type();
5446 5485
5447 return s; 5486 return s;
5448} 5487}
@@ -5487,7 +5526,7 @@ static BcStatus bc_program_read(void)
5487 for (i = 0; i < G.prog.stack.len; ++i) { 5526 for (i = 0; i < G.prog.stack.len; ++i) {
5488 BcInstPtr *ip_ptr = bc_vec_item(&G.prog.stack, i); 5527 BcInstPtr *ip_ptr = bc_vec_item(&G.prog.stack, i);
5489 if (ip_ptr->func == BC_PROG_READ) 5528 if (ip_ptr->func == BC_PROG_READ)
5490 return bc_error("read() call inside of a read() call"); 5529 return bc_error_nested_read_call();
5491 } 5530 }
5492 5531
5493 bc_vec_pop_all(&f->code); 5532 bc_vec_pop_all(&f->code);
@@ -5649,7 +5688,7 @@ static BcStatus bc_program_print(char inst, size_t idx)
5649 bool pop = inst != BC_INST_PRINT; 5688 bool pop = inst != BC_INST_PRINT;
5650 5689
5651 if (!BC_PROG_STACK(&G.prog.results, idx + 1)) 5690 if (!BC_PROG_STACK(&G.prog.results, idx + 1))
5652 return bc_error("stack has too few elements"); 5691 return bc_error_stack_has_too_few_elements();
5653 5692
5654 r = bc_vec_item_rev(&G.prog.results, idx); 5693 r = bc_vec_item_rev(&G.prog.results, idx);
5655 s = bc_program_num(r, &num, false); 5694 s = bc_program_num(r, &num, false);
@@ -5781,7 +5820,7 @@ static BcStatus bc_program_assignStr(BcResult *r, BcVec *v,
5781 5820
5782 if (!push) { 5821 if (!push) {
5783 if (!BC_PROG_STACK(&G.prog.results, 2)) 5822 if (!BC_PROG_STACK(&G.prog.results, 2))
5784 return bc_error("stack has too few elements"); 5823 return bc_error_stack_has_too_few_elements();
5785 bc_vec_pop(v); 5824 bc_vec_pop(v);
5786 bc_vec_pop(&G.prog.results); 5825 bc_vec_pop(&G.prog.results);
5787 } 5826 }
@@ -5803,16 +5842,16 @@ static BcStatus bc_program_copyToVar(char *name, bool var)
5803 BcNum *n; 5842 BcNum *n;
5804 5843
5805 if (!BC_PROG_STACK(&G.prog.results, 1)) 5844 if (!BC_PROG_STACK(&G.prog.results, 1))
5806 return bc_error("stack has too few elements"); 5845 return bc_error_stack_has_too_few_elements();
5807 5846
5808 ptr = bc_vec_top(&G.prog.results); 5847 ptr = bc_vec_top(&G.prog.results);
5809 if ((ptr->t == BC_RESULT_ARRAY) != !var) 5848 if ((ptr->t == BC_RESULT_ARRAY) != !var)
5810 return bc_error("variable is wrong type"); 5849 return bc_error_variable_is_wrong_type();
5811 v = bc_program_search(name, var); 5850 v = bc_program_search(name, var);
5812 5851
5813#if ENABLE_DC 5852#if ENABLE_DC
5814 if (ptr->t == BC_RESULT_STR && !var) 5853 if (ptr->t == BC_RESULT_STR && !var)
5815 return bc_error("variable is wrong type"); 5854 return bc_error_variable_is_wrong_type();
5816 if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(ptr, v, true); 5855 if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(ptr, v, true);
5817#endif 5856#endif
5818 5857
@@ -5858,7 +5897,7 @@ static BcStatus bc_program_assign(char inst)
5858 BcVec *v; 5897 BcVec *v;
5859 5898
5860 if (left->t != BC_RESULT_VAR) 5899 if (left->t != BC_RESULT_VAR)
5861 return bc_error("variable is wrong type"); 5900 return bc_error_variable_is_wrong_type();
5862 v = bc_program_search(left->d.id.name, true); 5901 v = bc_program_search(left->d.id.name, true);
5863 5902
5864 return bc_program_assignStr(right, v, false); 5903 return bc_program_assignStr(right, v, false);
@@ -5952,7 +5991,7 @@ static BcStatus bc_program_pushVar(char *code, size_t *bgn,
5952 5991
5953 if (!BC_PROG_STACK(v, 2 - copy)) { 5992 if (!BC_PROG_STACK(v, 2 - copy)) {
5954 free(name); 5993 free(name);
5955 return bc_error("stack has too few elements"); 5994 return bc_error_stack_has_too_few_elements();
5956 } 5995 }
5957 5996
5958 free(name); 5997 free(name);
@@ -6068,7 +6107,7 @@ static BcStatus bc_program_call(char *code, size_t *idx)
6068 return bc_error("undefined function"); 6107 return bc_error("undefined function");
6069 } 6108 }
6070 if (nparams != func->nparams) { 6109 if (nparams != func->nparams) {
6071 return bc_error("function has %u parameters, but called with %u", func->nparams, nparams); 6110 return bc_error_fmt("function has %u parameters, but called with %u", func->nparams, nparams);
6072 } 6111 }
6073 ip.len = G.prog.results.len - nparams; 6112 ip.len = G.prog.results.len - nparams;
6074 6113
@@ -6078,7 +6117,7 @@ static BcStatus bc_program_call(char *code, size_t *idx)
6078 arg = bc_vec_top(&G.prog.results); 6117 arg = bc_vec_top(&G.prog.results);
6079 6118
6080 if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR) 6119 if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR)
6081 return bc_error("variable is wrong type"); 6120 return bc_error_variable_is_wrong_type();
6082 6121
6083 s = bc_program_copyToVar(a->name, a->idx); 6122 s = bc_program_copyToVar(a->name, a->idx);
6084 if (s) return s; 6123 if (s) return s;
@@ -6114,7 +6153,7 @@ static BcStatus bc_program_return(char inst)
6114 BcInstPtr *ip = bc_vec_top(&G.prog.stack); 6153 BcInstPtr *ip = bc_vec_top(&G.prog.stack);
6115 6154
6116 if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET)) 6155 if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET))
6117 return bc_error("stack has too few elements"); 6156 return bc_error_stack_has_too_few_elements();
6118 6157
6119 f = bc_vec_item(&G.prog.fns, ip->func); 6158 f = bc_vec_item(&G.prog.fns, ip->func);
6120 res.t = BC_RESULT_TEMP; 6159 res.t = BC_RESULT_TEMP;
@@ -6177,7 +6216,7 @@ static BcStatus bc_program_builtin(char inst)
6177 bool len = inst == BC_INST_LENGTH; 6216 bool len = inst == BC_INST_LENGTH;
6178 6217
6179 if (!BC_PROG_STACK(&G.prog.results, 1)) 6218 if (!BC_PROG_STACK(&G.prog.results, 1))
6180 return bc_error("stack has too few elements"); 6219 return bc_error_stack_has_too_few_elements();
6181 opnd = bc_vec_top(&G.prog.results); 6220 opnd = bc_vec_top(&G.prog.results);
6182 6221
6183 s = bc_program_num(opnd, &num, false); 6222 s = bc_program_num(opnd, &num, false);
@@ -6185,7 +6224,7 @@ static BcStatus bc_program_builtin(char inst)
6185 6224
6186#if ENABLE_DC 6225#if ENABLE_DC
6187 if (!BC_PROG_NUM(opnd, num) && !len) 6226 if (!BC_PROG_NUM(opnd, num) && !len)
6188 return bc_error("variable is wrong type"); 6227 return bc_error_variable_is_wrong_type();
6189#endif 6228#endif
6190 6229
6191 bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); 6230 bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
@@ -6251,7 +6290,7 @@ static BcStatus bc_program_modexp(void)
6251 BcNum *n1, *n2, *n3; 6290 BcNum *n1, *n2, *n3;
6252 6291
6253 if (!BC_PROG_STACK(&G.prog.results, 3)) 6292 if (!BC_PROG_STACK(&G.prog.results, 3))
6254 return bc_error("stack has too few elements"); 6293 return bc_error_stack_has_too_few_elements();
6255 s = bc_program_binOpPrep(&r2, &n2, &r3, &n3, false); 6294 s = bc_program_binOpPrep(&r2, &n2, &r3, &n3, false);
6256 if (s) return s; 6295 if (s) return s;
6257 6296
@@ -6259,7 +6298,7 @@ static BcStatus bc_program_modexp(void)
6259 s = bc_program_num(r1, &n1, false); 6298 s = bc_program_num(r1, &n1, false);
6260 if (s) return s; 6299 if (s) return s;
6261 if (!BC_PROG_NUM(r1, n1)) 6300 if (!BC_PROG_NUM(r1, n1))
6262 return bc_error("variable is wrong type"); 6301 return bc_error_variable_is_wrong_type();
6263 6302
6264 // Make sure that the values have their pointers updated, if necessary. 6303 // Make sure that the values have their pointers updated, if necessary.
6265 if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) { 6304 if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) {
@@ -6311,7 +6350,7 @@ static BcStatus bc_program_asciify(void)
6311 unsigned long val; 6350 unsigned long val;
6312 6351
6313 if (!BC_PROG_STACK(&G.prog.results, 1)) 6352 if (!BC_PROG_STACK(&G.prog.results, 1))
6314 return bc_error("stack has too few elements"); 6353 return bc_error_stack_has_too_few_elements();
6315 r = bc_vec_top(&G.prog.results); 6354 r = bc_vec_top(&G.prog.results);
6316 6355
6317 s = bc_program_num(r, &num, false); 6356 s = bc_program_num(r, &num, false);
@@ -6380,7 +6419,7 @@ static BcStatus bc_program_printStream(void)
6380 char *str; 6419 char *str;
6381 6420
6382 if (!BC_PROG_STACK(&G.prog.results, 1)) 6421 if (!BC_PROG_STACK(&G.prog.results, 1))
6383 return bc_error("stack has too few elements"); 6422 return bc_error_stack_has_too_few_elements();
6384 r = bc_vec_top(&G.prog.results); 6423 r = bc_vec_top(&G.prog.results);
6385 6424
6386 s = bc_program_num(r, &n, false); 6425 s = bc_program_num(r, &n, false);
@@ -6412,7 +6451,7 @@ static BcStatus bc_program_nquit(void)
6412 bc_vec_pop(&G.prog.results); 6451 bc_vec_pop(&G.prog.results);
6413 6452
6414 if (G.prog.stack.len < val) 6453 if (G.prog.stack.len < val)
6415 return bc_error("stack has too few elements"); 6454 return bc_error_stack_has_too_few_elements();
6416 if (G.prog.stack.len == val) 6455 if (G.prog.stack.len == val)
6417 quit(); 6456 quit();
6418 6457
@@ -6435,7 +6474,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
6435 bool exec; 6474 bool exec;
6436 6475
6437 if (!BC_PROG_STACK(&G.prog.results, 1)) 6476 if (!BC_PROG_STACK(&G.prog.results, 1))
6438 return bc_error("stack has too few elements"); 6477 return bc_error_stack_has_too_few_elements();
6439 6478
6440 r = bc_vec_top(&G.prog.results); 6479 r = bc_vec_top(&G.prog.results);
6441 6480
@@ -6468,7 +6507,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
6468 6507
6469 if (!exec) goto exit; 6508 if (!exec) goto exit;
6470 if (!BC_PROG_STR(n)) { 6509 if (!BC_PROG_STR(n)) {
6471 s = bc_error("variable is wrong type"); 6510 s = bc_error_variable_is_wrong_type();
6472 goto exit; 6511 goto exit;
6473 } 6512 }
6474 6513
@@ -6500,7 +6539,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
6500 if (s) goto err; 6539 if (s) goto err;
6501 6540
6502 if (prs.l.t.t != BC_LEX_EOF) { 6541 if (prs.l.t.t != BC_LEX_EOF) {
6503 s = bc_error("bad expression"); 6542 s = bc_error_bad_expression();
6504 goto err; 6543 goto err;
6505 } 6544 }
6506 6545
@@ -6723,7 +6762,7 @@ static BcStatus bc_program_exec(void)
6723 case BC_INST_POP: 6762 case BC_INST_POP:
6724 { 6763 {
6725 if (!BC_PROG_STACK(&G.prog.results, 1)) 6764 if (!BC_PROG_STACK(&G.prog.results, 1))
6726 s = bc_error("stack has too few elements"); 6765 s = bc_error_stack_has_too_few_elements();
6727 else 6766 else
6728 bc_vec_pop(&G.prog.results); 6767 bc_vec_pop(&G.prog.results);
6729 break; 6768 break;
@@ -6836,7 +6875,7 @@ static BcStatus bc_program_exec(void)
6836 case BC_INST_DUPLICATE: 6875 case BC_INST_DUPLICATE:
6837 { 6876 {
6838 if (!BC_PROG_STACK(&G.prog.results, 1)) 6877 if (!BC_PROG_STACK(&G.prog.results, 1))
6839 return bc_error("stack has too few elements"); 6878 return bc_error_stack_has_too_few_elements();
6840 ptr = bc_vec_top(&G.prog.results); 6879 ptr = bc_vec_top(&G.prog.results);
6841 bc_result_copy(&r, ptr); 6880 bc_result_copy(&r, ptr);
6842 bc_vec_push(&G.prog.results, &r); 6881 bc_vec_push(&G.prog.results, &r);
@@ -6848,7 +6887,7 @@ static BcStatus bc_program_exec(void)
6848 BcResult *ptr2; 6887 BcResult *ptr2;
6849 6888
6850 if (!BC_PROG_STACK(&G.prog.results, 2)) 6889 if (!BC_PROG_STACK(&G.prog.results, 2))
6851 return bc_error("stack has too few elements"); 6890 return bc_error_stack_has_too_few_elements();
6852 6891
6853 ptr = bc_vec_item_rev(&G.prog.results, 0); 6892 ptr = bc_vec_item_rev(&G.prog.results, 0);
6854 ptr2 = bc_vec_item_rev(&G.prog.results, 1); 6893 ptr2 = bc_vec_item_rev(&G.prog.results, 1);
@@ -7009,7 +7048,7 @@ static BcStatus bc_vm_file(const char *file)
7009 7048
7010 G.prog.file = file; 7049 G.prog.file = file;
7011 data = bc_read_file(file); 7050 data = bc_read_file(file);
7012 if (!data) return bc_error("file '%s' is not text", file); 7051 if (!data) return bc_error_fmt("file '%s' is not text", file);
7013 7052
7014 bc_lex_file(&G.prs.l, file); 7053 bc_lex_file(&G.prs.l, file);
7015 s = bc_vm_process(data); 7054 s = bc_vm_process(data);
@@ -7019,7 +7058,7 @@ static BcStatus bc_vm_file(const char *file)
7019 ip = bc_vec_item(&G.prog.stack, 0); 7058 ip = bc_vec_item(&G.prog.stack, 0);
7020 7059
7021 if (main_func->code.len < ip->idx) 7060 if (main_func->code.len < ip->idx)
7022 s = bc_error("file '%s' is not executable", file); 7061 s = bc_error_fmt("file '%s' is not executable", file);
7023 7062
7024err: 7063err:
7025 free(data); 7064 free(data);