aboutsummaryrefslogtreecommitdiff
path: root/miscutils/bc.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/bc.c')
-rw-r--r--miscutils/bc.c271
1 files changed, 185 insertions, 86 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 7fecb264d..36e978ed8 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -4,8 +4,8 @@
4 * Adapted from https://github.com/gavinhoward/bc 4 * Adapted from https://github.com/gavinhoward/bc
5 * Original code copyright (c) 2018 Gavin D. Howard and contributors. 5 * Original code copyright (c) 2018 Gavin D. Howard and contributors.
6 */ 6 */
7//TODO: GNU extensions: 7//TODO:
8// support "define f(*param[])" - "pass array by reference" syntax 8// maybe implement a^b for non-integer b?
9 9
10#define DEBUG_LEXER 0 10#define DEBUG_LEXER 0
11#define DEBUG_COMPILE 0 11#define DEBUG_COMPILE 0
@@ -380,6 +380,12 @@ typedef struct BcInstPtr {
380 size_t inst_idx; 380 size_t inst_idx;
381} BcInstPtr; 381} BcInstPtr;
382 382
383typedef enum BcType {
384 BC_TYPE_VAR,
385 BC_TYPE_ARRAY,
386 BC_TYPE_REF,
387} BcType;
388
383typedef enum BcLexType { 389typedef enum BcLexType {
384 XC_LEX_EOF, 390 XC_LEX_EOF,
385 XC_LEX_INVALID, 391 XC_LEX_INVALID,
@@ -1092,15 +1098,25 @@ static void bc_vec_pop_all(BcVec *v)
1092 bc_vec_npop(v, v->len); 1098 bc_vec_npop(v, v->len);
1093} 1099}
1094 1100
1095static size_t bc_vec_push(BcVec *v, const void *data) 1101static size_t bc_vec_npush(BcVec *v, size_t n, const void *data)
1096{ 1102{
1097 size_t len = v->len; 1103 size_t len = v->len;
1098 if (len >= v->cap) bc_vec_grow(v, 1); 1104 if (len + n > v->cap) bc_vec_grow(v, n);
1099 memmove(v->v + (v->size * len), data, v->size); 1105 memmove(v->v + (v->size * len), data, v->size * n);
1100 v->len++; 1106 v->len = len + n;
1101 return len; 1107 return len;
1102} 1108}
1103 1109
1110static size_t bc_vec_push(BcVec *v, const void *data)
1111{
1112 return bc_vec_npush(v, 1, data);
1113 //size_t len = v->len;
1114 //if (len >= v->cap) bc_vec_grow(v, 1);
1115 //memmove(v->v + (v->size * len), data, v->size);
1116 //v->len = len + 1;
1117 //return len;
1118}
1119
1104// G.prog.results often needs "pop old operand, push result" idiom. 1120// G.prog.results often needs "pop old operand, push result" idiom.
1105// Can do this without a few extra ops 1121// Can do this without a few extra ops
1106static size_t bc_result_pop_and_push(const void *data) 1122static size_t bc_result_pop_and_push(const void *data)
@@ -3528,14 +3544,14 @@ static void xc_parse_pushName(char *name)
3528// (The above describes 32-bit case). 3544// (The above describes 32-bit case).
3529#define SMALL_INDEX_LIMIT (0x100 - sizeof(size_t)) 3545#define SMALL_INDEX_LIMIT (0x100 - sizeof(size_t))
3530 3546
3531static void xc_parse_pushIndex(size_t idx) 3547static void bc_vec_pushIndex(BcVec *v, size_t idx)
3532{ 3548{
3533 size_t mask; 3549 size_t mask;
3534 unsigned amt; 3550 unsigned amt;
3535 3551
3536 dbg_lex("%s:%d pushing index %zd", __func__, __LINE__, idx); 3552 dbg_lex("%s:%d pushing index %zd", __func__, __LINE__, idx);
3537 if (idx < SMALL_INDEX_LIMIT) { 3553 if (idx < SMALL_INDEX_LIMIT) {
3538 xc_parse_push(idx); 3554 bc_vec_pushByte(v, idx);
3539 return; 3555 return;
3540 } 3556 }
3541 3557
@@ -3548,14 +3564,19 @@ static void xc_parse_pushIndex(size_t idx)
3548 } 3564 }
3549 // amt is at least 1 here - "one byte of length data follows" 3565 // amt is at least 1 here - "one byte of length data follows"
3550 3566
3551 xc_parse_push((SMALL_INDEX_LIMIT - 1) + amt); 3567 bc_vec_pushByte(v, (SMALL_INDEX_LIMIT - 1) + amt);
3552 3568
3553 do { 3569 do {
3554 xc_parse_push((unsigned char)idx); 3570 bc_vec_pushByte(v, (unsigned char)idx);
3555 idx >>= 8; 3571 idx >>= 8;
3556 } while (idx != 0); 3572 } while (idx != 0);
3557} 3573}
3558 3574
3575static void xc_parse_pushIndex(size_t idx)
3576{
3577 bc_vec_pushIndex(&G.prs.func->code, idx);
3578}
3579
3559static void xc_parse_pushInst_and_Index(unsigned inst, size_t idx) 3580static void xc_parse_pushInst_and_Index(unsigned inst, size_t idx)
3560{ 3581{
3561 xc_parse_push(inst); 3582 xc_parse_push(inst);
@@ -4340,7 +4361,7 @@ static BC_STATUS zbc_parse_break_or_continue(BcLexType type)
4340} 4361}
4341#define zbc_parse_break_or_continue(...) (zbc_parse_break_or_continue(__VA_ARGS__) COMMA_SUCCESS) 4362#define zbc_parse_break_or_continue(...) (zbc_parse_break_or_continue(__VA_ARGS__) COMMA_SUCCESS)
4342 4363
4343static BC_STATUS zbc_func_insert(BcFunc *f, char *name, bool var) 4364static BC_STATUS zbc_func_insert(BcFunc *f, char *name, BcType type)
4344{ 4365{
4345 BcId *autoid; 4366 BcId *autoid;
4346 BcId a; 4367 BcId a;
@@ -4349,13 +4370,13 @@ static BC_STATUS zbc_func_insert(BcFunc *f, char *name, bool var)
4349 autoid = (void*)f->autos.v; 4370 autoid = (void*)f->autos.v;
4350 for (i = 0; i < f->autos.len; i++, autoid++) { 4371 for (i = 0; i < f->autos.len; i++, autoid++) {
4351 if (strcmp(name, autoid->name) == 0 4372 if (strcmp(name, autoid->name) == 0
4352 && var == autoid->idx 4373 && type == (BcType) autoid->idx
4353 ) { 4374 ) {
4354 RETURN_STATUS(bc_error("duplicate function parameter or auto name")); 4375 RETURN_STATUS(bc_error("duplicate function parameter or auto name"));
4355 } 4376 }
4356 } 4377 }
4357 4378
4358 a.idx = var; 4379 a.idx = type;
4359 a.name = name; 4380 a.name = name;
4360 4381
4361 bc_vec_push(&f->autos, &a); 4382 bc_vec_push(&f->autos, &a);
@@ -4368,7 +4389,7 @@ static BC_STATUS zbc_parse_funcdef(void)
4368{ 4389{
4369 BcParse *p = &G.prs; 4390 BcParse *p = &G.prs;
4370 BcStatus s; 4391 BcStatus s;
4371 bool var, comma, voidfunc; 4392 bool comma, voidfunc;
4372 char *name; 4393 char *name;
4373 4394
4374 dbg_lex_enter("%s:%d entered", __func__, __LINE__); 4395 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
@@ -4406,6 +4427,16 @@ static BC_STATUS zbc_parse_funcdef(void)
4406 4427
4407 comma = false; 4428 comma = false;
4408 while (p->lex != BC_LEX_RPAREN) { 4429 while (p->lex != BC_LEX_RPAREN) {
4430 BcType t = BC_TYPE_VAR;
4431
4432 if (p->lex == XC_LEX_OP_MULTIPLY) {
4433 t = BC_TYPE_REF;
4434 s = zxc_lex_next();
4435 if (s) RETURN_STATUS(s);
4436 s = zbc_POSIX_does_not_allow("references");
4437 if (s) RETURN_STATUS(s);
4438 }
4439
4409 if (p->lex != XC_LEX_NAME) 4440 if (p->lex != XC_LEX_NAME)
4410 RETURN_STATUS(bc_error_bad_function_definition()); 4441 RETURN_STATUS(bc_error_bad_function_definition());
4411 4442
@@ -4415,9 +4446,8 @@ static BC_STATUS zbc_parse_funcdef(void)
4415 s = zxc_lex_next(); 4446 s = zxc_lex_next();
4416 if (s) goto err; 4447 if (s) goto err;
4417 4448
4418 var = p->lex != BC_LEX_LBRACKET; 4449 if (p->lex == BC_LEX_LBRACKET) {
4419 4450 if (t == BC_TYPE_VAR) t = BC_TYPE_ARRAY;
4420 if (!var) {
4421 s = zxc_lex_next(); 4451 s = zxc_lex_next();
4422 if (s) goto err; 4452 if (s) goto err;
4423 4453
@@ -4429,6 +4459,10 @@ static BC_STATUS zbc_parse_funcdef(void)
4429 s = zxc_lex_next(); 4459 s = zxc_lex_next();
4430 if (s) goto err; 4460 if (s) goto err;
4431 } 4461 }
4462 else if (t == BC_TYPE_REF) {
4463 s = bc_error_at("vars can't be references");
4464 goto err;
4465 }
4432 4466
4433 comma = p->lex == BC_LEX_COMMA; 4467 comma = p->lex == BC_LEX_COMMA;
4434 if (comma) { 4468 if (comma) {
@@ -4436,7 +4470,7 @@ static BC_STATUS zbc_parse_funcdef(void)
4436 if (s) goto err; 4470 if (s) goto err;
4437 } 4471 }
4438 4472
4439 s = zbc_func_insert(p->func, name, var); 4473 s = zbc_func_insert(p->func, name, t);
4440 if (s) goto err; 4474 if (s) goto err;
4441 } 4475 }
4442 4476
@@ -4488,7 +4522,7 @@ static BC_STATUS zbc_parse_auto(void)
4488 if (s) RETURN_STATUS(s); 4522 if (s) RETURN_STATUS(s);
4489 4523
4490 for (;;) { 4524 for (;;) {
4491 bool var; 4525 BcType t;
4492 4526
4493 if (p->lex != XC_LEX_NAME) 4527 if (p->lex != XC_LEX_NAME)
4494 RETURN_STATUS(bc_error_at("bad 'auto' syntax")); 4528 RETURN_STATUS(bc_error_at("bad 'auto' syntax"));
@@ -4497,8 +4531,9 @@ static BC_STATUS zbc_parse_auto(void)
4497 s = zxc_lex_next(); 4531 s = zxc_lex_next();
4498 if (s) goto err; 4532 if (s) goto err;
4499 4533
4500 var = (p->lex != BC_LEX_LBRACKET); 4534 t = BC_TYPE_VAR;
4501 if (!var) { 4535 if (p->lex == BC_LEX_LBRACKET) {
4536 t = BC_TYPE_ARRAY;
4502 s = zxc_lex_next(); 4537 s = zxc_lex_next();
4503 if (s) goto err; 4538 if (s) goto err;
4504 4539
@@ -4510,7 +4545,7 @@ static BC_STATUS zbc_parse_auto(void)
4510 if (s) goto err; 4545 if (s) goto err;
4511 } 4546 }
4512 4547
4513 s = zbc_func_insert(p->func, name, var); 4548 s = zbc_func_insert(p->func, name, t);
4514 if (s) goto err; 4549 if (s) goto err;
4515 4550
4516 if (p->lex == XC_LEX_NLINE 4551 if (p->lex == XC_LEX_NLINE
@@ -5119,12 +5154,64 @@ static BC_STATUS zdc_parse_exprs_until_eof(void)
5119#define STACK_HAS_MORE_THAN(s, n) ((s)->len > ((size_t)(n))) 5154#define STACK_HAS_MORE_THAN(s, n) ((s)->len > ((size_t)(n)))
5120#define STACK_HAS_EQUAL_OR_MORE_THAN(s, n) ((s)->len >= ((size_t)(n))) 5155#define STACK_HAS_EQUAL_OR_MORE_THAN(s, n) ((s)->len >= ((size_t)(n)))
5121 5156
5122static BcVec* xc_program_search(char *id, bool var) 5157static size_t xc_program_index(char *code, size_t *bgn)
5158{
5159 unsigned char *bytes = (void*)(code + *bgn);
5160 unsigned amt;
5161 unsigned i;
5162 size_t res;
5163
5164 amt = *bytes++;
5165 if (amt < SMALL_INDEX_LIMIT) {
5166 *bgn += 1;
5167 return amt;
5168 }
5169 amt -= (SMALL_INDEX_LIMIT - 1); // amt is 1 or more here
5170 *bgn += amt + 1;
5171
5172 res = 0;
5173 i = 0;
5174 do {
5175 res |= (size_t)(*bytes++) << i;
5176 i += 8;
5177 } while (--amt != 0);
5178
5179 return res;
5180}
5181
5182static char *xc_program_name(char *code, size_t *bgn)
5183{
5184 code += *bgn;
5185 *bgn += strlen(code) + 1;
5186
5187 return xstrdup(code);
5188}
5189
5190static BcVec* xc_program_dereference(BcVec *vec)
5191{
5192 BcVec *v;
5193 size_t vidx, nidx, i = 0;
5194
5195 //assert(vec->size == sizeof(uint8_t));
5196
5197 vidx = xc_program_index(vec->v, &i);
5198 nidx = xc_program_index(vec->v, &i);
5199
5200 v = bc_vec_item(&G.prog.arrs, vidx);
5201 v = bc_vec_item(v, nidx);
5202
5203 //assert(v->size != sizeof(uint8_t));
5204
5205 return v;
5206}
5207
5208static BcVec* xc_program_search(char *id, BcType type)
5123{ 5209{
5124 BcId e, *ptr; 5210 BcId e, *ptr;
5125 BcVec *v, *map; 5211 BcVec *v, *map;
5126 size_t i; 5212 size_t i;
5127 int new; 5213 int new;
5214 bool var = (type == BC_TYPE_VAR);
5128 5215
5129 v = var ? &G.prog.vars : &G.prog.arrs; 5216 v = var ? &G.prog.vars : &G.prog.arrs;
5130 map = var ? &G.prog.var_map : &G.prog.arr_map; 5217 map = var ? &G.prog.var_map : &G.prog.arr_map;
@@ -5178,17 +5265,20 @@ static BC_STATUS zxc_program_num(BcResult *r, BcNum **num)
5178 case XC_RESULT_VAR: 5265 case XC_RESULT_VAR:
5179 case XC_RESULT_ARRAY: 5266 case XC_RESULT_ARRAY:
5180 case XC_RESULT_ARRAY_ELEM: { 5267 case XC_RESULT_ARRAY_ELEM: {
5181 BcVec *v; 5268 BcType type = (r->t == XC_RESULT_VAR) ? BC_TYPE_VAR : BC_TYPE_ARRAY;
5182 void *p; 5269 BcVec *v = xc_program_search(r->d.id.name, type);
5183 v = xc_program_search(r->d.id.name, r->t == XC_RESULT_VAR); 5270 void *p = bc_vec_top(v);
5184// dc variables are all stacks, so here we have this: 5271
5185 p = bc_vec_top(v);
5186// TODO: eliminate these stacks for bc-only config?
5187 if (r->t == XC_RESULT_ARRAY_ELEM) { 5272 if (r->t == XC_RESULT_ARRAY_ELEM) {
5273 size_t idx = r->d.id.idx;
5274
5188 v = p; 5275 v = p;
5189 if (v->len <= r->d.id.idx) 5276 if (v->size == sizeof(uint8_t))
5190 bc_array_expand(v, r->d.id.idx + 1); 5277 v = xc_program_dereference(v);
5191 *num = bc_vec_item(v, r->d.id.idx); 5278 //assert(v->size == sizeof(BcNum));
5279 if (v->len <= idx)
5280 bc_array_expand(v, idx + 1);
5281 *num = bc_vec_item(v, idx);
5192 } else { 5282 } else {
5193 *num = p; 5283 *num = p;
5194 } 5284 }
@@ -5347,39 +5437,6 @@ static BC_STATUS zxc_program_read(void)
5347} 5437}
5348#define zxc_program_read(...) (zxc_program_read(__VA_ARGS__) COMMA_SUCCESS) 5438#define zxc_program_read(...) (zxc_program_read(__VA_ARGS__) COMMA_SUCCESS)
5349 5439
5350static size_t xc_program_index(char *code, size_t *bgn)
5351{
5352 unsigned char *bytes = (void*)(code + *bgn);
5353 unsigned amt;
5354 unsigned i;
5355 size_t res;
5356
5357 amt = *bytes++;
5358 if (amt < SMALL_INDEX_LIMIT) {
5359 *bgn += 1;
5360 return amt;
5361 }
5362 amt -= (SMALL_INDEX_LIMIT - 1); // amt is 1 or more here
5363 *bgn += amt + 1;
5364
5365 res = 0;
5366 i = 0;
5367 do {
5368 res |= (size_t)(*bytes++) << i;
5369 i += 8;
5370 } while (--amt != 0);
5371
5372 return res;
5373}
5374
5375static char *xc_program_name(char *code, size_t *bgn)
5376{
5377 code += *bgn;
5378 *bgn += strlen(code) + 1;
5379
5380 return xstrdup(code);
5381}
5382
5383static void xc_program_printString(const char *str) 5440static void xc_program_printString(const char *str)
5384{ 5441{
5385#if ENABLE_DC 5442#if ENABLE_DC
@@ -5755,43 +5812,81 @@ static BC_STATUS zdc_program_assignStr(BcResult *r, BcVec *v, bool push)
5755#define zdc_program_assignStr(...) (zdc_program_assignStr(__VA_ARGS__) COMMA_SUCCESS) 5812#define zdc_program_assignStr(...) (zdc_program_assignStr(__VA_ARGS__) COMMA_SUCCESS)
5756#endif // ENABLE_DC 5813#endif // ENABLE_DC
5757 5814
5758static BC_STATUS zxc_program_popResultAndCopyToVar(char *name, bool var) 5815static BC_STATUS zxc_program_popResultAndCopyToVar(char *name, BcType t)
5759{ 5816{
5760 BcStatus s; 5817 BcStatus s;
5761 BcResult *ptr, r; 5818 BcResult *ptr, r;
5762 BcVec *v; 5819 BcVec *vec;
5763 BcNum *n; 5820 BcNum *n;
5821 bool var = (t == BC_TYPE_VAR);
5764 5822
5765 if (!STACK_HAS_MORE_THAN(&G.prog.results, 0)) 5823 if (!STACK_HAS_MORE_THAN(&G.prog.results, 0))
5766 RETURN_STATUS(bc_error_stack_has_too_few_elements()); 5824 RETURN_STATUS(bc_error_stack_has_too_few_elements());
5767 5825
5768 ptr = bc_vec_top(&G.prog.results); 5826 ptr = bc_vec_top(&G.prog.results);
5769 if ((ptr->t == XC_RESULT_ARRAY) != !var) 5827 if ((ptr->t == XC_RESULT_ARRAY) == var)
5770 RETURN_STATUS(bc_error_variable_is_wrong_type()); 5828 RETURN_STATUS(bc_error_variable_is_wrong_type());
5771 v = xc_program_search(name, var); 5829 vec = xc_program_search(name, t);
5772 5830
5773#if ENABLE_DC 5831#if ENABLE_DC
5774 if (ptr->t == XC_RESULT_STR && !var) 5832 if (ptr->t == XC_RESULT_STR) {
5775 RETURN_STATUS(bc_error_variable_is_wrong_type()); 5833 if (!var)
5776 if (ptr->t == XC_RESULT_STR) 5834 RETURN_STATUS(bc_error_variable_is_wrong_type());
5777 RETURN_STATUS(zdc_program_assignStr(ptr, v, true)); 5835 RETURN_STATUS(zdc_program_assignStr(ptr, vec, true));
5836 }
5778#endif 5837#endif
5779 5838
5780 s = zxc_program_num(ptr, &n); 5839 s = zxc_program_num(ptr, &n);
5781 if (s) RETURN_STATUS(s); 5840 if (s) RETURN_STATUS(s);
5782 5841
5783 // Do this once more to make sure that pointers were not invalidated. 5842 // Do this once more to make sure that pointers were not invalidated.
5784 v = xc_program_search(name, var); 5843 vec = xc_program_search(name, t);
5785 5844
5786 if (var) { 5845 if (var) {
5787 bc_num_init_DEF_SIZE(&r.d.n); 5846 bc_num_init_DEF_SIZE(&r.d.n);
5788 bc_num_copy(&r.d.n, n); 5847 bc_num_copy(&r.d.n, n);
5789 } else { 5848 } else {
5849 BcVec *v = (BcVec*) n;
5850 bool ref, ref_size;
5851
5852 ref = (v->size == sizeof(BcVec) && t != BC_TYPE_ARRAY);
5853 ref_size = (v->size == sizeof(uint8_t));
5854
5855 if (ref || (ref_size && t == BC_TYPE_REF)) {
5856 bc_vec_init(&r.d.v, sizeof(uint8_t), NULL);
5857 if (ref) {
5858 size_t vidx, idx;
5859 BcId id;
5860
5861 id.name = ptr->d.id.name;
5862 v = xc_program_search(ptr->d.id.name, BC_TYPE_REF);
5863
5864 // Make sure the pointer was not invalidated.
5865 vec = xc_program_search(name, t);
5866
5867 vidx = bc_map_find_exact(&G.prog.arr_map, &id);
5868 //assert(vidx != BC_VEC_INVALID_IDX);
5869 vidx = ((BcId*) bc_vec_item(&G.prog.arr_map, vidx))->idx;
5870 idx = v->len - 1;
5871
5872 bc_vec_pushIndex(&r.d.v, vidx);
5873 bc_vec_pushIndex(&r.d.v, idx);
5874 }
5875 // If we get here, we are copying a ref to a ref.
5876 else bc_vec_npush(&r.d.v, v->len, v->v);
5877
5878 // We need to return early.
5879 goto ret;
5880 }
5881
5882 if (ref_size && t != BC_TYPE_REF)
5883 v = xc_program_dereference(v);
5884
5790 bc_array_init(&r.d.v, true); 5885 bc_array_init(&r.d.v, true);
5791 bc_array_copy(&r.d.v, (BcVec *) n); 5886 bc_array_copy(&r.d.v, v);
5792 } 5887 }
5793 5888 ret:
5794 bc_vec_push(v, &r.d); 5889 bc_vec_push(vec, &r.d);
5795 bc_vec_pop(&G.prog.results); 5890 bc_vec_pop(&G.prog.results);
5796 5891
5797 RETURN_STATUS(s); 5892 RETURN_STATUS(s);
@@ -5818,7 +5913,7 @@ static BC_STATUS zxc_program_assign(char inst)
5818 5913
5819 if (left->t != XC_RESULT_VAR) 5914 if (left->t != XC_RESULT_VAR)
5820 RETURN_STATUS(bc_error_variable_is_wrong_type()); 5915 RETURN_STATUS(bc_error_variable_is_wrong_type());
5821 v = xc_program_search(left->d.id.name, true); 5916 v = xc_program_search(left->d.id.name, BC_TYPE_VAR);
5822 5917
5823 RETURN_STATUS(zdc_program_assignStr(right, v, false)); 5918 RETURN_STATUS(zdc_program_assignStr(right, v, false));
5824 } 5919 }
@@ -5897,7 +5992,7 @@ static BC_STATUS xc_program_pushVar(char *code, size_t *bgn,
5897 5992
5898#if ENABLE_DC 5993#if ENABLE_DC
5899 if (pop || copy) { 5994 if (pop || copy) {
5900 BcVec *v = xc_program_search(name, true); 5995 BcVec *v = xc_program_search(name, BC_TYPE_VAR);
5901 BcNum *num = bc_vec_top(v); 5996 BcNum *num = bc_vec_top(v);
5902 5997
5903 free(name); 5998 free(name);
@@ -6014,16 +6109,19 @@ static BC_STATUS zbc_program_call(char *code, size_t *idx)
6014 for (i = 0; i < nparams; ++i) { 6109 for (i = 0; i < nparams; ++i) {
6015 BcResult *arg; 6110 BcResult *arg;
6016 BcStatus s; 6111 BcStatus s;
6112 bool arr;
6017 6113
6018 a = bc_vec_item(&func->autos, nparams - 1 - i); 6114 a = bc_vec_item(&func->autos, nparams - 1 - i);
6019 arg = bc_vec_top(&G.prog.results); 6115 arg = bc_vec_top(&G.prog.results);
6020 6116
6021 if ((!a->idx) != (arg->t == XC_RESULT_ARRAY) // array/variable mismatch 6117 arr = (a->idx == BC_TYPE_ARRAY || a->idx == BC_TYPE_REF);
6118
6119 if (arr != (arg->t == XC_RESULT_ARRAY) // array/variable mismatch
6022 // || arg->t == XC_RESULT_STR - impossible, f("str") is not a legal syntax (strings are not bc expressions) 6120 // || arg->t == XC_RESULT_STR - impossible, f("str") is not a legal syntax (strings are not bc expressions)
6023 ) { 6121 ) {
6024 RETURN_STATUS(bc_error_variable_is_wrong_type()); 6122 RETURN_STATUS(bc_error_variable_is_wrong_type());
6025 } 6123 }
6026 s = zxc_program_popResultAndCopyToVar(a->name, a->idx); 6124 s = zxc_program_popResultAndCopyToVar(a->name, (BcType) a->idx);
6027 if (s) RETURN_STATUS(s); 6125 if (s) RETURN_STATUS(s);
6028 } 6126 }
6029 6127
@@ -6031,12 +6129,13 @@ static BC_STATUS zbc_program_call(char *code, size_t *idx)
6031 for (; i < func->autos.len; i++, a++) { 6129 for (; i < func->autos.len; i++, a++) {
6032 BcVec *v; 6130 BcVec *v;
6033 6131
6034 v = xc_program_search(a->name, a->idx); 6132 v = xc_program_search(a->name, (BcType) a->idx);
6035 if (a->idx) { 6133 if (a->idx == BC_TYPE_VAR) {
6036 BcNum n2; 6134 BcNum n2;
6037 bc_num_init_DEF_SIZE(&n2); 6135 bc_num_init_DEF_SIZE(&n2);
6038 bc_vec_push(v, &n2); 6136 bc_vec_push(v, &n2);
6039 } else { 6137 } else {
6138 //assert(a->idx == BC_TYPE_ARRAY);
6040 BcVec v2; 6139 BcVec v2;
6041 bc_array_init(&v2, true); 6140 bc_array_init(&v2, true);
6042 bc_vec_push(v, &v2); 6141 bc_vec_push(v, &v2);
@@ -6087,7 +6186,7 @@ static BC_STATUS zbc_program_return(char inst)
6087 a = (void*)f->autos.v; 6186 a = (void*)f->autos.v;
6088 for (i = 0; i < f->autos.len; i++, a++) { 6187 for (i = 0; i < f->autos.len; i++, a++) {
6089 BcVec *v; 6188 BcVec *v;
6090 v = xc_program_search(a->name, a->idx); 6189 v = xc_program_search(a->name, (BcType) a->idx);
6091 bc_vec_pop(v); 6190 bc_vec_pop(v);
6092 } 6191 }
6093 6192
@@ -6399,7 +6498,7 @@ static BC_STATUS zdc_program_execStr(char *code, size_t *bgn, bool cond)
6399 6498
6400 if (exec) { 6499 if (exec) {
6401 BcVec *v; 6500 BcVec *v;
6402 v = xc_program_search(name, true); 6501 v = xc_program_search(name, BC_TYPE_VAR);
6403 n = bc_vec_top(v); 6502 n = bc_vec_top(v);
6404 } 6503 }
6405 6504
@@ -6724,7 +6823,7 @@ static BC_STATUS zxc_program_exec(void)
6724 } 6823 }
6725 case DC_INST_PUSH_TO_VAR: { 6824 case DC_INST_PUSH_TO_VAR: {
6726 char *name = xc_program_name(code, &ip->inst_idx); 6825 char *name = xc_program_name(code, &ip->inst_idx);
6727 s = zxc_program_popResultAndCopyToVar(name, true); 6826 s = zxc_program_popResultAndCopyToVar(name, BC_TYPE_VAR);
6728 free(name); 6827 free(name);
6729 break; 6828 break;
6730 } 6829 }