aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--builtins.c36
-rw-r--r--builtins.h2
-rw-r--r--ops.c19
-rw-r--r--parser.c67
4 files changed, 96 insertions, 28 deletions
diff --git a/builtins.c b/builtins.c
index 7dba1aa..5186e8b 100644
--- a/builtins.c
+++ b/builtins.c
@@ -12,13 +12,14 @@ int ifunc_if(interpreter *it);
int ifunc_do(interpreter *it);
int ifunc_while(interpreter *it);
int ifunc_ret(interpreter *it);
+int ifunc_else(interpreter *it);
const func_t indent_up[IUP_COUNT] = {
ifunc_if, ifunc_do, ifunc_label
};
const func_t indent_down[IDOWN_COUNT] = {
- ifunc_end, ifunc_while
+ ifunc_else, ifunc_end, ifunc_while,
};
void iload_core(interpreter *interp)
@@ -30,6 +31,7 @@ void iload_core(interpreter *interp)
inew_cfunc(interp, "do", ifunc_do);
inew_cfunc(interp, "while", ifunc_while);
inew_cfunc(interp, "ret", ifunc_ret);
+ inew_cfunc(interp, "else", ifunc_else);
}
int ifunc_set(interpreter *it)
@@ -65,9 +67,10 @@ int ifunc_if(interpreter *it)
int v = igetarg(it, 0)->value.p;
if (v == 0)
iskip(it);
- void *tmp = ipop(it);
+ void *arg = ipop(it);
+ ipush(it, (void *)v);
ipush(it, (void *)-1);
- ipush(it, tmp);
+ ipush(it, arg);
return 0;
}
@@ -77,8 +80,33 @@ int ifunc_end(interpreter *it)
return 0;
uint32_t lnidx = (uint32_t)ipop(it) + 1;
- if (lnidx != 0)
+ if (lnidx == 0) { // from an if, have conditional
+ ipop(it); // whatever
+ } else {
+ if (lnidx == (uint32_t)-1) {
+ // script-func call
+ lnidx = (uint32_t)ipop(it);
+ it->indent = (uint32_t)ipop(it);
+ }
it->lnidx = lnidx;
+ }
+ return 0;
+}
+
+int ifunc_else(interpreter *it)
+{
+ if (it->stidx == 0)
+ return 0;
+
+ ipop(it); // the -1
+ int cond = (int)ipop(it);
+ it->indent++;
+ if (cond != 0)
+ iskip(it);
+ // otherwise it's whatever?
+ ipush(it, 0);
+ ipush(it, (void *)-1);
+
return 0;
}
diff --git a/builtins.h b/builtins.h
index 9d18093..5c8e350 100644
--- a/builtins.h
+++ b/builtins.h
@@ -4,7 +4,7 @@
#include "parser.h"
#define IUP_COUNT 3
-#define IDOWN_COUNT 2
+#define IDOWN_COUNT 3
void iload_core(interpreter *it);
diff --git a/ops.c b/ops.c
index cb07093..5267b6f 100644
--- a/ops.c
+++ b/ops.c
@@ -1,5 +1,7 @@
#include "ops.h"
+#include <string.h>
+
void iop_add(variable *, variable *, variable *);
void iop_sub(variable *, variable *, variable *);
void iop_mult(variable *, variable *, variable *);
@@ -18,15 +20,15 @@ void iop_ne(variable *, variable *, variable *);
void iop_mod(variable *, variable *, variable *);
char *iops[IOPS_COUNT] = {
- "+", "-", "*", "/", "&", "|", "^", ">>", "<<",
- "==", "<", ">", "<=", ">=", "!=", "%"
+ "*", "/", "%", "+", "-", "<<", ">>", "<=",
+ "<", ">=", ">", "==", "!=", "&", "^", "|"
};
operation_t iopfuncs[IOPS_COUNT] = {
- iop_add, iop_sub, iop_mult, iop_div, iop_and,
- iop_or, iop_xor, iop_shr, iop_shl,
- iop_eq, iop_lt, iop_gt, iop_lte, iop_gte, iop_ne,
- iop_mod
+ iop_mult, iop_div, iop_mod, iop_add, iop_sub,
+ iop_shl, iop_shr, iop_lte, iop_lt, iop_gte,
+ iop_gt, iop_eq, iop_ne, iop_and, iop_xor,
+ iop_or
};
@@ -77,7 +79,10 @@ void iop_shl(variable *r, variable *a, variable *b)
void iop_eq(variable *r, variable *a, variable *b)
{
- r->value.f = a->value.f == b->value.f;
+ if (a->valtype == STRING && b->valtype == STRING)
+ r->value.f = (float)!strcmp((char *)a->value.p, (char *)b->value.p);
+ else
+ r->value.f = a->value.f == b->value.f;
}
void iop_lt(variable *r, variable *a, variable *b)
diff --git a/parser.c b/parser.c
index 3311d5c..d7ba5ac 100644
--- a/parser.c
+++ b/parser.c
@@ -10,7 +10,7 @@
#include <memory.h>
#include <string.h>
-#define MAX_VARS 64
+#define MAX_VARS 100
#define MAX_STACK 32
#define MAX_LINES 1000
@@ -100,9 +100,9 @@ variable *inew_string(interpreter *interp, const char *name, const char *value)
{
variable *v = interpreter_get_variable(interp, name);
if (v != 0) {
- v->valtype = STRING;
- if (v->value.p != 0)
+ if (v->valtype == STRING && v->value.p != 0)
free((void *)v->value.p);
+ v->valtype = STRING;
v->value.p = (uint32_t)strclone(value);
}
return v;
@@ -326,7 +326,9 @@ cont:
}
}
- ipush(interp, (void *)(interp->lnidx));
+ ipush(interp, (void *)(uint32_t)interp->indent);
+ ipush(interp, (void *)interp->lnidx);
+ ipush(interp, (void *)-2); // magic
interp->lnidx = ops[0]->value.p;
interp->indent++;
}
@@ -365,6 +367,8 @@ variable *idoexpr(interpreter *interp, const char *line)
uint32_t next = 0;
// step 1 - break apart line
+ for (uint8_t i = 0; i < 16; i++)
+ ops[i] = 0;
// skip whitespace
skipblank(line, eol, &offset);
@@ -429,21 +433,52 @@ variable *idoexpr(interpreter *interp, const char *line)
return 0;
// step 2 - do operations
- variable *result = (variable *)calloc(1, sizeof(variable));
- result->valtype = ((variable *)ops[0])->valtype;
- result->value.p = ((variable *)ops[0])->value.p;
- for (uint32_t i = 1; i < ooffset; i += 2)
- iopfuncs[(uint32_t)ops[i] - 1](result, result, ops[i + 1]);
-
- for (uint32_t i = 0; i < ooffset; i += 2) {
- variable *v = (variable *)ops[i];
- if (!v->used) {
- if (v->valtype == STRING || v->valtype == EXPR)
- free((void *)v->value.p);
- free(ops[i]);
+ // for every operator, ordered by importance
+ for (uint32_t i = 0; i < IOPS_COUNT; i++) {
+ // find instances of the operation
+ for (uint32_t j = 1; j < ooffset; j += 2) {
+ // if a match
+ if ((uint32_t)ops[j] == i + 1) {
+ // find args
+ uint32_t ai = j - 1;
+ uint32_t bi = j + 1;
+ while (ops[ai] == 0)
+ ai--;
+ while (ops[bi] == 0)
+ bi++;
+
+ variable *r = (variable *)calloc(1, sizeof(variable));
+ iopfuncs[i](r, ops[ai], ops[bi]);
+
+ variable *v = (variable *)ops[ai];
+ if (!v->used)
+ free(v);
+ ops[ai] = r;
+ v = (variable *)ops[bi];
+ if (!v->used)
+ free(v);
+ ops[bi] = 0;
+ ops[j] = 0;
+ }
}
}
+ variable *result = make_varn(0, ((variable *)ops[0])->value.f);
+ if (!((variable *)ops[0])->used)
+ free(ops[0]);
+
+ //for (uint32_t i = 1; i < ooffset; i += 2)
+ // iopfuncs[(uint32_t)ops[i] - 1](result, result, ops[i + 1]);
+
+ //for (uint32_t i = 0; i < ooffset; i += 2) {
+ // variable *v = (variable *)ops[i];
+ // if (!v->used) {
+ // if (v->valtype == STRING || v->valtype == EXPR)
+ // free((void *)v->value.p);
+ // free(ops[i]);
+ // }
+ //}
+
return result;
}