arrays, implicit multiply

master
Clyne Sullivan 7 years ago
parent 14fd4de5d5
commit 7f64da46ff

@ -42,11 +42,11 @@
#define FUNC_SIG (uint32_t)-4 #define FUNC_SIG (uint32_t)-4
variable bopen = { variable bopen = {
0, CFUNC, 0, {.p = (uint32_t)bracket_open} 0, CFUNC, 0, 0, {.p = (uint32_t)bracket_open}
}; };
variable bclose = { variable bclose = {
0, CFUNC, 0, {.p = (uint32_t)bracket_close} 0, CFUNC, 0, 0, {.p = (uint32_t)bracket_close}
}; };
int bn_if(instance *it); int bn_if(instance *it);
@ -55,6 +55,7 @@ int bn_end(instance *it);
int bn_while(instance *it); int bn_while(instance *it);
int bn_func(instance *it); int bn_func(instance *it);
int bn_solve(instance *it); int bn_solve(instance *it);
int bn_array(instance *it);
void iload_builtins(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, "while", bn_while);
inew_cfunc(it, "func", bn_func); inew_cfunc(it, "func", bn_func);
inew_cfunc(it, "solve", bn_solve); inew_cfunc(it, "solve", bn_solve);
inew_cfunc(it, "array", bn_array);
} }
/** /**
@ -187,3 +189,15 @@ int bn_solve(instance *it)
return 0; 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;
}

107
ops.c

@ -35,10 +35,11 @@
#include <stdlib.h> #include <stdlib.h>
#define OP_DEF(o) int op_##o(variable *r, variable *a, variable *b) #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_VAR(o) {0, OPERATOR, 0, 0, {.p = (uint32_t)op_##o}}
#define OP_NONE {0, OPERATOR, 0, {.p = 0x0BADCAFE}} #define OP_NONE {0, OPERATOR, 0, 0, {.p = 0x0BADCAFE}}
OP_DEF(idx);
OP_DEF(mul); OP_DEF(mul);
OP_DEF(div); OP_DEF(div);
OP_DEF(mod); OP_DEF(mod);
@ -67,6 +68,7 @@ OP_DEF(set);
* priority, they will be evaluated from left-to-right by the parser. * priority, they will be evaluated from left-to-right by the parser.
*/ */
variable opvars[] = { variable opvars[] = {
OP_VAR(idx), OP_NONE,
OP_VAR(mul), OP_VAR(div), OP_VAR(mod), 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(add), OP_VAR(sub), OP_VAR(shl), OP_VAR(shr),
OP_VAR(lte), OP_VAR(lt), OP_VAR(gte), OP_VAR(gt), OP_VAR(lte), OP_VAR(lt), OP_VAR(gte), OP_VAR(gt),
@ -75,6 +77,7 @@ variable opvars[] = {
}; };
const char *opnames[] = { const char *opnames[] = {
".", 0,
"*", "/", "%", 0, "*", "/", "%", 0,
"+", "-", "<<", ">>", "+", "-", "<<", ">>",
"<=", "<", ">=", ">", "<=", "<", ">=", ">",
@ -97,103 +100,125 @@ variable *igetop(const char *name, int *retlen)
return 0; 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) OP_DEF(mul)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f * b->value.f; (*r)->value.f = a->value.f * b->value.f;
return 0; return 0;
} }
OP_DEF(div) OP_DEF(div)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f / b->value.f; (*r)->value.f = a->value.f / b->value.f;
return 0; return 0;
} }
OP_DEF(mod) OP_DEF(mod)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = (int)a->value.f % (int)b->value.f; (*r)->value.f = (int)a->value.f % (int)b->value.f;
return 0; return 0;
} }
OP_DEF(add) OP_DEF(add)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f + b->value.f; (*r)->value.f = a->value.f + b->value.f;
return 0; return 0;
} }
OP_DEF(sub) OP_DEF(sub)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f - b->value.f; (*r)->value.f = a->value.f - b->value.f;
return 0; return 0;
} }
OP_DEF(shl) OP_DEF(shl)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = (int)a->value.f << (int)b->value.f; (*r)->value.f = (int)a->value.f << (int)b->value.f;
return 0; return 0;
} }
OP_DEF(shr) OP_DEF(shr)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = (int)a->value.f >> (int)b->value.f; (*r)->value.f = (int)a->value.f >> (int)b->value.f;
return 0; return 0;
} }
OP_DEF(lte) OP_DEF(lte)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f <= b->value.f; (*r)->value.f = a->value.f <= b->value.f;
return 0; return 0;
} }
OP_DEF(lt) OP_DEF(lt)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f < b->value.f; (*r)->value.f = a->value.f < b->value.f;
return 0; return 0;
} }
OP_DEF(gte) OP_DEF(gte)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f >= b->value.f; (*r)->value.f = a->value.f >= b->value.f;
return 0; return 0;
} }
OP_DEF(gt) OP_DEF(gt)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f > b->value.f; (*r)->value.f = a->value.f > b->value.f;
return 0; return 0;
} }
OP_DEF(eq) OP_DEF(eq)
{ {
r->type = NUMBER; (*r)->type = NUMBER;
if (a->type == NUMBER && b->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) 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 else
r->value.f = 0.0f; // *sshhh* (*r)->value.f = 0.0f; // *sshhh*
//return seterror(EBADPARAM); //return seterror(EBADPARAM);
return 0; return 0;
@ -202,32 +227,32 @@ OP_DEF(ne)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f != b->value.f; (*r)->value.f = a->value.f != b->value.f;
return 0; return 0;
} }
OP_DEF(and) OP_DEF(and)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = (int)a->value.f & (int)b->value.f; (*r)->value.f = (int)a->value.f & (int)b->value.f;
return 0; return 0;
} }
OP_DEF(xor) OP_DEF(xor)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = (int)a->value.f ^ (int)b->value.f; (*r)->value.f = (int)a->value.f ^ (int)b->value.f;
return 0; return 0;
} }
OP_DEF(or) OP_DEF(or)
{ {
if (a->type != NUMBER || b->type != NUMBER) if (a->type != NUMBER || b->type != NUMBER)
return seterror(EBADPARAM); return seterror(EBADPARAM);
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = (int)a->value.f | (int)b->value.f; (*r)->value.f = (int)a->value.f | (int)b->value.f;
return 0; return 0;
} }
OP_DEF(set) OP_DEF(set)
@ -235,14 +260,14 @@ OP_DEF(set)
if (b->type == NUMBER) { if (b->type == NUMBER) {
a->type = NUMBER; a->type = NUMBER;
a->value.f = b->value.f; a->value.f = b->value.f;
r->type = NUMBER; (*r)->type = NUMBER;
r->value.f = a->value.f; (*r)->value.f = a->value.f;
} else if (b->type == STRING) { } else if (b->type == STRING) {
a->type = STRING; a->type = STRING;
free((void *)a->value.p); free((void *)a->value.p);
a->value.p = (uint32_t)strclone((char *)b->value.p); a->value.p = (uint32_t)strclone((char *)b->value.p);
r->type = STRING; (*r)->type = STRING;
r->value.p = (uint32_t)strclone((char *)a->value.p); (*r)->value.p = (uint32_t)strclone((char *)a->value.p);
} else { } else {
return seterror(EBADPARAM); return seterror(EBADPARAM);
} }

