arrays, implicit multiply

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

@ -42,11 +42,11 @@
#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;
}

107
ops.c

@ -35,10 +35,11 @@
#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);
}

@ -26,11 +26,11 @@
/**
* 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.

@ -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

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 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;

Loading…
Cancel
Save