better expressions, type handling

master
Clyne Sullivan 7 years ago
parent a944239682
commit 3b6bcc0e6e

@ -8,6 +8,10 @@
#define MAX_VARS 32 #define MAX_VARS 32
#define MAX_STACK 32 #define MAX_STACK 32
#define INT(v) (*((int32_t *)&v->value))
#define FLOAT(v) (*((float *)&v->value))
#define STR(v) (*((char **)&v->value))
char *strclone(const char *s) char *strclone(const char *s)
{ {
char *clone = (char *)malloc(strlen(s)); char *clone = (char *)malloc(strlen(s));
@ -70,7 +74,7 @@ void inew_string(interpreter *interp, const char *name, char *value)
variable *v = interpreter_get_variable(interp, name); variable *v = interpreter_get_variable(interp, name);
if (v != 0) { if (v != 0) {
v->valtype = STRING; v->valtype = STRING;
v->value = (uint32_t)value; STR(v) = value;
} }
} }
@ -79,7 +83,7 @@ void inew_integer(interpreter *interp, const char *name, int32_t value)
variable *v = interpreter_get_variable(interp, name); variable *v = interpreter_get_variable(interp, name);
if (v != 0) { if (v != 0) {
v->valtype = INTEGER; v->valtype = INTEGER;
v->value = (uint32_t)value; INT(v) = value;
} }
} }
@ -88,7 +92,7 @@ void inew_float(interpreter *interp, const char *name, float value)
variable *v = interpreter_get_variable(interp, name); variable *v = interpreter_get_variable(interp, name);
if (v != 0) { if (v != 0) {
v->valtype = FLOAT; v->valtype = FLOAT;
v->value = (uint32_t)value; FLOAT(v) = value;
} }
} }
@ -128,7 +132,7 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
// TODO string breakdown // TODO string breakdown
variable *v = (variable *)malloc(sizeof(variable)); variable *v = (variable *)malloc(sizeof(variable));
v->valtype = STRING; v->valtype = STRING;
v->value = (uint32_t)strnclone(line + 1, end - 1); STR(v) = strnclone(line + 1, end - 1);
*next = end + 1; *next = end + 1;
return v; return v;
} }
@ -175,10 +179,10 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
variable *v = (variable *)malloc(sizeof(variable)); variable *v = (variable *)malloc(sizeof(variable));
if (dec) { if (dec) {
v->valtype = FLOAT; v->valtype = FLOAT;
*((float *)&v->value) = strtof(line, 0); FLOAT(v) = strtof(line, 0);
} else { } else {
v->valtype = INTEGER; v->valtype = INTEGER;
v->value = atoi(line); INT(v) = atoi(line);
} }
*next = end; *next = end;
return v; return v;
@ -221,22 +225,31 @@ int idoline(interpreter *interp, const char *line)
interp->stack[i] = ops[i + 1]; interp->stack[i] = ops[i + 1];
((func_t)ops[0]->value)(interp); ((func_t)ops[0]->value)(interp);
interp->stidx = 0;
return 0; return 0;
} }
typedef void (*operation_t)(variable *, variable *, variable *); typedef void (*operation_t)(variable *, variable *, variable *);
#define IOPS_COUNT 2 #define IOPS_COUNT 9
static char *iops[IOPS_COUNT] = { static char *iops[IOPS_COUNT] = {
"+", "-" "+", "-", "*", "/", "&", "|", "^", ">>", "<<"
}; };
void iop_add(variable *, variable *, variable *); void iop_add(variable *, variable *, variable *);
void iop_sub(variable *, variable *, variable *); void iop_sub(variable *, variable *, variable *);
void iop_mult(variable *, variable *, variable *);
void iop_div(variable *, variable *, variable *);
void iop_and(variable *, variable *, variable *);
void iop_or(variable *, variable *, variable *);
void iop_xor(variable *, variable *, variable *);
void iop_shr(variable *, variable *, variable *);
void iop_shl(variable *, variable *, variable *);
static operation_t iopfuncs[IOPS_COUNT] = { static operation_t iopfuncs[IOPS_COUNT] = {
iop_add, iop_sub iop_add, iop_sub, iop_mult, iop_div, iop_and,
iop_or, iop_xor, iop_shr, iop_shl
}; };
variable *idoexpr(interpreter *interp, const char *line) variable *idoexpr(interpreter *interp, const char *line)
@ -248,14 +261,16 @@ variable *idoexpr(interpreter *interp, const char *line)
uint32_t offset = 0; uint32_t offset = 0;
uint32_t next; uint32_t next;
// step 1 - break aprt line // step 1 - break apart line
// skip whitespace // skip whitespace
for (; line[offset] == ' ' && !eol(line[offset]); offset++); for (; line[offset] == ' ' && !eol(line[offset]); offset++);
while (!eoe(line[offset])) { while (!eoe(line[offset])) {
uint32_t end = offset; uint32_t end = offset;
char cend; char cend;
if (line[offset] != '\"' && line[offset] != '(') { if (line[offset] == '(') {
} else if (line[offset] != '\"') {
for (; isalnum(line[end]) || line[end] == '.'; end++); for (; isalnum(line[end]) || line[end] == '.'; end++);
cend = line[end]; cend = line[end];
mline[end] = ' '; mline[end] = ' ';
@ -307,21 +322,21 @@ char *igetarg_string(interpreter *interp, uint32_t index)
{ {
if (index >= interp->stidx) if (index >= interp->stidx)
return 0; return 0;
return (char *)itostring(interp->stack[index])->value; return STR(itostring(interp->stack[index]));
} }
int igetarg_integer(interpreter *interp, uint32_t index) int igetarg_integer(interpreter *interp, uint32_t index)
{ {
if (index >= interp->stidx) if (index >= interp->stidx)
return 0; return 0;
return *((int32_t *)&itoint(interp->stack[index])->value); return INT(itoint(interp->stack[index]));
} }
float igetarg_float(interpreter *interp, uint32_t index) float igetarg_float(interpreter *interp, uint32_t index)
{ {
if (index >= interp->stidx) if (index >= interp->stidx)
return 0; return 0;
return *((float *)&itofloat(interp->stack[index])->value); return FLOAT(itofloat(interp->stack[index]));
} }
variable *itostring(variable *v) variable *itostring(variable *v)
@ -334,13 +349,13 @@ variable *itostring(variable *v)
buf = (char *)malloc(12); buf = (char *)malloc(12);
sprintf(buf, "%d", *((int32_t *)&v->value)); sprintf(buf, "%d", *((int32_t *)&v->value));
v->valtype = STRING; v->valtype = STRING;
v->value = (uint32_t)buf; STR(v) = buf;
break; break;
case FLOAT: case FLOAT:
buf = (char *)malloc(24); buf = (char *)malloc(24);
sprintf(buf, "%f", *((float *)&v->value)); sprintf(buf, "%f", *((float *)&v->value));
v->valtype = STRING; v->valtype = STRING;
v->value = (uint32_t)buf; STR(v) = buf;
break; break;
case FUNC: case FUNC:
// no // no
@ -354,13 +369,13 @@ variable *itoint(variable *v)
switch (v->valtype) { switch (v->valtype) {
case STRING: case STRING:
v->valtype = INTEGER; v->valtype = INTEGER;
*((int32_t *)&v->value) = atoi((char *)v->value); INT(v) = atoi(STR(v));
break; break;
case INTEGER: case INTEGER:
break; break;
case FLOAT: case FLOAT:
v->valtype = INTEGER; v->valtype = INTEGER;
*((int32_t *)&v->value) = (int32_t)*((float *)&v->value); INT(v) = (int32_t)FLOAT(v);
break; break;
case FUNC: case FUNC:
break; break;
@ -373,11 +388,11 @@ variable *itofloat(variable *v)
switch (v->valtype) { switch (v->valtype) {
case STRING: case STRING:
v->valtype = FLOAT; v->valtype = FLOAT;
*((float *)&v->value) = strtof((char *)v->value, 0); FLOAT(v) = strtof(STR(v), 0);
break; break;
case INTEGER: case INTEGER:
v->valtype = FLOAT; v->valtype = FLOAT;
*((float *)&v->value) = (float)*((int32_t *)&v->value); FLOAT(v) = (float)INT(v);
break; break;
case FLOAT: case FLOAT:
break; break;
@ -408,10 +423,14 @@ float iget_float(interpreter *, const char *)
void ifunc_set(interpreter *it) void ifunc_set(interpreter *it)
{ {
char *v = igetarg_string(it, 1); if (it->stidx != 2)
if (v == 0)
return; return;
inew_string(it, interpreter_get_name(it, it->stack[0]), v);
variable *n = (variable *)it->stack[0];
variable *v = (variable *)it->stack[1];
n->valtype = v->valtype;
n->value = v->value;
} }
/** /**
@ -420,15 +439,79 @@ void ifunc_set(interpreter *it)
void iop_add(variable *r, variable *a, variable *b) void iop_add(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) + INT(b);
} else {
itofloat(a); itofloat(a);
itofloat(b); itofloat(b);
*((float *)&r->value) = *((float *)&a->value) + *((float *)&b->value); FLOAT(r) = FLOAT(a) + FLOAT(b);
}
} }
void iop_sub(variable *r, variable *a, variable *b) void iop_sub(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) - INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) - FLOAT(b);
}
}
void iop_mult(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) * INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) * FLOAT(b);
}
}
void iop_div(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) / INT(b);
} else {
itofloat(a); itofloat(a);
itofloat(b); itofloat(b);
*((float *)r->value) = *((float *)&a->value) - *((float *)&b->value); FLOAT(r) = FLOAT(a) / FLOAT(b);
}
}
void iop_and(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) & INT(b);
}
} }
void iop_or(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) | INT(b);
}
}
void iop_xor(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) ^ INT(b);
}
}
void iop_shr(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) >> INT(b);
}
}
void iop_shl(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) << INT(b);
}
}

@ -4,7 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
void test(interpreter *it) void s_put(interpreter *it)
{ {
char *s = igetarg_string(it, 0); char *s = igetarg_string(it, 0);
if (s == 0) if (s == 0)
@ -12,6 +12,30 @@ void test(interpreter *it)
printf("%s\n", s); printf("%s\n", s);
} }
void s_type(interpreter *it)
{
if (it->stidx != 1)
return;
variable *v = (variable *)it->stack[0];
switch (v->valtype) {
case STRING:
puts("string");
break;
case INTEGER:
puts("integer");
break;
case FLOAT:
puts("float");
break;
case FUNC:
puts(v->value == 0 ? "undefined" : "func" );
break;
default:
puts("unknown");
break;
}
}
void quit(interpreter *it) void quit(interpreter *it)
{ {
(void)it; (void)it;
@ -23,9 +47,9 @@ int main()
interpreter interp; interpreter interp;
iinit(&interp); iinit(&interp);
inew_integer(&interp, "answer", 42); inew_cfunc(&interp, "put", s_put);
inew_cfunc(&interp, "put", test); inew_cfunc(&interp, "tp", s_type);
inew_cfunc(&interp, "exit", quit); inew_cfunc(&interp, "q", quit);
char *line = 0; char *line = 0;

Loading…
Cancel
Save