Start fixing the recursion bug
*** BROKEN!!! DO NOT USE!!! ***
diff --git a/include/lang.h b/include/lang.h
index 0e8db21..ad65c6a 100644
--- a/include/lang.h
+++ b/include/lang.h
@@ -98,18 +98,18 @@
} BcEntry;
+typedef union BcLocal {
+
+ BcNum num;
+ BcVec array;
+
+} BcLocal;
+
typedef struct BcAuto {
char *name;
bool var;
- union {
-
- BcNum num;
- BcVec array;
-
- } data;
-
} BcAuto;
typedef struct BcFunc {
@@ -134,8 +134,14 @@
BC_RESULT_CONSTANT,
+ BC_RESULT_AUTO_VAR,
+ BC_RESULT_AUTO_ARRAY,
+
+ BC_RESULT_LOCAL_VAR,
+ BC_RESULT_LOCAL_ARRAY,
+
BC_RESULT_VAR,
- BC_RESULT_ARRAY,
+ BC_RESULT_ARRAY_ELEM,
BC_RESULT_SCALE,
BC_RESULT_LAST,
@@ -152,7 +158,7 @@
union {
- BcNum num;
+ BcLocal local;
struct {
@@ -199,7 +205,7 @@
void bc_constant_free(void *constant);
// ** Exclude end. **
-BcStatus bc_auto_init(void *auto1, char *name, bool var);
+void bc_auto_init(void *auto1, char *name, bool var);
void bc_auto_free(void *auto1);
extern const char *bc_lang_func_main;
diff --git a/src/bc/data.c b/src/bc/data.c
index 8aa5710..df01e7f 100644
--- a/src/bc/data.c
+++ b/src/bc/data.c
@@ -424,3 +424,5 @@
const char *bc_program_ready_prompt = "ready for more input\n\n";
const char *bc_program_sigint_msg = "\n\ninterrupt (type \"quit\" to exit)\n\n";
+
+const
diff --git a/src/bc/lang.c b/src/bc/lang.c
index 6de78db..3592a1a 100644
--- a/src/bc/lang.c
+++ b/src/bc/lang.c
@@ -47,9 +47,7 @@
return BC_STATUS_PARSE_DUPLICATE_LOCAL;
}
- status = bc_auto_init(&a, name, var);
-
- if (status) return status;
+ bc_auto_init(&a, name, var);
status = bc_vec_push(vec, &a);
@@ -278,22 +276,16 @@
free(e->name);
}
-BcStatus bc_auto_init(void *auto1, char *name, bool var) {
+void bc_auto_init(void *auto1, char *name, bool var) {
- BcStatus status;
BcAuto *a;
- if (!auto1) return BC_STATUS_INVALID_PARAM;
+ if (!auto1) return;
a = (BcAuto*) auto1;
a->var = var;
a->name = name;
-
- if (var) status = bc_num_init(&a->data.num, BC_NUM_DEF_SIZE);
- else status = bc_vec_init(&a->data.array, sizeof(BcNum), bc_num_free);
-
- return status;
}
void bc_auto_free(void *auto1) {
@@ -305,9 +297,6 @@
a = (BcAuto*) auto1;
if (a->name) free(a->name);
-
- if (a->var) bc_num_free(&a->data.num);
- else bc_vec_free(&a->data.array);
}
void bc_result_free(void *result) {
@@ -322,13 +311,20 @@
case BC_RESULT_INTERMEDIATE:
case BC_RESULT_SCALE:
+ case BC_RESULT_AUTO_VAR:
{
- bc_num_free(&r->data.num);
+ bc_num_free(&r->data.local.num);
+ break;
+ }
+
+ case BC_RESULT_AUTO_ARRAY:
+ {
+ bc_vec_free(&r->data.local.array);
break;
}
case BC_RESULT_VAR:
- case BC_RESULT_ARRAY:
+ case BC_RESULT_ARRAY_ELEM:
{
if (r->data.id.name) free(r->data.id.name);
break;
diff --git a/src/bc/program.c b/src/bc/program.c
index 231e928..c6e01dc 100644
--- a/src/bc/program.c
+++ b/src/bc/program.c
@@ -33,42 +33,48 @@
#include <parse.h>
#include <instructions.h>
-static BcStatus bc_program_searchVec(const BcVec *vec, const BcResult *result,
- BcNum **ret, uint8_t flags)
+static BcStatus bc_program_auto(BcProgram *p, BcInstPtr *ip,
+ BcAuto *a, size_t idx, uint8_t flags)
+{
+ BcStatus status;
+ uint8_t cond;
+
+ cond = flags & BC_PROGRAM_SEARCH_VAR;
+
+ if (!a->var != !cond) return BC_STATUS_EXEC_INVALID_TYPE;
+
+ if (BC_PROGRAM_CHECK_EXPR_STACK(p, ip->len + idx))
+ return BC_STATUS_EXEC_INVALID_STACK;
+
+ if (cond) *ret = &a->data.num;
+ else if (flags & BC_PROGRAM_SEARCH_ARRAY_ONLY)
+ *ret = (BcNum*) &a->data.array;
+ else {
+
+ status = bc_array_expand(&a->data.array, result->data.id.idx + 1);
+
+ if (status) return status;
+
+ *ret = bc_vec_item(&a->data.array, result->data.id.idx);
+ }
+}
+
+static BcStatus bc_program_searchFunc(BcProgram *p, const BcFunc *func,
+ const BcInstPtr *ip,
+ const BcResult *result,
+ BcNum **ret, uint8_t flags)
{
BcStatus status;
BcAuto *a;
- size_t i;
+ size_t len, param_len, i;
- for (i = 0; i < vec->len; ++i) {
+ param_len = func->params.len;
- a = bc_vec_item(vec, i);
-
+ for (i = 0; i < func->params.len; ++i) {
+ a = bc_vec_item(&func->params, i);
if (!a) return BC_STATUS_EXEC_UNDEFINED_VAR;
-
- if (!strcmp(a->name, result->data.id.name)) {
-
- uint8_t cond;
-
- cond = flags & BC_PROGRAM_SEARCH_VAR;
-
- if (!a->var != !cond)
- return BC_STATUS_EXEC_INVALID_TYPE;
-
- if (cond) *ret = &a->data.num;
- else if (flags & BC_PROGRAM_SEARCH_ARRAY_ONLY)
- *ret = (BcNum*) &a->data.array;
- else {
-
- status = bc_array_expand(&a->data.array, result->data.id.idx + 1);
-
- if (status) return status;
-
- *ret = bc_vec_item(&a->data.array, result->data.id.idx);
- }
-
- return BC_STATUS_SUCCESS;
- }
+ if (!strcmp(a->name, result->data.id.name))
+ return bc_program_auto(p, a, flags);
}
return BC_STATUS_EXEC_UNDEFINED_VAR;
@@ -85,10 +91,7 @@
BcVecO *veco;
size_t idx;
BcEntry *entry_ptr;
-
- // We use this as either a number or an array, since
- // a BcAuto has a union inside that has both.
- BcAuto a;
+ BcLocal l;
ip = bc_vec_top(&p->stack);
@@ -105,11 +108,11 @@
if (!func) return BC_STATUS_EXEC_INVALID_STACK;
- status = bc_program_searchVec(&func->params, result, ret, flags);
+ status = bc_program_searchFunc(&func->params, result, ret, flags);
if (status != BC_STATUS_EXEC_UNDEFINED_VAR) return status;
- status = bc_program_searchVec(&func->autos, result, ret, flags);
+ status = bc_program_searchFunc(&func->autos, result, ret, flags);
if (status != BC_STATUS_EXEC_UNDEFINED_VAR) return status;
}
@@ -229,7 +232,7 @@
}
case BC_RESULT_VAR:
- case BC_RESULT_ARRAY:
+ case BC_RESULT_ARRAY_ELEM:
{
uint8_t flags;
@@ -678,7 +681,7 @@
result.data.id.idx = (size_t) temp;
- status = bc_program_unaryOpRetire(p, &result, BC_RESULT_ARRAY);
+ status = bc_program_unaryOpRetire(p, &result, BC_RESULT_ARRAY_ELEM);
}
if (status) goto err;
@@ -1060,7 +1063,7 @@
BcArray *array;
- if (param->type != BC_RESULT_VAR || param->type != BC_RESULT_ARRAY)
+ if (param->type != BC_RESULT_VAR || param->type != BC_RESULT_ARRAY_ELEM)
return BC_STATUS_EXEC_INVALID_TYPE;
status = bc_program_search(p, param, (BcNum**) &array,