diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-04 20:05:28 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | 60cf747b6c234958387298068da658cfee9c42cb (patch) | |
tree | 1cd11d916fc420266dc11e98a9af867dcc7330d9 | |
parent | d38af48e0ae96fc4dc4a794ae8129372ed7c593f (diff) | |
download | busybox-w32-60cf747b6c234958387298068da658cfee9c42cb.tar.gz busybox-w32-60cf747b6c234958387298068da658cfee9c42cb.tar.bz2 busybox-w32-60cf747b6c234958387298068da658cfee9c42cb.zip |
bc: convert all non-POSIX BC_STATUS_foo codes
function old new delta
bc_program_asciify - 469 +469
bc_parse_parse 432 495 +63
dc_parse_expr 727 775 +48
bc_vm_run 1955 1995 +40
bc_program_num 1115 1147 +32
bc_program_binOpPrep 296 324 +28
static.msg - 24 +24
bc_parse_name 570 593 +23
bc_lex_token 1344 1367 +23
dc_lex_token 695 714 +19
bc_num_ulong 85 103 +18
bc_program_read 336 353 +17
dc_parse_parse 47 60 +13
bc_parse_stmt 2301 2313 +12
bc_parse_auto 291 302 +11
bc_program_prep 89 99 +10
bc_lex_next 71 81 +10
dc_parse_register 52 61 +9
bc_program_print 775 784 +9
bc_func_insert 89 98 +9
bc_program_assignStr 159 167 +8
bc_program_assign 476 484 +8
bc_parse_body 116 124 +8
bc_lex_name 83 91 +8
bc_program_pushVar 215 221 +6
bc_parse_text 141 147 +6
bc_num_shift 68 74 +6
bc_num_p 472 478 +6
bc_program_execStr 559 564 +5
bc_parse_else 139 143 +4
bc_lex_number 301 305 +4
bc_num_d 558 561 +3
bc_parse_endBody 422 424 +2
bc_num_r 231 230 -1
bc_program_copyToVar 343 340 -3
bc_program_call 372 367 -5
bc_parse_expr 2215 2210 -5
bc_program_modexp 763 756 -7
bc_err_msgs 164 60 -104
bc_program_pushArray 136 - -136
bc_program_exec 4453 4153 -300
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 31/7 up/down: 961/-561) Total: 400 bytes
text data bss dec hex filename
987766 485 7296 995547 f30db busybox_old
988258 485 7296 996039 f32c7 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 475 |
1 files changed, 271 insertions, 204 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index bd70670d5..7b20a94cc 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -168,8 +168,9 @@ | |||
168 | #include "libbb.h" | 168 | #include "libbb.h" |
169 | 169 | ||
170 | typedef enum BcStatus { | 170 | typedef enum BcStatus { |
171 | BC_STATUS_SUCCESS, | 171 | BC_STATUS_SUCCESS = 0, |
172 | BC_STATUS_FAILURE, | 172 | BC_STATUS_FAILURE = 1, |
173 | BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr() uses this | ||
173 | 174 | ||
174 | // BC_STATUS_ALLOC_ERR, | 175 | // BC_STATUS_ALLOC_ERR, |
175 | // BC_STATUS_INPUT_EOF, | 176 | // BC_STATUS_INPUT_EOF, |
@@ -177,48 +178,47 @@ typedef enum BcStatus { | |||
177 | // BC_STATUS_PATH_IS_DIR, | 178 | // BC_STATUS_PATH_IS_DIR, |
178 | 179 | ||
179 | // BC_STATUS_LEX_BAD_CHAR, | 180 | // BC_STATUS_LEX_BAD_CHAR, |
180 | BC_STATUS_LEX_NO_STRING_END, | 181 | // BC_STATUS_LEX_NO_STRING_END, |
181 | BC_STATUS_LEX_NO_COMMENT_END, | 182 | // BC_STATUS_LEX_NO_COMMENT_END, |
182 | BC_STATUS_LEX_EOF, | 183 | // BC_STATUS_LEX_EOF, |
183 | #if ENABLE_DC | 184 | #if ENABLE_DC |
184 | BC_STATUS_LEX_EXTENDED_REG, | 185 | // BC_STATUS_LEX_EXTENDED_REG, |
185 | #endif | 186 | #endif |
186 | BC_STATUS_PARSE_BAD_TOKEN, | 187 | // BC_STATUS_PARSE_BAD_TOKEN, |
187 | BC_STATUS_PARSE_BAD_EXP, | 188 | // BC_STATUS_PARSE_BAD_EXP, |
188 | BC_STATUS_PARSE_EMPTY_EXP, | 189 | // BC_STATUS_PARSE_BAD_PRINT, |
189 | BC_STATUS_PARSE_BAD_PRINT, | 190 | // BC_STATUS_PARSE_BAD_FUNC, |
190 | BC_STATUS_PARSE_BAD_FUNC, | 191 | // BC_STATUS_PARSE_BAD_ASSIGN, |
191 | BC_STATUS_PARSE_BAD_ASSIGN, | ||
192 | // BC_STATUS_PARSE_NO_AUTO, | 192 | // BC_STATUS_PARSE_NO_AUTO, |
193 | BC_STATUS_PARSE_DUPLICATE_LOCAL, | 193 | // BC_STATUS_PARSE_DUPLICATE_LOCAL, |
194 | BC_STATUS_PARSE_NO_BLOCK_END, | 194 | // BC_STATUS_PARSE_NO_BLOCK_END, |
195 | 195 | ||
196 | BC_STATUS_MATH_NEGATIVE, | 196 | // BC_STATUS_MATH_NEGATIVE, |
197 | BC_STATUS_MATH_NON_INTEGER, | 197 | // BC_STATUS_MATH_NON_INTEGER, |
198 | BC_STATUS_MATH_OVERFLOW, | 198 | // BC_STATUS_MATH_OVERFLOW, |
199 | BC_STATUS_MATH_DIVIDE_BY_ZERO, | 199 | // BC_STATUS_MATH_DIVIDE_BY_ZERO, |
200 | BC_STATUS_MATH_BAD_STRING, | 200 | // BC_STATUS_MATH_BAD_STRING, |
201 | 201 | ||
202 | // BC_STATUS_EXEC_FILE_ERR, | 202 | // BC_STATUS_EXEC_FILE_ERR, |
203 | // BC_STATUS_EXEC_MISMATCHED_PARAMS, | 203 | // BC_STATUS_EXEC_MISMATCHED_PARAMS, |
204 | // BC_STATUS_EXEC_UNDEFINED_FUNC, | 204 | // BC_STATUS_EXEC_UNDEFINED_FUNC, |
205 | BC_STATUS_EXEC_FILE_NOT_EXECUTABLE, | 205 | // BC_STATUS_EXEC_FILE_NOT_EXECUTABLE, |
206 | BC_STATUS_EXEC_NUM_LEN, | 206 | // BC_STATUS_EXEC_NUM_LEN, |
207 | BC_STATUS_EXEC_NAME_LEN, | 207 | // BC_STATUS_EXEC_NAME_LEN, |
208 | BC_STATUS_EXEC_STRING_LEN, | 208 | // BC_STATUS_EXEC_STRING_LEN, |
209 | BC_STATUS_EXEC_ARRAY_LEN, | 209 | // BC_STATUS_EXEC_ARRAY_LEN, |
210 | BC_STATUS_EXEC_BAD_IBASE, | 210 | // BC_STATUS_EXEC_BAD_IBASE, |
211 | // BC_STATUS_EXEC_BAD_SCALE, | 211 | // BC_STATUS_EXEC_BAD_SCALE, |
212 | BC_STATUS_EXEC_BAD_READ_EXPR, | 212 | // BC_STATUS_EXEC_BAD_READ_EXPR, |
213 | BC_STATUS_EXEC_REC_READ, | 213 | // BC_STATUS_EXEC_REC_READ, |
214 | BC_STATUS_EXEC_BAD_TYPE, | 214 | // BC_STATUS_EXEC_BAD_TYPE, |
215 | // BC_STATUS_EXEC_BAD_OBASE, | 215 | // BC_STATUS_EXEC_BAD_OBASE, |
216 | // BC_STATUS_EXEC_SIGNAL, | 216 | // BC_STATUS_EXEC_SIGNAL, |
217 | BC_STATUS_EXEC_STACK, | 217 | // BC_STATUS_EXEC_STACK, |
218 | 218 | ||
219 | // BC_STATUS_VEC_OUT_OF_BOUNDS, | 219 | // BC_STATUS_VEC_OUT_OF_BOUNDS, |
220 | // BC_STATUS_VEC_ITEM_EXISTS, | 220 | // BC_STATUS_VEC_ITEM_EXISTS, |
221 | BC_STATUS_BEFORE_POSIX = BC_STATUS_EXEC_STACK, | 221 | BC_STATUS_BEFORE_POSIX = BC_STATUS_PARSE_EMPTY_EXP, |
222 | #if ENABLE_BC | 222 | #if ENABLE_BC |
223 | BC_STATUS_POSIX_NAME_LEN, | 223 | BC_STATUS_POSIX_NAME_LEN, |
224 | BC_STATUS_POSIX_COMMENT, | 224 | BC_STATUS_POSIX_COMMENT, |
@@ -242,51 +242,52 @@ typedef enum BcStatus { | |||
242 | static const char *const bc_err_msgs[] = { | 242 | static const char *const bc_err_msgs[] = { |
243 | NULL, | 243 | NULL, |
244 | NULL, | 244 | NULL, |
245 | NULL, | ||
246 | |||
245 | // "memory allocation error", | 247 | // "memory allocation error", |
246 | // "I/O error", | 248 | // "I/O error", |
247 | // "file is not text:", | 249 | // "file is not text:", |
248 | // "path is a directory:", | 250 | // "path is a directory:", |
249 | 251 | ||
250 | // "bad character", | 252 | // "bad character", |
251 | "string end could not be found", | 253 | // "string end could not be found", |
252 | "comment end could not be found", | 254 | // "comment end could not be found", |
253 | "end of file", | 255 | // "end of file", |
254 | #if ENABLE_DC | 256 | #if ENABLE_DC |
255 | "extended register", | 257 | // "extended register", |
256 | #endif | 258 | #endif |
257 | "bad token", | 259 | // "bad token", |
258 | "bad expression", | 260 | // "bad expression", |
259 | "empty expression", | 261 | // "bad print statement", |
260 | "bad print statement", | 262 | // "bad function definition", |
261 | "bad function definition", | 263 | // "bad assignment: left side must be scale, ibase, " |
262 | "bad assignment: left side must be scale, ibase, " | 264 | // "obase, last, var, or array element", |
263 | "obase, last, var, or array element", | ||
264 | // "no auto variable found", | 265 | // "no auto variable found", |
265 | "function parameter or auto var has the same name as another", | 266 | // "function parameter or auto var has the same name as another", |
266 | "block end could not be found", | 267 | // "block end could not be found", |
267 | 268 | ||
268 | "negative number", | 269 | // "negative number", |
269 | "non integer number", | 270 | // "non integer number", |
270 | "overflow", | 271 | // "overflow", |
271 | "divide by zero", | 272 | // "divide by zero", |
272 | "bad number string", | 273 | // "bad number string", |
273 | 274 | ||
274 | // "could not open file:", | 275 | // "could not open file:", |
275 | // "mismatched parameters", // wrong number of them, to be exact | 276 | // "mismatched parameters", // wrong number of them, to be exact |
276 | // "undefined function", | 277 | // "undefined function", |
277 | "file is not executable:", | 278 | // "file is not executable:", |
278 | "number too long: must be [1, BC_NUM_MAX]", | 279 | // "number too long: must be [1, BC_NUM_MAX]", |
279 | "name too long: must be [1, BC_NAME_MAX]", | 280 | // "name too long: must be [1, BC_NAME_MAX]", |
280 | "string too long: must be [1, BC_STRING_MAX]", | 281 | // "string too long: must be [1, BC_STRING_MAX]", |
281 | "array too long; must be [1, BC_DIM_MAX]", | 282 | // "array too long; must be [1, BC_DIM_MAX]", |
282 | "bad ibase; must be [2, 16]", | 283 | // "bad ibase; must be [2, 16]", |
283 | // "bad scale; must be [0, BC_SCALE_MAX]", | 284 | // "bad scale; must be [0, BC_SCALE_MAX]", |
284 | "bad read() expression", | 285 | // "bad read() expression", |
285 | "read() call inside of a read() call", | 286 | // "read() call inside of a read() call", |
286 | "variable is wrong type", | 287 | // "variable is wrong type", |
287 | // "bad obase; must be [2, BC_BASE_MAX]", | 288 | // "bad obase; must be [2, BC_BASE_MAX]", |
288 | // "signal caught and not handled", | 289 | // "signal caught and not handled", |
289 | "stack has too few elements", | 290 | // "stack has too few elements", |
290 | 291 | ||
291 | // "index is out of bounds", | 292 | // "index is out of bounds", |
292 | // "item already exists", | 293 | // "item already exists", |
@@ -1577,7 +1578,8 @@ static void bc_num_split(BcNum *restrict n, size_t idx, BcNum *restrict a, | |||
1577 | static BcStatus bc_num_shift(BcNum *n, size_t places) | 1578 | static BcStatus bc_num_shift(BcNum *n, size_t places) |
1578 | { | 1579 | { |
1579 | if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS; | 1580 | if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS; |
1580 | if (places + n->len > BC_MAX_NUM) return BC_STATUS_EXEC_NUM_LEN; | 1581 | if (places + n->len > BC_MAX_NUM) |
1582 | return bc_error("number too long: must be [1, BC_NUM_MAX]"); | ||
1581 | 1583 | ||
1582 | if (n->rdx >= places) | 1584 | if (n->rdx >= places) |
1583 | n->rdx -= places; | 1585 | n->rdx -= places; |
@@ -1885,7 +1887,7 @@ static BcStatus bc_num_d(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
1885 | bool zero = true; | 1887 | bool zero = true; |
1886 | 1888 | ||
1887 | if (b->len == 0) | 1889 | if (b->len == 0) |
1888 | return BC_STATUS_MATH_DIVIDE_BY_ZERO; | 1890 | return bc_error("divide by zero"); |
1889 | else if (a->len == 0) { | 1891 | else if (a->len == 0) { |
1890 | bc_num_setToZero(c, scale); | 1892 | bc_num_setToZero(c, scale); |
1891 | return BC_STATUS_SUCCESS; | 1893 | return BC_STATUS_SUCCESS; |
@@ -1948,7 +1950,8 @@ static BcStatus bc_num_r(BcNum *a, BcNum *b, BcNum *restrict c, | |||
1948 | BcNum temp; | 1950 | BcNum temp; |
1949 | bool neg; | 1951 | bool neg; |
1950 | 1952 | ||
1951 | if (b->len == 0) return BC_STATUS_MATH_DIVIDE_BY_ZERO; | 1953 | if (b->len == 0) |
1954 | return bc_error("divide by zero"); | ||
1952 | 1955 | ||
1953 | if (a->len == 0) { | 1956 | if (a->len == 0) { |
1954 | bc_num_setToZero(d, ts); | 1957 | bc_num_setToZero(d, ts); |
@@ -1997,7 +2000,7 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
1997 | size_t i, powrdx, resrdx; | 2000 | size_t i, powrdx, resrdx; |
1998 | bool neg, zero; | 2001 | bool neg, zero; |
1999 | 2002 | ||
2000 | if (b->rdx) return BC_STATUS_MATH_NON_INTEGER; | 2003 | if (b->rdx) return bc_error("non integer number"); |
2001 | 2004 | ||
2002 | if (b->len == 0) { | 2005 | if (b->len == 0) { |
2003 | bc_num_one(c); | 2006 | bc_num_one(c); |
@@ -2435,7 +2438,8 @@ static void bc_num_copy(BcNum *d, BcNum *s) | |||
2435 | static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base, | 2438 | static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base, |
2436 | size_t base_t) | 2439 | size_t base_t) |
2437 | { | 2440 | { |
2438 | if (!bc_num_strValid(val, base_t)) return BC_STATUS_MATH_BAD_STRING; | 2441 | if (!bc_num_strValid(val, base_t)) |
2442 | return bc_error("bad number string"); | ||
2439 | 2443 | ||
2440 | if (base_t == 10) | 2444 | if (base_t == 10) |
2441 | bc_num_parseDecimal(n, val); | 2445 | bc_num_parseDecimal(n, val); |
@@ -2474,7 +2478,7 @@ static BcStatus bc_num_ulong(BcNum *n, unsigned long *result) | |||
2474 | size_t i; | 2478 | size_t i; |
2475 | unsigned long pow; | 2479 | unsigned long pow; |
2476 | 2480 | ||
2477 | if (n->neg) return BC_STATUS_MATH_NEGATIVE; | 2481 | if (n->neg) return bc_error("negative number"); |
2478 | 2482 | ||
2479 | for (*result = 0, pow = 1, i = n->rdx; i < n->len; ++i) { | 2483 | for (*result = 0, pow = 1, i = n->rdx; i < n->len; ++i) { |
2480 | 2484 | ||
@@ -2483,7 +2487,8 @@ static BcStatus bc_num_ulong(BcNum *n, unsigned long *result) | |||
2483 | *result += ((unsigned long) n->num[i]) * pow; | 2487 | *result += ((unsigned long) n->num[i]) * pow; |
2484 | pow *= 10; | 2488 | pow *= 10; |
2485 | 2489 | ||
2486 | if (*result < prev || pow < powprev) return BC_STATUS_MATH_OVERFLOW; | 2490 | if (*result < prev || pow < powprev) |
2491 | return bc_error("overflow"); | ||
2487 | } | 2492 | } |
2488 | 2493 | ||
2489 | return BC_STATUS_SUCCESS; | 2494 | return BC_STATUS_SUCCESS; |
@@ -2555,7 +2560,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale) | |||
2555 | return BC_STATUS_SUCCESS; | 2560 | return BC_STATUS_SUCCESS; |
2556 | } | 2561 | } |
2557 | else if (a->neg) | 2562 | else if (a->neg) |
2558 | return BC_STATUS_MATH_NEGATIVE; | 2563 | return bc_error("negative number"); |
2559 | else if (BC_NUM_ONE(a)) { | 2564 | else if (BC_NUM_ONE(a)) { |
2560 | bc_num_one(b); | 2565 | bc_num_one(b); |
2561 | bc_num_extend(b, scale); | 2566 | bc_num_extend(b, scale); |
@@ -2674,9 +2679,12 @@ static BcStatus bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d) | |||
2674 | BcStatus s; | 2679 | BcStatus s; |
2675 | BcNum base, exp, two, temp; | 2680 | BcNum base, exp, two, temp; |
2676 | 2681 | ||
2677 | if (c->len == 0) return BC_STATUS_MATH_DIVIDE_BY_ZERO; | 2682 | if (c->len == 0) |
2678 | if (a->rdx || b->rdx || c->rdx) return BC_STATUS_MATH_NON_INTEGER; | 2683 | return bc_error("divide by zero"); |
2679 | if (b->neg) return BC_STATUS_MATH_NEGATIVE; | 2684 | if (a->rdx || b->rdx || c->rdx) |
2685 | return bc_error("non integer number"); | ||
2686 | if (b->neg) | ||
2687 | return bc_error("negative number"); | ||
2680 | 2688 | ||
2681 | bc_num_expand(d, c->len); | 2689 | bc_num_expand(d, c->len); |
2682 | bc_num_init(&base, c->len); | 2690 | bc_num_init(&base, c->len); |
@@ -2735,8 +2743,8 @@ static BcStatus bc_func_insert(BcFunc *f, char *name, bool var) | |||
2735 | size_t i; | 2743 | size_t i; |
2736 | 2744 | ||
2737 | for (i = 0; i < f->autos.len; ++i) { | 2745 | for (i = 0; i < f->autos.len; ++i) { |
2738 | if (!strcmp(name, ((BcId *) bc_vec_item(&f->autos, i))->name)) | 2746 | if (strcmp(name, ((BcId *) bc_vec_item(&f->autos, i))->name) == 0) |
2739 | return BC_STATUS_PARSE_DUPLICATE_LOCAL; | 2747 | return bc_error("function parameter or auto var has the same name as another"); |
2740 | } | 2748 | } |
2741 | 2749 | ||
2742 | a.idx = var; | 2750 | a.idx = var; |
@@ -2918,7 +2926,8 @@ static BcStatus bc_lex_number(BcLex *l, char start) | |||
2918 | } | 2926 | } |
2919 | 2927 | ||
2920 | len = i + 1 * !last_pt - bslashes * 2; | 2928 | len = i + 1 * !last_pt - bslashes * 2; |
2921 | if (len > BC_MAX_NUM) return BC_STATUS_EXEC_NUM_LEN; | 2929 | if (len > BC_MAX_NUM) |
2930 | return bc_error("number too long: must be [1, BC_NUM_MAX]"); | ||
2922 | 2931 | ||
2923 | bc_vec_npop(&l->t.v, l->t.v.len); | 2932 | bc_vec_npop(&l->t.v, l->t.v.len); |
2924 | bc_vec_expand(&l->t.v, len + 1); | 2933 | bc_vec_expand(&l->t.v, len + 1); |
@@ -2955,7 +2964,8 @@ static BcStatus bc_lex_name(BcLex *l) | |||
2955 | 2964 | ||
2956 | while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i]; | 2965 | while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i]; |
2957 | 2966 | ||
2958 | if (i > BC_MAX_STRING) return BC_STATUS_EXEC_NAME_LEN; | 2967 | if (i > BC_MAX_STRING) |
2968 | return bc_error("name too long: must be [1, BC_NAME_MAX]"); | ||
2959 | bc_vec_string(&l->t.v, i, buf); | 2969 | bc_vec_string(&l->t.v, i, buf); |
2960 | 2970 | ||
2961 | // Increment the index. We minus 1 because it has already been incremented. | 2971 | // Increment the index. We minus 1 because it has already been incremented. |
@@ -2987,7 +2997,7 @@ static BcStatus bc_lex_next(BcLex *l) | |||
2987 | BcStatus s; | 2997 | BcStatus s; |
2988 | 2998 | ||
2989 | l->t.last = l->t.t; | 2999 | l->t.last = l->t.t; |
2990 | if (l->t.last == BC_LEX_EOF) return BC_STATUS_LEX_EOF; | 3000 | if (l->t.last == BC_LEX_EOF) return bc_error("end of file"); |
2991 | 3001 | ||
2992 | l->line += l->newline; | 3002 | l->line += l->newline; |
2993 | l->t.t = BC_LEX_EOF; | 3003 | l->t.t = BC_LEX_EOF; |
@@ -3060,11 +3070,12 @@ static BcStatus bc_lex_string(BcLex *l) | |||
3060 | 3070 | ||
3061 | if (c == '\0') { | 3071 | if (c == '\0') { |
3062 | l->i = i; | 3072 | l->i = i; |
3063 | return BC_STATUS_LEX_NO_STRING_END; | 3073 | return bc_error("string end could not be found"); |
3064 | } | 3074 | } |
3065 | 3075 | ||
3066 | len = i - l->i; | 3076 | len = i - l->i; |
3067 | if (len > BC_MAX_STRING) return BC_STATUS_EXEC_STRING_LEN; | 3077 | if (len > BC_MAX_STRING) |
3078 | return bc_error("string too long: must be [1, BC_STRING_MAX]"); | ||
3068 | bc_vec_string(&l->t.v, len, l->buf + l->i); | 3079 | bc_vec_string(&l->t.v, len, l->buf + l->i); |
3069 | 3080 | ||
3070 | l->i = i + 1; | 3081 | l->i = i + 1; |
@@ -3101,7 +3112,7 @@ static BcStatus bc_lex_comment(BcLex *l) | |||
3101 | } | 3112 | } |
3102 | if (c == '\0') { | 3113 | if (c == '\0') { |
3103 | l->i = i; | 3114 | l->i = i; |
3104 | return BC_STATUS_LEX_NO_COMMENT_END; | 3115 | return bc_error("comment end could not be found"); |
3105 | } | 3116 | } |
3106 | nls += (c == '\n'); | 3117 | nls += (c == '\n'); |
3107 | i++; | 3118 | i++; |
@@ -3404,7 +3415,7 @@ static BcStatus dc_lex_register(BcLex *l) | |||
3404 | bc_lex_whitespace(l); | 3415 | bc_lex_whitespace(l); |
3405 | ++l->i; | 3416 | ++l->i; |
3406 | if (!G_exreg) | 3417 | if (!G_exreg) |
3407 | s = BC_STATUS_LEX_EXTENDED_REG; | 3418 | s = bc_error("extended register"); |
3408 | else | 3419 | else |
3409 | s = bc_lex_name(l); | 3420 | s = bc_lex_name(l); |
3410 | } | 3421 | } |
@@ -3437,11 +3448,12 @@ static BcStatus dc_lex_string(BcLex *l) | |||
3437 | 3448 | ||
3438 | if (c == '\0') { | 3449 | if (c == '\0') { |
3439 | l->i = i; | 3450 | l->i = i; |
3440 | return BC_STATUS_LEX_NO_STRING_END; | 3451 | return bc_error("string end could not be found"); |
3441 | } | 3452 | } |
3442 | 3453 | ||
3443 | bc_vec_pushByte(&l->t.v, '\0'); | 3454 | bc_vec_pushByte(&l->t.v, '\0'); |
3444 | if (i - l->i > BC_MAX_STRING) return BC_STATUS_EXEC_STRING_LEN; | 3455 | if (i - l->i > BC_MAX_STRING) |
3456 | return bc_error("string too long: must be [1, BC_STRING_MAX]"); | ||
3445 | 3457 | ||
3446 | l->i = i; | 3458 | l->i = i; |
3447 | l->line += nls; | 3459 | l->line += nls; |
@@ -3606,11 +3618,12 @@ static BcStatus bc_parse_text(BcParse *p, const char *text) | |||
3606 | 3618 | ||
3607 | p->func = bc_vec_item(&G.prog.fns, p->fidx); | 3619 | p->func = bc_vec_item(&G.prog.fns, p->fidx); |
3608 | 3620 | ||
3609 | if (!strcmp(text, "") && !BC_PARSE_CAN_EXEC(p)) { | 3621 | if (!text[0] && !BC_PARSE_CAN_EXEC(p)) { |
3610 | p->l.t.t = BC_LEX_INVALID; | 3622 | p->l.t.t = BC_LEX_INVALID; |
3611 | s = p->parse(p); | 3623 | s = p->parse(p); |
3612 | if (s) return s; | 3624 | if (s) return s; |
3613 | if (!BC_PARSE_CAN_EXEC(p)) return BC_STATUS_EXEC_FILE_NOT_EXECUTABLE; | 3625 | if (!BC_PARSE_CAN_EXEC(p)) |
3626 | return bc_error("file is not executable"); | ||
3614 | } | 3627 | } |
3615 | 3628 | ||
3616 | return bc_lex_text(&p->l, text); | 3629 | return bc_lex_text(&p->l, text); |
@@ -3703,7 +3716,8 @@ static BcStatus bc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs) | |||
3703 | { | 3716 | { |
3704 | BcLexType top; | 3717 | BcLexType top; |
3705 | 3718 | ||
3706 | if (p->ops.len <= ops_bgn) return BC_STATUS_PARSE_BAD_EXP; | 3719 | if (p->ops.len <= ops_bgn) |
3720 | return bc_error("bad expression"); | ||
3707 | top = BC_PARSE_TOP_OP(p); | 3721 | top = BC_PARSE_TOP_OP(p); |
3708 | 3722 | ||
3709 | while (top != BC_LEX_LPAREN) { | 3723 | while (top != BC_LEX_LPAREN) { |
@@ -3713,7 +3727,8 @@ static BcStatus bc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs) | |||
3713 | bc_vec_pop(&p->ops); | 3727 | bc_vec_pop(&p->ops); |
3714 | *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG; | 3728 | *nexs -= top != BC_LEX_OP_BOOL_NOT && top != BC_LEX_NEG; |
3715 | 3729 | ||
3716 | if (p->ops.len <= ops_bgn) return BC_STATUS_PARSE_BAD_EXP; | 3730 | if (p->ops.len <= ops_bgn) |
3731 | return bc_error("bad expression"); | ||
3717 | top = BC_PARSE_TOP_OP(p); | 3732 | top = BC_PARSE_TOP_OP(p); |
3718 | } | 3733 | } |
3719 | 3734 | ||
@@ -3744,7 +3759,7 @@ static BcStatus bc_parse_params(BcParse *p, uint8_t flags) | |||
3744 | } | 3759 | } |
3745 | } | 3760 | } |
3746 | 3761 | ||
3747 | if (comma) return BC_STATUS_PARSE_BAD_TOKEN; | 3762 | if (comma) return bc_error("bad token"); |
3748 | bc_parse_push(p, BC_INST_CALL); | 3763 | bc_parse_push(p, BC_INST_CALL); |
3749 | bc_parse_pushIndex(p, nparams); | 3764 | bc_parse_pushIndex(p, nparams); |
3750 | 3765 | ||
@@ -3763,7 +3778,7 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags) | |||
3763 | if (s) goto err; | 3778 | if (s) goto err; |
3764 | 3779 | ||
3765 | if (p->l.t.t != BC_LEX_RPAREN) { | 3780 | if (p->l.t.t != BC_LEX_RPAREN) { |
3766 | s = BC_STATUS_PARSE_BAD_TOKEN; | 3781 | s = bc_error("bad token"); |
3767 | goto err; | 3782 | goto err; |
3768 | } | 3783 | } |
3769 | 3784 | ||
@@ -3805,7 +3820,7 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags) | |||
3805 | if (p->l.t.t == BC_LEX_RBRACKET) { | 3820 | if (p->l.t.t == BC_LEX_RBRACKET) { |
3806 | 3821 | ||
3807 | if (!(flags & BC_PARSE_ARRAY)) { | 3822 | if (!(flags & BC_PARSE_ARRAY)) { |
3808 | s = BC_STATUS_PARSE_BAD_EXP; | 3823 | s = bc_error("bad expression"); |
3809 | goto err; | 3824 | goto err; |
3810 | } | 3825 | } |
3811 | 3826 | ||
@@ -3828,7 +3843,7 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags) | |||
3828 | else if (p->l.t.t == BC_LEX_LPAREN) { | 3843 | else if (p->l.t.t == BC_LEX_LPAREN) { |
3829 | 3844 | ||
3830 | if (flags & BC_PARSE_NOCALL) { | 3845 | if (flags & BC_PARSE_NOCALL) { |
3831 | s = BC_STATUS_PARSE_BAD_TOKEN; | 3846 | s = bc_error("bad token"); |
3832 | goto err; | 3847 | goto err; |
3833 | } | 3848 | } |
3834 | 3849 | ||
@@ -3854,11 +3869,11 @@ static BcStatus bc_parse_read(BcParse *p) | |||
3854 | 3869 | ||
3855 | s = bc_lex_next(&p->l); | 3870 | s = bc_lex_next(&p->l); |
3856 | if (s) return s; | 3871 | if (s) return s; |
3857 | if (p->l.t.t != BC_LEX_LPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 3872 | if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); |
3858 | 3873 | ||
3859 | s = bc_lex_next(&p->l); | 3874 | s = bc_lex_next(&p->l); |
3860 | if (s) return s; | 3875 | if (s) return s; |
3861 | if (p->l.t.t != BC_LEX_RPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 3876 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); |
3862 | 3877 | ||
3863 | bc_parse_push(p, BC_INST_READ); | 3878 | bc_parse_push(p, BC_INST_READ); |
3864 | 3879 | ||
@@ -3872,7 +3887,7 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, | |||
3872 | 3887 | ||
3873 | s = bc_lex_next(&p->l); | 3888 | s = bc_lex_next(&p->l); |
3874 | if (s) return s; | 3889 | if (s) return s; |
3875 | if (p->l.t.t != BC_LEX_LPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 3890 | if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); |
3876 | 3891 | ||
3877 | flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; | 3892 | flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; |
3878 | 3893 | ||
@@ -3882,7 +3897,7 @@ static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, | |||
3882 | s = bc_parse_expr(p, flags, bc_parse_next_rel); | 3897 | s = bc_parse_expr(p, flags, bc_parse_next_rel); |
3883 | if (s) return s; | 3898 | if (s) return s; |
3884 | 3899 | ||
3885 | if (p->l.t.t != BC_LEX_RPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 3900 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); |
3886 | 3901 | ||
3887 | *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT; | 3902 | *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT; |
3888 | bc_parse_push(p, *prev); | 3903 | bc_parse_push(p, *prev); |
@@ -3911,7 +3926,7 @@ static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags) | |||
3911 | 3926 | ||
3912 | s = bc_parse_expr(p, flags, bc_parse_next_rel); | 3927 | s = bc_parse_expr(p, flags, bc_parse_next_rel); |
3913 | if (s) return s; | 3928 | if (s) return s; |
3914 | if (p->l.t.t != BC_LEX_RPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 3929 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); |
3915 | bc_parse_push(p, BC_INST_SCALE_FUNC); | 3930 | bc_parse_push(p, BC_INST_SCALE_FUNC); |
3916 | 3931 | ||
3917 | return bc_lex_next(&p->l); | 3932 | return bc_lex_next(&p->l); |
@@ -3968,7 +3983,7 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, | |||
3968 | s = bc_lex_next(&p->l); | 3983 | s = bc_lex_next(&p->l); |
3969 | if (s) return s; | 3984 | if (s) return s; |
3970 | if (p->l.t.t == BC_LEX_LPAREN) | 3985 | if (p->l.t.t == BC_LEX_LPAREN) |
3971 | s = BC_STATUS_PARSE_BAD_TOKEN; | 3986 | s = bc_error("bad token"); |
3972 | else | 3987 | else |
3973 | bc_parse_push(p, BC_INST_SCALE); | 3988 | bc_parse_push(p, BC_INST_SCALE); |
3974 | break; | 3989 | break; |
@@ -3976,7 +3991,7 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, | |||
3976 | 3991 | ||
3977 | default: | 3992 | default: |
3978 | { | 3993 | { |
3979 | s = BC_STATUS_PARSE_BAD_TOKEN; | 3994 | s = bc_error("bad token"); |
3980 | break; | 3995 | break; |
3981 | } | 3996 | } |
3982 | } | 3997 | } |
@@ -4037,7 +4052,7 @@ static BcStatus bc_parse_print(BcParse *p) | |||
4037 | type = p->l.t.t; | 4052 | type = p->l.t.t; |
4038 | 4053 | ||
4039 | if (type == BC_LEX_SCOLON || type == BC_LEX_NLINE) | 4054 | if (type == BC_LEX_SCOLON || type == BC_LEX_NLINE) |
4040 | return BC_STATUS_PARSE_BAD_PRINT; | 4055 | return bc_error("bad print statement"); |
4041 | 4056 | ||
4042 | while (!s && type != BC_LEX_SCOLON && type != BC_LEX_NLINE) { | 4057 | while (!s && type != BC_LEX_SCOLON && type != BC_LEX_NLINE) { |
4043 | 4058 | ||
@@ -4057,7 +4072,7 @@ static BcStatus bc_parse_print(BcParse *p) | |||
4057 | } | 4072 | } |
4058 | 4073 | ||
4059 | if (s) return s; | 4074 | if (s) return s; |
4060 | if (comma) return BC_STATUS_PARSE_BAD_TOKEN; | 4075 | if (comma) return bc_error("bad token"); |
4061 | 4076 | ||
4062 | return bc_lex_next(&p->l); | 4077 | return bc_lex_next(&p->l); |
4063 | } | 4078 | } |
@@ -4068,7 +4083,7 @@ static BcStatus bc_parse_return(BcParse *p) | |||
4068 | BcLexType t; | 4083 | BcLexType t; |
4069 | bool paren; | 4084 | bool paren; |
4070 | 4085 | ||
4071 | if (!BC_PARSE_FUNC(p)) return BC_STATUS_PARSE_BAD_TOKEN; | 4086 | if (!BC_PARSE_FUNC(p)) return bc_error("bad token"); |
4072 | 4087 | ||
4073 | s = bc_lex_next(&p->l); | 4088 | s = bc_lex_next(&p->l); |
4074 | if (s) return s; | 4089 | if (s) return s; |
@@ -4083,7 +4098,8 @@ static BcStatus bc_parse_return(BcParse *p) | |||
4083 | s = bc_parse_expr(p, 0, bc_parse_next_expr); | 4098 | s = bc_parse_expr(p, 0, bc_parse_next_expr); |
4084 | if (s && s != BC_STATUS_PARSE_EMPTY_EXP) | 4099 | if (s && s != BC_STATUS_PARSE_EMPTY_EXP) |
4085 | return s; | 4100 | return s; |
4086 | else if (s == BC_STATUS_PARSE_EMPTY_EXP) { | 4101 | |
4102 | if (s == BC_STATUS_PARSE_EMPTY_EXP) { | ||
4087 | bc_parse_push(p, BC_INST_RET0); | 4103 | bc_parse_push(p, BC_INST_RET0); |
4088 | s = bc_lex_next(&p->l); | 4104 | s = bc_lex_next(&p->l); |
4089 | if (s) return s; | 4105 | if (s) return s; |
@@ -4105,18 +4121,18 @@ static BcStatus bc_parse_endBody(BcParse *p, bool brace) | |||
4105 | BcStatus s = BC_STATUS_SUCCESS; | 4121 | BcStatus s = BC_STATUS_SUCCESS; |
4106 | 4122 | ||
4107 | if (p->flags.len <= 1 || (brace && p->nbraces == 0)) | 4123 | if (p->flags.len <= 1 || (brace && p->nbraces == 0)) |
4108 | return BC_STATUS_PARSE_BAD_TOKEN; | 4124 | return bc_error("bad token"); |
4109 | 4125 | ||
4110 | if (brace) { | 4126 | if (brace) { |
4111 | 4127 | ||
4112 | if (p->l.t.t == BC_LEX_RBRACE) { | 4128 | if (p->l.t.t == BC_LEX_RBRACE) { |
4113 | if (!p->nbraces) return BC_STATUS_PARSE_BAD_TOKEN; | 4129 | if (!p->nbraces) return bc_error("bad token"); |
4114 | --p->nbraces; | 4130 | --p->nbraces; |
4115 | s = bc_lex_next(&p->l); | 4131 | s = bc_lex_next(&p->l); |
4116 | if (s) return s; | 4132 | if (s) return s; |
4117 | } | 4133 | } |
4118 | else | 4134 | else |
4119 | return BC_STATUS_PARSE_BAD_TOKEN; | 4135 | return bc_error("bad token"); |
4120 | } | 4136 | } |
4121 | 4137 | ||
4122 | if (BC_PARSE_IF(p)) { | 4138 | if (BC_PARSE_IF(p)) { |
@@ -4202,13 +4218,13 @@ static BcStatus bc_parse_if(BcParse *p) | |||
4202 | 4218 | ||
4203 | s = bc_lex_next(&p->l); | 4219 | s = bc_lex_next(&p->l); |
4204 | if (s) return s; | 4220 | if (s) return s; |
4205 | if (p->l.t.t != BC_LEX_LPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 4221 | if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); |
4206 | 4222 | ||
4207 | s = bc_lex_next(&p->l); | 4223 | s = bc_lex_next(&p->l); |
4208 | if (s) return s; | 4224 | if (s) return s; |
4209 | s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); | 4225 | s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); |
4210 | if (s) return s; | 4226 | if (s) return s; |
4211 | if (p->l.t.t != BC_LEX_RPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 4227 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); |
4212 | 4228 | ||
4213 | s = bc_lex_next(&p->l); | 4229 | s = bc_lex_next(&p->l); |
4214 | if (s) return s; | 4230 | if (s) return s; |
@@ -4229,7 +4245,7 @@ static BcStatus bc_parse_else(BcParse *p) | |||
4229 | { | 4245 | { |
4230 | BcInstPtr ip; | 4246 | BcInstPtr ip; |
4231 | 4247 | ||
4232 | if (!BC_PARSE_IF_END(p)) return BC_STATUS_PARSE_BAD_TOKEN; | 4248 | if (!BC_PARSE_IF_END(p)) return bc_error("bad token"); |
4233 | 4249 | ||
4234 | ip.idx = p->func->labels.len; | 4250 | ip.idx = p->func->labels.len; |
4235 | ip.func = ip.len = 0; | 4251 | ip.func = ip.len = 0; |
@@ -4253,7 +4269,7 @@ static BcStatus bc_parse_while(BcParse *p) | |||
4253 | 4269 | ||
4254 | s = bc_lex_next(&p->l); | 4270 | s = bc_lex_next(&p->l); |
4255 | if (s) return s; | 4271 | if (s) return s; |
4256 | if (p->l.t.t != BC_LEX_LPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 4272 | if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); |
4257 | s = bc_lex_next(&p->l); | 4273 | s = bc_lex_next(&p->l); |
4258 | if (s) return s; | 4274 | if (s) return s; |
4259 | 4275 | ||
@@ -4271,7 +4287,7 @@ static BcStatus bc_parse_while(BcParse *p) | |||
4271 | 4287 | ||
4272 | s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); | 4288 | s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_rel); |
4273 | if (s) return s; | 4289 | if (s) return s; |
4274 | if (p->l.t.t != BC_LEX_RPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 4290 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); |
4275 | s = bc_lex_next(&p->l); | 4291 | s = bc_lex_next(&p->l); |
4276 | if (s) return s; | 4292 | if (s) return s; |
4277 | 4293 | ||
@@ -4290,7 +4306,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4290 | 4306 | ||
4291 | s = bc_lex_next(&p->l); | 4307 | s = bc_lex_next(&p->l); |
4292 | if (s) return s; | 4308 | if (s) return s; |
4293 | if (p->l.t.t != BC_LEX_LPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 4309 | if (p->l.t.t != BC_LEX_LPAREN) return bc_error("bad token"); |
4294 | s = bc_lex_next(&p->l); | 4310 | s = bc_lex_next(&p->l); |
4295 | if (s) return s; | 4311 | if (s) return s; |
4296 | 4312 | ||
@@ -4300,7 +4316,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4300 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR1, p->l.f, p->l.line, NULL); | 4316 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR1, p->l.f, p->l.line, NULL); |
4301 | 4317 | ||
4302 | if (s) return s; | 4318 | if (s) return s; |
4303 | if (p->l.t.t != BC_LEX_SCOLON) return BC_STATUS_PARSE_BAD_TOKEN; | 4319 | if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); |
4304 | s = bc_lex_next(&p->l); | 4320 | s = bc_lex_next(&p->l); |
4305 | if (s) return s; | 4321 | if (s) return s; |
4306 | 4322 | ||
@@ -4317,7 +4333,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4317 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR2, p->l.f, p->l.line, NULL); | 4333 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR2, p->l.f, p->l.line, NULL); |
4318 | 4334 | ||
4319 | if (s) return s; | 4335 | if (s) return s; |
4320 | if (p->l.t.t != BC_LEX_SCOLON) return BC_STATUS_PARSE_BAD_TOKEN; | 4336 | if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); |
4321 | 4337 | ||
4322 | s = bc_lex_next(&p->l); | 4338 | s = bc_lex_next(&p->l); |
4323 | if (s) return s; | 4339 | if (s) return s; |
@@ -4339,7 +4355,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4339 | 4355 | ||
4340 | if (s) return s; | 4356 | if (s) return s; |
4341 | 4357 | ||
4342 | if (p->l.t.t != BC_LEX_RPAREN) return BC_STATUS_PARSE_BAD_TOKEN; | 4358 | if (p->l.t.t != BC_LEX_RPAREN) return bc_error("bad token"); |
4343 | bc_parse_push(p, BC_INST_JUMP); | 4359 | bc_parse_push(p, BC_INST_JUMP); |
4344 | bc_parse_pushIndex(p, cond_idx); | 4360 | bc_parse_pushIndex(p, cond_idx); |
4345 | bc_vec_push(&p->func->labels, &p->func->code.len); | 4361 | bc_vec_push(&p->func->labels, &p->func->code.len); |
@@ -4362,17 +4378,17 @@ static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type) | |||
4362 | size_t i; | 4378 | size_t i; |
4363 | BcInstPtr *ip; | 4379 | BcInstPtr *ip; |
4364 | 4380 | ||
4365 | if (!BC_PARSE_LOOP(p)) return BC_STATUS_PARSE_BAD_TOKEN; | 4381 | if (!BC_PARSE_LOOP(p)) return bc_error("bad token"); |
4366 | 4382 | ||
4367 | if (type == BC_LEX_KEY_BREAK) { | 4383 | if (type == BC_LEX_KEY_BREAK) { |
4368 | 4384 | ||
4369 | if (p->exits.len == 0) return BC_STATUS_PARSE_BAD_TOKEN; | 4385 | if (p->exits.len == 0) return bc_error("bad token"); |
4370 | 4386 | ||
4371 | i = p->exits.len - 1; | 4387 | i = p->exits.len - 1; |
4372 | ip = bc_vec_item(&p->exits, i); | 4388 | ip = bc_vec_item(&p->exits, i); |
4373 | 4389 | ||
4374 | while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--); | 4390 | while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--); |
4375 | if (i >= p->exits.len && !ip->func) return BC_STATUS_PARSE_BAD_TOKEN; | 4391 | if (i >= p->exits.len && !ip->func) return bc_error("bad token"); |
4376 | 4392 | ||
4377 | i = ip->idx; | 4393 | i = ip->idx; |
4378 | } | 4394 | } |
@@ -4386,7 +4402,7 @@ static BcStatus bc_parse_loopExit(BcParse *p, BcLexType type) | |||
4386 | if (s) return s; | 4402 | if (s) return s; |
4387 | 4403 | ||
4388 | if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE) | 4404 | if (p->l.t.t != BC_LEX_SCOLON && p->l.t.t != BC_LEX_NLINE) |
4389 | return BC_STATUS_PARSE_BAD_TOKEN; | 4405 | return bc_error("bad token"); |
4390 | 4406 | ||
4391 | return bc_lex_next(&p->l); | 4407 | return bc_lex_next(&p->l); |
4392 | } | 4408 | } |
@@ -4400,20 +4416,23 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4400 | 4416 | ||
4401 | s = bc_lex_next(&p->l); | 4417 | s = bc_lex_next(&p->l); |
4402 | if (s) return s; | 4418 | if (s) return s; |
4403 | if (p->l.t.t != BC_LEX_NAME) return BC_STATUS_PARSE_BAD_FUNC; | 4419 | if (p->l.t.t != BC_LEX_NAME) |
4420 | return bc_error("bad function definition"); | ||
4404 | 4421 | ||
4405 | name = xstrdup(p->l.t.v.v); | 4422 | name = xstrdup(p->l.t.v.v); |
4406 | bc_parse_addFunc(p, name, &p->fidx); | 4423 | bc_parse_addFunc(p, name, &p->fidx); |
4407 | 4424 | ||
4408 | s = bc_lex_next(&p->l); | 4425 | s = bc_lex_next(&p->l); |
4409 | if (s) return s; | 4426 | if (s) return s; |
4410 | if (p->l.t.t != BC_LEX_LPAREN) return BC_STATUS_PARSE_BAD_FUNC; | 4427 | if (p->l.t.t != BC_LEX_LPAREN) |
4428 | return bc_error("bad function definition"); | ||
4411 | s = bc_lex_next(&p->l); | 4429 | s = bc_lex_next(&p->l); |
4412 | if (s) return s; | 4430 | if (s) return s; |
4413 | 4431 | ||
4414 | while (p->l.t.t != BC_LEX_RPAREN) { | 4432 | while (p->l.t.t != BC_LEX_RPAREN) { |
4415 | 4433 | ||
4416 | if (p->l.t.t != BC_LEX_NAME) return BC_STATUS_PARSE_BAD_FUNC; | 4434 | if (p->l.t.t != BC_LEX_NAME) |
4435 | return bc_error("bad function definition"); | ||
4417 | 4436 | ||
4418 | ++p->func->nparams; | 4437 | ++p->func->nparams; |
4419 | 4438 | ||
@@ -4429,7 +4448,7 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4429 | if (s) goto err; | 4448 | if (s) goto err; |
4430 | 4449 | ||
4431 | if (p->l.t.t != BC_LEX_RBRACKET) { | 4450 | if (p->l.t.t != BC_LEX_RBRACKET) { |
4432 | s = BC_STATUS_PARSE_BAD_FUNC; | 4451 | s = bc_error("bad function definition"); |
4433 | goto err; | 4452 | goto err; |
4434 | } | 4453 | } |
4435 | 4454 | ||
@@ -4447,7 +4466,7 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4447 | if (s) goto err; | 4466 | if (s) goto err; |
4448 | } | 4467 | } |
4449 | 4468 | ||
4450 | if (comma) return BC_STATUS_PARSE_BAD_FUNC; | 4469 | if (comma) return bc_error("bad function definition"); |
4451 | 4470 | ||
4452 | flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY; | 4471 | flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY; |
4453 | bc_parse_startBody(p, flags); | 4472 | bc_parse_startBody(p, flags); |
@@ -4471,7 +4490,7 @@ static BcStatus bc_parse_auto(BcParse *p) | |||
4471 | bool comma, var, one; | 4490 | bool comma, var, one; |
4472 | char *name; | 4491 | char *name; |
4473 | 4492 | ||
4474 | if (!p->auto_part) return BC_STATUS_PARSE_BAD_TOKEN; | 4493 | if (!p->auto_part) return bc_error("bad token"); |
4475 | s = bc_lex_next(&p->l); | 4494 | s = bc_lex_next(&p->l); |
4476 | if (s) return s; | 4495 | if (s) return s; |
4477 | 4496 | ||
@@ -4491,7 +4510,7 @@ static BcStatus bc_parse_auto(BcParse *p) | |||
4491 | if (s) goto err; | 4510 | if (s) goto err; |
4492 | 4511 | ||
4493 | if (p->l.t.t != BC_LEX_RBRACKET) { | 4512 | if (p->l.t.t != BC_LEX_RBRACKET) { |
4494 | s = BC_STATUS_PARSE_BAD_FUNC; | 4513 | s = bc_error("bad function definition"); |
4495 | goto err; | 4514 | goto err; |
4496 | } | 4515 | } |
4497 | 4516 | ||
@@ -4509,11 +4528,11 @@ static BcStatus bc_parse_auto(BcParse *p) | |||
4509 | if (s) goto err; | 4528 | if (s) goto err; |
4510 | } | 4529 | } |
4511 | 4530 | ||
4512 | if (comma) return BC_STATUS_PARSE_BAD_FUNC; | 4531 | if (comma) return bc_error("bad function definition"); |
4513 | if (!one) return bc_error("no auto variable found"); | 4532 | if (!one) return bc_error("no auto variable found"); |
4514 | 4533 | ||
4515 | if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON) | 4534 | if (p->l.t.t != BC_LEX_NLINE && p->l.t.t != BC_LEX_SCOLON) |
4516 | return BC_STATUS_PARSE_BAD_TOKEN; | 4535 | return bc_error("bad token"); |
4517 | 4536 | ||
4518 | return bc_lex_next(&p->l); | 4537 | return bc_lex_next(&p->l); |
4519 | 4538 | ||
@@ -4531,7 +4550,7 @@ static BcStatus bc_parse_body(BcParse *p, bool brace) | |||
4531 | 4550 | ||
4532 | if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) { | 4551 | if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) { |
4533 | 4552 | ||
4534 | if (!brace) return BC_STATUS_PARSE_BAD_TOKEN; | 4553 | if (!brace) return bc_error("bad token"); |
4535 | p->auto_part = p->l.t.t != BC_LEX_KEY_AUTO; | 4554 | p->auto_part = p->l.t.t != BC_LEX_KEY_AUTO; |
4536 | 4555 | ||
4537 | if (!p->auto_part) { | 4556 | if (!p->auto_part) { |
@@ -4568,7 +4587,7 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4568 | 4587 | ||
4569 | case BC_LEX_LBRACE: | 4588 | case BC_LEX_LBRACE: |
4570 | { | 4589 | { |
4571 | if (!BC_PARSE_BODY(p)) return BC_STATUS_PARSE_BAD_TOKEN; | 4590 | if (!BC_PARSE_BODY(p)) return bc_error("bad token"); |
4572 | 4591 | ||
4573 | ++p->nbraces; | 4592 | ++p->nbraces; |
4574 | s = bc_lex_next(&p->l); | 4593 | s = bc_lex_next(&p->l); |
@@ -4713,7 +4732,7 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4713 | 4732 | ||
4714 | default: | 4733 | default: |
4715 | { | 4734 | { |
4716 | s = BC_STATUS_PARSE_BAD_TOKEN; | 4735 | s = bc_error("bad token"); |
4717 | break; | 4736 | break; |
4718 | } | 4737 | } |
4719 | } | 4738 | } |
@@ -4726,9 +4745,9 @@ static BcStatus bc_parse_parse(BcParse *p) | |||
4726 | BcStatus s; | 4745 | BcStatus s; |
4727 | 4746 | ||
4728 | if (p->l.t.t == BC_LEX_EOF) | 4747 | if (p->l.t.t == BC_LEX_EOF) |
4729 | s = p->flags.len > 0 ? BC_STATUS_PARSE_NO_BLOCK_END : BC_STATUS_LEX_EOF; | 4748 | s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file"); |
4730 | else if (p->l.t.t == BC_LEX_KEY_DEFINE) { | 4749 | else if (p->l.t.t == BC_LEX_KEY_DEFINE) { |
4731 | if (!BC_PARSE_CAN_EXEC(p)) return BC_STATUS_PARSE_BAD_TOKEN; | 4750 | if (!BC_PARSE_CAN_EXEC(p)) return bc_error("bad token"); |
4732 | s = bc_parse_func(p); | 4751 | s = bc_parse_func(p); |
4733 | } | 4752 | } |
4734 | else | 4753 | else |
@@ -4787,7 +4806,11 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4787 | prev != BC_INST_SCALE && prev != BC_INST_IBASE && | 4806 | prev != BC_INST_SCALE && prev != BC_INST_IBASE && |
4788 | prev != BC_INST_OBASE && prev != BC_INST_LAST) | 4807 | prev != BC_INST_OBASE && prev != BC_INST_LAST) |
4789 | { | 4808 | { |
4790 | s = BC_STATUS_PARSE_BAD_ASSIGN; | 4809 | s = bc_error("bad assignment:" |
4810 | " left side must be scale," | ||
4811 | " ibase, obase, last, var," | ||
4812 | " or array element" | ||
4813 | ); | ||
4791 | break; | 4814 | break; |
4792 | } | 4815 | } |
4793 | } | 4816 | } |
@@ -4807,10 +4830,10 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4807 | case BC_LEX_OP_BOOL_OR: | 4830 | case BC_LEX_OP_BOOL_OR: |
4808 | case BC_LEX_OP_BOOL_AND: | 4831 | case BC_LEX_OP_BOOL_AND: |
4809 | { | 4832 | { |
4810 | if (((t == BC_LEX_OP_BOOL_NOT) != bin_last) || | 4833 | if (((t == BC_LEX_OP_BOOL_NOT) != bin_last) |
4811 | (t != BC_LEX_OP_BOOL_NOT && prev == BC_INST_BOOL_NOT)) | 4834 | || (t != BC_LEX_OP_BOOL_NOT && prev == BC_INST_BOOL_NOT) |
4812 | { | 4835 | ) { |
4813 | return BC_STATUS_PARSE_BAD_EXP; | 4836 | return bc_error("bad expression"); |
4814 | } | 4837 | } |
4815 | 4838 | ||
4816 | nrelops += t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT; | 4839 | nrelops += t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT; |
@@ -4824,8 +4847,8 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4824 | 4847 | ||
4825 | case BC_LEX_LPAREN: | 4848 | case BC_LEX_LPAREN: |
4826 | { | 4849 | { |
4827 | if (BC_PARSE_LEAF(prev, rprn)) return BC_STATUS_PARSE_BAD_EXP; | 4850 | if (BC_PARSE_LEAF(prev, rprn)) |
4828 | 4851 | return bc_error("bad expression"); | |
4829 | ++nparens; | 4852 | ++nparens; |
4830 | paren_expr = rprn = bin_last = false; | 4853 | paren_expr = rprn = bin_last = false; |
4831 | get_token = true; | 4854 | get_token = true; |
@@ -4837,7 +4860,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4837 | case BC_LEX_RPAREN: | 4860 | case BC_LEX_RPAREN: |
4838 | { | 4861 | { |
4839 | if (bin_last || prev == BC_INST_BOOL_NOT) | 4862 | if (bin_last || prev == BC_INST_BOOL_NOT) |
4840 | return BC_STATUS_PARSE_BAD_EXP; | 4863 | return bc_error("bad expression"); |
4841 | 4864 | ||
4842 | if (nparens == 0) { | 4865 | if (nparens == 0) { |
4843 | s = BC_STATUS_SUCCESS; | 4866 | s = BC_STATUS_SUCCESS; |
@@ -4859,8 +4882,8 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4859 | 4882 | ||
4860 | case BC_LEX_NAME: | 4883 | case BC_LEX_NAME: |
4861 | { | 4884 | { |
4862 | if (BC_PARSE_LEAF(prev, rprn)) return BC_STATUS_PARSE_BAD_EXP; | 4885 | if (BC_PARSE_LEAF(prev, rprn)) |
4863 | 4886 | return bc_error("bad expression"); | |
4864 | paren_expr = true; | 4887 | paren_expr = true; |
4865 | rprn = get_token = bin_last = false; | 4888 | rprn = get_token = bin_last = false; |
4866 | s = bc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL); | 4889 | s = bc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL); |
@@ -4871,8 +4894,8 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4871 | 4894 | ||
4872 | case BC_LEX_NUMBER: | 4895 | case BC_LEX_NUMBER: |
4873 | { | 4896 | { |
4874 | if (BC_PARSE_LEAF(prev, rprn)) return BC_STATUS_PARSE_BAD_EXP; | 4897 | if (BC_PARSE_LEAF(prev, rprn)) |
4875 | 4898 | return bc_error("bad expression"); | |
4876 | bc_parse_number(p, &prev, &nexprs); | 4899 | bc_parse_number(p, &prev, &nexprs); |
4877 | paren_expr = get_token = true; | 4900 | paren_expr = get_token = true; |
4878 | rprn = bin_last = false; | 4901 | rprn = bin_last = false; |
@@ -4884,8 +4907,8 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4884 | case BC_LEX_KEY_LAST: | 4907 | case BC_LEX_KEY_LAST: |
4885 | case BC_LEX_KEY_OBASE: | 4908 | case BC_LEX_KEY_OBASE: |
4886 | { | 4909 | { |
4887 | if (BC_PARSE_LEAF(prev, rprn)) return BC_STATUS_PARSE_BAD_EXP; | 4910 | if (BC_PARSE_LEAF(prev, rprn)) |
4888 | 4911 | return bc_error("bad expression"); | |
4889 | prev = (char) (t - BC_LEX_KEY_IBASE + BC_INST_IBASE); | 4912 | prev = (char) (t - BC_LEX_KEY_IBASE + BC_INST_IBASE); |
4890 | bc_parse_push(p, (char) prev); | 4913 | bc_parse_push(p, (char) prev); |
4891 | 4914 | ||
@@ -4899,8 +4922,8 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4899 | case BC_LEX_KEY_LENGTH: | 4922 | case BC_LEX_KEY_LENGTH: |
4900 | case BC_LEX_KEY_SQRT: | 4923 | case BC_LEX_KEY_SQRT: |
4901 | { | 4924 | { |
4902 | if (BC_PARSE_LEAF(prev, rprn)) return BC_STATUS_PARSE_BAD_EXP; | 4925 | if (BC_PARSE_LEAF(prev, rprn)) |
4903 | 4926 | return bc_error("bad expression"); | |
4904 | s = bc_parse_builtin(p, t, flags, &prev); | 4927 | s = bc_parse_builtin(p, t, flags, &prev); |
4905 | paren_expr = true; | 4928 | paren_expr = true; |
4906 | rprn = get_token = bin_last = false; | 4929 | rprn = get_token = bin_last = false; |
@@ -4912,9 +4935,9 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4912 | case BC_LEX_KEY_READ: | 4935 | case BC_LEX_KEY_READ: |
4913 | { | 4936 | { |
4914 | if (BC_PARSE_LEAF(prev, rprn)) | 4937 | if (BC_PARSE_LEAF(prev, rprn)) |
4915 | return BC_STATUS_PARSE_BAD_EXP; | 4938 | return bc_error("bad expression"); |
4916 | else if (flags & BC_PARSE_NOREAD) | 4939 | else if (flags & BC_PARSE_NOREAD) |
4917 | s = BC_STATUS_EXEC_REC_READ; | 4940 | s = bc_error("read() call inside of a read() call"); |
4918 | else | 4941 | else |
4919 | s = bc_parse_read(p); | 4942 | s = bc_parse_read(p); |
4920 | 4943 | ||
@@ -4928,8 +4951,8 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4928 | 4951 | ||
4929 | case BC_LEX_KEY_SCALE: | 4952 | case BC_LEX_KEY_SCALE: |
4930 | { | 4953 | { |
4931 | if (BC_PARSE_LEAF(prev, rprn)) return BC_STATUS_PARSE_BAD_EXP; | 4954 | if (BC_PARSE_LEAF(prev, rprn)) |
4932 | 4955 | return bc_error("bad expression"); | |
4933 | s = bc_parse_scale(p, &prev, flags); | 4956 | s = bc_parse_scale(p, &prev, flags); |
4934 | paren_expr = true; | 4957 | paren_expr = true; |
4935 | rprn = get_token = bin_last = false; | 4958 | rprn = get_token = bin_last = false; |
@@ -4941,7 +4964,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4941 | 4964 | ||
4942 | default: | 4965 | default: |
4943 | { | 4966 | { |
4944 | s = BC_STATUS_PARSE_BAD_TOKEN; | 4967 | s = bc_error("bad token"); |
4945 | break; | 4968 | break; |
4946 | } | 4969 | } |
4947 | } | 4970 | } |
@@ -4958,7 +4981,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4958 | assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN; | 4981 | assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN; |
4959 | 4982 | ||
4960 | if (top == BC_LEX_LPAREN || top == BC_LEX_RPAREN) | 4983 | if (top == BC_LEX_LPAREN || top == BC_LEX_RPAREN) |
4961 | return BC_STATUS_PARSE_BAD_EXP; | 4984 | return bc_error("bad expression"); |
4962 | 4985 | ||
4963 | bc_parse_push(p, BC_PARSE_TOKEN_INST(top)); | 4986 | bc_parse_push(p, BC_PARSE_TOKEN_INST(top)); |
4964 | 4987 | ||
@@ -4966,11 +4989,14 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4966 | bc_vec_pop(&p->ops); | 4989 | bc_vec_pop(&p->ops); |
4967 | } | 4990 | } |
4968 | 4991 | ||
4969 | s = BC_STATUS_PARSE_BAD_EXP; | 4992 | if (prev == BC_INST_BOOL_NOT || nexprs != 1) |
4970 | if (prev == BC_INST_BOOL_NOT || nexprs != 1) return s; | 4993 | return bc_error("bad expression"); |
4971 | 4994 | ||
4972 | for (i = 0; s && i < next.len; ++i) s *= t != next.tokens[i]; | 4995 | for (i = 0; i < next.len; ++i) |
4973 | if (s) return s; | 4996 | if (t == next.tokens[i]) |
4997 | goto ok; | ||
4998 | return bc_error("bad expression"); | ||
4999 | ok: | ||
4974 | 5000 | ||
4975 | if (!(flags & BC_PARSE_REL) && nrelops) { | 5001 | if (!(flags & BC_PARSE_REL) && nrelops) { |
4976 | s = bc_vm_posixError(BC_STATUS_POSIX_REL_POS, p->l.f, p->l.line, NULL); | 5002 | s = bc_vm_posixError(BC_STATUS_POSIX_REL_POS, p->l.f, p->l.line, NULL); |
@@ -5008,7 +5034,7 @@ static BcStatus dc_parse_register(BcParse *p) | |||
5008 | 5034 | ||
5009 | s = bc_lex_next(&p->l); | 5035 | s = bc_lex_next(&p->l); |
5010 | if (s) return s; | 5036 | if (s) return s; |
5011 | if (p->l.t.t != BC_LEX_NAME) return BC_STATUS_PARSE_BAD_TOKEN; | 5037 | if (p->l.t.t != BC_LEX_NAME) return bc_error("bad token"); |
5012 | 5038 | ||
5013 | name = xstrdup(p->l.t.v.v); | 5039 | name = xstrdup(p->l.t.v.v); |
5014 | bc_parse_pushName(p, name); | 5040 | bc_parse_pushName(p, name); |
@@ -5115,7 +5141,8 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | |||
5115 | if (t == BC_LEX_NEG) { | 5141 | if (t == BC_LEX_NEG) { |
5116 | s = bc_lex_next(&p->l); | 5142 | s = bc_lex_next(&p->l); |
5117 | if (s) return s; | 5143 | if (s) return s; |
5118 | if (p->l.t.t != BC_LEX_NUMBER) return BC_STATUS_PARSE_BAD_TOKEN; | 5144 | if (p->l.t.t != BC_LEX_NUMBER) |
5145 | return bc_error("bad token"); | ||
5119 | } | 5146 | } |
5120 | 5147 | ||
5121 | bc_parse_number(p, &prev, &p->nbraces); | 5148 | bc_parse_number(p, &prev, &p->nbraces); |
@@ -5129,7 +5156,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | |||
5129 | case BC_LEX_KEY_READ: | 5156 | case BC_LEX_KEY_READ: |
5130 | { | 5157 | { |
5131 | if (flags & BC_PARSE_NOREAD) | 5158 | if (flags & BC_PARSE_NOREAD) |
5132 | s = BC_STATUS_EXEC_REC_READ; | 5159 | s = bc_error("read() call inside of a read() call"); |
5133 | else | 5160 | else |
5134 | bc_parse_push(p, BC_INST_READ); | 5161 | bc_parse_push(p, BC_INST_READ); |
5135 | get_token = true; | 5162 | get_token = true; |
@@ -5164,7 +5191,7 @@ static BcStatus dc_parse_token(BcParse *p, BcLexType t, uint8_t flags) | |||
5164 | 5191 | ||
5165 | default: | 5192 | default: |
5166 | { | 5193 | { |
5167 | s = BC_STATUS_PARSE_BAD_TOKEN; | 5194 | s = bc_error("bad token"); |
5168 | get_token = true; | 5195 | get_token = true; |
5169 | break; | 5196 | break; |
5170 | } | 5197 | } |
@@ -5206,7 +5233,7 @@ static BcStatus dc_parse_parse(BcParse *p) | |||
5206 | BcStatus s; | 5233 | BcStatus s; |
5207 | 5234 | ||
5208 | if (p->l.t.t == BC_LEX_EOF) | 5235 | if (p->l.t.t == BC_LEX_EOF) |
5209 | s = BC_STATUS_LEX_EOF; | 5236 | s = bc_error("end of file"); |
5210 | else | 5237 | else |
5211 | s = dc_parse_expr(p, 0); | 5238 | s = dc_parse_expr(p, 0); |
5212 | 5239 | ||
@@ -5349,7 +5376,8 @@ static BcStatus bc_program_binOpPrep(BcResult **l, BcNum **ln, | |||
5349 | bool hex; | 5376 | bool hex; |
5350 | BcResultType lt, rt; | 5377 | BcResultType lt, rt; |
5351 | 5378 | ||
5352 | if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK; | 5379 | if (!BC_PROG_STACK(&G.prog.results, 2)) |
5380 | return bc_error("stack has too few elements"); | ||
5353 | 5381 | ||
5354 | *r = bc_vec_item_rev(&G.prog.results, 0); | 5382 | *r = bc_vec_item_rev(&G.prog.results, 0); |
5355 | *l = bc_vec_item_rev(&G.prog.results, 1); | 5383 | *l = bc_vec_item_rev(&G.prog.results, 1); |
@@ -5371,8 +5399,9 @@ static BcStatus bc_program_binOpPrep(BcResult **l, BcNum **ln, | |||
5371 | } | 5399 | } |
5372 | 5400 | ||
5373 | if (!BC_PROG_NUM((*l), (*ln)) && (!assign || (*l)->t != BC_RESULT_VAR)) | 5401 | if (!BC_PROG_NUM((*l), (*ln)) && (!assign || (*l)->t != BC_RESULT_VAR)) |
5374 | return BC_STATUS_EXEC_BAD_TYPE; | 5402 | return bc_error("variable is wrong type"); |
5375 | if (!assign && !BC_PROG_NUM((*r), (*ln))) return BC_STATUS_EXEC_BAD_TYPE; | 5403 | if (!assign && !BC_PROG_NUM((*r), (*ln))) |
5404 | return bc_error("variable is wrong type"); | ||
5376 | 5405 | ||
5377 | return s; | 5406 | return s; |
5378 | } | 5407 | } |
@@ -5389,13 +5418,15 @@ static BcStatus bc_program_prep(BcResult **r, BcNum **n) | |||
5389 | { | 5418 | { |
5390 | BcStatus s; | 5419 | BcStatus s; |
5391 | 5420 | ||
5392 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 5421 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
5422 | return bc_error("stack has too few elements"); | ||
5393 | *r = bc_vec_top(&G.prog.results); | 5423 | *r = bc_vec_top(&G.prog.results); |
5394 | 5424 | ||
5395 | s = bc_program_num(*r, n, false); | 5425 | s = bc_program_num(*r, n, false); |
5396 | if (s) return s; | 5426 | if (s) return s; |
5397 | 5427 | ||
5398 | if (!BC_PROG_NUM((*r), (*n))) return BC_STATUS_EXEC_BAD_TYPE; | 5428 | if (!BC_PROG_NUM((*r), (*n))) |
5429 | return bc_error("variable is wrong type"); | ||
5399 | 5430 | ||
5400 | return s; | 5431 | return s; |
5401 | } | 5432 | } |
@@ -5439,7 +5470,8 @@ static BcStatus bc_program_read(void) | |||
5439 | 5470 | ||
5440 | for (i = 0; i < G.prog.stack.len; ++i) { | 5471 | for (i = 0; i < G.prog.stack.len; ++i) { |
5441 | BcInstPtr *ip_ptr = bc_vec_item(&G.prog.stack, i); | 5472 | BcInstPtr *ip_ptr = bc_vec_item(&G.prog.stack, i); |
5442 | if (ip_ptr->func == BC_PROG_READ) return BC_STATUS_EXEC_REC_READ; | 5473 | if (ip_ptr->func == BC_PROG_READ) |
5474 | return bc_error("read() call inside of a read() call"); | ||
5443 | } | 5475 | } |
5444 | 5476 | ||
5445 | bc_vec_npop(&f->code, f->code.len); | 5477 | bc_vec_npop(&f->code, f->code.len); |
@@ -5457,7 +5489,7 @@ static BcStatus bc_program_read(void) | |||
5457 | if (s) goto exec_err; | 5489 | if (s) goto exec_err; |
5458 | 5490 | ||
5459 | if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) { | 5491 | if (parse.l.t.t != BC_LEX_NLINE && parse.l.t.t != BC_LEX_EOF) { |
5460 | s = BC_STATUS_EXEC_BAD_READ_EXPR; | 5492 | s = bc_error("bad read() expression"); |
5461 | goto exec_err; | 5493 | goto exec_err; |
5462 | } | 5494 | } |
5463 | 5495 | ||
@@ -5600,7 +5632,8 @@ static BcStatus bc_program_print(char inst, size_t idx) | |||
5600 | BcNum *num = NULL; | 5632 | BcNum *num = NULL; |
5601 | bool pop = inst != BC_INST_PRINT; | 5633 | bool pop = inst != BC_INST_PRINT; |
5602 | 5634 | ||
5603 | if (!BC_PROG_STACK(&G.prog.results, idx + 1)) return BC_STATUS_EXEC_STACK; | 5635 | if (!BC_PROG_STACK(&G.prog.results, idx + 1)) |
5636 | return bc_error("stack has too few elements"); | ||
5604 | 5637 | ||
5605 | r = bc_vec_item_rev(&G.prog.results, idx); | 5638 | r = bc_vec_item_rev(&G.prog.results, idx); |
5606 | s = bc_program_num(r, &num, false); | 5639 | s = bc_program_num(r, &num, false); |
@@ -5731,7 +5764,8 @@ static BcStatus bc_program_assignStr(BcResult *r, BcVec *v, | |||
5731 | res.t = BC_RESULT_STR; | 5764 | res.t = BC_RESULT_STR; |
5732 | 5765 | ||
5733 | if (!push) { | 5766 | if (!push) { |
5734 | if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK; | 5767 | if (!BC_PROG_STACK(&G.prog.results, 2)) |
5768 | return bc_error("stack has too few elements"); | ||
5735 | bc_vec_pop(v); | 5769 | bc_vec_pop(v); |
5736 | bc_vec_pop(&G.prog.results); | 5770 | bc_vec_pop(&G.prog.results); |
5737 | } | 5771 | } |
@@ -5752,14 +5786,17 @@ static BcStatus bc_program_copyToVar(char *name, bool var) | |||
5752 | BcVec *v; | 5786 | BcVec *v; |
5753 | BcNum *n; | 5787 | BcNum *n; |
5754 | 5788 | ||
5755 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 5789 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
5790 | return bc_error("stack has too few elements"); | ||
5756 | 5791 | ||
5757 | ptr = bc_vec_top(&G.prog.results); | 5792 | ptr = bc_vec_top(&G.prog.results); |
5758 | if ((ptr->t == BC_RESULT_ARRAY) != !var) return BC_STATUS_EXEC_BAD_TYPE; | 5793 | if ((ptr->t == BC_RESULT_ARRAY) != !var) |
5794 | return bc_error("variable is wrong type"); | ||
5759 | v = bc_program_search(name, var); | 5795 | v = bc_program_search(name, var); |
5760 | 5796 | ||
5761 | #if ENABLE_DC | 5797 | #if ENABLE_DC |
5762 | if (ptr->t == BC_RESULT_STR && !var) return BC_STATUS_EXEC_BAD_TYPE; | 5798 | if (ptr->t == BC_RESULT_STR && !var) |
5799 | return bc_error("variable is wrong type"); | ||
5763 | if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(ptr, v, true); | 5800 | if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(ptr, v, true); |
5764 | #endif | 5801 | #endif |
5765 | 5802 | ||
@@ -5804,7 +5841,8 @@ static BcStatus bc_program_assign(char inst) | |||
5804 | 5841 | ||
5805 | BcVec *v; | 5842 | BcVec *v; |
5806 | 5843 | ||
5807 | if (left->t != BC_RESULT_VAR) return BC_STATUS_EXEC_BAD_TYPE; | 5844 | if (left->t != BC_RESULT_VAR) |
5845 | return bc_error("variable is wrong type"); | ||
5808 | v = bc_program_search(left->d.id.name, true); | 5846 | v = bc_program_search(left->d.id.name, true); |
5809 | 5847 | ||
5810 | return bc_program_assignStr(right, v, false); | 5848 | return bc_program_assignStr(right, v, false); |
@@ -5812,11 +5850,15 @@ static BcStatus bc_program_assign(char inst) | |||
5812 | #endif | 5850 | #endif |
5813 | 5851 | ||
5814 | if (left->t == BC_RESULT_CONSTANT || left->t == BC_RESULT_TEMP) | 5852 | if (left->t == BC_RESULT_CONSTANT || left->t == BC_RESULT_TEMP) |
5815 | return BC_STATUS_PARSE_BAD_ASSIGN; | 5853 | return bc_error("bad assignment:" |
5854 | " left side must be scale," | ||
5855 | " ibase, obase, last, var," | ||
5856 | " or array element" | ||
5857 | ); | ||
5816 | 5858 | ||
5817 | #if ENABLE_BC | 5859 | #if ENABLE_BC |
5818 | if (inst == BC_INST_ASSIGN_DIVIDE && !bc_num_cmp(r, &G.prog.zero)) | 5860 | if (inst == BC_INST_ASSIGN_DIVIDE && !bc_num_cmp(r, &G.prog.zero)) |
5819 | return BC_STATUS_MATH_DIVIDE_BY_ZERO; | 5861 | return bc_error("divide by zero"); |
5820 | 5862 | ||
5821 | if (assign) | 5863 | if (assign) |
5822 | bc_num_copy(l, r); | 5864 | bc_num_copy(l, r); |
@@ -5829,25 +5871,35 @@ static BcStatus bc_program_assign(char inst) | |||
5829 | #endif | 5871 | #endif |
5830 | 5872 | ||
5831 | if (ib || sc || left->t == BC_RESULT_OBASE) { | 5873 | if (ib || sc || left->t == BC_RESULT_OBASE) { |
5832 | 5874 | static const char *const msg[] = { | |
5875 | "bad ibase; must be [2, 16]", //BC_RESULT_IBASE | ||
5876 | "bad scale; must be [0, BC_SCALE_MAX]", //BC_RESULT_SCALE | ||
5877 | "?1", //BC_RESULT_LAST | ||
5878 | "?2", //BC_RESULT_CONSTANT | ||
5879 | "?3", //BC_RESULT_ONE | ||
5880 | "bad obase; must be [2, BC_BASE_MAX]", //BC_RESULT_OBASE | ||
5881 | }; | ||
5833 | size_t *ptr; | 5882 | size_t *ptr; |
5834 | 5883 | ||
5835 | s = bc_num_ulong(l, &val); | 5884 | s = bc_num_ulong(l, &val); |
5836 | if (s) return s; | 5885 | if (s) |
5837 | s = left->t - BC_RESULT_IBASE + BC_STATUS_EXEC_BAD_IBASE; | 5886 | return s; |
5838 | 5887 | s = left->t - BC_RESULT_IBASE; | |
5839 | if (sc) { | 5888 | if (sc) { |
5840 | max = BC_MAX_SCALE; | 5889 | max = BC_MAX_SCALE; |
5841 | ptr = &G.prog.scale; | 5890 | ptr = &G.prog.scale; |
5842 | } | 5891 | } |
5843 | else { | 5892 | else { |
5844 | if (val < BC_NUM_MIN_BASE) return s; | 5893 | if (val < BC_NUM_MIN_BASE) |
5894 | return bc_error(msg[s]); | ||
5845 | max = ib ? BC_NUM_MAX_IBASE : BC_MAX_OBASE; | 5895 | max = ib ? BC_NUM_MAX_IBASE : BC_MAX_OBASE; |
5846 | ptr = ib ? &G.prog.ib_t : &G.prog.ob_t; | 5896 | ptr = ib ? &G.prog.ib_t : &G.prog.ob_t; |
5847 | } | 5897 | } |
5848 | 5898 | ||
5849 | if (val > max) return s; | 5899 | if (val > max) |
5850 | if (!sc) bc_num_copy(ib ? &G.prog.ib : &G.prog.ob, l); | 5900 | return bc_error(msg[s]); |
5901 | if (!sc) | ||
5902 | bc_num_copy(ib ? &G.prog.ib : &G.prog.ob, l); | ||
5851 | 5903 | ||
5852 | *ptr = (size_t) val; | 5904 | *ptr = (size_t) val; |
5853 | s = BC_STATUS_SUCCESS; | 5905 | s = BC_STATUS_SUCCESS; |
@@ -5884,7 +5936,7 @@ static BcStatus bc_program_pushVar(char *code, size_t *bgn, | |||
5884 | 5936 | ||
5885 | if (!BC_PROG_STACK(v, 2 - copy)) { | 5937 | if (!BC_PROG_STACK(v, 2 - copy)) { |
5886 | free(name); | 5938 | free(name); |
5887 | return BC_STATUS_EXEC_STACK; | 5939 | return bc_error("stack has too few elements"); |
5888 | } | 5940 | } |
5889 | 5941 | ||
5890 | free(name); | 5942 | free(name); |
@@ -5936,7 +5988,7 @@ static BcStatus bc_program_pushArray(char *code, size_t *bgn, | |||
5936 | if (s) goto err; | 5988 | if (s) goto err; |
5937 | 5989 | ||
5938 | if (temp > BC_MAX_DIM) { | 5990 | if (temp > BC_MAX_DIM) { |
5939 | s = BC_STATUS_EXEC_ARRAY_LEN; | 5991 | s = bc_error("array too long; must be [1, BC_DIM_MAX]"); |
5940 | goto err; | 5992 | goto err; |
5941 | } | 5993 | } |
5942 | 5994 | ||
@@ -6010,7 +6062,7 @@ static BcStatus bc_program_call(char *code, size_t *idx) | |||
6010 | arg = bc_vec_top(&G.prog.results); | 6062 | arg = bc_vec_top(&G.prog.results); |
6011 | 6063 | ||
6012 | if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR) | 6064 | if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR) |
6013 | return BC_STATUS_EXEC_BAD_TYPE; | 6065 | return bc_error("variable is wrong type"); |
6014 | 6066 | ||
6015 | s = bc_program_copyToVar(a->name, a->idx); | 6067 | s = bc_program_copyToVar(a->name, a->idx); |
6016 | if (s) return s; | 6068 | if (s) return s; |
@@ -6046,7 +6098,7 @@ static BcStatus bc_program_return(char inst) | |||
6046 | BcInstPtr *ip = bc_vec_top(&G.prog.stack); | 6098 | BcInstPtr *ip = bc_vec_top(&G.prog.stack); |
6047 | 6099 | ||
6048 | if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET)) | 6100 | if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET)) |
6049 | return BC_STATUS_EXEC_STACK; | 6101 | return bc_error("stack has too few elements"); |
6050 | 6102 | ||
6051 | f = bc_vec_item(&G.prog.fns, ip->func); | 6103 | f = bc_vec_item(&G.prog.fns, ip->func); |
6052 | res.t = BC_RESULT_TEMP; | 6104 | res.t = BC_RESULT_TEMP; |
@@ -6108,14 +6160,16 @@ static BcStatus bc_program_builtin(char inst) | |||
6108 | BcResult res; | 6160 | BcResult res; |
6109 | bool len = inst == BC_INST_LENGTH; | 6161 | bool len = inst == BC_INST_LENGTH; |
6110 | 6162 | ||
6111 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 6163 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6164 | return bc_error("stack has too few elements"); | ||
6112 | opnd = bc_vec_top(&G.prog.results); | 6165 | opnd = bc_vec_top(&G.prog.results); |
6113 | 6166 | ||
6114 | s = bc_program_num(opnd, &num, false); | 6167 | s = bc_program_num(opnd, &num, false); |
6115 | if (s) return s; | 6168 | if (s) return s; |
6116 | 6169 | ||
6117 | #if ENABLE_DC | 6170 | #if ENABLE_DC |
6118 | if (!BC_PROG_NUM(opnd, num) && !len) return BC_STATUS_EXEC_BAD_TYPE; | 6171 | if (!BC_PROG_NUM(opnd, num) && !len) |
6172 | return bc_error("variable is wrong type"); | ||
6119 | #endif | 6173 | #endif |
6120 | 6174 | ||
6121 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 6175 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
@@ -6180,14 +6234,16 @@ static BcStatus bc_program_modexp(void) | |||
6180 | BcResult *r1, *r2, *r3, res; | 6234 | BcResult *r1, *r2, *r3, res; |
6181 | BcNum *n1, *n2, *n3; | 6235 | BcNum *n1, *n2, *n3; |
6182 | 6236 | ||
6183 | if (!BC_PROG_STACK(&G.prog.results, 3)) return BC_STATUS_EXEC_STACK; | 6237 | if (!BC_PROG_STACK(&G.prog.results, 3)) |
6238 | return bc_error("stack has too few elements"); | ||
6184 | s = bc_program_binOpPrep(&r2, &n2, &r3, &n3, false); | 6239 | s = bc_program_binOpPrep(&r2, &n2, &r3, &n3, false); |
6185 | if (s) return s; | 6240 | if (s) return s; |
6186 | 6241 | ||
6187 | r1 = bc_vec_item_rev(&G.prog.results, 2); | 6242 | r1 = bc_vec_item_rev(&G.prog.results, 2); |
6188 | s = bc_program_num(r1, &n1, false); | 6243 | s = bc_program_num(r1, &n1, false); |
6189 | if (s) return s; | 6244 | if (s) return s; |
6190 | if (!BC_PROG_NUM(r1, n1)) return BC_STATUS_EXEC_BAD_TYPE; | 6245 | if (!BC_PROG_NUM(r1, n1)) |
6246 | return bc_error("variable is wrong type"); | ||
6191 | 6247 | ||
6192 | // Make sure that the values have their pointers updated, if necessary. | 6248 | // Make sure that the values have their pointers updated, if necessary. |
6193 | if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) { | 6249 | if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) { |
@@ -6238,7 +6294,8 @@ static BcStatus bc_program_asciify(void) | |||
6238 | size_t len = G.prog.strs.len, idx; | 6294 | size_t len = G.prog.strs.len, idx; |
6239 | unsigned long val; | 6295 | unsigned long val; |
6240 | 6296 | ||
6241 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 6297 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6298 | return bc_error("stack has too few elements"); | ||
6242 | r = bc_vec_top(&G.prog.results); | 6299 | r = bc_vec_top(&G.prog.results); |
6243 | 6300 | ||
6244 | s = bc_program_num(r, &num, false); | 6301 | s = bc_program_num(r, &num, false); |
@@ -6306,7 +6363,8 @@ static BcStatus bc_program_printStream(void) | |||
6306 | size_t idx; | 6363 | size_t idx; |
6307 | char *str; | 6364 | char *str; |
6308 | 6365 | ||
6309 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 6366 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6367 | return bc_error("stack has too few elements"); | ||
6310 | r = bc_vec_top(&G.prog.results); | 6368 | r = bc_vec_top(&G.prog.results); |
6311 | 6369 | ||
6312 | s = bc_program_num(r, &n, false); | 6370 | s = bc_program_num(r, &n, false); |
@@ -6338,7 +6396,7 @@ static BcStatus bc_program_nquit(void) | |||
6338 | bc_vec_pop(&G.prog.results); | 6396 | bc_vec_pop(&G.prog.results); |
6339 | 6397 | ||
6340 | if (G.prog.stack.len < val) | 6398 | if (G.prog.stack.len < val) |
6341 | return BC_STATUS_EXEC_STACK; | 6399 | return bc_error("stack has too few elements"); |
6342 | if (G.prog.stack.len == val) | 6400 | if (G.prog.stack.len == val) |
6343 | quit(); | 6401 | quit(); |
6344 | 6402 | ||
@@ -6360,7 +6418,8 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6360 | BcNum *n; | 6418 | BcNum *n; |
6361 | bool exec; | 6419 | bool exec; |
6362 | 6420 | ||
6363 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 6421 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6422 | return bc_error("stack has too few elements"); | ||
6364 | 6423 | ||
6365 | r = bc_vec_top(&G.prog.results); | 6424 | r = bc_vec_top(&G.prog.results); |
6366 | 6425 | ||
@@ -6393,7 +6452,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6393 | 6452 | ||
6394 | if (!exec) goto exit; | 6453 | if (!exec) goto exit; |
6395 | if (!BC_PROG_STR(n)) { | 6454 | if (!BC_PROG_STR(n)) { |
6396 | s = BC_STATUS_EXEC_BAD_TYPE; | 6455 | s = bc_error("variable is wrong type"); |
6397 | goto exit; | 6456 | goto exit; |
6398 | } | 6457 | } |
6399 | 6458 | ||
@@ -6425,7 +6484,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6425 | if (s) goto err; | 6484 | if (s) goto err; |
6426 | 6485 | ||
6427 | if (prs.l.t.t != BC_LEX_EOF) { | 6486 | if (prs.l.t.t != BC_LEX_EOF) { |
6428 | s = BC_STATUS_PARSE_BAD_EXP; | 6487 | s = bc_error("bad expression"); |
6429 | goto err; | 6488 | goto err; |
6430 | } | 6489 | } |
6431 | 6490 | ||
@@ -6652,7 +6711,7 @@ static BcStatus bc_program_exec(void) | |||
6652 | case BC_INST_POP: | 6711 | case BC_INST_POP: |
6653 | { | 6712 | { |
6654 | if (!BC_PROG_STACK(&G.prog.results, 1)) | 6713 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6655 | s = BC_STATUS_EXEC_STACK; | 6714 | s = bc_error("stack has too few elements"); |
6656 | else | 6715 | else |
6657 | bc_vec_pop(&G.prog.results); | 6716 | bc_vec_pop(&G.prog.results); |
6658 | break; | 6717 | break; |
@@ -6764,7 +6823,8 @@ static BcStatus bc_program_exec(void) | |||
6764 | 6823 | ||
6765 | case BC_INST_DUPLICATE: | 6824 | case BC_INST_DUPLICATE: |
6766 | { | 6825 | { |
6767 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; | 6826 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6827 | return bc_error("stack has too few elements"); | ||
6768 | ptr = bc_vec_top(&G.prog.results); | 6828 | ptr = bc_vec_top(&G.prog.results); |
6769 | bc_result_copy(&r, ptr); | 6829 | bc_result_copy(&r, ptr); |
6770 | bc_vec_push(&G.prog.results, &r); | 6830 | bc_vec_push(&G.prog.results, &r); |
@@ -6775,7 +6835,8 @@ static BcStatus bc_program_exec(void) | |||
6775 | { | 6835 | { |
6776 | BcResult *ptr2; | 6836 | BcResult *ptr2; |
6777 | 6837 | ||
6778 | if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK; | 6838 | if (!BC_PROG_STACK(&G.prog.results, 2)) |
6839 | return bc_error("stack has too few elements"); | ||
6779 | 6840 | ||
6780 | ptr = bc_vec_item_rev(&G.prog.results, 0); | 6841 | ptr = bc_vec_item_rev(&G.prog.results, 0); |
6781 | ptr2 = bc_vec_item_rev(&G.prog.results, 1); | 6842 | ptr2 = bc_vec_item_rev(&G.prog.results, 1); |
@@ -6863,6 +6924,7 @@ static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line) | |||
6863 | fprintf(stderr, bc_err_line + 4 * !line, line); | 6924 | fprintf(stderr, bc_err_line + 4 * !line, line); |
6864 | } | 6925 | } |
6865 | 6926 | ||
6927 | /// | ||
6866 | return s * (!G.ttyin || !!strcmp(file, bc_program_stdin_name)); | 6928 | return s * (!G.ttyin || !!strcmp(file, bc_program_stdin_name)); |
6867 | } | 6929 | } |
6868 | 6930 | ||
@@ -6983,7 +7045,8 @@ static BcStatus bc_vm_file(const char *file) | |||
6983 | main_func = bc_vec_item(&G.prog.fns, BC_PROG_MAIN); | 7045 | main_func = bc_vec_item(&G.prog.fns, BC_PROG_MAIN); |
6984 | ip = bc_vec_item(&G.prog.stack, 0); | 7046 | ip = bc_vec_item(&G.prog.stack, 0); |
6985 | 7047 | ||
6986 | if (main_func->code.len < ip->idx) s = BC_STATUS_EXEC_FILE_NOT_EXECUTABLE; | 7048 | if (main_func->code.len < ip->idx) |
7049 | s = bc_error("file '%s' is not executable", file); | ||
6987 | 7050 | ||
6988 | err: | 7051 | err: |
6989 | free(data); | 7052 | free(data); |
@@ -7057,12 +7120,16 @@ static BcStatus bc_vm_stdin(void) | |||
7057 | bc_vec_npop(&buffer, buffer.len); | 7120 | bc_vec_npop(&buffer, buffer.len); |
7058 | } | 7121 | } |
7059 | 7122 | ||
7060 | if (str) | 7123 | if (str) { |
7061 | s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, G.prs.l.f, | 7124 | bc_error("string end could not be found"); |
7125 | s = bc_vm_error(BC_STATUS_FAILURE, G.prs.l.f, | ||
7062 | G.prs.l.line); | 7126 | G.prs.l.line); |
7063 | else if (comment) | 7127 | } |
7064 | s = bc_vm_error(BC_STATUS_LEX_NO_COMMENT_END, G.prs.l.f, | 7128 | else if (comment) { |
7129 | bc_error("comment end could not be found"); | ||
7130 | s = bc_vm_error(BC_STATUS_FAILURE, G.prs.l.f, | ||
7065 | G.prs.l.line); | 7131 | G.prs.l.line); |
7132 | } | ||
7066 | 7133 | ||
7067 | err: | 7134 | err: |
7068 | bc_vec_free(&buf); | 7135 | bc_vec_free(&buf); |