]> code.bitgloo.com Git - clyne/interpreter.git/commitdiff
arrays, implicit multiply
authorClyne Sullivan <tullivan99@gmail.com>
Fri, 13 Apr 2018 12:43:47 +0000 (08:43 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Fri, 13 Apr 2018 12:43:47 +0000 (08:43 -0400)
builtins.c
ops.c
ops.h
parser.c
test7 [new file with mode: 0644]
test8 [new file with mode: 0644]
test9 [new file with mode: 0644]
variable.h

index 73ce360694c1f9825f450bb2ec99b4a37592cb00..e3be39c76b33061ca57e3af249cb3e04ea173fe9 100644 (file)
 #define FUNC_SIG  (uint32_t)-4
 
 variable bopen = {
-       0, CFUNC, 0, {.p = (uint32_t)bracket_open}
+       0, CFUNC, 0, 0, {.p = (uint32_t)bracket_open}
 };
 
 variable bclose = {
-       0, CFUNC, 0, {.p = (uint32_t)bracket_close}
+       0, CFUNC, 0, 0, {.p = (uint32_t)bracket_close}
 };
 
 int bn_if(instance *it);
@@ -55,6 +55,7 @@ int bn_end(instance *it);
 int bn_while(instance *it);
 int bn_func(instance *it);
 int bn_solve(instance *it);
+int bn_array(instance *it);
 
 void iload_builtins(instance *it)
 {
@@ -63,6 +64,7 @@ void iload_builtins(instance *it)
        inew_cfunc(it, "while", bn_while);
        inew_cfunc(it, "func", bn_func);
        inew_cfunc(it, "solve", bn_solve);
+       inew_cfunc(it, "array", bn_array);
 }
 
 /**
@@ -187,3 +189,15 @@ int bn_solve(instance *it)
        return 0;
 }
 
+int bn_array(instance *it)
+{
+       variable *a = igetarg(it, 0);
+       int size = igetarg(it, 1)->value.f;
+       uint32_t i0 = a->value.p;
+       variable *array = calloc(size, sizeof(variable));
+       array[0].type = a->type;
+       array[0].value.p = i0;
+       a->array = size;
+       a->value.p = (uint32_t)array;
+       return 0;
+}
diff --git a/ops.c b/ops.c
index 8e6cc66963b8e03ad09225c89e9c91f1bcd24325..f79503fcc62e1be73beac4329199c03fa984c8e1 100644 (file)
--- a/ops.c
+++ b/ops.c
 
 #include <stdlib.h>
 
-#define OP_DEF(o) int op_##o(variable *r, variable *a, variable *b)
-#define OP_VAR(o) {0, OPERATOR, 0, {.p = (uint32_t)op_##o}}
-#define OP_NONE   {0, OPERATOR, 0, {.p = 0x0BADCAFE}}
+#define OP_DEF(o) int op_##o(variable **r, variable *a, variable *b)
+#define OP_VAR(o) {0, OPERATOR, 0, 0, {.p = (uint32_t)op_##o}}
+#define OP_NONE   {0, OPERATOR, 0, 0, {.p = 0x0BADCAFE}}
 
+OP_DEF(idx);
 OP_DEF(mul);
 OP_DEF(div);
 OP_DEF(mod);
@@ -67,6 +68,7 @@ OP_DEF(set);
  * priority, they will be evaluated from left-to-right by the parser.
  */
 variable opvars[] = {
+       OP_VAR(idx), OP_NONE,
        OP_VAR(mul), OP_VAR(div), OP_VAR(mod), OP_NONE,
        OP_VAR(add), OP_VAR(sub), OP_VAR(shl), OP_VAR(shr),
        OP_VAR(lte), OP_VAR(lt), OP_VAR(gte), OP_VAR(gt),
@@ -75,6 +77,7 @@ variable opvars[] = {
 };
 
 const char *opnames[] = {
+       ".", 0,
        "*", "/", "%", 0,
        "+", "-", "<<", ">>",
        "<=", "<", ">=", ">",
@@ -97,103 +100,125 @@ variable *igetop(const char *name, int *retlen)
        return 0;
 }
 
+OP_DEF(idx)
+{
+       if (a->array == 0)
+               return seterror(EBADPARAM);
+
+       extern void itryfree(variable *);
+       itryfree(*r);
+
+       int idx = b->value.f;
+       if (idx >= a->array) {
+               variable *newarray = calloc(idx + 1, sizeof(variable));
+               void *old = (void *)a->value.p;
+               a->value.p = (uint32_t)memcpy(newarray, (variable *)a->value.p,
+                       a->array * sizeof(variable));
+               free(old);
+               a->array = idx + 1;
+       }
+
+       variable *array = (variable *)a->value.p;
+       *r = &array[idx];
+       return 0;
+}
 OP_DEF(mul)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f * b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f * b->value.f;
        return 0;
 }
 OP_DEF(div)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f / b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f / b->value.f;
        return 0;
 }
 OP_DEF(mod)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = (int)a->value.f % (int)b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = (int)a->value.f % (int)b->value.f;
        return 0;
 }
 OP_DEF(add)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f + b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f + b->value.f;
        return 0;
 }
 OP_DEF(sub)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f - b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f - b->value.f;
        return 0;
 }
 OP_DEF(shl)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = (int)a->value.f << (int)b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = (int)a->value.f << (int)b->value.f;
        return 0;
 }
 OP_DEF(shr)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = (int)a->value.f >> (int)b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = (int)a->value.f >> (int)b->value.f;
        return 0;
 }
 OP_DEF(lte)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f <= b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f <= b->value.f;
        return 0;
 }
 OP_DEF(lt)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f < b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f < b->value.f;
        return 0;
 }
 OP_DEF(gte)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f >= b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f >= b->value.f;
        return 0;
 }
 OP_DEF(gt)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f > b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f > b->value.f;
        return 0;
 }
 OP_DEF(eq)
 {
-       r->type = NUMBER;
+       (*r)->type = NUMBER;
        if (a->type == NUMBER && b->type == NUMBER)
-               r->value.f = a->value.f == b->value.f;
+               (*r)->value.f = a->value.f == b->value.f;
        else if (a->type == STRING && b->type == STRING)
-               r->value.f = !strcmp((const char *)a->value.p, (const char *)b->value.p);
+               (*r)->value.f = !strcmp((const char *)a->value.p, (const char *)b->value.p);
        else
-               r->value.f = 0.0f; // *sshhh*
+               (*r)->value.f = 0.0f; // *sshhh*
                //return seterror(EBADPARAM);
 
        return 0;
@@ -202,32 +227,32 @@ OP_DEF(ne)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = a->value.f != b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = a->value.f != b->value.f;
        return 0;
 }
 OP_DEF(and)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = (int)a->value.f & (int)b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = (int)a->value.f & (int)b->value.f;
        return 0;
 }
 OP_DEF(xor)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = (int)a->value.f ^ (int)b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = (int)a->value.f ^ (int)b->value.f;
        return 0;
 }
 OP_DEF(or)
 {
        if (a->type != NUMBER || b->type != NUMBER)
                return seterror(EBADPARAM);
-       r->type = NUMBER;
-       r->value.f = (int)a->value.f | (int)b->value.f;
+       (*r)->type = NUMBER;
+       (*r)->value.f = (int)a->value.f | (int)b->value.f;
        return 0;
 }
 OP_DEF(set)
