diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2018-02-07 09:26:36 -0500 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2018-02-07 09:26:36 -0500 |
commit | 2b8cf5e771cac4c2b087dc96a7ca05a459f630b5 (patch) | |
tree | d1e25ef8520e9df936c231af0d5b760177d6cbde /builtins.c | |
parent | e3cbc8086c25d4fc1d9413815643b3ecaaee2062 (diff) |
conditionals, returns, cleaner code
Diffstat (limited to 'builtins.c')
-rw-r--r-- | builtins.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/builtins.c b/builtins.c new file mode 100644 index 0000000..cda7a93 --- /dev/null +++ b/builtins.c @@ -0,0 +1,118 @@ +#include "builtins.h" +#include "stack.h" + +extern char *str_func; + +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); + +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); +} + +int ifunc_set(interpreter *it) +{ + variable *n = igetarg(it, 0); + variable *v = igetarg(it, 1); + + if (n == 0) + return -1; + + n->valtype = v->valtype; + n->value = v->value; + n->svalue = v->svalue; + return 0; +} + +int ifunc_label(interpreter *it) +{ + variable *n = igetarg(it, 0); + + if (n == 0) + return -1; + + n->valtype = FUNC; + n->value = it->lnidx; + n->svalue = str_func; + it->indent++; + return 0; +} + +int ifunc_if(interpreter *it) +{ + int v = igetarg_integer(it, 0); + if (v == 0) { + it->indent++; + } else { + void *tmp = ipop(it); + ipush(it, (void *)-1); + ipush(it, tmp); + } + return 0; +} + +int ifunc_end(interpreter *it) +{ + uint32_t lnidx = (uint32_t)ipop(it) + 1; + if (lnidx != 0) + it->lnidx = lnidx; + return 0; +} + +int ifunc_do(interpreter *it) +{ + ipush(it, (void *)it->lnidx); + return 0; +} + +int ifunc_while(interpreter *it) +{ + int c = igetarg_integer(it, 0); + ipop(it); + int nidx = (int)ipop(it); + if (c != 0) { + ipush(it, (void *)nidx); + it->lnidx = nidx; + } + ipush(it, 0); + return 0; +} + +int ifunc_ret(interpreter *it) +{ + variable *v = igetarg(it, 0); + switch (v->valtype) { + case INTEGER: + inew_integer(it, "RET", INT(v)); + break; + case FLOAT: + inew_float(it, "RET", FLOAT(v)); + break; + case STRING: + inew_string(it, "RET", v->svalue); + break; + default: + return -1; + break; + } + if (it->ret != 0) { + it->ret->valtype = v->valtype; + it->ret->value = v->value; + it->ret->svalue = v->svalue; + it->ret = 0; + } + return 0; +} + |