Pass func args on the expr_stack
diff --git a/include/lang.h b/include/lang.h
index a49c647..4df4f47 100644
--- a/include/lang.h
+++ b/include/lang.h
@@ -105,19 +105,6 @@
} BcAuto;
-typedef struct BcLocal {
-
- bool var;
-
- union {
-
- BcNum num;
- BcVec array;
-
- } data;
-
-} BcLocal;
-
typedef struct BcFunc {
BcVec code;
@@ -125,9 +112,7 @@
BcVec labels;
size_t num_params;
-
BcVec autos;
- BcVec auto_stack;
} BcFunc;
@@ -137,6 +122,9 @@
BC_RESULT_CONSTANT,
+ BC_RESULT_ARRAY_AUTO,
+ BC_RESULT_VAR_AUTO,
+
BC_RESULT_VAR,
BC_RESULT_ARRAY,
@@ -198,9 +186,6 @@
void bc_auto_init(BcAuto *a, char *name, bool var);
void bc_auto_free(void *auto1);
-BcStatus bc_local_init(BcLocal *l, bool var);
-void bc_local_free(void *local);
-
extern const char *bc_lang_func_main;
extern const char *bc_lang_func_read;
diff --git a/src/bc/lang.c b/src/bc/lang.c
index 360bf69..8569057 100644
--- a/src/bc/lang.c
+++ b/src/bc/lang.c
@@ -33,7 +33,7 @@
size_t i;
BcAuto *ptr;
- if (!func || !name) return BC_STATUS_INVALID_PARAM;
+ if (!func || !name) return BC_STATUS_INVALID_ARG;
for (i = 0; i < func->autos.len; ++i) {
ptr = bc_vec_item(&func->autos, i);
@@ -54,7 +54,7 @@
BcStatus status;
- if (!func) return BC_STATUS_INVALID_PARAM;
+ if (!func) return BC_STATUS_INVALID_ARG;
status = bc_vec_init(&func->code, sizeof(uint8_t), NULL);
@@ -64,10 +64,6 @@
if (status) goto auto_err;
- status = bc_vec_init(&func->auto_stack, sizeof(BcLocal), bc_local_free);
-
- if (status) goto auto_stack_err;
-
status = bc_vec_init(&func->labels, sizeof(size_t), NULL);
if (status) goto label_err;
@@ -78,10 +74,6 @@
label_err:
- bc_vec_free(&func->auto_stack);
-
-auto_stack_err:
-
bc_vec_free(&func->autos);
auto_err:
@@ -101,7 +93,6 @@
bc_vec_free(&f->code);
bc_vec_free(&f->autos);
- bc_vec_free(&f->auto_stack);
bc_vec_free(&f->labels);
}
@@ -237,11 +228,18 @@
case BC_RESULT_INTERMEDIATE:
case BC_RESULT_SCALE:
+ case BC_RESULT_VAR_AUTO:
{
bc_num_free(&r->data.num);
break;
}
+ case BC_RESULT_ARRAY_AUTO:
+ {
+ bc_vec_free(&r->data.array);
+ break;
+ }
+
case BC_RESULT_VAR:
case BC_RESULT_ARRAY:
{
@@ -261,17 +259,3 @@
char **c = constant;
if (c) free(*c);
}
-
-BcStatus bc_local_init(BcLocal *l, bool var) {
- if (!l) return BC_STATUS_INVALID_PARAM;
- l->var = var;
- if (var) return bc_num_init(&l->data.num, BC_NUM_DEF_SIZE);
- else return bc_vec_init(&l->data.array, sizeof(BcNum), bc_num_free);
-}
-
-void bc_local_free(void *local) {
- BcLocal *l = local;
- if (!l) return;
- if (l->var) bc_num_free(&l->data.num);
- else bc_vec_free(&l->data.array);
-}
diff --git a/src/bc/program.c b/src/bc/program.c
index 5237dc0..486f21c 100644
--- a/src/bc/program.c
+++ b/src/bc/program.c
@@ -66,23 +66,23 @@
if (!a) return BC_STATUS_EXEC_UNDEFINED_VAR;
if (!strcmp(a->name, result->data.id.name)) {
- BcLocal *l;
+ BcResult *r;
uint8_t cond;
cond = flags & BC_PROGRAM_SEARCH_VAR;
if (!a->var != !cond) return BC_STATUS_EXEC_BAD_TYPE;
- l = bc_vec_item_rev(&func->auto_stack, idx);
+ r = bc_vec_item(&p->expr_stack, ip->len + idx);
- if (!l) return cond ? BC_STATUS_EXEC_UNDEFINED_VAR :
+ if (!r) return cond ? BC_STATUS_EXEC_UNDEFINED_VAR :
BC_STATUS_EXEC_UNDEFINED_ARRAY;
- if (cond || flags & BC_PROGRAM_SEARCH_ARRAY_ONLY) *ret = &l->data.num;
+ if (cond || flags & BC_PROGRAM_SEARCH_ARRAY_ONLY) *ret = &r->data.num;
else {
- status = bc_array_expand(&l->data.array, result->data.id.idx + 1);
+ status = bc_array_expand(&r->data.array, result->data.id.idx + 1);
if (status) return status;
- *ret = bc_vec_item(&l->data.array, result->data.id.idx);
+ *ret = bc_vec_item(&r->data.array, result->data.id.idx);
}
return BC_STATUS_SUCCESS;
@@ -100,7 +100,8 @@
if (status != BC_STATUS_VEC_ITEM_EXISTS) {
- BcLocal local;
+ // We use this because it has a union of BcNum and BcVec.
+ BcResult data;
size_t len;
if (status) return status;
@@ -113,11 +114,13 @@
strcpy(result->data.id.name, entry.name);
- status = bc_local_init(&local, flags & BC_PROGRAM_SEARCH_VAR);
+ if (flags & BC_PROGRAM_SEARCH_VAR)
+ status = bc_num_init(&data.data.num, BC_NUM_DEF_SIZE);
+ else status = bc_vec_init(&data.data.array, sizeof(BcNum), bc_num_free);
if (status) return status;
- status = bc_vec_push(vec, &local.data);
+ status = bc_vec_push(vec, &data.data);
if (status) return status;
}
@@ -976,11 +979,11 @@
BcStatus status;
BcInstPtr ip;
- size_t nparams, i, diff;
+ size_t nparams, i;
BcFunc *func;
BcAuto *auto_ptr;
- BcResult *param;
- BcLocal local;
+ BcResult param;
+ BcResult *arg;
nparams = bc_program_index(code, idx);
@@ -995,66 +998,69 @@
if (nparams != func->num_params) return BC_STATUS_EXEC_MISMATCHED_PARAMS;
- for (i = 0; i < func->autos.len - func->num_params; ++i) {
+ for (i = 0; i < func->num_params; ++i) {
auto_ptr = bc_vec_item_rev(&func->autos, i);
+ arg = bc_vec_item_rev(&p->expr_stack, i);
- if (!auto_ptr) return BC_STATUS_EXEC_UNDEFINED_VAR;
+ if (!auto_ptr || !arg) return BC_STATUS_EXEC_UNDEFINED_VAR;
- status = bc_local_init(&local, auto_ptr->var);
-
- if (status) return status;
-
- status = bc_vec_push(&func->auto_stack, &local);
-
- if (status) goto err;
- }
-
- diff = func->autos.len - func->num_params;
-
- for (; i < func->autos.len; ++i) {
-
- auto_ptr = bc_vec_item_rev(&func->autos, i);
- param = bc_vec_item_rev(&p->expr_stack, i - diff);
-
- if (!auto_ptr || !param) return BC_STATUS_EXEC_UNDEFINED_VAR;
-
- status = bc_local_init(&local, auto_ptr->var);
-
- if (status) return status;
+ param.type = auto_ptr->var + BC_RESULT_ARRAY_AUTO;
if (auto_ptr->var) {
BcNum *num;
- status = bc_program_num(p, param, &num, false);
+ status = bc_program_num(p, arg, &num, false);
- if (status) goto err;
+ if (status) return status;
- status = bc_num_copy(&local.data.num, num);
+ status = bc_num_init(¶m.data.num, num->len);
- if (status) goto err;
+ if (status) return status;
+
+ status = bc_num_copy(¶m.data.num, num);
}
else {
BcVec *array;
- if (param->type != BC_RESULT_VAR || param->type != BC_RESULT_ARRAY) {
- status = BC_STATUS_EXEC_BAD_TYPE;
- goto err;
- }
+ if (arg->type != BC_RESULT_VAR || arg->type != BC_RESULT_ARRAY)
+ return BC_STATUS_EXEC_BAD_TYPE;
- status = bc_program_search(p, param, (BcNum**) &array,
+ status = bc_program_search(p, arg, (BcNum**) &array,
BC_PROGRAM_SEARCH_ARRAY_ONLY);
- if (status) goto err;
+ if (status) return status;
- status = bc_array_copy(&local.data.array, array);
+ status = bc_vec_init(¶m.data.array, sizeof(BcNum), bc_num_free);
- if (status) goto err;
+ if (status) return status;
+
+ status = bc_array_copy(¶m.data.array, array);
}
- status = bc_vec_push(&func->auto_stack, &local);
+ if (status) goto err;
+
+ status = bc_vec_push(&p->expr_stack, ¶m);
+
+ if (status) goto err;
+ }
+
+ for (; i < func->autos.len; ++i) {
+
+ auto_ptr = bc_vec_item_rev(&func->autos, i);
+
+ if (!auto_ptr) return BC_STATUS_EXEC_UNDEFINED_VAR;
+
+ param.type = auto_ptr->var + BC_RESULT_ARRAY_AUTO;
+
+ if (auto_ptr->var) status = bc_num_init(¶m.data.num, BC_NUM_DEF_SIZE);
+ else status = bc_vec_init(¶m.data.array, sizeof(BcNum), bc_num_free);
+
+ if (status) return status;
+
+ status = bc_vec_push(&p->expr_stack, ¶m);
if (status) goto err;
}
@@ -1063,7 +1069,7 @@
err:
- bc_local_free(&local);
+ bc_result_free(¶m);
return status;
}
@@ -1073,7 +1079,7 @@
BcStatus status;
BcResult result;
BcResult *operand;
- size_t req, len, i;
+ size_t req, len;
BcInstPtr *ip;
BcFunc *func;
@@ -1134,14 +1140,7 @@
if (status) goto err;
- status = bc_vec_pop(&p->stack);
-
- if (status) return status;
-
- for (i = 0; !status && i < func->autos.len; ++i)
- status = bc_vec_pop(&func->auto_stack);
-
- return status;
+ return bc_vec_pop(&p->stack);
err:
@@ -1608,10 +1607,9 @@
status = BC_STATUS_SUCCESS;
- // We need to reset these so the function can be repopulated.
+ // We need to reset these, so the function can be repopulated.
+ func->num_params = 0;
while (!status && func->autos.len) status = bc_vec_pop(&func->autos);
- while (!status && func->auto_stack.len)
- status = bc_vec_pop(&func->auto_stack);
}
else {