]> code.bitgloo.com Git - clyne/interpreter.git/commitdiff
jumps and functions
authorClyne Sullivan <tullivan99@gmail.com>
Thu, 1 Feb 2018 17:01:25 +0000 (12:01 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Thu, 1 Feb 2018 17:01:25 +0000 (12:01 -0500)
parser.c
parser.h
shell.c

index 72fd3f6e5316c13b0fd43e8344a4526611475511..04aeb9d7e80a3d88a5ecf8b0103f015096afcb44 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -27,6 +27,9 @@ char *strnclone(const char *s, uint32_t n)
 }
 
 void ifunc_set(interpreter *it);
+void ifunc_jmp(interpreter *it);
+void ifunc_label(interpreter *it);
+void ifunc_end(interpreter *it);
 
 variable *idoexpr(interpreter *interp, const char *line);
 
@@ -40,8 +43,24 @@ void iinit(interpreter *interp)
        interp->vnames = (char **)calloc(MAX_VARS, sizeof(char *));
        interp->stack = (stack_t *)calloc(MAX_STACK, sizeof(stack_t));
        interp->stidx = 0;
+       interp->lines = (char **)calloc(20, sizeof(char *));
+       interp->lnidx = 0;
+       interp->indent = 0;
 
        inew_cfunc(interp, "set", ifunc_set);
+       inew_cfunc(interp, "jmp", ifunc_jmp);
+       inew_cfunc(interp, "func", ifunc_label);
+       inew_cfunc(interp, "end", ifunc_end);
+}
+
+void ipush(interpreter *it, void *v)
+{
+       it->stack[it->stidx++] = v;
+}
+
+void *ipop(interpreter *it)
+{
+       return it->stack[--it->stidx];
 }
 
 variable *interpreter_get_variable(interpreter *interp, const char *name)
@@ -193,9 +212,20 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
 int idoline(interpreter *interp, const char *line)
 {
        variable *ops[8];
-       uint32_t ooffset = 0;
-       uint32_t offset = 0;
-       uint32_t next;
+       uint32_t ooffset, offset, next;
+
+       interp->lines[interp->lnidx] = strclone(line);
+loop:
+       if (line[0] == '`') {
+               goto norun;
+       } else if (interp->indent > 0) {
+               if (!strcmp(line, "end"))
+                       interp->indent--;
+               goto norun;
+       }
+
+       ooffset = 0;
+       offset = 0;
 
        // step 1 - convert to tokens
        while (!eol(line[offset])) {
@@ -221,11 +251,29 @@ int idoline(interpreter *interp, const char *line)
        if (ops[0]->value == 0)
                return -3;
 
-       for (uint32_t i = 0; i < ooffset - 1; i++, interp->stidx++)
-               interp->stack[i] = ops[i + 1];
+       for (uint32_t i = ooffset; --i > 0;)
+               ipush(interp, ops[i]);
 
-       ((func_t)ops[0]->value)(interp);
-       interp->stidx = 0;
+       if (ops[0]->fromc) {
+               ((func_t)ops[0]->value)(interp);
+       } else {
+               ipush(interp, (void *)(interp->lnidx + 1));
+               interp->lnidx = ops[0]->value;
+       }
+
+       interp->stidx -= ooffset - 1;
+
+       if ((int32_t)interp->stidx < 0) {
+               interp->stidx = 0;
+               return -5;
+       }
+
+norun:
+       interp->lnidx++;
+       if (interp->lines[interp->lnidx] != 0) {
+               line = interp->lines[interp->lnidx];
+               goto loop;
+       }
 
        return 0;
 }
@@ -318,25 +366,35 @@ variable *idoexpr(interpreter *interp, const char *line)
        return &result;
 }
 
+variable *igetarg(interpreter *interp, uint32_t index)
+{
+       return interp->stack[interp->stidx - index - 1];
+}
+
 char *igetarg_string(interpreter *interp, uint32_t index)
 {
        if (index >= interp->stidx)
                return 0;
-       return STR(itostring(interp->stack[index]));
+       variable *v = igetarg(interp, index);
+       if (v->valtype == FUNC)
+               return "(func)";
+       return STR(itostring(v));
 }
 
 int igetarg_integer(interpreter *interp, uint32_t index)
 {
        if (index >= interp->stidx)
                return 0;
-       return INT(itoint(interp->stack[index]));
+       variable *v = igetarg(interp, index);
+       return INT(itoint(v));
 }
 
 float igetarg_float(interpreter *interp, uint32_t index)
 {
        if (index >= interp->stidx)
                return 0;
-       return FLOAT(itofloat(interp->stack[index]));
+       variable *v = igetarg(interp, index);
+       return FLOAT(itofloat(v));
 }
 
 variable *itostring(variable *v)
@@ -423,16 +481,36 @@ float iget_float(interpreter *, const char *)
 
 void ifunc_set(interpreter *it)
 {
-       if (it->stidx != 2)
-               return;
-
-       variable *n = (variable *)it->stack[0];
-       variable *v = (variable *)it->stack[1];
+       variable *n = igetarg(it, 0);
+       variable *v = igetarg(it, 1);
 
        n->valtype = v->valtype;
        n->value = v->value;
 }
 
+void ifunc_label(interpreter *it)
+{
+       variable *n = igetarg(it, 0);
+       n->valtype = FUNC;
+       n->value = it->lnidx;
+
+       it->indent++;
+}
+
+void ifunc_end(interpreter *it)
+{
+       if (it->stidx > 0) {
+               uint32_t line = (uint32_t)ipop(it);
+               it->lnidx = line - 1;
+       }
+}
+
+void ifunc_jmp(interpreter *it)
+{
+       int newidx = igetarg_integer(it, 0);
+       it->lnidx = newidx - 1;
+}
+
 /**
  * Builtin operations
  */
index c2efba37fc752d70af0a726e3a72e4a9aa3b6ba9..822adf0e68beea1b3e337f369fad58ee2559ca74 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -10,6 +10,9 @@ typedef struct {
        char **vnames;
        stack_t *stack;
        uint32_t stidx;
+       char **lines;
+       uint32_t lnidx;
+       uint8_t indent;
 } interpreter;
 
 typedef void (*func_t)(interpreter *);
@@ -23,6 +26,7 @@ void inew_cfunc(interpreter *, const char *, func_t);
 
 int idoline(interpreter *, const char *);
 
+variable *igetarg(interpreter *, uint32_t);
 char *igetarg_string(interpreter *, uint32_t);
 int igetarg_integer(interpreter *, uint32_t); 
 float igetarg_float(interpreter *, uint32_t);
diff --git a/shell.c b/shell.c
index 221cd0787ea876eabf9baafc7c7a149aadbbab26..bd877a179fa2d19b5f6789f607006db269758f5f 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -14,8 +14,6 @@ void s_put(interpreter *it)
 
 void s_type(interpreter *it)
 {
-       if (it->stidx != 1)
-               return;
        variable *v = (variable *)it->stack[0];
        switch (v->valtype) {
        case STRING:
@@ -56,6 +54,7 @@ int main()
        unsigned int size;
        int result;
        while (1) {
+               printf("%d> ", interp.lnidx);
                getline(&line, &size, stdin);
                *strchr(line, '\n') = '\0';
                result = idoline(&interp, line);