#include "builtins.h" #include "stack.h" #include "shelpers.h" #include #include int ifunc_set(interpreter *it); int ifunc_label(interpreter *it); int ifunc_end(interpreter *it); 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_else, ifunc_end, ifunc_while, }; void iload_core(interpreter *interp) { inew_cfunc(interp, "set", ifunc_set); inew_cfunc(interp, "func", ifunc_label); inew_cfunc(interp, "end", ifunc_end); inew_cfunc(interp, "if", ifunc_if); 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) { variable *n = igetarg(it, 0); variable *v = igetarg(it, 1); if (n == 0) return -1; if (n->valtype == STRING) free((void *)n->value.p); n->valtype = v->valtype; n->value.p = v->value.p; return 0; } int ifunc_label(interpreter *it) { variable *n = igetarg(it, 0); if (n == 0) return -1; n->valtype = FUNC; n->value.p = it->lnidx; iskip(it); return 0; } int ifunc_if(interpreter *it) { int v = igetarg(it, 0)->value.p; if (v == 0) iskip(it); void *arg = ipop(it); ipush(it, (void *)v); ipush(it, (void *)-1); ipush(it, arg); return 0; } int ifunc_end(interpreter *it) { if (it->stidx == 0) return 0; uint32_t lnidx = (uint32_t)ipop(it) + 1; 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; } int ifunc_do(interpreter *it) { ipush(it, (void *)it->lnidx); return 0; } int ifunc_while(interpreter *it) { int c = igetarg(it, 0)->value.p; ipop(it); int nidx = (int)ipop(it); if (c != 0) { //ipush(it, (void *)nidx); it->lnidx = nidx - 1; } ipush(it, 0); return 0; } void iret(interpreter *it, variable *v) { switch (v->valtype) { case NUMBER: inew_number(it, "RET", v->value.f); break; case STRING: inew_string(it, "RET", (char *)v->value.p); break; default: return; break; } if (it->ret != 0) { if (it->ret->valtype == STRING && it->ret->value.p != 0) free((void *)it->ret->value.p); it->ret->valtype = v->valtype; it->ret->value.p = v->value.p; it->ret = 0; } } int ifunc_ret(interpreter *it) { variable *v = igetarg(it, 0); iret(it, v); return 0; }