#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);
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)
{
inew_cfunc(it, "while", bn_while);
inew_cfunc(it, "func", bn_func);
inew_cfunc(it, "solve", bn_solve);
+ inew_cfunc(it, "array", bn_array);
}
/**
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;
+}
#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);
* 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),
};
const char *opnames[] = {
+ ".", 0,
"*", "/", "%", 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)
{
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;
{
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)
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);
}
{
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);
}
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]);
}
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 {
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
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]))) {
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] == '\\')
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--)
} 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