@ -26,11 +26,11 @@
/** /**
* Defines the number of available operators. * Defines the number of available operators.
*/ */
#define OPS_COUNT 18 #define OPS_COUNT 20
#define OP_MAGIC 0xCAFE3900 #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. * An array of variable objects for each operator, exposed for the parser.

@ -46,8 +46,9 @@ void itryfree(variable *v)
{ {
if (v == 0 || v->tmp == 0) if (v == 0 || v->tmp == 0)
return; return;
if (v->type == STRING) if (v->type == STRING)// || v->array > 0)
free((void *)v->value.p); free((void *)v->value.p);
free(v); free(v);
} }
@ -87,7 +88,7 @@ void idelinstance(instance *it)
free(it->lines); free(it->lines);
for (uint32_t i = 0; i < MAX_VARS; i++) { 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((void *)it->vars[i].value.p);
free(it->names[i]); free(it->names[i]);
} }
@ -356,7 +357,7 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
if (!(it->sindent & SKIP)) { if (!(it->sindent & SKIP)) {
variable *v = !ops[aidx]->tmp ? make_varf(0, 0.0f) : ops[aidx]; 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; return 0;
ops[aidx] = v; ops[aidx] = v;
} else { } else {
@ -387,6 +388,7 @@ variable **iparse(instance *it, const char *s)
uint32_t ooffset = 0; uint32_t ooffset = 0;
int32_t boffset = 1; int32_t boffset = 1;
size_t offset = 0; size_t offset = 0;
uint8_t prevNum = 0;
// advance to first character // advance to first character
// and insure there's runnable script on the line // and insure there's runnable script on the line
@ -442,6 +444,8 @@ variable **iparse(instance *it, const char *s)
ops[argidx] = (variable *)argcount; ops[argidx] = (variable *)argcount;
} else if (ops[ooffset - 1]->type == FUNC || ops[ooffset - 1]->type == CFUNC) { } else if (ops[ooffset - 1]->type == FUNC || ops[ooffset - 1]->type == CFUNC) {
ops[ooffset++] = (variable *)1; ops[ooffset++] = (variable *)1;
} else {
prevNum += 2;
} }
offset = end; offset = end;
} else if (isdigit(s[offset])) {// || (s[offset] == '-' && isdigit(s[offset + 1]))) { } 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); ops[ooffset++] = make_num(word);
free(word); free(word);
offset = end; offset = end;
prevNum += 2;
} else if (s[offset] == '\"') { } else if (s[offset] == '\"') {
size_t end = offset + 1; size_t end = offset + 1;
while (s[end] != '\"')// && s[end - 1] == '\\') while (s[end] != '\"')// && s[end - 1] == '\\')
@ -483,6 +488,15 @@ variable **iparse(instance *it, const char *s)
free(word); free(word);
ops[parenidx] = (variable *)(OP_MAGIC | count); ops[parenidx] = (variable *)(OP_MAGIC | count);
offset = i; 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])) { } else if (!isblank(s[offset])) {
if (s[offset] == '{' || s[offset] == '}') { if (s[offset] == '{' || s[offset] == '}') {
for (int32_t i = ooffset - 1; i >= boffset - 1; i--) for (int32_t i = ooffset - 1; i >= boffset - 1; i--)
@ -513,6 +527,16 @@ variable **iparse(instance *it, const char *s)
} else { } else {
offset++; offset++;
} }
if (prevNum > 0) {
if (--prevNum == 2) {
--prevNum;
variable *mul = igetop("*", 0);
ops[ooffset] = ops[ooffset - 1];
ops[ooffset - 1] = mul;
ooffset++;
}
}
} }
// mark end // mark end

14
test7

@ -0,0 +1,14 @@
j = 6
func(test) {
i = 0
while (i < 10) {
i = i + 1
}
j = 15
}
print(i)
print(" ")
print(j)

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

@ -0,0 +1,7 @@
x = 9
print(3x)
print(2x + 5)
print(x - 9x)
print(5 + (3x))
print((x - 4 * 5)2)

@ -31,6 +31,7 @@ typedef struct {
uint8_t tmp :1; /**< If zero, variable cannot be free'd */ uint8_t tmp :1; /**< If zero, variable cannot be free'd */
uint8_t type :3; /**< The variable's type */ uint8_t type :3; /**< The variable's type */
uint8_t unused :4; /**< Unused... */ uint8_t unused :4; /**< Unused... */
uint8_t array; /**< ">0?" -> array w/ this size */
union { union {
float f; float f;
uint32_t p; uint32_t p;

Loading…
Cancel
Save