diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-02 18:26:38 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | a1d3ca24559254e10549746833a878a3a3273cbe (patch) | |
tree | bfe0bc0b1b668789fc3a5407a2723a62dc5b3cd5 | |
parent | f6c1da5ff38c7f1cf3f3d04875330e56d0937894 (diff) | |
download | busybox-w32-a1d3ca24559254e10549746833a878a3a3273cbe.tar.gz busybox-w32-a1d3ca24559254e10549746833a878a3a3273cbe.tar.bz2 busybox-w32-a1d3ca24559254e10549746833a878a3a3273cbe.zip |
bc: stop passing around pointers to G.prog, they are all constant
function old new delta
bc_program_exec 4523 4562 +39
bc_program_assign 450 482 +32
bc_program_assignStr 131 159 +28
bc_program_print 762 775 +13
bc_program_num 1134 1147 +13
bc_program_search 154 164 +10
bc_num_ulong 85 95 +10
dc_parse_expr 719 727 +8
bc_program_retire 34 40 +6
bc_program_reset 168 174 +6
bc_program_binOpRetire 50 56 +6
bc_program_addFunc 220 226 +6
bc_program_prep 88 89 +1
dc_parse_init 18 17 -1
bc_program_copyToVar 355 354 -1
bc_parse_text 142 141 -1
bc_parse_number 88 87 -1
bc_parse_init 18 17 -1
bc_parse_endBody 423 422 -1
common_parse_init 29 26 -3
bc_parse_string 103 100 -3
bc_parse_addFunc 44 41 -3
bc_program_call 371 366 -5
bc_program_binOpPrep 301 296 -5
bc_program_read 342 336 -6
bc_parse_create 198 192 -6
bc_program_pushArray 143 136 -7
bc_parse_reset 194 187 -7
bc_vm_process 323 315 -8
bc_program_pushVar 236 225 -11
bc_vm_run 1872 1854 -18
bc_parse_name 590 570 -20
bc_program_execStr 594 573 -21
bc_program_modexp 793 763 -30
bc_program_printStream 172 - -172
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 13/21 up/down: 178/-331) Total: -153 bytes
text data bss dec hex filename
988728 485 7296 996509 f349d busybox_old
988575 485 7296 996356 f3404 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 577 |
1 files changed, 284 insertions, 293 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 18d388bd3..221e1529f 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -599,7 +599,7 @@ typedef struct BcLex { | |||
599 | 599 | ||
600 | #define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (char) (i))) | 600 | #define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (char) (i))) |
601 | #define bc_parse_updateFunc(p, f) \ | 601 | #define bc_parse_updateFunc(p, f) \ |
602 | ((p)->func = bc_vec_item(&(p)->prog->fns, ((p)->fidx = (f)))) | 602 | ((p)->func = bc_vec_item(&G.prog.fns, ((p)->fidx = (f)))) |
603 | 603 | ||
604 | #define BC_PARSE_REL (1 << 0) | 604 | #define BC_PARSE_REL (1 << 0) |
605 | #define BC_PARSE_PRINT (1 << 1) | 605 | #define BC_PARSE_PRINT (1 << 1) |
@@ -677,7 +677,6 @@ typedef struct BcParse { | |||
677 | 677 | ||
678 | BcVec ops; | 678 | BcVec ops; |
679 | 679 | ||
680 | struct BcProgram *prog; | ||
681 | BcFunc *func; | 680 | BcFunc *func; |
682 | size_t fidx; | 681 | size_t fidx; |
683 | 682 | ||
@@ -782,8 +781,8 @@ typedef struct BcProgram { | |||
782 | 781 | ||
783 | typedef unsigned long (*BcProgramBuiltIn)(BcNum *); | 782 | typedef unsigned long (*BcProgramBuiltIn)(BcNum *); |
784 | 783 | ||
785 | static void bc_program_addFunc(BcProgram *p, char *name, size_t *idx); | 784 | static void bc_program_addFunc(char *name, size_t *idx); |
786 | static BcStatus bc_program_reset(BcProgram *p, BcStatus s); | 785 | static BcStatus bc_program_reset(BcStatus s); |
787 | 786 | ||
788 | #define BC_FLAG_X (1 << 0) | 787 | #define BC_FLAG_X (1 << 0) |
789 | #define BC_FLAG_W (1 << 1) | 788 | #define BC_FLAG_W (1 << 1) |
@@ -3603,8 +3602,8 @@ static BcStatus dc_lex_token(BcLex *l) | |||
3603 | 3602 | ||
3604 | static void bc_parse_addFunc(BcParse *p, char *name, size_t *idx) | 3603 | static void bc_parse_addFunc(BcParse *p, char *name, size_t *idx) |
3605 | { | 3604 | { |
3606 | bc_program_addFunc(p->prog, name, idx); | 3605 | bc_program_addFunc(name, idx); |
3607 | p->func = bc_vec_item(&p->prog->fns, p->fidx); | 3606 | p->func = bc_vec_item(&G.prog.fns, p->fidx); |
3608 | } | 3607 | } |
3609 | 3608 | ||
3610 | static void bc_parse_pushName(BcParse *p, char *name) | 3609 | static void bc_parse_pushName(BcParse *p, char *name) |
@@ -3633,9 +3632,9 @@ static void bc_parse_pushIndex(BcParse *p, size_t idx) | |||
3633 | static void bc_parse_number(BcParse *p, BcInst *prev, size_t *nexs) | 3632 | static void bc_parse_number(BcParse *p, BcInst *prev, size_t *nexs) |
3634 | { | 3633 | { |
3635 | char *num = xstrdup(p->l.t.v.v); | 3634 | char *num = xstrdup(p->l.t.v.v); |
3636 | size_t idx = p->prog->consts.len; | 3635 | size_t idx = G.prog.consts.len; |
3637 | 3636 | ||
3638 | bc_vec_push(&p->prog->consts, &num); | 3637 | bc_vec_push(&G.prog.consts, &num); |
3639 | 3638 | ||
3640 | bc_parse_push(p, BC_INST_NUM); | 3639 | bc_parse_push(p, BC_INST_NUM); |
3641 | bc_parse_pushIndex(p, idx); | 3640 | bc_parse_pushIndex(p, idx); |
@@ -3648,7 +3647,7 @@ static BcStatus bc_parse_text(BcParse *p, const char *text) | |||
3648 | { | 3647 | { |
3649 | BcStatus s; | 3648 | BcStatus s; |
3650 | 3649 | ||
3651 | p->func = bc_vec_item(&p->prog->fns, p->fidx); | 3650 | p->func = bc_vec_item(&G.prog.fns, p->fidx); |
3652 | 3651 | ||
3653 | if (!strcmp(text, "") && !BC_PARSE_CAN_EXEC(p)) { | 3652 | if (!strcmp(text, "") && !BC_PARSE_CAN_EXEC(p)) { |
3654 | p->l.t.t = BC_LEX_INVALID; | 3653 | p->l.t.t = BC_LEX_INVALID; |
@@ -3681,7 +3680,7 @@ static BcStatus bc_parse_reset(BcParse *p, BcStatus s) | |||
3681 | bc_vec_npop(&p->conds, p->conds.len); | 3680 | bc_vec_npop(&p->conds, p->conds.len); |
3682 | bc_vec_npop(&p->ops, p->ops.len); | 3681 | bc_vec_npop(&p->ops, p->ops.len); |
3683 | 3682 | ||
3684 | return bc_program_reset(p->prog, s); | 3683 | return bc_program_reset(s); |
3685 | } | 3684 | } |
3686 | 3685 | ||
3687 | static void bc_parse_free(BcParse *p) | 3686 | static void bc_parse_free(BcParse *p) |
@@ -3693,7 +3692,7 @@ static void bc_parse_free(BcParse *p) | |||
3693 | bc_lex_free(&p->l); | 3692 | bc_lex_free(&p->l); |
3694 | } | 3693 | } |
3695 | 3694 | ||
3696 | static void bc_parse_create(BcParse *p, BcProgram *prog, size_t func, | 3695 | static void bc_parse_create(BcParse *p, size_t func, |
3697 | BcParseParse parse, BcLexNext next) | 3696 | BcParseParse parse, BcLexNext next) |
3698 | { | 3697 | { |
3699 | memset(p, 0, sizeof(BcParse)); | 3698 | memset(p, 0, sizeof(BcParse)); |
@@ -3706,7 +3705,6 @@ static void bc_parse_create(BcParse *p, BcProgram *prog, size_t func, | |||
3706 | bc_vec_init(&p->ops, sizeof(BcLexType), NULL); | 3705 | bc_vec_init(&p->ops, sizeof(BcLexType), NULL); |
3707 | 3706 | ||
3708 | p->parse = parse; | 3707 | p->parse = parse; |
3709 | p->prog = prog; | ||
3710 | p->auto_part = (p->nbraces = 0); | 3708 | p->auto_part = (p->nbraces = 0); |
3711 | bc_parse_updateFunc(p, func); | 3709 | bc_parse_updateFunc(p, func); |
3712 | } | 3710 | } |
@@ -3810,18 +3808,18 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags) | |||
3810 | goto err; | 3808 | goto err; |
3811 | } | 3809 | } |
3812 | 3810 | ||
3813 | idx = bc_map_index(&p->prog->fn_map, &entry); | 3811 | idx = bc_map_index(&G.prog.fn_map, &entry); |
3814 | 3812 | ||
3815 | if (idx == BC_VEC_INVALID_IDX) { | 3813 | if (idx == BC_VEC_INVALID_IDX) { |
3816 | name = xstrdup(entry.name); | 3814 | name = xstrdup(entry.name); |
3817 | bc_parse_addFunc(p, name, &idx); | 3815 | bc_parse_addFunc(p, name, &idx); |
3818 | idx = bc_map_index(&p->prog->fn_map, &entry); | 3816 | idx = bc_map_index(&G.prog.fn_map, &entry); |
3819 | free(entry.name); | 3817 | free(entry.name); |
3820 | } | 3818 | } |
3821 | else | 3819 | else |
3822 | free(name); | 3820 | free(name); |
3823 | 3821 | ||
3824 | entry_ptr = bc_vec_item(&p->prog->fn_map, idx); | 3822 | entry_ptr = bc_vec_item(&G.prog.fn_map, idx); |
3825 | bc_parse_pushIndex(p, entry_ptr->idx); | 3823 | bc_parse_pushIndex(p, entry_ptr->idx); |
3826 | 3824 | ||
3827 | return bc_lex_next(&p->l); | 3825 | return bc_lex_next(&p->l); |
@@ -4061,8 +4059,8 @@ static BcStatus bc_parse_string(BcParse *p, char inst) | |||
4061 | char *str = xstrdup(p->l.t.v.v); | 4059 | char *str = xstrdup(p->l.t.v.v); |
4062 | 4060 | ||
4063 | bc_parse_push(p, BC_INST_STR); | 4061 | bc_parse_push(p, BC_INST_STR); |
4064 | bc_parse_pushIndex(p, p->prog->strs.len); | 4062 | bc_parse_pushIndex(p, G.prog.strs.len); |
4065 | bc_vec_push(&p->prog->strs, &str); | 4063 | bc_vec_push(&G.prog.strs, &str); |
4066 | bc_parse_push(p, inst); | 4064 | bc_parse_push(p, inst); |
4067 | 4065 | ||
4068 | return bc_lex_next(&p->l); | 4066 | return bc_lex_next(&p->l); |
@@ -5021,9 +5019,9 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
5021 | return s; | 5019 | return s; |
5022 | } | 5020 | } |
5023 | 5021 | ||
5024 | static void bc_parse_init(BcParse *p, BcProgram *prog, size_t func) | 5022 | static void bc_parse_init(BcParse *p, size_t func) |
5025 | { | 5023 | { |
5026 | bc_parse_create(p, prog, func, bc_parse_parse, bc_lex_token); | 5024 | bc_parse_create(p, func, bc_parse_parse, bc_lex_token); |
5027 | } | 5025 | } |
5028 | 5026 | ||
5029 | static BcStatus bc_parse_expression(BcParse *p, uint8_t flags) | 5027 | static BcStatus bc_parse_expression(BcParse *p, uint8_t flags) |
@@ -5051,7 +5049,7 @@ static BcStatus dc_parse_register(BcParse *p) | |||
5051 | static BcStatus dc_parse_string(BcParse *p) | 5049 | static BcStatus dc_parse_string(BcParse *p) |
5052 | { | 5050 | { |
5053 | char *str, *name, b[DC_PARSE_BUF_LEN + 1]; | 5051 | char *str, *name, b[DC_PARSE_BUF_LEN + 1]; |
5054 | size_t idx, len = p->prog->strs.len; | 5052 | size_t idx, len = G.prog.strs.len; |
5055 | 5053 | ||
5056 | sprintf(b, "%0*zu", DC_PARSE_BUF_LEN, len); | 5054 | sprintf(b, "%0*zu", DC_PARSE_BUF_LEN, len); |
5057 | name = xstrdup(b); | 5055 | name = xstrdup(b); |
@@ -5059,7 +5057,7 @@ static BcStatus dc_parse_string(BcParse *p) | |||
5059 | str = xstrdup(p->l.t.v.v); | 5057 | str = xstrdup(p->l.t.v.v); |
5060 | bc_parse_push(p, BC_INST_STR); | 5058 | bc_parse_push(p, BC_INST_STR); |
5061 | bc_parse_pushIndex(p, len); | 5059 | bc_parse_pushIndex(p, len); |
5062 | bc_vec_push(&p->prog->strs, &str); | 5060 | bc_vec_push(&G.prog.strs, &str); |
5063 | bc_parse_addFunc(p, name, &idx); | 5061 | bc_parse_addFunc(p, name, &idx); |
5064 | 5062 | ||
5065 | return bc_lex_next(&p->l); | 5063 | return bc_lex_next(&p->l); |
@@ -5213,7 +5211,7 @@ static BcStatus dc_parse_expr(BcParse *p, uint8_t flags) | |||
5213 | BcInst inst; | 5211 | BcInst inst; |
5214 | BcLexType t; | 5212 | BcLexType t; |
5215 | 5213 | ||
5216 | if (flags & BC_PARSE_NOCALL) p->nbraces = p->prog->results.len; | 5214 | if (flags & BC_PARSE_NOCALL) p->nbraces = G.prog.results.len; |
5217 | 5215 | ||
5218 | for (t = p->l.t.t; !s && t != BC_LEX_EOF; t = p->l.t.t) { | 5216 | for (t = p->l.t.t; !s && t != BC_LEX_EOF; t = p->l.t.t) { |
5219 | 5217 | ||
@@ -5247,18 +5245,18 @@ static BcStatus dc_parse_parse(BcParse *p) | |||
5247 | return s; | 5245 | return s; |
5248 | } | 5246 | } |
5249 | 5247 | ||
5250 | static void dc_parse_init(BcParse *p, BcProgram *prog, size_t func) | 5248 | static void dc_parse_init(BcParse *p, size_t func) |
5251 | { | 5249 | { |
5252 | bc_parse_create(p, prog, func, dc_parse_parse, dc_lex_token); | 5250 | bc_parse_create(p, func, dc_parse_parse, dc_lex_token); |
5253 | } | 5251 | } |
5254 | #endif // ENABLE_DC | 5252 | #endif // ENABLE_DC |
5255 | 5253 | ||
5256 | static void common_parse_init(BcParse *p, BcProgram *prog, size_t func) | 5254 | static void common_parse_init(BcParse *p, size_t func) |
5257 | { | 5255 | { |
5258 | if (IS_BC) { | 5256 | if (IS_BC) { |
5259 | bc_parse_init(p, prog, func); | 5257 | bc_parse_init(p, func); |
5260 | } else { | 5258 | } else { |
5261 | dc_parse_init(p, prog, func); | 5259 | dc_parse_init(p, func); |
5262 | } | 5260 | } |
5263 | } | 5261 | } |
5264 | 5262 | ||
@@ -5271,7 +5269,7 @@ static BcStatus common_parse_expr(BcParse *p, uint8_t flags) | |||
5271 | } | 5269 | } |
5272 | } | 5270 | } |
5273 | 5271 | ||
5274 | static void bc_program_search(BcProgram *p, char *id, BcVec **ret, bool var) | 5272 | static void bc_program_search(char *id, BcVec **ret, bool var) |
5275 | { | 5273 | { |
5276 | BcStatus s; | 5274 | BcStatus s; |
5277 | BcId e, *ptr; | 5275 | BcId e, *ptr; |
@@ -5280,8 +5278,8 @@ static void bc_program_search(BcProgram *p, char *id, BcVec **ret, bool var) | |||
5280 | BcResultData data; | 5278 | BcResultData data; |
5281 | bool new; | 5279 | bool new; |
5282 | 5280 | ||
5283 | v = var ? &p->vars : &p->arrs; | 5281 | v = var ? &G.prog.vars : &G.prog.arrs; |
5284 | map = var ? &p->var_map : &p->arr_map; | 5282 | map = var ? &G.prog.var_map : &G.prog.arr_map; |
5285 | 5283 | ||
5286 | e.name = id; | 5284 | e.name = id; |
5287 | e.idx = v->len; | 5285 | e.idx = v->len; |
@@ -5296,9 +5294,10 @@ static void bc_program_search(BcProgram *p, char *id, BcVec **ret, bool var) | |||
5296 | ptr = bc_vec_item(map, i); | 5294 | ptr = bc_vec_item(map, i); |
5297 | if (new) ptr->name = xstrdup(e.name); | 5295 | if (new) ptr->name = xstrdup(e.name); |
5298 | *ret = bc_vec_item(v, ptr->idx); | 5296 | *ret = bc_vec_item(v, ptr->idx); |
5297 | /// convert to better return convention | ||
5299 | } | 5298 | } |
5300 | 5299 | ||
5301 | static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex) | 5300 | static BcStatus bc_program_num(BcResult *r, BcNum **num, bool hex) |
5302 | { | 5301 | { |
5303 | BcStatus s = BC_STATUS_SUCCESS; | 5302 | BcStatus s = BC_STATUS_SUCCESS; |
5304 | 5303 | ||
@@ -5316,15 +5315,15 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex) | |||
5316 | 5315 | ||
5317 | case BC_RESULT_CONSTANT: | 5316 | case BC_RESULT_CONSTANT: |
5318 | { | 5317 | { |
5319 | char **str = bc_vec_item(&p->consts, r->d.id.idx); | 5318 | char **str = bc_vec_item(&G.prog.consts, r->d.id.idx); |
5320 | size_t base_t, len = strlen(*str); | 5319 | size_t base_t, len = strlen(*str); |
5321 | BcNum *base; | 5320 | BcNum *base; |
5322 | 5321 | ||
5323 | bc_num_init(&r->d.n, len); | 5322 | bc_num_init(&r->d.n, len); |
5324 | 5323 | ||
5325 | hex = hex && len == 1; | 5324 | hex = hex && len == 1; |
5326 | base = hex ? &p->hexb : &p->ib; | 5325 | base = hex ? &G.prog.hexb : &G.prog.ib; |
5327 | base_t = hex ? BC_NUM_MAX_IBASE : p->ib_t; | 5326 | base_t = hex ? BC_NUM_MAX_IBASE : G.prog.ib_t; |
5328 | s = bc_num_parse(&r->d.n, *str, base, base_t); | 5327 | s = bc_num_parse(&r->d.n, *str, base, base_t); |
5329 | 5328 | ||
5330 | if (s) { | 5329 | if (s) { |
@@ -5344,7 +5343,7 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex) | |||
5344 | { | 5343 | { |
5345 | BcVec *v; | 5344 | BcVec *v; |
5346 | 5345 | ||
5347 | bc_program_search(p, r->d.id.name, &v, r->t == BC_RESULT_VAR); | 5346 | bc_program_search(r->d.id.name, &v, r->t == BC_RESULT_VAR); |
5348 | 5347 | ||
5349 | if (r->t == BC_RESULT_ARRAY_ELEM) { | 5348 | if (r->t == BC_RESULT_ARRAY_ELEM) { |
5350 | v = bc_vec_top(v); | 5349 | v = bc_vec_top(v); |
@@ -5359,13 +5358,13 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex) | |||
5359 | 5358 | ||
5360 | case BC_RESULT_LAST: | 5359 | case BC_RESULT_LAST: |
5361 | { | 5360 | { |
5362 | *num = &p->last; | 5361 | *num = &G.prog.last; |
5363 | break; | 5362 | break; |
5364 | } | 5363 | } |
5365 | 5364 | ||
5366 | case BC_RESULT_ONE: | 5365 | case BC_RESULT_ONE: |
5367 | { | 5366 | { |
5368 | *num = &p->one; | 5367 | *num = &G.prog.one; |
5369 | break; | 5368 | break; |
5370 | } | 5369 | } |
5371 | } | 5370 | } |
@@ -5373,31 +5372,31 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex) | |||
5373 | return s; | 5372 | return s; |
5374 | } | 5373 | } |
5375 | 5374 | ||
5376 | static BcStatus bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln, | 5375 | static BcStatus bc_program_binOpPrep(BcResult **l, BcNum **ln, |
5377 | BcResult **r, BcNum **rn, bool assign) | 5376 | BcResult **r, BcNum **rn, bool assign) |
5378 | { | 5377 | { |
5379 | BcStatus s; | 5378 | BcStatus s; |
5380 | bool hex; | 5379 | bool hex; |
5381 | BcResultType lt, rt; | 5380 | BcResultType lt, rt; |
5382 | 5381 | ||
5383 | if (!BC_PROG_STACK(&p->results, 2)) return BC_STATUS_EXEC_STACK; | 5382 | if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK; |
5384 | 5383 | ||
5385 | *r = bc_vec_item_rev(&p->results, 0); | 5384 | *r = bc_vec_item_rev(&G.prog.results, 0); |
5386 | *l = bc_vec_item_rev(&p->results, 1); | 5385 | *l = bc_vec_item_rev(&G.prog.results, 1); |
5387 | 5386 | ||
5388 | lt = (*l)->t; | 5387 | lt = (*l)->t; |
5389 | rt = (*r)->t; | 5388 | rt = (*r)->t; |
5390 | hex = assign && (lt == BC_RESULT_IBASE || lt == BC_RESULT_OBASE); | 5389 | hex = assign && (lt == BC_RESULT_IBASE || lt == BC_RESULT_OBASE); |
5391 | 5390 | ||
5392 | s = bc_program_num(p, *l, ln, false); | 5391 | s = bc_program_num(*l, ln, false); |
5393 | if (s) return s; | 5392 | if (s) return s; |
5394 | s = bc_program_num(p, *r, rn, hex); | 5393 | s = bc_program_num(*r, rn, hex); |
5395 | if (s) return s; | 5394 | if (s) return s; |
5396 | 5395 | ||
5397 | // We run this again under these conditions in case any vector has been | 5396 | // We run this again under these conditions in case any vector has been |
5398 | // reallocated out from under the BcNums or arrays we had. | 5397 | // reallocated out from under the BcNums or arrays we had. |
5399 | if (lt == rt && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM)) { | 5398 | if (lt == rt && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM)) { |
5400 | s = bc_program_num(p, *l, ln, false); | 5399 | s = bc_program_num(*l, ln, false); |
5401 | if (s) return s; | 5400 | if (s) return s; |
5402 | } | 5401 | } |
5403 | 5402 | ||
@@ -5408,22 +5407,22 @@ static BcStatus bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln, | |||
5408 | return s; | 5407 | return s; |
5409 | } | 5408 | } |
5410 | 5409 | ||
5411 | static void bc_program_binOpRetire(BcProgram *p, BcResult *r) | 5410 | static void bc_program_binOpRetire(BcResult *r) |
5412 | { | 5411 | { |
5413 | r->t = BC_RESULT_TEMP; | 5412 | r->t = BC_RESULT_TEMP; |
5414 | bc_vec_pop(&p->results); | 5413 | bc_vec_pop(&G.prog.results); |
5415 | bc_vec_pop(&p->results); | 5414 | bc_vec_pop(&G.prog.results); |
5416 | bc_vec_push(&p->results, r); | 5415 | bc_vec_push(&G.prog.results, r); |
5417 | } | 5416 | } |
5418 | 5417 | ||
5419 | static BcStatus bc_program_prep(BcProgram *p, BcResult **r, BcNum **n) | 5418 | static BcStatus bc_program_prep(BcResult **r, BcNum **n) |
5420 | { | 5419 | { |
5421 | BcStatus s; | 5420 | BcStatus s; |
5422 | 5421 | ||
5423 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 5422 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
5424 | *r = bc_vec_top(&p->results); | 5423 | *r = bc_vec_top(&G.prog.results); |
5425 | 5424 | ||
5426 | s = bc_program_num(p, *r, n, false); | 5425 | s = bc_program_num(*r, n, false); |
5427 | if (s) return s; | 5426 | if (s) return s; |
5428 | 5427 | ||
5429 | if (!BC_PROG_NUM((*r), (*n))) return BC_STATUS_EXEC_BAD_TYPE; | 5428 | if (!BC_PROG_NUM((*r), (*n))) return BC_STATUS_EXEC_BAD_TYPE; |
@@ -5431,26 +5430,26 @@ static BcStatus bc_program_prep(BcProgram *p, BcResult **r, BcNum **n) | |||
5431 | return s; | 5430 | return s; |
5432 | } | 5431 | } |
5433 | 5432 | ||
5434 | static void bc_program_retire(BcProgram *p, BcResult *r, BcResultType t) | 5433 | static void bc_program_retire(BcResult *r, BcResultType t) |
5435 | { | 5434 | { |
5436 | r->t = t; | 5435 | r->t = t; |
5437 | bc_vec_pop(&p->results); | 5436 | bc_vec_pop(&G.prog.results); |
5438 | bc_vec_push(&p->results, r); | 5437 | bc_vec_push(&G.prog.results, r); |
5439 | } | 5438 | } |
5440 | 5439 | ||
5441 | static BcStatus bc_program_op(BcProgram *p, char inst) | 5440 | static BcStatus bc_program_op(char inst) |
5442 | { | 5441 | { |
5443 | BcStatus s; | 5442 | BcStatus s; |
5444 | BcResult *opd1, *opd2, res; | 5443 | BcResult *opd1, *opd2, res; |
5445 | BcNum *n1, *n2 = NULL; | 5444 | BcNum *n1, *n2 = NULL; |
5446 | 5445 | ||
5447 | s = bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, false); | 5446 | s = bc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false); |
5448 | if (s) return s; | 5447 | if (s) return s; |
5449 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 5448 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
5450 | 5449 | ||
5451 | s = bc_program_ops[inst - BC_INST_POWER](n1, n2, &res.d.n, p->scale); | 5450 | s = bc_program_ops[inst - BC_INST_POWER](n1, n2, &res.d.n, G.prog.scale); |
5452 | if (s) goto err; | 5451 | if (s) goto err; |
5453 | bc_program_binOpRetire(p, &res); | 5452 | bc_program_binOpRetire(&res); |
5454 | 5453 | ||
5455 | return s; | 5454 | return s; |
5456 | 5455 | ||
@@ -5461,17 +5460,15 @@ err: | |||
5461 | 5460 | ||
5462 | static BcStatus bc_program_read(void) | 5461 | static BcStatus bc_program_read(void) |
5463 | { | 5462 | { |
5464 | BcProgram *p = &G.prog; | ||
5465 | |||
5466 | BcStatus s; | 5463 | BcStatus s; |
5467 | BcParse parse; | 5464 | BcParse parse; |
5468 | BcVec buf; | 5465 | BcVec buf; |
5469 | BcInstPtr ip; | 5466 | BcInstPtr ip; |
5470 | size_t i; | 5467 | size_t i; |
5471 | BcFunc *f = bc_vec_item(&p->fns, BC_PROG_READ); | 5468 | BcFunc *f = bc_vec_item(&G.prog.fns, BC_PROG_READ); |
5472 | 5469 | ||
5473 | for (i = 0; i < p->stack.len; ++i) { | 5470 | for (i = 0; i < G.prog.stack.len; ++i) { |
5474 | BcInstPtr *ip_ptr = bc_vec_item(&p->stack, i); | 5471 | BcInstPtr *ip_ptr = bc_vec_item(&G.prog.stack, i); |
5475 | if (ip_ptr->func == BC_PROG_READ) return BC_STATUS_EXEC_REC_READ; | 5472 | if (ip_ptr->func == BC_PROG_READ) return BC_STATUS_EXEC_REC_READ; |
5476 | } | 5473 | } |
5477 | 5474 | ||
@@ -5481,7 +5478,7 @@ static BcStatus bc_program_read(void) | |||
5481 | s = bc_read_line(&buf, "read> "); | 5478 | s = bc_read_line(&buf, "read> "); |
5482 | if (s) goto io_err; | 5479 | if (s) goto io_err; |
5483 | 5480 | ||
5484 | common_parse_init(&parse, p, BC_PROG_READ); | 5481 | common_parse_init(&parse, BC_PROG_READ); |
5485 | bc_lex_file(&parse.l, bc_program_stdin_name); | 5482 | bc_lex_file(&parse.l, bc_program_stdin_name); |
5486 | 5483 | ||
5487 | s = bc_parse_text(&parse, buf.v); | 5484 | s = bc_parse_text(&parse, buf.v); |
@@ -5496,13 +5493,13 @@ static BcStatus bc_program_read(void) | |||
5496 | 5493 | ||
5497 | ip.func = BC_PROG_READ; | 5494 | ip.func = BC_PROG_READ; |
5498 | ip.idx = 0; | 5495 | ip.idx = 0; |
5499 | ip.len = p->results.len; | 5496 | ip.len = G.prog.results.len; |
5500 | 5497 | ||
5501 | // Update this pointer, just in case. | 5498 | // Update this pointer, just in case. |
5502 | f = bc_vec_item(&p->fns, BC_PROG_READ); | 5499 | f = bc_vec_item(&G.prog.fns, BC_PROG_READ); |
5503 | 5500 | ||
5504 | bc_vec_pushByte(&f->code, BC_INST_POP_EXEC); | 5501 | bc_vec_pushByte(&f->code, BC_INST_POP_EXEC); |
5505 | bc_vec_push(&p->stack, &ip); | 5502 | bc_vec_push(&G.prog.stack, &ip); |
5506 | 5503 | ||
5507 | exec_err: | 5504 | exec_err: |
5508 | bc_parse_free(&parse); | 5505 | bc_parse_free(&parse); |
@@ -5624,7 +5621,7 @@ static void bc_program_printString(const char *str, size_t *nchars) | |||
5624 | } | 5621 | } |
5625 | } | 5622 | } |
5626 | 5623 | ||
5627 | static BcStatus bc_program_print(BcProgram *p, char inst, size_t idx) | 5624 | static BcStatus bc_program_print(char inst, size_t idx) |
5628 | { | 5625 | { |
5629 | BcStatus s = BC_STATUS_SUCCESS; | 5626 | BcStatus s = BC_STATUS_SUCCESS; |
5630 | BcResult *r; | 5627 | BcResult *r; |
@@ -5633,59 +5630,59 @@ static BcStatus bc_program_print(BcProgram *p, char inst, size_t idx) | |||
5633 | BcNum *num = NULL; | 5630 | BcNum *num = NULL; |
5634 | bool pop = inst != BC_INST_PRINT; | 5631 | bool pop = inst != BC_INST_PRINT; |
5635 | 5632 | ||
5636 | if (!BC_PROG_STACK(&p->results, idx + 1)) return BC_STATUS_EXEC_STACK; | 5633 | if (!BC_PROG_STACK(&G.prog.results, idx + 1)) return BC_STATUS_EXEC_STACK; |
5637 | 5634 | ||
5638 | r = bc_vec_item_rev(&p->results, idx); | 5635 | r = bc_vec_item_rev(&G.prog.results, idx); |
5639 | s = bc_program_num(p, r, &num, false); | 5636 | s = bc_program_num(r, &num, false); |
5640 | if (s) return s; | 5637 | if (s) return s; |
5641 | 5638 | ||
5642 | if (BC_PROG_NUM(r, num)) { | 5639 | if (BC_PROG_NUM(r, num)) { |
5643 | s = bc_num_print(num, &p->ob, p->ob_t, !pop, &p->nchars, p->len); | 5640 | s = bc_num_print(num, &G.prog.ob, G.prog.ob_t, !pop, &G.prog.nchars, G.prog.len); |
5644 | if (!s) bc_num_copy(&p->last, num); | 5641 | if (!s) bc_num_copy(&G.prog.last, num); |
5645 | } | 5642 | } |
5646 | else { | 5643 | else { |
5647 | 5644 | ||
5648 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : num->rdx; | 5645 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : num->rdx; |
5649 | str = *((char **) bc_vec_item(&p->strs, idx)); | 5646 | str = *((char **) bc_vec_item(&G.prog.strs, idx)); |
5650 | 5647 | ||
5651 | if (inst == BC_INST_PRINT_STR) { | 5648 | if (inst == BC_INST_PRINT_STR) { |
5652 | for (i = 0, len = strlen(str); i < len; ++i) { | 5649 | for (i = 0, len = strlen(str); i < len; ++i) { |
5653 | char c = str[i]; | 5650 | char c = str[i]; |
5654 | bb_putchar(c); | 5651 | bb_putchar(c); |
5655 | if (c == '\n') p->nchars = SIZE_MAX; | 5652 | if (c == '\n') G.prog.nchars = SIZE_MAX; |
5656 | ++p->nchars; | 5653 | ++G.prog.nchars; |
5657 | } | 5654 | } |
5658 | } | 5655 | } |
5659 | else { | 5656 | else { |
5660 | bc_program_printString(str, &p->nchars); | 5657 | bc_program_printString(str, &G.prog.nchars); |
5661 | if (inst == BC_INST_PRINT) bb_putchar('\n'); | 5658 | if (inst == BC_INST_PRINT) bb_putchar('\n'); |
5662 | } | 5659 | } |
5663 | } | 5660 | } |
5664 | 5661 | ||
5665 | if (!s && pop) bc_vec_pop(&p->results); | 5662 | if (!s && pop) bc_vec_pop(&G.prog.results); |
5666 | 5663 | ||
5667 | return s; | 5664 | return s; |
5668 | } | 5665 | } |
5669 | 5666 | ||
5670 | static BcStatus bc_program_negate(BcProgram *p) | 5667 | static BcStatus bc_program_negate(void) |
5671 | { | 5668 | { |
5672 | BcStatus s; | 5669 | BcStatus s; |
5673 | BcResult res, *ptr; | 5670 | BcResult res, *ptr; |
5674 | BcNum *num = NULL; | 5671 | BcNum *num = NULL; |
5675 | 5672 | ||
5676 | s = bc_program_prep(p, &ptr, &num); | 5673 | s = bc_program_prep(&ptr, &num); |
5677 | if (s) return s; | 5674 | if (s) return s; |
5678 | 5675 | ||
5679 | bc_num_init(&res.d.n, num->len); | 5676 | bc_num_init(&res.d.n, num->len); |
5680 | bc_num_copy(&res.d.n, num); | 5677 | bc_num_copy(&res.d.n, num); |
5681 | if (res.d.n.len) res.d.n.neg = !res.d.n.neg; | 5678 | if (res.d.n.len) res.d.n.neg = !res.d.n.neg; |
5682 | 5679 | ||
5683 | bc_program_retire(p, &res, BC_RESULT_TEMP); | 5680 | bc_program_retire(&res, BC_RESULT_TEMP); |
5684 | 5681 | ||
5685 | return s; | 5682 | return s; |
5686 | } | 5683 | } |
5687 | 5684 | ||
5688 | static BcStatus bc_program_logical(BcProgram *p, char inst) | 5685 | static BcStatus bc_program_logical(char inst) |
5689 | { | 5686 | { |
5690 | BcStatus s; | 5687 | BcStatus s; |
5691 | BcResult *opd1, *opd2, res; | 5688 | BcResult *opd1, *opd2, res; |
@@ -5693,14 +5690,14 @@ static BcStatus bc_program_logical(BcProgram *p, char inst) | |||
5693 | bool cond = 0; | 5690 | bool cond = 0; |
5694 | ssize_t cmp; | 5691 | ssize_t cmp; |
5695 | 5692 | ||
5696 | s = bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, false); | 5693 | s = bc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false); |
5697 | if (s) return s; | 5694 | if (s) return s; |
5698 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 5695 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
5699 | 5696 | ||
5700 | if (inst == BC_INST_BOOL_AND) | 5697 | if (inst == BC_INST_BOOL_AND) |
5701 | cond = bc_num_cmp(n1, &p->zero) && bc_num_cmp(n2, &p->zero); | 5698 | cond = bc_num_cmp(n1, &G.prog.zero) && bc_num_cmp(n2, &G.prog.zero); |
5702 | else if (inst == BC_INST_BOOL_OR) | 5699 | else if (inst == BC_INST_BOOL_OR) |
5703 | cond = bc_num_cmp(n1, &p->zero) || bc_num_cmp(n2, &p->zero); | 5700 | cond = bc_num_cmp(n1, &G.prog.zero) || bc_num_cmp(n2, &G.prog.zero); |
5704 | else { | 5701 | else { |
5705 | 5702 | ||
5706 | cmp = bc_num_cmp(n1, n2); | 5703 | cmp = bc_num_cmp(n1, n2); |
@@ -5747,13 +5744,13 @@ static BcStatus bc_program_logical(BcProgram *p, char inst) | |||
5747 | 5744 | ||
5748 | (cond ? bc_num_one : bc_num_zero)(&res.d.n); | 5745 | (cond ? bc_num_one : bc_num_zero)(&res.d.n); |
5749 | 5746 | ||
5750 | bc_program_binOpRetire(p, &res); | 5747 | bc_program_binOpRetire(&res); |
5751 | 5748 | ||
5752 | return s; | 5749 | return s; |
5753 | } | 5750 | } |
5754 | 5751 | ||
5755 | #if ENABLE_DC | 5752 | #if ENABLE_DC |
5756 | static BcStatus bc_program_assignStr(BcProgram *p, BcResult *r, BcVec *v, | 5753 | static BcStatus bc_program_assignStr(BcResult *r, BcVec *v, |
5757 | bool push) | 5754 | bool push) |
5758 | { | 5755 | { |
5759 | BcNum n2; | 5756 | BcNum n2; |
@@ -5764,43 +5761,43 @@ static BcStatus bc_program_assignStr(BcProgram *p, BcResult *r, BcVec *v, | |||
5764 | res.t = BC_RESULT_STR; | 5761 | res.t = BC_RESULT_STR; |
5765 | 5762 | ||
5766 | if (!push) { | 5763 | if (!push) { |
5767 | if (!BC_PROG_STACK(&p->results, 2)) return BC_STATUS_EXEC_STACK; | 5764 | if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK; |
5768 | bc_vec_pop(v); | 5765 | bc_vec_pop(v); |
5769 | bc_vec_pop(&p->results); | 5766 | bc_vec_pop(&G.prog.results); |
5770 | } | 5767 | } |
5771 | 5768 | ||
5772 | bc_vec_pop(&p->results); | 5769 | bc_vec_pop(&G.prog.results); |
5773 | 5770 | ||
5774 | bc_vec_push(&p->results, &res); | 5771 | bc_vec_push(&G.prog.results, &res); |
5775 | bc_vec_push(v, &n2); | 5772 | bc_vec_push(v, &n2); |
5776 | 5773 | ||
5777 | return BC_STATUS_SUCCESS; | 5774 | return BC_STATUS_SUCCESS; |
5778 | } | 5775 | } |
5779 | #endif // ENABLE_DC | 5776 | #endif // ENABLE_DC |
5780 | 5777 | ||
5781 | static BcStatus bc_program_copyToVar(BcProgram *p, char *name, bool var) | 5778 | static BcStatus bc_program_copyToVar(char *name, bool var) |
5782 | { | 5779 | { |
5783 | BcStatus s; | 5780 | BcStatus s; |
5784 | BcResult *ptr, r; | 5781 | BcResult *ptr, r; |
5785 | BcVec *v; | 5782 | BcVec *v; |
5786 | BcNum *n; | 5783 | BcNum *n; |
5787 | 5784 | ||
5788 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 5785 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
5789 | 5786 | ||
5790 | ptr = bc_vec_top(&p->results); | 5787 | ptr = bc_vec_top(&G.prog.results); |
5791 | if ((ptr->t == BC_RESULT_ARRAY) != !var) return BC_STATUS_EXEC_BAD_TYPE; | 5788 | if ((ptr->t == BC_RESULT_ARRAY) != !var) return BC_STATUS_EXEC_BAD_TYPE; |
5792 | bc_program_search(p, name, &v, var); | 5789 | bc_program_search(name, &v, var); |
5793 | 5790 | ||
5794 | #if ENABLE_DC | 5791 | #if ENABLE_DC |
5795 | if (ptr->t == BC_RESULT_STR && !var) return BC_STATUS_EXEC_BAD_TYPE; | 5792 | if (ptr->t == BC_RESULT_STR && !var) return BC_STATUS_EXEC_BAD_TYPE; |
5796 | if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(p, ptr, v, true); | 5793 | if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(ptr, v, true); |
5797 | #endif | 5794 | #endif |
5798 | 5795 | ||
5799 | s = bc_program_num(p, ptr, &n, false); | 5796 | s = bc_program_num(ptr, &n, false); |
5800 | if (s) return s; | 5797 | if (s) return s; |
5801 | 5798 | ||
5802 | // Do this once more to make sure that pointers were not invalidated. | 5799 | // Do this once more to make sure that pointers were not invalidated. |
5803 | bc_program_search(p, name, &v, var); | 5800 | bc_program_search(name, &v, var); |
5804 | 5801 | ||
5805 | if (var) { | 5802 | if (var) { |
5806 | bc_num_init(&r.d.n, BC_NUM_DEF_SIZE); | 5803 | bc_num_init(&r.d.n, BC_NUM_DEF_SIZE); |
@@ -5812,12 +5809,12 @@ static BcStatus bc_program_copyToVar(BcProgram *p, char *name, bool var) | |||
5812 | } | 5809 | } |
5813 | 5810 | ||
5814 | bc_vec_push(v, &r.d); | 5811 | bc_vec_push(v, &r.d); |
5815 | bc_vec_pop(&p->results); | 5812 | bc_vec_pop(&G.prog.results); |
5816 | 5813 | ||
5817 | return s; | 5814 | return s; |
5818 | } | 5815 | } |
5819 | 5816 | ||
5820 | static BcStatus bc_program_assign(BcProgram *p, char inst) | 5817 | static BcStatus bc_program_assign(char inst) |
5821 | { | 5818 | { |
5822 | BcStatus s; | 5819 | BcStatus s; |
5823 | BcResult *left, *right, res; | 5820 | BcResult *left, *right, res; |
@@ -5825,7 +5822,7 @@ static BcStatus bc_program_assign(BcProgram *p, char inst) | |||
5825 | unsigned long val, max; | 5822 | unsigned long val, max; |
5826 | bool assign = inst == BC_INST_ASSIGN, ib, sc; | 5823 | bool assign = inst == BC_INST_ASSIGN, ib, sc; |
5827 | 5824 | ||
5828 | s = bc_program_binOpPrep(p, &left, &l, &right, &r, assign); | 5825 | s = bc_program_binOpPrep(&left, &l, &right, &r, assign); |
5829 | if (s) return s; | 5826 | if (s) return s; |
5830 | 5827 | ||
5831 | ib = left->t == BC_RESULT_IBASE; | 5828 | ib = left->t == BC_RESULT_IBASE; |
@@ -5838,9 +5835,9 @@ static BcStatus bc_program_assign(BcProgram *p, char inst) | |||
5838 | BcVec *v; | 5835 | BcVec *v; |
5839 | 5836 | ||
5840 | if (left->t != BC_RESULT_VAR) return BC_STATUS_EXEC_BAD_TYPE; | 5837 | if (left->t != BC_RESULT_VAR) return BC_STATUS_EXEC_BAD_TYPE; |
5841 | bc_program_search(p, left->d.id.name, &v, true); | 5838 | bc_program_search(left->d.id.name, &v, true); |
5842 | 5839 | ||
5843 | return bc_program_assignStr(p, right, v, false); | 5840 | return bc_program_assignStr(right, v, false); |
5844 | } | 5841 | } |
5845 | #endif | 5842 | #endif |
5846 | 5843 | ||
@@ -5848,13 +5845,13 @@ static BcStatus bc_program_assign(BcProgram *p, char inst) | |||
5848 | return BC_STATUS_PARSE_BAD_ASSIGN; | 5845 | return BC_STATUS_PARSE_BAD_ASSIGN; |
5849 | 5846 | ||
5850 | #if ENABLE_BC | 5847 | #if ENABLE_BC |
5851 | if (inst == BC_INST_ASSIGN_DIVIDE && !bc_num_cmp(r, &p->zero)) | 5848 | if (inst == BC_INST_ASSIGN_DIVIDE && !bc_num_cmp(r, &G.prog.zero)) |
5852 | return BC_STATUS_MATH_DIVIDE_BY_ZERO; | 5849 | return BC_STATUS_MATH_DIVIDE_BY_ZERO; |
5853 | 5850 | ||
5854 | if (assign) | 5851 | if (assign) |
5855 | bc_num_copy(l, r); | 5852 | bc_num_copy(l, r); |
5856 | else | 5853 | else |
5857 | s = bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, p->scale); | 5854 | s = bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, G.prog.scale); |
5858 | 5855 | ||
5859 | if (s) return s; | 5856 | if (s) return s; |
5860 | #else | 5857 | #else |
@@ -5871,16 +5868,16 @@ static BcStatus bc_program_assign(BcProgram *p, char inst) | |||
5871 | 5868 | ||
5872 | if (sc) { | 5869 | if (sc) { |
5873 | max = BC_MAX_SCALE; | 5870 | max = BC_MAX_SCALE; |
5874 | ptr = &p->scale; | 5871 | ptr = &G.prog.scale; |
5875 | } | 5872 | } |
5876 | else { | 5873 | else { |
5877 | if (val < BC_NUM_MIN_BASE) return s; | 5874 | if (val < BC_NUM_MIN_BASE) return s; |
5878 | max = ib ? BC_NUM_MAX_IBASE : BC_MAX_OBASE; | 5875 | max = ib ? BC_NUM_MAX_IBASE : BC_MAX_OBASE; |
5879 | ptr = ib ? &p->ib_t : &p->ob_t; | 5876 | ptr = ib ? &G.prog.ib_t : &G.prog.ob_t; |
5880 | } | 5877 | } |
5881 | 5878 | ||
5882 | if (val > max) return s; | 5879 | if (val > max) return s; |
5883 | if (!sc) bc_num_copy(ib ? &p->ib : &p->ob, l); | 5880 | if (!sc) bc_num_copy(ib ? &G.prog.ib : &G.prog.ob, l); |
5884 | 5881 | ||
5885 | *ptr = (size_t) val; | 5882 | *ptr = (size_t) val; |
5886 | s = BC_STATUS_SUCCESS; | 5883 | s = BC_STATUS_SUCCESS; |
@@ -5888,12 +5885,12 @@ static BcStatus bc_program_assign(BcProgram *p, char inst) | |||
5888 | 5885 | ||
5889 | bc_num_init(&res.d.n, l->len); | 5886 | bc_num_init(&res.d.n, l->len); |
5890 | bc_num_copy(&res.d.n, l); | 5887 | bc_num_copy(&res.d.n, l); |
5891 | bc_program_binOpRetire(p, &res); | 5888 | bc_program_binOpRetire(&res); |
5892 | 5889 | ||
5893 | return s; | 5890 | return s; |
5894 | } | 5891 | } |
5895 | 5892 | ||
5896 | static BcStatus bc_program_pushVar(BcProgram *p, char *code, size_t *bgn, | 5893 | static BcStatus bc_program_pushVar(char *code, size_t *bgn, |
5897 | bool pop, bool copy) | 5894 | bool pop, bool copy) |
5898 | { | 5895 | { |
5899 | BcStatus s = BC_STATUS_SUCCESS; | 5896 | BcStatus s = BC_STATUS_SUCCESS; |
@@ -5910,7 +5907,7 @@ static BcStatus bc_program_pushVar(BcProgram *p, char *code, size_t *bgn, | |||
5910 | r.d.id.name = name; | 5907 | r.d.id.name = name; |
5911 | 5908 | ||
5912 | #if ENABLE_DC | 5909 | #if ENABLE_DC |
5913 | bc_program_search(p, name, &v, true); | 5910 | bc_program_search(name, &v, true); |
5914 | num = bc_vec_top(v); | 5911 | num = bc_vec_top(v); |
5915 | 5912 | ||
5916 | if (pop || copy) { | 5913 | if (pop || copy) { |
@@ -5939,12 +5936,12 @@ static BcStatus bc_program_pushVar(BcProgram *p, char *code, size_t *bgn, | |||
5939 | } | 5936 | } |
5940 | #endif // ENABLE_DC | 5937 | #endif // ENABLE_DC |
5941 | 5938 | ||
5942 | bc_vec_push(&p->results, &r); | 5939 | bc_vec_push(&G.prog.results, &r); |
5943 | 5940 | ||
5944 | return s; | 5941 | return s; |
5945 | } | 5942 | } |
5946 | 5943 | ||
5947 | static BcStatus bc_program_pushArray(BcProgram *p, char *code, size_t *bgn, | 5944 | static BcStatus bc_program_pushArray(char *code, size_t *bgn, |
5948 | char inst) | 5945 | char inst) |
5949 | { | 5946 | { |
5950 | BcStatus s = BC_STATUS_SUCCESS; | 5947 | BcStatus s = BC_STATUS_SUCCESS; |
@@ -5955,14 +5952,14 @@ static BcStatus bc_program_pushArray(BcProgram *p, char *code, size_t *bgn, | |||
5955 | 5952 | ||
5956 | if (inst == BC_INST_ARRAY) { | 5953 | if (inst == BC_INST_ARRAY) { |
5957 | r.t = BC_RESULT_ARRAY; | 5954 | r.t = BC_RESULT_ARRAY; |
5958 | bc_vec_push(&p->results, &r); | 5955 | bc_vec_push(&G.prog.results, &r); |
5959 | } | 5956 | } |
5960 | else { | 5957 | else { |
5961 | 5958 | ||
5962 | BcResult *operand; | 5959 | BcResult *operand; |
5963 | unsigned long temp; | 5960 | unsigned long temp; |
5964 | 5961 | ||
5965 | s = bc_program_prep(p, &operand, &num); | 5962 | s = bc_program_prep(&operand, &num); |
5966 | if (s) goto err; | 5963 | if (s) goto err; |
5967 | s = bc_num_ulong(num, &temp); | 5964 | s = bc_num_ulong(num, &temp); |
5968 | if (s) goto err; | 5965 | if (s) goto err; |
@@ -5973,7 +5970,7 @@ static BcStatus bc_program_pushArray(BcProgram *p, char *code, size_t *bgn, | |||
5973 | } | 5970 | } |
5974 | 5971 | ||
5975 | r.d.id.idx = (size_t) temp; | 5972 | r.d.id.idx = (size_t) temp; |
5976 | bc_program_retire(p, &r, BC_RESULT_ARRAY_ELEM); | 5973 | bc_program_retire(&r, BC_RESULT_ARRAY_ELEM); |
5977 | } | 5974 | } |
5978 | 5975 | ||
5979 | err: | 5976 | err: |
@@ -5982,14 +5979,14 @@ err: | |||
5982 | } | 5979 | } |
5983 | 5980 | ||
5984 | #if ENABLE_BC | 5981 | #if ENABLE_BC |
5985 | static BcStatus bc_program_incdec(BcProgram *p, char inst) | 5982 | static BcStatus bc_program_incdec(char inst) |
5986 | { | 5983 | { |
5987 | BcStatus s; | 5984 | BcStatus s; |
5988 | BcResult *ptr, res, copy; | 5985 | BcResult *ptr, res, copy; |
5989 | BcNum *num = NULL; | 5986 | BcNum *num = NULL; |
5990 | char inst2 = inst; | 5987 | char inst2 = inst; |
5991 | 5988 | ||
5992 | s = bc_program_prep(p, &ptr, &num); | 5989 | s = bc_program_prep(&ptr, &num); |
5993 | if (s) return s; | 5990 | if (s) return s; |
5994 | 5991 | ||
5995 | if (inst == BC_INST_INC_POST || inst == BC_INST_DEC_POST) { | 5992 | if (inst == BC_INST_INC_POST || inst == BC_INST_DEC_POST) { |
@@ -6003,18 +6000,18 @@ static BcStatus bc_program_incdec(BcProgram *p, char inst) | |||
6003 | BC_INST_ASSIGN_PLUS : | 6000 | BC_INST_ASSIGN_PLUS : |
6004 | BC_INST_ASSIGN_MINUS; | 6001 | BC_INST_ASSIGN_MINUS; |
6005 | 6002 | ||
6006 | bc_vec_push(&p->results, &res); | 6003 | bc_vec_push(&G.prog.results, &res); |
6007 | bc_program_assign(p, inst); | 6004 | bc_program_assign(inst); |
6008 | 6005 | ||
6009 | if (inst2 == BC_INST_INC_POST || inst2 == BC_INST_DEC_POST) { | 6006 | if (inst2 == BC_INST_INC_POST || inst2 == BC_INST_DEC_POST) { |
6010 | bc_vec_pop(&p->results); | 6007 | bc_vec_pop(&G.prog.results); |
6011 | bc_vec_push(&p->results, ©); | 6008 | bc_vec_push(&G.prog.results, ©); |
6012 | } | 6009 | } |
6013 | 6010 | ||
6014 | return s; | 6011 | return s; |
6015 | } | 6012 | } |
6016 | 6013 | ||
6017 | static BcStatus bc_program_call(BcProgram *p, char *code, size_t *idx) | 6014 | static BcStatus bc_program_call(char *code, size_t *idx) |
6018 | { | 6015 | { |
6019 | BcStatus s = BC_STATUS_SUCCESS; | 6016 | BcStatus s = BC_STATUS_SUCCESS; |
6020 | BcInstPtr ip; | 6017 | BcInstPtr ip; |
@@ -6027,28 +6024,28 @@ static BcStatus bc_program_call(BcProgram *p, char *code, size_t *idx) | |||
6027 | 6024 | ||
6028 | ip.idx = 0; | 6025 | ip.idx = 0; |
6029 | ip.func = bc_program_index(code, idx); | 6026 | ip.func = bc_program_index(code, idx); |
6030 | func = bc_vec_item(&p->fns, ip.func); | 6027 | func = bc_vec_item(&G.prog.fns, ip.func); |
6031 | 6028 | ||
6032 | if (func->code.len == 0) return BC_STATUS_EXEC_UNDEFINED_FUNC; | 6029 | if (func->code.len == 0) return BC_STATUS_EXEC_UNDEFINED_FUNC; |
6033 | if (nparams != func->nparams) return BC_STATUS_EXEC_MISMATCHED_PARAMS; | 6030 | if (nparams != func->nparams) return BC_STATUS_EXEC_MISMATCHED_PARAMS; |
6034 | ip.len = p->results.len - nparams; | 6031 | ip.len = G.prog.results.len - nparams; |
6035 | 6032 | ||
6036 | for (i = 0; i < nparams; ++i) { | 6033 | for (i = 0; i < nparams; ++i) { |
6037 | 6034 | ||
6038 | a = bc_vec_item(&func->autos, nparams - 1 - i); | 6035 | a = bc_vec_item(&func->autos, nparams - 1 - i); |
6039 | arg = bc_vec_top(&p->results); | 6036 | arg = bc_vec_top(&G.prog.results); |
6040 | 6037 | ||
6041 | if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR) | 6038 | if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR) |
6042 | return BC_STATUS_EXEC_BAD_TYPE; | 6039 | return BC_STATUS_EXEC_BAD_TYPE; |
6043 | 6040 | ||
6044 | s = bc_program_copyToVar(p, a->name, a->idx); | 6041 | s = bc_program_copyToVar(a->name, a->idx); |
6045 | if (s) return s; | 6042 | if (s) return s; |
6046 | } | 6043 | } |
6047 | 6044 | ||
6048 | for (; i < func->autos.len; ++i) { | 6045 | for (; i < func->autos.len; ++i) { |
6049 | 6046 | ||
6050 | a = bc_vec_item(&func->autos, i); | 6047 | a = bc_vec_item(&func->autos, i); |
6051 | bc_program_search(p, a->name, &v, a->idx); | 6048 | bc_program_search(a->name, &v, a->idx); |
6052 | 6049 | ||
6053 | if (a->idx) { | 6050 | if (a->idx) { |
6054 | bc_num_init(¶m.n, BC_NUM_DEF_SIZE); | 6051 | bc_num_init(¶m.n, BC_NUM_DEF_SIZE); |
@@ -6060,31 +6057,31 @@ static BcStatus bc_program_call(BcProgram *p, char *code, size_t *idx) | |||
6060 | } | 6057 | } |
6061 | } | 6058 | } |
6062 | 6059 | ||
6063 | bc_vec_push(&p->stack, &ip); | 6060 | bc_vec_push(&G.prog.stack, &ip); |
6064 | 6061 | ||
6065 | return BC_STATUS_SUCCESS; | 6062 | return BC_STATUS_SUCCESS; |
6066 | } | 6063 | } |
6067 | 6064 | ||
6068 | static BcStatus bc_program_return(BcProgram *p, char inst) | 6065 | static BcStatus bc_program_return(char inst) |
6069 | { | 6066 | { |
6070 | BcStatus s; | 6067 | BcStatus s; |
6071 | BcResult res; | 6068 | BcResult res; |
6072 | BcFunc *f; | 6069 | BcFunc *f; |
6073 | size_t i; | 6070 | size_t i; |
6074 | BcInstPtr *ip = bc_vec_top(&p->stack); | 6071 | BcInstPtr *ip = bc_vec_top(&G.prog.stack); |
6075 | 6072 | ||
6076 | if (!BC_PROG_STACK(&p->results, ip->len + inst == BC_INST_RET)) | 6073 | if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET)) |
6077 | return BC_STATUS_EXEC_STACK; | 6074 | return BC_STATUS_EXEC_STACK; |
6078 | 6075 | ||
6079 | f = bc_vec_item(&p->fns, ip->func); | 6076 | f = bc_vec_item(&G.prog.fns, ip->func); |
6080 | res.t = BC_RESULT_TEMP; | 6077 | res.t = BC_RESULT_TEMP; |
6081 | 6078 | ||
6082 | if (inst == BC_INST_RET) { | 6079 | if (inst == BC_INST_RET) { |
6083 | 6080 | ||
6084 | BcNum *num; | 6081 | BcNum *num; |
6085 | BcResult *operand = bc_vec_top(&p->results); | 6082 | BcResult *operand = bc_vec_top(&G.prog.results); |
6086 | 6083 | ||
6087 | s = bc_program_num(p, operand, &num, false); | 6084 | s = bc_program_num(operand, &num, false); |
6088 | if (s) return s; | 6085 | if (s) return s; |
6089 | bc_num_init(&res.d.n, num->len); | 6086 | bc_num_init(&res.d.n, num->len); |
6090 | bc_num_copy(&res.d.n, num); | 6087 | bc_num_copy(&res.d.n, num); |
@@ -6100,13 +6097,13 @@ static BcStatus bc_program_return(BcProgram *p, char inst) | |||
6100 | BcVec *v; | 6097 | BcVec *v; |
6101 | BcId *a = bc_vec_item(&f->autos, i); | 6098 | BcId *a = bc_vec_item(&f->autos, i); |
6102 | 6099 | ||
6103 | bc_program_search(p, a->name, &v, a->idx); | 6100 | bc_program_search(a->name, &v, a->idx); |
6104 | bc_vec_pop(v); | 6101 | bc_vec_pop(v); |
6105 | } | 6102 | } |
6106 | 6103 | ||
6107 | bc_vec_npop(&p->results, p->results.len - ip->len); | 6104 | bc_vec_npop(&G.prog.results, G.prog.results.len - ip->len); |
6108 | bc_vec_push(&p->results, &res); | 6105 | bc_vec_push(&G.prog.results, &res); |
6109 | bc_vec_pop(&p->stack); | 6106 | bc_vec_pop(&G.prog.stack); |
6110 | 6107 | ||
6111 | return BC_STATUS_SUCCESS; | 6108 | return BC_STATUS_SUCCESS; |
6112 | } | 6109 | } |
@@ -6128,7 +6125,7 @@ static unsigned long bc_program_len(BcNum *n) | |||
6128 | return len; | 6125 | return len; |
6129 | } | 6126 | } |
6130 | 6127 | ||
6131 | static BcStatus bc_program_builtin(BcProgram *p, char inst) | 6128 | static BcStatus bc_program_builtin(char inst) |
6132 | { | 6129 | { |
6133 | BcStatus s; | 6130 | BcStatus s; |
6134 | BcResult *opnd; | 6131 | BcResult *opnd; |
@@ -6136,10 +6133,10 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst) | |||
6136 | BcResult res; | 6133 | BcResult res; |
6137 | bool len = inst == BC_INST_LENGTH; | 6134 | bool len = inst == BC_INST_LENGTH; |
6138 | 6135 | ||
6139 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 6136 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
6140 | opnd = bc_vec_top(&p->results); | 6137 | opnd = bc_vec_top(&G.prog.results); |
6141 | 6138 | ||
6142 | s = bc_program_num(p, opnd, &num, false); | 6139 | s = bc_program_num(opnd, &num, false); |
6143 | if (s) return s; | 6140 | if (s) return s; |
6144 | 6141 | ||
6145 | #if ENABLE_DC | 6142 | #if ENABLE_DC |
@@ -6148,7 +6145,7 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst) | |||
6148 | 6145 | ||
6149 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 6146 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
6150 | 6147 | ||
6151 | if (inst == BC_INST_SQRT) s = bc_num_sqrt(num, &res.d.n, p->scale); | 6148 | if (inst == BC_INST_SQRT) s = bc_num_sqrt(num, &res.d.n, G.prog.scale); |
6152 | #if ENABLE_BC | 6149 | #if ENABLE_BC |
6153 | else if (len != 0 && opnd->t == BC_RESULT_ARRAY) { | 6150 | else if (len != 0 && opnd->t == BC_RESULT_ARRAY) { |
6154 | s = bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); | 6151 | s = bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); |
@@ -6160,7 +6157,7 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst) | |||
6160 | char **str; | 6157 | char **str; |
6161 | size_t idx = opnd->t == BC_RESULT_STR ? opnd->d.id.idx : num->rdx; | 6158 | size_t idx = opnd->t == BC_RESULT_STR ? opnd->d.id.idx : num->rdx; |
6162 | 6159 | ||
6163 | str = bc_vec_item(&p->strs, idx); | 6160 | str = bc_vec_item(&G.prog.strs, idx); |
6164 | s = bc_num_ulong2num(&res.d.n, strlen(*str)); | 6161 | s = bc_num_ulong2num(&res.d.n, strlen(*str)); |
6165 | if (s) goto err; | 6162 | if (s) goto err; |
6166 | } | 6163 | } |
@@ -6171,7 +6168,7 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst) | |||
6171 | if (s) goto err; | 6168 | if (s) goto err; |
6172 | } | 6169 | } |
6173 | 6170 | ||
6174 | bc_program_retire(p, &res, BC_RESULT_TEMP); | 6171 | bc_program_retire(&res, BC_RESULT_TEMP); |
6175 | 6172 | ||
6176 | return s; | 6173 | return s; |
6177 | 6174 | ||
@@ -6181,24 +6178,24 @@ err: | |||
6181 | } | 6178 | } |
6182 | 6179 | ||
6183 | #if ENABLE_DC | 6180 | #if ENABLE_DC |
6184 | static BcStatus bc_program_divmod(BcProgram *p) | 6181 | static BcStatus bc_program_divmod(void) |
6185 | { | 6182 | { |
6186 | BcStatus s; | 6183 | BcStatus s; |
6187 | BcResult *opd1, *opd2, res, res2; | 6184 | BcResult *opd1, *opd2, res, res2; |
6188 | BcNum *n1, *n2 = NULL; | 6185 | BcNum *n1, *n2 = NULL; |
6189 | 6186 | ||
6190 | s = bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, false); | 6187 | s = bc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false); |
6191 | if (s) return s; | 6188 | if (s) return s; |
6192 | 6189 | ||
6193 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 6190 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
6194 | bc_num_init(&res2.d.n, n2->len); | 6191 | bc_num_init(&res2.d.n, n2->len); |
6195 | 6192 | ||
6196 | s = bc_num_divmod(n1, n2, &res2.d.n, &res.d.n, p->scale); | 6193 | s = bc_num_divmod(n1, n2, &res2.d.n, &res.d.n, G.prog.scale); |
6197 | if (s) goto err; | 6194 | if (s) goto err; |
6198 | 6195 | ||
6199 | bc_program_binOpRetire(p, &res2); | 6196 | bc_program_binOpRetire(&res2); |
6200 | res.t = BC_RESULT_TEMP; | 6197 | res.t = BC_RESULT_TEMP; |
6201 | bc_vec_push(&p->results, &res); | 6198 | bc_vec_push(&G.prog.results, &res); |
6202 | 6199 | ||
6203 | return s; | 6200 | return s; |
6204 | 6201 | ||
@@ -6208,18 +6205,18 @@ err: | |||
6208 | return s; | 6205 | return s; |
6209 | } | 6206 | } |
6210 | 6207 | ||
6211 | static BcStatus bc_program_modexp(BcProgram *p) | 6208 | static BcStatus bc_program_modexp(void) |
6212 | { | 6209 | { |
6213 | BcStatus s; | 6210 | BcStatus s; |
6214 | BcResult *r1, *r2, *r3, res; | 6211 | BcResult *r1, *r2, *r3, res; |
6215 | BcNum *n1, *n2, *n3; | 6212 | BcNum *n1, *n2, *n3; |
6216 | 6213 | ||
6217 | if (!BC_PROG_STACK(&p->results, 3)) return BC_STATUS_EXEC_STACK; | 6214 | if (!BC_PROG_STACK(&G.prog.results, 3)) return BC_STATUS_EXEC_STACK; |
6218 | s = bc_program_binOpPrep(p, &r2, &n2, &r3, &n3, false); | 6215 | s = bc_program_binOpPrep(&r2, &n2, &r3, &n3, false); |
6219 | if (s) return s; | 6216 | if (s) return s; |
6220 | 6217 | ||
6221 | r1 = bc_vec_item_rev(&p->results, 2); | 6218 | r1 = bc_vec_item_rev(&G.prog.results, 2); |
6222 | s = bc_program_num(p, r1, &n1, false); | 6219 | s = bc_program_num(r1, &n1, false); |
6223 | if (s) return s; | 6220 | if (s) return s; |
6224 | if (!BC_PROG_NUM(r1, n1)) return BC_STATUS_EXEC_BAD_TYPE; | 6221 | if (!BC_PROG_NUM(r1, n1)) return BC_STATUS_EXEC_BAD_TYPE; |
6225 | 6222 | ||
@@ -6227,12 +6224,12 @@ static BcStatus bc_program_modexp(BcProgram *p) | |||
6227 | if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) { | 6224 | if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) { |
6228 | 6225 | ||
6229 | if (r1->t == r2->t) { | 6226 | if (r1->t == r2->t) { |
6230 | s = bc_program_num(p, r2, &n2, false); | 6227 | s = bc_program_num(r2, &n2, false); |
6231 | if (s) return s; | 6228 | if (s) return s; |
6232 | } | 6229 | } |
6233 | 6230 | ||
6234 | if (r1->t == r3->t) { | 6231 | if (r1->t == r3->t) { |
6235 | s = bc_program_num(p, r3, &n3, false); | 6232 | s = bc_program_num(r3, &n3, false); |
6236 | if (s) return s; | 6233 | if (s) return s; |
6237 | } | 6234 | } |
6238 | } | 6235 | } |
@@ -6241,8 +6238,8 @@ static BcStatus bc_program_modexp(BcProgram *p) | |||
6241 | s = bc_num_modexp(n1, n2, n3, &res.d.n); | 6238 | s = bc_num_modexp(n1, n2, n3, &res.d.n); |
6242 | if (s) goto err; | 6239 | if (s) goto err; |
6243 | 6240 | ||
6244 | bc_vec_pop(&p->results); | 6241 | bc_vec_pop(&G.prog.results); |
6245 | bc_program_binOpRetire(p, &res); | 6242 | bc_program_binOpRetire(&res); |
6246 | 6243 | ||
6247 | return s; | 6244 | return s; |
6248 | 6245 | ||
@@ -6251,18 +6248,18 @@ err: | |||
6251 | return s; | 6248 | return s; |
6252 | } | 6249 | } |
6253 | 6250 | ||
6254 | static BcStatus bc_program_stackLen(BcProgram *p) | 6251 | static BcStatus bc_program_stackLen(void) |
6255 | { | 6252 | { |
6256 | BcStatus s; | 6253 | BcStatus s; |
6257 | BcResult res; | 6254 | BcResult res; |
6258 | size_t len = p->results.len; | 6255 | size_t len = G.prog.results.len; |
6259 | 6256 | ||
6260 | res.t = BC_RESULT_TEMP; | 6257 | res.t = BC_RESULT_TEMP; |
6261 | 6258 | ||
6262 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 6259 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
6263 | s = bc_num_ulong2num(&res.d.n, len); | 6260 | s = bc_num_ulong2num(&res.d.n, len); |
6264 | if (s) goto err; | 6261 | if (s) goto err; |
6265 | bc_vec_push(&p->results, &res); | 6262 | bc_vec_push(&G.prog.results, &res); |
6266 | 6263 | ||
6267 | return s; | 6264 | return s; |
6268 | 6265 | ||
@@ -6271,19 +6268,19 @@ err: | |||
6271 | return s; | 6268 | return s; |
6272 | } | 6269 | } |
6273 | 6270 | ||
6274 | static BcStatus bc_program_asciify(BcProgram *p) | 6271 | static BcStatus bc_program_asciify(void) |
6275 | { | 6272 | { |
6276 | BcStatus s; | 6273 | BcStatus s; |
6277 | BcResult *r, res; | 6274 | BcResult *r, res; |
6278 | BcNum *num = NULL, n; | 6275 | BcNum *num = NULL, n; |
6279 | char *str, *str2, c; | 6276 | char *str, *str2, c; |
6280 | size_t len = p->strs.len, idx; | 6277 | size_t len = G.prog.strs.len, idx; |
6281 | unsigned long val; | 6278 | unsigned long val; |
6282 | 6279 | ||
6283 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 6280 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
6284 | r = bc_vec_top(&p->results); | 6281 | r = bc_vec_top(&G.prog.results); |
6285 | 6282 | ||
6286 | s = bc_program_num(p, r, &num, false); | 6283 | s = bc_program_num(r, &num, false); |
6287 | if (s) return s; | 6284 | if (s) return s; |
6288 | 6285 | ||
6289 | if (BC_PROG_NUM(r, num)) { | 6286 | if (BC_PROG_NUM(r, num)) { |
@@ -6292,7 +6289,7 @@ static BcStatus bc_program_asciify(BcProgram *p) | |||
6292 | bc_num_copy(&n, num); | 6289 | bc_num_copy(&n, num); |
6293 | bc_num_truncate(&n, n.rdx); | 6290 | bc_num_truncate(&n, n.rdx); |
6294 | 6291 | ||
6295 | s = bc_num_mod(&n, &p->strmb, &n, 0); | 6292 | s = bc_num_mod(&n, &G.prog.strmb, &n, 0); |
6296 | if (s) goto num_err; | 6293 | if (s) goto num_err; |
6297 | s = bc_num_ulong(&n, &val); | 6294 | s = bc_num_ulong(&n, &val); |
6298 | if (s) goto num_err; | 6295 | if (s) goto num_err; |
@@ -6303,7 +6300,7 @@ static BcStatus bc_program_asciify(BcProgram *p) | |||
6303 | } | 6300 | } |
6304 | else { | 6301 | else { |
6305 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : num->rdx; | 6302 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : num->rdx; |
6306 | str2 = *((char **) bc_vec_item(&p->strs, idx)); | 6303 | str2 = *((char **) bc_vec_item(&G.prog.strs, idx)); |
6307 | c = str2[0]; | 6304 | c = str2[0]; |
6308 | } | 6305 | } |
6309 | 6306 | ||
@@ -6312,12 +6309,12 @@ static BcStatus bc_program_asciify(BcProgram *p) | |||
6312 | str[1] = '\0'; | 6309 | str[1] = '\0'; |
6313 | 6310 | ||
6314 | str2 = xstrdup(str); | 6311 | str2 = xstrdup(str); |
6315 | bc_program_addFunc(p, str2, &idx); | 6312 | bc_program_addFunc(str2, &idx); |
6316 | 6313 | ||
6317 | if (idx != len + BC_PROG_REQ_FUNCS) { | 6314 | if (idx != len + BC_PROG_REQ_FUNCS) { |
6318 | 6315 | ||
6319 | for (idx = 0; idx < p->strs.len; ++idx) { | 6316 | for (idx = 0; idx < G.prog.strs.len; ++idx) { |
6320 | if (!strcmp(*((char **) bc_vec_item(&p->strs, idx)), str)) { | 6317 | if (!strcmp(*((char **) bc_vec_item(&G.prog.strs, idx)), str)) { |
6321 | len = idx; | 6318 | len = idx; |
6322 | break; | 6319 | break; |
6323 | } | 6320 | } |
@@ -6326,12 +6323,12 @@ static BcStatus bc_program_asciify(BcProgram *p) | |||
6326 | free(str); | 6323 | free(str); |
6327 | } | 6324 | } |
6328 | else | 6325 | else |
6329 | bc_vec_push(&p->strs, &str); | 6326 | bc_vec_push(&G.prog.strs, &str); |
6330 | 6327 | ||
6331 | res.t = BC_RESULT_STR; | 6328 | res.t = BC_RESULT_STR; |
6332 | res.d.id.idx = len; | 6329 | res.d.id.idx = len; |
6333 | bc_vec_pop(&p->results); | 6330 | bc_vec_pop(&G.prog.results); |
6334 | bc_vec_push(&p->results, &res); | 6331 | bc_vec_push(&G.prog.results, &res); |
6335 | 6332 | ||
6336 | return BC_STATUS_SUCCESS; | 6333 | return BC_STATUS_SUCCESS; |
6337 | 6334 | ||
@@ -6340,7 +6337,7 @@ num_err: | |||
6340 | return s; | 6337 | return s; |
6341 | } | 6338 | } |
6342 | 6339 | ||
6343 | static BcStatus bc_program_printStream(BcProgram *p) | 6340 | static BcStatus bc_program_printStream(void) |
6344 | { | 6341 | { |
6345 | BcStatus s; | 6342 | BcStatus s; |
6346 | BcResult *r; | 6343 | BcResult *r; |
@@ -6348,17 +6345,17 @@ static BcStatus bc_program_printStream(BcProgram *p) | |||
6348 | size_t idx; | 6345 | size_t idx; |
6349 | char *str; | 6346 | char *str; |
6350 | 6347 | ||
6351 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 6348 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
6352 | r = bc_vec_top(&p->results); | 6349 | r = bc_vec_top(&G.prog.results); |
6353 | 6350 | ||
6354 | s = bc_program_num(p, r, &n, false); | 6351 | s = bc_program_num(r, &n, false); |
6355 | if (s) return s; | 6352 | if (s) return s; |
6356 | 6353 | ||
6357 | if (BC_PROG_NUM(r, n)) | 6354 | if (BC_PROG_NUM(r, n)) |
6358 | s = bc_num_stream(n, &p->strmb, &p->nchars, p->len); | 6355 | s = bc_num_stream(n, &G.prog.strmb, &G.prog.nchars, G.prog.len); |
6359 | else { | 6356 | else { |
6360 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx; | 6357 | idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx; |
6361 | str = *((char **) bc_vec_item(&p->strs, idx)); | 6358 | str = *((char **) bc_vec_item(&G.prog.strs, idx)); |
6362 | printf("%s", str); | 6359 | printf("%s", str); |
6363 | } | 6360 | } |
6364 | 6361 | ||
@@ -6367,26 +6364,24 @@ static BcStatus bc_program_printStream(BcProgram *p) | |||
6367 | 6364 | ||
6368 | static BcStatus bc_program_nquit(void) | 6365 | static BcStatus bc_program_nquit(void) |
6369 | { | 6366 | { |
6370 | BcProgram *p = &G.prog; | ||
6371 | |||
6372 | BcStatus s; | 6367 | BcStatus s; |
6373 | BcResult *opnd; | 6368 | BcResult *opnd; |
6374 | BcNum *num = NULL; | 6369 | BcNum *num = NULL; |
6375 | unsigned long val; | 6370 | unsigned long val; |
6376 | 6371 | ||
6377 | s = bc_program_prep(p, &opnd, &num); | 6372 | s = bc_program_prep(&opnd, &num); |
6378 | if (s) return s; | 6373 | if (s) return s; |
6379 | s = bc_num_ulong(num, &val); | 6374 | s = bc_num_ulong(num, &val); |
6380 | if (s) return s; | 6375 | if (s) return s; |
6381 | 6376 | ||
6382 | bc_vec_pop(&p->results); | 6377 | bc_vec_pop(&G.prog.results); |
6383 | 6378 | ||
6384 | if (p->stack.len < val) | 6379 | if (G.prog.stack.len < val) |
6385 | return BC_STATUS_EXEC_STACK; | 6380 | return BC_STATUS_EXEC_STACK; |
6386 | else if (p->stack.len == val) | 6381 | else if (G.prog.stack.len == val) |
6387 | return BC_STATUS_QUIT; | 6382 | return BC_STATUS_QUIT; |
6388 | 6383 | ||
6389 | bc_vec_npop(&p->stack, val); | 6384 | bc_vec_npop(&G.prog.stack, val); |
6390 | 6385 | ||
6391 | return s; | 6386 | return s; |
6392 | } | 6387 | } |
@@ -6394,8 +6389,6 @@ static BcStatus bc_program_nquit(void) | |||
6394 | static BcStatus bc_program_execStr(char *code, size_t *bgn, | 6389 | static BcStatus bc_program_execStr(char *code, size_t *bgn, |
6395 | bool cond) | 6390 | bool cond) |
6396 | { | 6391 | { |
6397 | BcProgram *p = &G.prog; | ||
6398 | |||
6399 | BcStatus s = BC_STATUS_SUCCESS; | 6392 | BcStatus s = BC_STATUS_SUCCESS; |
6400 | BcResult *r; | 6393 | BcResult *r; |
6401 | char **str; | 6394 | char **str; |
@@ -6406,9 +6399,9 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6406 | BcNum *n; | 6399 | BcNum *n; |
6407 | bool exec; | 6400 | bool exec; |
6408 | 6401 | ||
6409 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 6402 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
6410 | 6403 | ||
6411 | r = bc_vec_top(&p->results); | 6404 | r = bc_vec_top(&G.prog.results); |
6412 | 6405 | ||
6413 | if (cond) { | 6406 | if (cond) { |
6414 | 6407 | ||
@@ -6430,7 +6423,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6430 | } | 6423 | } |
6431 | 6424 | ||
6432 | if (exec) { | 6425 | if (exec) { |
6433 | bc_program_search(p, name, &v, true); | 6426 | bc_program_search(name, &v, true); |
6434 | n = bc_vec_top(v); | 6427 | n = bc_vec_top(v); |
6435 | } | 6428 | } |
6436 | 6429 | ||
@@ -6450,7 +6443,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6450 | if (r->t == BC_RESULT_STR) | 6443 | if (r->t == BC_RESULT_STR) |
6451 | sidx = r->d.id.idx; | 6444 | sidx = r->d.id.idx; |
6452 | else if (r->t == BC_RESULT_VAR) { | 6445 | else if (r->t == BC_RESULT_VAR) { |
6453 | s = bc_program_num(p, r, &n, false); | 6446 | s = bc_program_num(r, &n, false); |
6454 | if (s || !BC_PROG_STR(n)) goto exit; | 6447 | if (s || !BC_PROG_STR(n)) goto exit; |
6455 | sidx = n->rdx; | 6448 | sidx = n->rdx; |
6456 | } | 6449 | } |
@@ -6460,11 +6453,11 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6460 | 6453 | ||
6461 | fidx = sidx + BC_PROG_REQ_FUNCS; | 6454 | fidx = sidx + BC_PROG_REQ_FUNCS; |
6462 | 6455 | ||
6463 | str = bc_vec_item(&p->strs, sidx); | 6456 | str = bc_vec_item(&G.prog.strs, sidx); |
6464 | f = bc_vec_item(&p->fns, fidx); | 6457 | f = bc_vec_item(&G.prog.fns, fidx); |
6465 | 6458 | ||
6466 | if (f->code.len == 0) { | 6459 | if (f->code.len == 0) { |
6467 | common_parse_init(&prs, p, fidx); | 6460 | common_parse_init(&prs, fidx); |
6468 | s = bc_parse_text(&prs, *str); | 6461 | s = bc_parse_text(&prs, *str); |
6469 | if (s) goto err; | 6462 | if (s) goto err; |
6470 | s = common_parse_expr(&prs, BC_PARSE_NOCALL); | 6463 | s = common_parse_expr(&prs, BC_PARSE_NOCALL); |
@@ -6479,25 +6472,25 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn, | |||
6479 | } | 6472 | } |
6480 | 6473 | ||
6481 | ip.idx = 0; | 6474 | ip.idx = 0; |
6482 | ip.len = p->results.len; | 6475 | ip.len = G.prog.results.len; |
6483 | ip.func = fidx; | 6476 | ip.func = fidx; |
6484 | 6477 | ||
6485 | bc_vec_pop(&p->results); | 6478 | bc_vec_pop(&G.prog.results); |
6486 | bc_vec_push(&p->stack, &ip); | 6479 | bc_vec_push(&G.prog.stack, &ip); |
6487 | 6480 | ||
6488 | return BC_STATUS_SUCCESS; | 6481 | return BC_STATUS_SUCCESS; |
6489 | 6482 | ||
6490 | err: | 6483 | err: |
6491 | bc_parse_free(&prs); | 6484 | bc_parse_free(&prs); |
6492 | f = bc_vec_item(&p->fns, fidx); | 6485 | f = bc_vec_item(&G.prog.fns, fidx); |
6493 | bc_vec_npop(&f->code, f->code.len); | 6486 | bc_vec_npop(&f->code, f->code.len); |
6494 | exit: | 6487 | exit: |
6495 | bc_vec_pop(&p->results); | 6488 | bc_vec_pop(&G.prog.results); |
6496 | return s; | 6489 | return s; |
6497 | } | 6490 | } |
6498 | #endif // ENABLE_DC | 6491 | #endif // ENABLE_DC |
6499 | 6492 | ||
6500 | static BcStatus bc_program_pushGlobal(BcProgram *p, char inst) | 6493 | static BcStatus bc_program_pushGlobal(char inst) |
6501 | { | 6494 | { |
6502 | BcStatus s; | 6495 | BcStatus s; |
6503 | BcResult res; | 6496 | BcResult res; |
@@ -6505,16 +6498,16 @@ static BcStatus bc_program_pushGlobal(BcProgram *p, char inst) | |||
6505 | 6498 | ||
6506 | res.t = inst - BC_INST_IBASE + BC_RESULT_IBASE; | 6499 | res.t = inst - BC_INST_IBASE + BC_RESULT_IBASE; |
6507 | if (inst == BC_INST_IBASE) | 6500 | if (inst == BC_INST_IBASE) |
6508 | val = (unsigned long) p->ib_t; | 6501 | val = (unsigned long) G.prog.ib_t; |
6509 | else if (inst == BC_INST_SCALE) | 6502 | else if (inst == BC_INST_SCALE) |
6510 | val = (unsigned long) p->scale; | 6503 | val = (unsigned long) G.prog.scale; |
6511 | else | 6504 | else |
6512 | val = (unsigned long) p->ob_t; | 6505 | val = (unsigned long) G.prog.ob_t; |
6513 | 6506 | ||
6514 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); | 6507 | bc_num_init(&res.d.n, BC_NUM_DEF_SIZE); |
6515 | s = bc_num_ulong2num(&res.d.n, val); | 6508 | s = bc_num_ulong2num(&res.d.n, val); |
6516 | if (s) goto err; | 6509 | if (s) goto err; |
6517 | bc_vec_push(&p->results, &res); | 6510 | bc_vec_push(&G.prog.results, &res); |
6518 | 6511 | ||
6519 | return s; | 6512 | return s; |
6520 | 6513 | ||
@@ -6523,24 +6516,24 @@ err: | |||
6523 | return s; | 6516 | return s; |
6524 | } | 6517 | } |
6525 | 6518 | ||
6526 | static void bc_program_addFunc(BcProgram *p, char *name, size_t *idx) | 6519 | static void bc_program_addFunc(char *name, size_t *idx) |
6527 | { | 6520 | { |
6528 | BcStatus s; | 6521 | BcStatus s; |
6529 | BcId entry, *entry_ptr; | 6522 | BcId entry, *entry_ptr; |
6530 | BcFunc f; | 6523 | BcFunc f; |
6531 | 6524 | ||
6532 | entry.name = name; | 6525 | entry.name = name; |
6533 | entry.idx = p->fns.len; | 6526 | entry.idx = G.prog.fns.len; |
6534 | 6527 | ||
6535 | s = bc_map_insert(&p->fn_map, &entry, idx); | 6528 | s = bc_map_insert(&G.prog.fn_map, &entry, idx); |
6536 | if (s) free(name); | 6529 | if (s) free(name); |
6537 | 6530 | ||
6538 | entry_ptr = bc_vec_item(&p->fn_map, *idx); | 6531 | entry_ptr = bc_vec_item(&G.prog.fn_map, *idx); |
6539 | *idx = entry_ptr->idx; | 6532 | *idx = entry_ptr->idx; |
6540 | 6533 | ||
6541 | if (s == BC_STATUS_VEC_ITEM_EXISTS) { | 6534 | if (s == BC_STATUS_VEC_ITEM_EXISTS) { |
6542 | 6535 | ||
6543 | BcFunc *func = bc_vec_item(&p->fns, entry_ptr->idx); | 6536 | BcFunc *func = bc_vec_item(&G.prog.fns, entry_ptr->idx); |
6544 | 6537 | ||
6545 | // We need to reset these, so the function can be repopulated. | 6538 | // We need to reset these, so the function can be repopulated. |
6546 | func->nparams = 0; | 6539 | func->nparams = 0; |
@@ -6550,20 +6543,20 @@ static void bc_program_addFunc(BcProgram *p, char *name, size_t *idx) | |||
6550 | } | 6543 | } |
6551 | else { | 6544 | else { |
6552 | bc_func_init(&f); | 6545 | bc_func_init(&f); |
6553 | bc_vec_push(&p->fns, &f); | 6546 | bc_vec_push(&G.prog.fns, &f); |
6554 | } | 6547 | } |
6555 | } | 6548 | } |
6556 | 6549 | ||
6557 | static BcStatus bc_program_reset(BcProgram *p, BcStatus s) | 6550 | static BcStatus bc_program_reset(BcStatus s) |
6558 | { | 6551 | { |
6559 | BcFunc *f; | 6552 | BcFunc *f; |
6560 | BcInstPtr *ip; | 6553 | BcInstPtr *ip; |
6561 | 6554 | ||
6562 | bc_vec_npop(&p->stack, p->stack.len - 1); | 6555 | bc_vec_npop(&G.prog.stack, G.prog.stack.len - 1); |
6563 | bc_vec_npop(&p->results, p->results.len); | 6556 | bc_vec_npop(&G.prog.results, G.prog.results.len); |
6564 | 6557 | ||
6565 | f = bc_vec_item(&p->fns, 0); | 6558 | f = bc_vec_item(&G.prog.fns, 0); |
6566 | ip = bc_vec_top(&p->stack); | 6559 | ip = bc_vec_top(&G.prog.stack); |
6567 | ip->idx = f->code.len; | 6560 | ip->idx = f->code.len; |
6568 | 6561 | ||
6569 | if (!s && G_interrupt && !G.tty) return BC_STATUS_QUIT; | 6562 | if (!s && G_interrupt && !G.tty) return BC_STATUS_QUIT; |
@@ -6584,14 +6577,12 @@ static BcStatus bc_program_reset(BcProgram *p, BcStatus s) | |||
6584 | 6577 | ||
6585 | static BcStatus bc_program_exec(void) | 6578 | static BcStatus bc_program_exec(void) |
6586 | { | 6579 | { |
6587 | BcProgram *p = &G.prog; | ||
6588 | |||
6589 | BcStatus s = BC_STATUS_SUCCESS; | 6580 | BcStatus s = BC_STATUS_SUCCESS; |
6590 | size_t idx; | 6581 | size_t idx; |
6591 | BcResult r, *ptr; | 6582 | BcResult r, *ptr; |
6592 | BcNum *num; | 6583 | BcNum *num; |
6593 | BcInstPtr *ip = bc_vec_top(&p->stack); | 6584 | BcInstPtr *ip = bc_vec_top(&G.prog.stack); |
6594 | BcFunc *func = bc_vec_item(&p->fns, ip->func); | 6585 | BcFunc *func = bc_vec_item(&G.prog.fns, ip->func); |
6595 | char *code = func->code.v; | 6586 | char *code = func->code.v; |
6596 | bool cond = false; | 6587 | bool cond = false; |
6597 | 6588 | ||
@@ -6604,10 +6595,10 @@ static BcStatus bc_program_exec(void) | |||
6604 | #if ENABLE_BC | 6595 | #if ENABLE_BC |
6605 | case BC_INST_JUMP_ZERO: | 6596 | case BC_INST_JUMP_ZERO: |
6606 | { | 6597 | { |
6607 | s = bc_program_prep(p, &ptr, &num); | 6598 | s = bc_program_prep(&ptr, &num); |
6608 | if (s) return s; | 6599 | if (s) return s; |
6609 | cond = !bc_num_cmp(num, &p->zero); | 6600 | cond = !bc_num_cmp(num, &G.prog.zero); |
6610 | bc_vec_pop(&p->results); | 6601 | bc_vec_pop(&G.prog.results); |
6611 | } | 6602 | } |
6612 | // Fallthrough. | 6603 | // Fallthrough. |
6613 | case BC_INST_JUMP: | 6604 | case BC_INST_JUMP: |
@@ -6621,7 +6612,7 @@ static BcStatus bc_program_exec(void) | |||
6621 | 6612 | ||
6622 | case BC_INST_CALL: | 6613 | case BC_INST_CALL: |
6623 | { | 6614 | { |
6624 | s = bc_program_call(p, code, &ip->idx); | 6615 | s = bc_program_call(code, &ip->idx); |
6625 | break; | 6616 | break; |
6626 | } | 6617 | } |
6627 | 6618 | ||
@@ -6630,7 +6621,7 @@ static BcStatus bc_program_exec(void) | |||
6630 | case BC_INST_INC_POST: | 6621 | case BC_INST_INC_POST: |
6631 | case BC_INST_DEC_POST: | 6622 | case BC_INST_DEC_POST: |
6632 | { | 6623 | { |
6633 | s = bc_program_incdec(p, inst); | 6624 | s = bc_program_incdec(inst); |
6634 | break; | 6625 | break; |
6635 | } | 6626 | } |
6636 | 6627 | ||
@@ -6643,7 +6634,7 @@ static BcStatus bc_program_exec(void) | |||
6643 | case BC_INST_RET: | 6634 | case BC_INST_RET: |
6644 | case BC_INST_RET0: | 6635 | case BC_INST_RET0: |
6645 | { | 6636 | { |
6646 | s = bc_program_return(p, inst); | 6637 | s = bc_program_return(inst); |
6647 | break; | 6638 | break; |
6648 | } | 6639 | } |
6649 | 6640 | ||
@@ -6657,7 +6648,7 @@ static BcStatus bc_program_exec(void) | |||
6657 | case BC_INST_REL_LT: | 6648 | case BC_INST_REL_LT: |
6658 | case BC_INST_REL_GT: | 6649 | case BC_INST_REL_GT: |
6659 | { | 6650 | { |
6660 | s = bc_program_logical(p, inst); | 6651 | s = bc_program_logical(inst); |
6661 | break; | 6652 | break; |
6662 | } | 6653 | } |
6663 | 6654 | ||
@@ -6669,21 +6660,21 @@ static BcStatus bc_program_exec(void) | |||
6669 | 6660 | ||
6670 | case BC_INST_VAR: | 6661 | case BC_INST_VAR: |
6671 | { | 6662 | { |
6672 | s = bc_program_pushVar(p, code, &ip->idx, false, false); | 6663 | s = bc_program_pushVar(code, &ip->idx, false, false); |
6673 | break; | 6664 | break; |
6674 | } | 6665 | } |
6675 | 6666 | ||
6676 | case BC_INST_ARRAY_ELEM: | 6667 | case BC_INST_ARRAY_ELEM: |
6677 | case BC_INST_ARRAY: | 6668 | case BC_INST_ARRAY: |
6678 | { | 6669 | { |
6679 | s = bc_program_pushArray(p, code, &ip->idx, inst); | 6670 | s = bc_program_pushArray(code, &ip->idx, inst); |
6680 | break; | 6671 | break; |
6681 | } | 6672 | } |
6682 | 6673 | ||
6683 | case BC_INST_LAST: | 6674 | case BC_INST_LAST: |
6684 | { | 6675 | { |
6685 | r.t = BC_RESULT_LAST; | 6676 | r.t = BC_RESULT_LAST; |
6686 | bc_vec_push(&p->results, &r); | 6677 | bc_vec_push(&G.prog.results, &r); |
6687 | break; | 6678 | break; |
6688 | } | 6679 | } |
6689 | 6680 | ||
@@ -6691,7 +6682,7 @@ static BcStatus bc_program_exec(void) | |||
6691 | case BC_INST_SCALE: | 6682 | case BC_INST_SCALE: |
6692 | case BC_INST_OBASE: | 6683 | case BC_INST_OBASE: |
6693 | { | 6684 | { |
6694 | s = bc_program_pushGlobal(p, inst); | 6685 | s = bc_program_pushGlobal(inst); |
6695 | break; | 6686 | break; |
6696 | } | 6687 | } |
6697 | 6688 | ||
@@ -6699,7 +6690,7 @@ static BcStatus bc_program_exec(void) | |||
6699 | case BC_INST_LENGTH: | 6690 | case BC_INST_LENGTH: |
6700 | case BC_INST_SQRT: | 6691 | case BC_INST_SQRT: |
6701 | { | 6692 | { |
6702 | s = bc_program_builtin(p, inst); | 6693 | s = bc_program_builtin(inst); |
6703 | break; | 6694 | break; |
6704 | } | 6695 | } |
6705 | 6696 | ||
@@ -6707,22 +6698,22 @@ static BcStatus bc_program_exec(void) | |||
6707 | { | 6698 | { |
6708 | r.t = BC_RESULT_CONSTANT; | 6699 | r.t = BC_RESULT_CONSTANT; |
6709 | r.d.id.idx = bc_program_index(code, &ip->idx); | 6700 | r.d.id.idx = bc_program_index(code, &ip->idx); |
6710 | bc_vec_push(&p->results, &r); | 6701 | bc_vec_push(&G.prog.results, &r); |
6711 | break; | 6702 | break; |
6712 | } | 6703 | } |
6713 | 6704 | ||
6714 | case BC_INST_POP: | 6705 | case BC_INST_POP: |
6715 | { | 6706 | { |
6716 | if (!BC_PROG_STACK(&p->results, 1)) | 6707 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6717 | s = BC_STATUS_EXEC_STACK; | 6708 | s = BC_STATUS_EXEC_STACK; |
6718 | else | 6709 | else |
6719 | bc_vec_pop(&p->results); | 6710 | bc_vec_pop(&G.prog.results); |
6720 | break; | 6711 | break; |
6721 | } | 6712 | } |
6722 | 6713 | ||
6723 | case BC_INST_POP_EXEC: | 6714 | case BC_INST_POP_EXEC: |
6724 | { | 6715 | { |
6725 | bc_vec_pop(&p->stack); | 6716 | bc_vec_pop(&G.prog.stack); |
6726 | break; | 6717 | break; |
6727 | } | 6718 | } |
6728 | 6719 | ||
@@ -6730,7 +6721,7 @@ static BcStatus bc_program_exec(void) | |||
6730 | case BC_INST_PRINT_POP: | 6721 | case BC_INST_PRINT_POP: |
6731 | case BC_INST_PRINT_STR: | 6722 | case BC_INST_PRINT_STR: |
6732 | { | 6723 | { |
6733 | s = bc_program_print(p, inst, 0); | 6724 | s = bc_program_print(inst, 0); |
6734 | break; | 6725 | break; |
6735 | } | 6726 | } |
6736 | 6727 | ||
@@ -6738,7 +6729,7 @@ static BcStatus bc_program_exec(void) | |||
6738 | { | 6729 | { |
6739 | r.t = BC_RESULT_STR; | 6730 | r.t = BC_RESULT_STR; |
6740 | r.d.id.idx = bc_program_index(code, &ip->idx); | 6731 | r.d.id.idx = bc_program_index(code, &ip->idx); |
6741 | bc_vec_push(&p->results, &r); | 6732 | bc_vec_push(&G.prog.results, &r); |
6742 | break; | 6733 | break; |
6743 | } | 6734 | } |
6744 | 6735 | ||
@@ -6749,25 +6740,25 @@ static BcStatus bc_program_exec(void) | |||
6749 | case BC_INST_PLUS: | 6740 | case BC_INST_PLUS: |
6750 | case BC_INST_MINUS: | 6741 | case BC_INST_MINUS: |
6751 | { | 6742 | { |
6752 | s = bc_program_op(p, inst); | 6743 | s = bc_program_op(inst); |
6753 | break; | 6744 | break; |
6754 | } | 6745 | } |
6755 | 6746 | ||
6756 | case BC_INST_BOOL_NOT: | 6747 | case BC_INST_BOOL_NOT: |
6757 | { | 6748 | { |
6758 | s = bc_program_prep(p, &ptr, &num); | 6749 | s = bc_program_prep(&ptr, &num); |
6759 | if (s) return s; | 6750 | if (s) return s; |
6760 | 6751 | ||
6761 | bc_num_init(&r.d.n, BC_NUM_DEF_SIZE); | 6752 | bc_num_init(&r.d.n, BC_NUM_DEF_SIZE); |
6762 | (!bc_num_cmp(num, &p->zero) ? bc_num_one : bc_num_zero)(&r.d.n); | 6753 | (!bc_num_cmp(num, &G.prog.zero) ? bc_num_one : bc_num_zero)(&r.d.n); |
6763 | bc_program_retire(p, &r, BC_RESULT_TEMP); | 6754 | bc_program_retire(&r, BC_RESULT_TEMP); |
6764 | 6755 | ||
6765 | break; | 6756 | break; |
6766 | } | 6757 | } |
6767 | 6758 | ||
6768 | case BC_INST_NEG: | 6759 | case BC_INST_NEG: |
6769 | { | 6760 | { |
6770 | s = bc_program_negate(p); | 6761 | s = bc_program_negate(); |
6771 | break; | 6762 | break; |
6772 | } | 6763 | } |
6773 | 6764 | ||
@@ -6781,19 +6772,19 @@ static BcStatus bc_program_exec(void) | |||
6781 | #endif | 6772 | #endif |
6782 | case BC_INST_ASSIGN: | 6773 | case BC_INST_ASSIGN: |
6783 | { | 6774 | { |
6784 | s = bc_program_assign(p, inst); | 6775 | s = bc_program_assign(inst); |
6785 | break; | 6776 | break; |
6786 | } | 6777 | } |
6787 | #if ENABLE_DC | 6778 | #if ENABLE_DC |
6788 | case BC_INST_MODEXP: | 6779 | case BC_INST_MODEXP: |
6789 | { | 6780 | { |
6790 | s = bc_program_modexp(p); | 6781 | s = bc_program_modexp(); |
6791 | break; | 6782 | break; |
6792 | } | 6783 | } |
6793 | 6784 | ||
6794 | case BC_INST_DIVMOD: | 6785 | case BC_INST_DIVMOD: |
6795 | { | 6786 | { |
6796 | s = bc_program_divmod(p); | 6787 | s = bc_program_divmod(); |
6797 | break; | 6788 | break; |
6798 | } | 6789 | } |
6799 | 6790 | ||
@@ -6807,29 +6798,29 @@ static BcStatus bc_program_exec(void) | |||
6807 | 6798 | ||
6808 | case BC_INST_PRINT_STACK: | 6799 | case BC_INST_PRINT_STACK: |
6809 | { | 6800 | { |
6810 | for (idx = 0; !s && idx < p->results.len; ++idx) | 6801 | for (idx = 0; !s && idx < G.prog.results.len; ++idx) |
6811 | s = bc_program_print(p, BC_INST_PRINT, idx); | 6802 | s = bc_program_print(BC_INST_PRINT, idx); |
6812 | break; | 6803 | break; |
6813 | } | 6804 | } |
6814 | 6805 | ||
6815 | case BC_INST_CLEAR_STACK: | 6806 | case BC_INST_CLEAR_STACK: |
6816 | { | 6807 | { |
6817 | bc_vec_npop(&p->results, p->results.len); | 6808 | bc_vec_npop(&G.prog.results, G.prog.results.len); |
6818 | break; | 6809 | break; |
6819 | } | 6810 | } |
6820 | 6811 | ||
6821 | case BC_INST_STACK_LEN: | 6812 | case BC_INST_STACK_LEN: |
6822 | { | 6813 | { |
6823 | s = bc_program_stackLen(p); | 6814 | s = bc_program_stackLen(); |
6824 | break; | 6815 | break; |
6825 | } | 6816 | } |
6826 | 6817 | ||
6827 | case BC_INST_DUPLICATE: | 6818 | case BC_INST_DUPLICATE: |
6828 | { | 6819 | { |
6829 | if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK; | 6820 | if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK; |
6830 | ptr = bc_vec_top(&p->results); | 6821 | ptr = bc_vec_top(&G.prog.results); |
6831 | bc_result_copy(&r, ptr); | 6822 | bc_result_copy(&r, ptr); |
6832 | bc_vec_push(&p->results, &r); | 6823 | bc_vec_push(&G.prog.results, &r); |
6833 | break; | 6824 | break; |
6834 | } | 6825 | } |
6835 | 6826 | ||
@@ -6837,10 +6828,10 @@ static BcStatus bc_program_exec(void) | |||
6837 | { | 6828 | { |
6838 | BcResult *ptr2; | 6829 | BcResult *ptr2; |
6839 | 6830 | ||
6840 | if (!BC_PROG_STACK(&p->results, 2)) return BC_STATUS_EXEC_STACK; | 6831 | if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK; |
6841 | 6832 | ||
6842 | ptr = bc_vec_item_rev(&p->results, 0); | 6833 | ptr = bc_vec_item_rev(&G.prog.results, 0); |
6843 | ptr2 = bc_vec_item_rev(&p->results, 1); | 6834 | ptr2 = bc_vec_item_rev(&G.prog.results, 1); |
6844 | memcpy(&r, ptr, sizeof(BcResult)); | 6835 | memcpy(&r, ptr, sizeof(BcResult)); |
6845 | memcpy(ptr, ptr2, sizeof(BcResult)); | 6836 | memcpy(ptr, ptr2, sizeof(BcResult)); |
6846 | memcpy(ptr2, &r, sizeof(BcResult)); | 6837 | memcpy(ptr2, &r, sizeof(BcResult)); |
@@ -6850,13 +6841,13 @@ static BcStatus bc_program_exec(void) | |||
6850 | 6841 | ||
6851 | case BC_INST_ASCIIFY: | 6842 | case BC_INST_ASCIIFY: |
6852 | { | 6843 | { |
6853 | s = bc_program_asciify(p); | 6844 | s = bc_program_asciify(); |
6854 | break; | 6845 | break; |
6855 | } | 6846 | } |
6856 | 6847 | ||
6857 | case BC_INST_PRINT_STREAM: | 6848 | case BC_INST_PRINT_STREAM: |
6858 | { | 6849 | { |
6859 | s = bc_program_printStream(p); | 6850 | s = bc_program_printStream(); |
6860 | break; | 6851 | break; |
6861 | } | 6852 | } |
6862 | 6853 | ||
@@ -6864,24 +6855,24 @@ static BcStatus bc_program_exec(void) | |||
6864 | case BC_INST_PUSH_VAR: | 6855 | case BC_INST_PUSH_VAR: |
6865 | { | 6856 | { |
6866 | bool copy = inst == BC_INST_LOAD; | 6857 | bool copy = inst == BC_INST_LOAD; |
6867 | s = bc_program_pushVar(p, code, &ip->idx, true, copy); | 6858 | s = bc_program_pushVar(code, &ip->idx, true, copy); |
6868 | break; | 6859 | break; |
6869 | } | 6860 | } |
6870 | 6861 | ||
6871 | case BC_INST_PUSH_TO_VAR: | 6862 | case BC_INST_PUSH_TO_VAR: |
6872 | { | 6863 | { |
6873 | char *name = bc_program_name(code, &ip->idx); | 6864 | char *name = bc_program_name(code, &ip->idx); |
6874 | s = bc_program_copyToVar(p, name, true); | 6865 | s = bc_program_copyToVar(name, true); |
6875 | free(name); | 6866 | free(name); |
6876 | break; | 6867 | break; |
6877 | } | 6868 | } |
6878 | 6869 | ||
6879 | case BC_INST_QUIT: | 6870 | case BC_INST_QUIT: |
6880 | { | 6871 | { |
6881 | if (p->stack.len <= 2) | 6872 | if (G.prog.stack.len <= 2) |
6882 | s = BC_STATUS_QUIT; | 6873 | s = BC_STATUS_QUIT; |
6883 | else | 6874 | else |
6884 | bc_vec_npop(&p->stack, 2); | 6875 | bc_vec_npop(&G.prog.stack, 2); |
6885 | break; | 6876 | break; |
6886 | } | 6877 | } |
6887 | 6878 | ||
@@ -6893,11 +6884,11 @@ static BcStatus bc_program_exec(void) | |||
6893 | #endif // ENABLE_DC | 6884 | #endif // ENABLE_DC |
6894 | } | 6885 | } |
6895 | 6886 | ||
6896 | if ((s && s != BC_STATUS_QUIT) || G_interrupt) s = bc_program_reset(p, s); | 6887 | if ((s && s != BC_STATUS_QUIT) || G_interrupt) s = bc_program_reset(s); |
6897 | 6888 | ||
6898 | // If the stack has changed, pointers may be invalid. | 6889 | // If the stack has changed, pointers may be invalid. |
6899 | ip = bc_vec_top(&p->stack); | 6890 | ip = bc_vec_top(&G.prog.stack); |
6900 | func = bc_vec_item(&p->fns, ip->func); | 6891 | func = bc_vec_item(&G.prog.fns, ip->func); |
6901 | code = func->code.v; | 6892 | code = func->code.v; |
6902 | } | 6893 | } |
6903 | 6894 | ||
@@ -7028,7 +7019,7 @@ static BcStatus bc_vm_process(const char *text) | |||
7028 | s = bc_program_exec(); | 7019 | s = bc_program_exec(); |
7029 | if (!s && G.tty) fflush(stdout); | 7020 | if (!s && G.tty) fflush(stdout); |
7030 | if (s && s != BC_STATUS_QUIT) | 7021 | if (s && s != BC_STATUS_QUIT) |
7031 | s = bc_vm_error(bc_program_reset(&G.prog, s), G.prs.l.f, 0); | 7022 | s = bc_vm_error(bc_program_reset(s), G.prs.l.f, 0); |
7032 | } | 7023 | } |
7033 | 7024 | ||
7034 | return s; | 7025 | return s; |
@@ -7179,33 +7170,33 @@ static BcStatus bc_vm_exec(void) | |||
7179 | } | 7170 | } |
7180 | 7171 | ||
7181 | #if ENABLE_FEATURE_CLEAN_UP | 7172 | #if ENABLE_FEATURE_CLEAN_UP |
7182 | static void bc_program_free(BcProgram *p) | 7173 | static void bc_program_free() |
7183 | { | 7174 | { |
7184 | bc_num_free(&p->ib); | 7175 | bc_num_free(&G.prog.ib); |
7185 | bc_num_free(&p->ob); | 7176 | bc_num_free(&G.prog.ob); |
7186 | bc_num_free(&p->hexb); | 7177 | bc_num_free(&G.prog.hexb); |
7187 | # if ENABLE_DC | 7178 | # if ENABLE_DC |
7188 | bc_num_free(&p->strmb); | 7179 | bc_num_free(&G.prog.strmb); |
7189 | # endif | 7180 | # endif |
7190 | bc_vec_free(&p->fns); | 7181 | bc_vec_free(&G.prog.fns); |
7191 | bc_vec_free(&p->fn_map); | 7182 | bc_vec_free(&G.prog.fn_map); |
7192 | bc_vec_free(&p->vars); | 7183 | bc_vec_free(&G.prog.vars); |
7193 | bc_vec_free(&p->var_map); | 7184 | bc_vec_free(&G.prog.var_map); |
7194 | bc_vec_free(&p->arrs); | 7185 | bc_vec_free(&G.prog.arrs); |
7195 | bc_vec_free(&p->arr_map); | 7186 | bc_vec_free(&G.prog.arr_map); |
7196 | bc_vec_free(&p->strs); | 7187 | bc_vec_free(&G.prog.strs); |
7197 | bc_vec_free(&p->consts); | 7188 | bc_vec_free(&G.prog.consts); |
7198 | bc_vec_free(&p->results); | 7189 | bc_vec_free(&G.prog.results); |
7199 | bc_vec_free(&p->stack); | 7190 | bc_vec_free(&G.prog.stack); |
7200 | bc_num_free(&p->last); | 7191 | bc_num_free(&G.prog.last); |
7201 | bc_num_free(&p->zero); | 7192 | bc_num_free(&G.prog.zero); |
7202 | bc_num_free(&p->one); | 7193 | bc_num_free(&G.prog.one); |
7203 | } | 7194 | } |
7204 | 7195 | ||
7205 | static void bc_vm_free(void) | 7196 | static void bc_vm_free(void) |
7206 | { | 7197 | { |
7207 | bc_vec_free(&G.files); | 7198 | bc_vec_free(&G.files); |
7208 | bc_program_free(&G.prog); | 7199 | bc_program_free(); |
7209 | bc_parse_free(&G.prs); | 7200 | bc_parse_free(&G.prs); |
7210 | free(G.env_args); | 7201 | free(G.env_args); |
7211 | } | 7202 | } |
@@ -7251,8 +7242,8 @@ static void bc_program_init(size_t line_len) | |||
7251 | bc_vec_init(&G.prog.fns, sizeof(BcFunc), bc_func_free); | 7242 | bc_vec_init(&G.prog.fns, sizeof(BcFunc), bc_func_free); |
7252 | bc_map_init(&G.prog.fn_map); | 7243 | bc_map_init(&G.prog.fn_map); |
7253 | 7244 | ||
7254 | bc_program_addFunc(&G.prog, xstrdup(bc_func_main), &idx); | 7245 | bc_program_addFunc(xstrdup(bc_func_main), &idx); |
7255 | bc_program_addFunc(&G.prog, xstrdup(bc_func_read), &idx); | 7246 | bc_program_addFunc(xstrdup(bc_func_read), &idx); |
7256 | 7247 | ||
7257 | bc_vec_init(&G.prog.vars, sizeof(BcVec), bc_vec_free); | 7248 | bc_vec_init(&G.prog.vars, sizeof(BcVec), bc_vec_free); |
7258 | bc_map_init(&G.prog.var_map); | 7249 | bc_map_init(&G.prog.var_map); |
@@ -7285,9 +7276,9 @@ static void bc_vm_init(const char *env_len) | |||
7285 | 7276 | ||
7286 | bc_program_init(len); | 7277 | bc_program_init(len); |
7287 | if (IS_BC) { | 7278 | if (IS_BC) { |
7288 | bc_parse_init(&G.prs, &G.prog, BC_PROG_MAIN); | 7279 | bc_parse_init(&G.prs, BC_PROG_MAIN); |
7289 | } else { | 7280 | } else { |
7290 | dc_parse_init(&G.prs, &G.prog, BC_PROG_MAIN); | 7281 | dc_parse_init(&G.prs, BC_PROG_MAIN); |
7291 | } | 7282 | } |
7292 | } | 7283 | } |
7293 | 7284 | ||