@@ -235,14 +260,14 @@ OP_DEF(set)
        if (b->type == NUMBER) {
                a->type = NUMBER;
                a->value.f = b->value.f;
-               r->type = NUMBER;
-               r->value.f = a->value.f;
+               (*r)->type = NUMBER;
+               (*r)->value.f = a->value.f;
        } else if (b->type == STRING) {
                a->type = STRING;
                free((void *)a->value.p);
                a->value.p = (uint32_t)strclone((char *)b->value.p);
-               r->type = STRING;
-               r->value.p = (uint32_t)strclone((char *)a->value.p);
+               (*r)->type = STRING;
+               (*r)->value.p = (uint32_t)strclone((char *)a->value.p);
        } else {
                return seterror(EBADPARAM);
        }
diff --git a/ops.h b/ops.h
index 4257f07eb2ad2debad92fec1b7f6c4ac045ccc5f..62e3821a29d7039bc0bd6578918c4719aff341f3 100644 (file)
--- a/ops.h
+++ b/ops.h
 /**
  * Defines the number of available operators.
  */
-#define OPS_COUNT 18
+#define OPS_COUNT 20
 
 #define OP_MAGIC  0xCAFE3900
 
-typedef int (*opfunc_t)(variable *, variable *, variable *);
+typedef int (*opfunc_t)(variable **, variable *, variable *);
 
 /**
  * An array of variable objects for each operator, exposed for the parser.
index 691e296ca24f5907cbd9eeaa44da4c1e15ef4b6f..2ae390b33d5df2f20f11856b551258532d693cef 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -46,8 +46,9 @@ void itryfree(variable *v)
 {
        if (v == 0 || v->tmp == 0)
                return;
-       if (v->type == STRING)
+       if (v->type == STRING)// || v->array > 0)
                free((void *)v->value.p);
+
        free(v);
 }
 
@@ -87,7 +88,7 @@ void idelinstance(instance *it)
        free(it->lines);
 
        for (uint32_t i = 0; i < MAX_VARS; i++) {
-               if (it->vars[i].type == STRING)
+               if (it->vars[i].type == STRING || it->vars[i].array > 0)
                        free((void *)it->vars[i].value.p);
                free(it->names[i]);
        }
@@ -356,7 +357,7 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
 
                                if (!(it->sindent & SKIP)) {
                                        variable *v = !ops[aidx]->tmp ? make_varf(0, 0.0f) : ops[aidx];
-                                       if (func(v, ops[aidx], ops[bidx]) != 0)
+                                       if (func(&v, ops[aidx], ops[bidx]) != 0)
                                                return 0;
                                        ops[aidx] = v;
                                } else {
@@ -387,6 +388,7 @@ variable **iparse(instance *it, const char *s)
        uint32_t ooffset = 0;
        int32_t boffset = 1;
        size_t offset = 0;
+       uint8_t prevNum = 0;
 
        // advance to first character
        // and insure there's runnable script on the line
@@ -442,6 +444,8 @@ variable **iparse(instance *it, const char *s)
                                ops[argidx] = (variable *)argcount;
                        } else if (ops[ooffset - 1]->type == FUNC || ops[ooffset - 1]->type == CFUNC) {
                                ops[ooffset++] = (variable *)1;
+                       } else {
+                               prevNum += 2;
                        }
                        offset = end;
                } else if (isdigit(s[offset])) {// || (s[offset] == '-' && isdigit(s[offset + 1]))) {
@@ -452,6 +456,7 @@ variable **iparse(instance *it, const char *s)
                        ops[ooffset++] = make_num(word);
                        free(word);
                        offset = end;
+                       prevNum += 2;
                } else if (s[offset] == '\"') {
                        size_t end = offset + 1;
                        while (s[end] != '\"')// && s[end - 1] == '\\')
@@ -483,6 +488,15 @@ variable **iparse(instance *it, const char *s)
                        free(word);
                        ops[parenidx] = (variable *)(OP_MAGIC | count);
                        offset = i;
+                       prevNum += 2;
+               } else if (s[offset] == '[') {
+                       /*uint32_t i = offset + 1;
+                       uint32_t j = i;
+                       while (s[offset] != ']') {
+                               if (s[offset] == ';') {
+
+                               }
+                       }*/
                } else if (!isblank(s[offset])) {
                        if (s[offset] == '{' || s[offset] == '}') {
                                for (int32_t i = ooffset - 1; i >= boffset - 1; i--)
@@ -513,6 +527,16 @@ variable **iparse(instance *it, const char *s)
                } else {
                        offset++;
                }
+
+               if (prevNum > 0) {
+                       if (--prevNum == 2) {
+                               --prevNum;
+                               variable *mul = igetop("*", 0);
+                               ops[ooffset] = ops[ooffset - 1];
+                               ops[ooffset - 1] = mul;
+                               ooffset++;
+                       }
+               }
        }
 
        // mark end
