added else, order of ops

master
Clyne Sullivan 7 years ago
parent 952cb2d6db
commit 40e157ffa2

@ -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;
}

@ -4,7 +4,7 @@
#include "parser.h"
#define IUP_COUNT 3
#define IDOWN_COUNT 2
#define IDOWN_COUNT 3
void iload_core(interpreter *it);

19
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)

@ -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;
}

Loading…
Cancel
Save