diff --git a/test7 b/test7
new file mode 100644 (file)
index 0000000..dd4defb
--- /dev/null
+++ b/test7
@@ -0,0 +1,14 @@
+j = 6
+
+func(test) {
+       i = 0
+       while (i < 10) {
+               i = i + 1
+       }
+
+       j = 15
+}
+
+print(i)
+print(" ")
+print(j)
diff --git a/test8 b/test8
new file mode 100644 (file)
index 0000000..8081b4c
--- /dev/null
+++ b/test8
@@ -0,0 +1,17 @@
+array(a, 10)
+
+i = 0
+while (i < 10) {
+       a.i = i * 2
+       i = i + 1
+}
+
+i = 0
+while (i < 10) {
+       print(a.i)
+       i = i + 1
+}
+
+a.20 = 143
+print(a.20)
+print(a.19)
diff --git a/test9 b/test9
new file mode 100644 (file)
index 0000000..3cfcd55
--- /dev/null
+++ b/test9
@@ -0,0 +1,7 @@
+x = 9
+print(3x)
+print(2x + 5)
+print(x - 9x)
+print(5 + (3x))
+print((x - 4 * 5)2)
+
index 0c4f584788511df8fc672512cf0789784217d19f..e40d1025435f9a6843d0eabbe67a4010795757e9 100644 (file)
@@ -31,6 +31,7 @@ typedef struct {
        uint8_t tmp    :1; /**< If zero, variable cannot be free'd */
        uint8_t type   :3; /**< The variable's type */
        uint8_t unused :4; /**< Unused... */
+       uint8_t array;     /**< ">0?" -> array w/ this size */
        union {
                float f;
                uint32_t p;