big changes; no ints; things work better

master
Clyne Sullivan 7 years ago
parent 0fb67b8d66
commit 952cb2d6db

@ -7,13 +7,17 @@ CFLAGS = -Wall -Wextra -Werror -pedantic \
-Wno-discarded-qualifiers \ -Wno-discarded-qualifiers \
-I. -fsigned-char -fno-builtin -ggdb -I. -fsigned-char -fno-builtin -ggdb
all: FILES = $(wildcard *.c)
$(CC) $(CFLAGS) -c shelpers.c OUTFILES = $(patsubst %.c, %.o, $(FILES))
$(CC) $(CFLAGS) -c parser.c
$(CC) $(CFLAGS) -c builtins.c all: $(OUTFILES)
$(CC) $(CFLAGS) -c stack.c @#$(CC) $(CFLAGS) *.o -o shell
$(CC) $(CFLAGS) -c ops.c @$(AR) r libinterp.a *.o
$(CC) $(CFLAGS) -c variable.c
$(AR) r libinterp.a *.o clean:
@rm -f *.o @echo " CLEAN"
#$(CC) $(CFLAGS) shell.c *.o -o shell @rm -f *.o shell libinterp.a
%.o: %.c
@echo " CC " $<
@$(CC) $(CFLAGS) -c $< -o $@

@ -3,9 +3,7 @@
#include "shelpers.h" #include "shelpers.h"
#include <memory.h> #include <memory.h>
#include <string.h>
extern char *str_func;
extern char *str_undef;
int ifunc_set(interpreter *it); int ifunc_set(interpreter *it);
int ifunc_label(interpreter *it); int ifunc_label(interpreter *it);
@ -42,11 +40,10 @@ int ifunc_set(interpreter *it)
if (n == 0) if (n == 0)
return -1; return -1;
if (n->valtype == STRING)
free((void *)n->value.p);
n->valtype = v->valtype; n->valtype = v->valtype;
n->value = v->value; n->value.p = v->value.p;
if (n->svalue != 0 && n->svalue != str_func && n->svalue != str_undef)
free(n->svalue);
n->svalue = strclone(v->svalue);
return 0; return 0;
} }
@ -58,15 +55,14 @@ int ifunc_label(interpreter *it)
return -1; return -1;
n->valtype = FUNC; n->valtype = FUNC;
n->value = it->lnidx; n->value.p = it->lnidx;
n->svalue = str_func;
iskip(it); iskip(it);
return 0; return 0;
} }
int ifunc_if(interpreter *it) int ifunc_if(interpreter *it)
{ {
int v = igetarg_integer(it, 0); int v = igetarg(it, 0)->value.p;
if (v == 0) if (v == 0)
iskip(it); iskip(it);
void *tmp = ipop(it); void *tmp = ipop(it);
@ -94,7 +90,7 @@ int ifunc_do(interpreter *it)
int ifunc_while(interpreter *it) int ifunc_while(interpreter *it)
{ {
int c = igetarg_integer(it, 0); int c = igetarg(it, 0)->value.p;
ipop(it); ipop(it);
int nidx = (int)ipop(it); int nidx = (int)ipop(it);
if (c != 0) { if (c != 0) {
@ -108,26 +104,21 @@ int ifunc_while(interpreter *it)
void iret(interpreter *it, variable *v) void iret(interpreter *it, variable *v)
{ {
switch (v->valtype) { switch (v->valtype) {
case INTEGER: case NUMBER:
inew_integer(it, "RET", INT(v)); inew_number(it, "RET", v->value.f);
break;
case FLOAT:
inew_float(it, "RET", FLOAT(v));
break; break;
case STRING: case STRING:
inew_string(it, "RET", v->svalue); inew_string(it, "RET", (char *)v->value.p);
break; break;
default: default:
return; return;
break; break;
} }
if (it->ret != 0) { if (it->ret != 0) {
if (it->ret->valtype == STRING && it->ret->value.p != 0)
free((void *)it->ret->value.p);
it->ret->valtype = v->valtype; it->ret->valtype = v->valtype;
it->ret->value = v->value; it->ret->value.p = v->value.p;
char *s = it->ret->svalue;
if (s != 0 && s != str_undef)
free(s);
it->ret->svalue = strclone(v->svalue);
it->ret = 0; it->ret = 0;
} }
} }

@ -1,225 +0,0 @@
#include <parser.h>
#include <stdbool.h>
#include <stdlib.h>
static const char *interpreter_operators = "=(";
bool strcmp(const char *a, const char *b)
{
int i = 0;
for (; a[i] == b[i] && a[i] != '\0'; i++);
return a[i] == b[i];
}
bool strncmp(const char *a, const char *b, int count)
{
int i = 0;
for (; a[i] == b[i] && i < count; i++);
return i == count;
}
uint8_t isalpha(char c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
uint8_t isnum(char c)
{
return (c >= '0' && c <= '9');
}
uint8_t isname(char c)
{
return isalpha(c) || isnum(c);
}
uint8_t isspace(char c)
{
return (c == ' ' || c == '\t' || c == '\n');
}
uint8_t isoper(char c)
{
for (uint8_t i = 0; i < sizeof(interpreter_operators); i++) {
if (c == interpreter_operators[i])
return 1;
}
return 0;
}
void interpreter_init(interpreter *interp)
{
interp->status = READY;
interp->vcount = 0;
interp->vars = (variable *)calloc(32, sizeof(variable));
interp->names = (char **)calloc(32, sizeof(char *));
interp->stack = (stack_t *)calloc(64, sizeof(stack_t));
}
void interpreter_define_value(interpreter *interp, const char *name, int32_t value)
{
interp->names[interp->vcount] = (char *)name;
interp->vars[interp->vcount].nameidx = interp->vcount;
interp->vars[interp->vcount].type = VALUE;
interp->vars[interp->vcount].value = (uint32_t)value;
interp->vcount++;
}
void interpreter_define_cfunc(interpreter *interp, const char *name, func_t addr)
{
interp->names[interp->vcount] = (char *)name;
interp->vars[interp->vcount].nameidx = interp->vcount;
interp->vars[interp->vcount].type = CFUNCTION;
interp->vars[interp->vcount].value = (uint32_t)addr;
interp->vcount++;
}
int32_t interpreter_get_value(interpreter *interp, const char *name)
{
for (uint16_t i = 0; i < interp->vcount; i++) {
if (!strcmp(interp->names[i], name))
return (int32_t)interp->vars[i].value;
}
return 0;
}
/**
* doline section
*/
bool namencmp(const char *name, const char *s)
{
uint16_t i;
for (i = 0; name[i] == s[i] && s[i] != '\0'; i++);
return (name[i] == '\0' && !isname(s[i]));
}
uint16_t spacecount(const char *s)
{
uint16_t i;
for (i = 0; isspace(s[i]); i++);
return i;
}
char *copystr(const char *s, char end)
{
uint16_t len = 0;
while (s[len++] != end);
char *buf = (char *)malloc(len);
for (uint16_t i = 0; i < len; i++)
buf[i] = s[i];
return buf;
}
char *copysubstr(const char *s, int end)
{
char *buf = (char *)malloc(end);
for (uint16_t i = 0; i < end; i++)
buf[i] = s[i];
return buf;
}
variable *interpreter_getvar(interpreter *interp, const char *line)
{
for (uint16_t i = 0; i < interp->vcount; i++) {
if (namencmp(interp->names[i], line))
return &interp->vars[i];
}
return 0;
}
int interpreter_doline(interpreter *interp, const char *line)
{
variable *bits[16];
uint16_t offset = 0, boffset = 0;
// check for var/func set or usage
int end;
getvar:
for (end = 0; isname(line[end]); end++);
variable *var = interpreter_getvar(interp, line);
if (var != 0) {
bits[boffset++] = var;
} else {
// defining new variable
interpreter_define_value(interp, copysubstr(line, end), 0);
goto getvar; // try again
}
// skip whitespace/name
offset += end;
offset += spacecount(line + offset);
if (boffset == 0 && line[offset] != '=')
return -1; // variable not found
// find operator
if (line[offset] == '\0') {
// print value
return -99;
} else if (line[offset] == '=') {
// assignment/expression
offset++;
offset += spacecount(line + offset);
bits[0]->value = (uint32_t)copystr(line + offset, '\0');
} else if (line[offset] == '(') {
// function call
offset++;
if (bits[0]->type != FUNCTION && bits[0]->type != CFUNCTION)
return -2;
offset += spacecount(line + offset);
// collect arg offsets
uint16_t offsets[8];
uint8_t ooffset = 0;
while (line[offset] != ')' && line[offset] != '\0') {
offsets[ooffset] = offset;
offset += spacecount(line + offset);
uint8_t isvn = 1;
do {
if (line[offset] == ' ' || line[offset] == '\t') {
offset += spacecount(line + offset);
isvn = 0;
}
if (line[offset] == ',') {
offset++;
ooffset++;
break;
} else if (line[offset] == ')') {
ooffset++;
break;
} else if (isvn == 0) {
return -3;
}
} while (++offset);
}
// populate stack
for (uint8_t i = 0; i < ooffset; i++) {
uint16_t j;
for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' &&
line[j] != ',' && line[j] != ')'; j++);
j -= offsets[i];
variable *var = interpreter_getvar(interp, line + offsets[i]);
if (var != 0)
interp->stack[i] = copystr((char *)var->value, '\0');
else
interp->stack[i] = copysubstr(line + offsets[i], j);
}
((func_t)bits[0]->value)(interp->stack);
} else {
return -2; // invalid operation
}
return 0;
}

@ -1,31 +0,0 @@
#ifndef PARSER_H_
#define PARSER_H_
#include <variable.h>
typedef void *stack_t;
typedef struct {
uint16_t status;
uint16_t vcount;
variable *vars;
char **names;
stack_t *stack;
} interpreter;
enum status {
READY = 0
};
typedef void (*func_t)(stack_t *);
void interpreter_init(interpreter *);
void interpreter_define_value(interpreter *, const char *, int32_t);
void interpreter_define_cfunc(interpreter *, const char *, func_t);
int32_t interpreter_get_value(interpreter *, const char *);
int interpreter_doline(interpreter *, const char *);
#endif // PARSER_H_

@ -1,24 +0,0 @@
#ifndef TOKEN_H_
#define TOKEN_H_
#include <stdint.h>
typedef struct {
uint16_t nameidx;
uint8_t type;
uint8_t info;
uint32_t value;
} variable;
#define INFO_ARGS(x) ((x) & 0x07)
#define INFO_RET (1 << 3)
enum vartype {
VALUE = 0,
VARIABLE,
OPERATOR,
FUNCTION,
CFUNCTION
};
#endif // TOKEN_H_

87
ops.c

@ -32,136 +32,81 @@ operation_t iopfuncs[IOPS_COUNT] = {
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) { r->value.f = a->value.f + b->value.f;
INT(r) = INT(a) + INT(b);
} else {
itofloat(a);
itofloat(b);
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) { r->value.f = a->value.f - b->value.f;
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) void iop_mult(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = a->value.f * b->value.f;
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) void iop_div(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = a->value.f / b->value.f;
INT(r) = INT(a) / INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) / FLOAT(b);
}
} }
void iop_and(variable *r, variable *a, variable *b) void iop_and(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = (float)((int)a->value.f & (int)b->value.f);
INT(r) = INT(a) & INT(b);
}
} }
void iop_or(variable *r, variable *a, variable *b) void iop_or(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = (float)((int)a->value.f | (int)b->value.f);
INT(r) = INT(a) | INT(b);
}
} }
void iop_xor(variable *r, variable *a, variable *b) void iop_xor(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = (float)((int)a->value.f ^ (int)b->value.f);
INT(r) = INT(a) ^ INT(b);
}
} }
void iop_shr(variable *r, variable *a, variable *b) void iop_shr(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = (float)((int)a->value.f >> (int)b->value.f);
INT(r) = INT(a) >> INT(b);
}
} }
void iop_shl(variable *r, variable *a, variable *b) void iop_shl(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) { r->value.f = (float)((int)a->value.f << (int)b->value.f);
INT(r) = INT(a) << INT(b);
}
} }
void iop_eq(variable *r, variable *a, variable *b) void iop_eq(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = a->value.f == b->value.f;
INT(r) = INT(a) == INT(b);
else
INT(r) = FLOAT(a) == FLOAT(b);
} }
void iop_lt(variable *r, variable *a, variable *b) void iop_lt(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = a->value.f < b->value.f;
INT(r) = INT(a) < INT(b);
else
INT(r) = FLOAT(a) < FLOAT(b);
} }
void iop_gt(variable *r, variable *a, variable *b) void iop_gt(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = a->value.f > b->value.f;
INT(r) = INT(a) > INT(b);
else
INT(r) = FLOAT(a) > FLOAT(b);
} }
void iop_lte(variable *r, variable *a, variable *b) void iop_lte(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = a->value.f <= b->value.f;
INT(r) = INT(a) <= INT(b);
else
INT(r) = FLOAT(a) <= FLOAT(b);
} }
void iop_gte(variable *r, variable *a, variable *b) void iop_gte(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = a->value.f >= b->value.f;
INT(r) = INT(a) >= INT(b);
else
INT(r) = FLOAT(a) >= FLOAT(b);
} }
void iop_ne(variable *r, variable *a, variable *b) void iop_ne(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = a->value.f != b->value.f;
INT(r) = INT(a) != INT(b);
else
INT(r) = FLOAT(a) != FLOAT(b);
} }
void iop_mod(variable *r, variable *a, variable *b) void iop_mod(variable *r, variable *a, variable *b)
{ {
if (a->valtype == INTEGER && b->valtype == INTEGER) r->value.f = (float)((int)a->value.f % (int)b->value.f);
INT(r) = INT(a) % INT(b);
else
INT(r) = 0;
} }

@ -17,9 +17,6 @@
extern int atoi(const char *); extern int atoi(const char *);
extern float strtof(const char *, char **); extern float strtof(const char *, char **);
char *str_func = "(func)";
char *str_undef = "(undefined)";
void iinit(interpreter *interp) void iinit(interpreter *interp)
{ {
interp->vars = (variable *)calloc(MAX_VARS, sizeof(variable)); interp->vars = (variable *)calloc(MAX_VARS, sizeof(variable));
@ -39,14 +36,30 @@ void iend(interpreter *it)
{ {
for (unsigned int i = 0; i < MAX_VARS; i++) { for (unsigned int i = 0; i < MAX_VARS; i++) {
if (it->vars[i].used == 1) { if (it->vars[i].used == 1) {
//char *s = it->vars[i].svalue; if (it->vars[i].valtype == STRING ||
//if (s != 0 && s != str_undef && s != str_func) it->vars[i].valtype == EXPR)
// free(s); free((void *)it->vars[i].value.p);
free(it->vnames[i]); free(it->vnames[i]);
} }
} }
for (unsigned int i = 0; i < MAX_LINES; i++) for (unsigned int i = 0; i < MAX_LINES; i++) {
if (it->lines[i] != 0) {
for (unsigned int j = 0; (int32_t)it->lines[i][j] > 0; j++) {
switch (it->lines[i][j]->valtype) {
case STRING:
case EXPR:
free((void *)it->lines[i][j]->value.p);
free(it->lines[i][j]);
break;
case NUMBER:
if (!it->lines[i][j]->used)
free(it->lines[i][j]);
break;
}
}
}
free(it->lines[i]); free(it->lines[i]);
}
free(it->vars); free(it->vars);
free(it->vnames); free(it->vnames);
free(it->stack); free(it->stack);
@ -63,14 +76,9 @@ variable *interpreter_get_variable(interpreter *interp, const char *name)
{ {
for (uint32_t i = 0; i < MAX_VARS; i++) { for (uint32_t i = 0; i < MAX_VARS; i++) {
if (!interp->vars[i].used) { if (!interp->vars[i].used) {
variable *v = &interp->vars[i]; variable *v = make_vars(&interp->vars[i], 0);
v->used = 1; v->used = 1;
v->fromc = 0; interp->vnames[i] = strclone(name);
v->valtype = STRING;
v->value = 0;
v->svalue = str_undef;
char *s = strclone(name);
interp->vnames[i] = s;
return v; return v;
} else if (interp->vnames[i] != 0 && !strcmp(interp->vnames[i], name)) { } else if (interp->vnames[i] != 0 && !strcmp(interp->vnames[i], name)) {
return &interp->vars[i]; return &interp->vars[i];
@ -85,51 +93,40 @@ char *interpreter_get_name(interpreter *interp, variable *v)
if (v == &interp->vars[i]) if (v == &interp->vars[i])
return interp->vnames[i]; return interp->vnames[i];
} }
return str_undef; return "(undefined)";
} }
variable *inew_string(interpreter *interp, const char *name, char *value) variable *inew_string(interpreter *interp, const char *name, const 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;
INT(v) = 0; if (v->value.p != 0)
v->svalue = strclone(value); free((void *)v->value.p);
} v->value.p = (uint32_t)strclone(value);
return v;
}
variable *inew_integer(interpreter *interp, const char *name, int32_t value)
{
variable *v = interpreter_get_variable(interp, name);
if (v != 0) {
v->valtype = INTEGER;
INT(v) = value;
isetstr(v);
} }
return v; return v;
} }
variable *inew_float(interpreter *interp, const char *name, float value) variable *inew_number(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 = NUMBER;
FLOAT(v) = value; v->value.f = value;
fsetstr(v);
} }
return v; return v;
} }
void inew_cfunc(interpreter *interp, const char *name, func_t func) variable *inew_cfunc(interpreter *interp, const char *name, func_t func)
{ {
variable *v = interpreter_get_variable(interp, name); variable *v = interpreter_get_variable(interp, name);
if (v != 0) { if (v != 0) {
v->fromc = 1; v->fromc = 1;
v->valtype = FUNC; v->valtype = FUNC;
v->value = (uint32_t)func; v->value.p = (uint32_t)func;
v->svalue = str_func;
} }
return v;
} }
variable *make_var(interpreter *interp, const char *line, uint32_t *next) variable *make_var(interpreter *interp, const char *line, uint32_t *next)
@ -142,7 +139,10 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
return 0; return 0;
// TODO string breakdown // TODO string breakdown
*next = end + 1; *next = end + 1;
return vmake(0, STRING, strnclone(line + 1, end - 1)); char *str = strnclone(line + 1, end - 1);
variable *v = make_vars(0, str);
free(str);
return v;
} }
end++; end++;
} }
@ -152,8 +152,10 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
if (eot(line[end])) if (eot(line[end]))
return 0; return 0;
*next = end + 1; *next = end + 1;
return vmake(0, EXPR, strnclone(line + 1, end)); char *expr = strnclone(line + 1, end);
//return idoexpr(interp, line + 1); variable *v = make_vare(0, expr);
free(expr);
return v;
} else if (isalpha(line[0])) { // variable/func } else if (isalpha(line[0])) { // variable/func
uint32_t end = 1; uint32_t end = 1;
for (; isalnum(line[end]); end++); for (; isalnum(line[end]); end++);
@ -186,9 +188,9 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
copy[end] = '\0'; copy[end] = '\0';
variable *v; variable *v;
if (dec) if (dec)
v = vmakef(strtof(copy, 0)); v = make_varn(0, strtof(copy, 0));
else else
v = vmake(0, INTEGER, (void *)atoi(copy)); v = make_varn(0, (float)atoi(copy));
free(copy); free(copy);
*next = end; *next = end;
return v; return v;
@ -246,7 +248,7 @@ int idoline(interpreter *interp, const char *line)
goto fail; goto fail;
} }
if (ops[0]->fromc && ops[0]->value == 0) { if (ops[0]->fromc && ops[0]->value.p == 0) {
fret = -3; fret = -3;
goto fail; goto fail;
} }
@ -256,14 +258,14 @@ int idoline(interpreter *interp, const char *line)
loop: loop:
for (uint8_t i = 0; i < IUP_COUNT; i++) { for (uint8_t i = 0; i < IUP_COUNT; i++) {
if (interp->lines[interp->lnidx][0]->value if (interp->lines[interp->lnidx][0]->value.p
== (uint32_t)indent_up[i]) { == (uint32_t)indent_up[i]) {
interp->indent++; interp->indent++;
goto cont; goto cont;
} }
} }
for (uint8_t i = 0; i < IDOWN_COUNT; i++) { for (uint8_t i = 0; i < IDOWN_COUNT; i++) {
if (interp->lines[interp->lnidx][0]->value if (interp->lines[interp->lnidx][0]->value.p
== (uint32_t)indent_down[i]) { == (uint32_t)indent_down[i]) {
if (--interp->indent < 0) { if (--interp->indent < 0) {
fret = -6; fret = -6;
@ -290,7 +292,7 @@ cont:
ooffset = 1; ooffset = 1;
for (; ops[ooffset] != 0 && ops[ooffset] != (void *)-1; ooffset++) { for (; ops[ooffset] != 0 && ops[ooffset] != (void *)-1; ooffset++) {
if (ops[ooffset]->valtype == EXPR) { if (ops[ooffset]->valtype == EXPR) {
char *expr = strclone(ops[ooffset]->svalue); char *expr = strclone((char *)ops[ooffset]->value.p);
variable *r = idoexpr(interp, expr); variable *r = idoexpr(interp, expr);
ops[ooffset] = r; ops[ooffset] = r;
free(expr); free(expr);
@ -304,7 +306,7 @@ cont:
for (uint32_t i = ooffset; --i > 0;) for (uint32_t i = ooffset; --i > 0;)
ipush(interp, ops[i]); ipush(interp, ops[i]);
int ret = ((func_t)ops[0]->value)(interp); int ret = ((func_t)ops[0]->value.p)(interp);
if (ret != 0) if (ret != 0)
return ret; return ret;
ipopm(interp, ooffset - 1); ipopm(interp, ooffset - 1);
@ -314,13 +316,10 @@ cont:
snprintf(an, 6, "arg%d", (int)(i - 1)); snprintf(an, 6, "arg%d", (int)(i - 1));
switch (ops[i]->valtype) { switch (ops[i]->valtype) {
case STRING: case STRING:
inew_string(interp, an, ops[i]->svalue); inew_string(interp, an, (char *)ops[i]->value.p);
break; break;
case INTEGER: case NUMBER:
inew_integer(interp, an, INT(ops[i])); inew_number(interp, an, ops[i]->value.f);
break;
case FLOAT:
inew_float(interp, an, FLOAT(ops[i]));
break; break;
default: default:
break; break;
@ -328,7 +327,7 @@ cont:
} }
ipush(interp, (void *)(interp->lnidx)); ipush(interp, (void *)(interp->lnidx));
interp->lnidx = ops[0]->value; interp->lnidx = ops[0]->value.p;
interp->indent++; interp->indent++;
} }
@ -339,7 +338,8 @@ cont:
for (uint32_t i = 1; i < ooffset; i++) { for (uint32_t i = 1; i < ooffset; i++) {
if (ops[i] != interp->lines[oldLnidx][i]) { if (ops[i] != interp->lines[oldLnidx][i]) {
free(ops[i]->svalue); if (ops[i]->valtype == STRING || ops[i]->valtype == EXPR)
free((void *)ops[i]->value.p);
free(ops[i]); free(ops[i]);
} }
} }
@ -431,20 +431,15 @@ variable *idoexpr(interpreter *interp, const char *line)
// step 2 - do operations // step 2 - do operations
variable *result = (variable *)calloc(1, sizeof(variable)); variable *result = (variable *)calloc(1, sizeof(variable));
result->valtype = ((variable *)ops[0])->valtype; result->valtype = ((variable *)ops[0])->valtype;
result->value = ((variable *)ops[0])->value; result->value.p = ((variable *)ops[0])->value.p;
for (uint32_t i = 1; i < ooffset; i += 2) for (uint32_t i = 1; i < ooffset; i += 2)
iopfuncs[(uint32_t)ops[i] - 1](result, result, ops[i + 1]); iopfuncs[(uint32_t)ops[i] - 1](result, result, ops[i + 1]);
if (result->valtype == INTEGER)
isetstr(result);
else
fsetstr(result);
for (uint32_t i = 0; i < ooffset; i += 2) { for (uint32_t i = 0; i < ooffset; i += 2) {
if (!((variable *)ops[i])->used) { variable *v = (variable *)ops[i];
char *s = ((variable *)ops[i])->svalue; if (!v->used) {
if (s != 0 && s != str_undef) if (v->valtype == STRING || v->valtype == EXPR)
free(s); free((void *)v->value.p);
free(ops[i]); free(ops[i]);
} }
} }

@ -26,10 +26,9 @@ void iend(interpreter *it);
void iskip(interpreter *it); void iskip(interpreter *it);
variable *inew_string(interpreter *, const char *, char *); variable *inew_string(interpreter *, const char *, const char *);
variable *inew_integer(interpreter *, const char *, int32_t); variable *inew_number(interpreter *, const char *, float);
variable *inew_float(interpreter *, const char *, float); variable *inew_cfunc(interpreter *, const char *, func_t);
void inew_cfunc(interpreter *, const char *, func_t);
int idoline(interpreter *, const char *); int idoline(interpreter *, const char *);
variable *idoexpr(interpreter *interp, const char *line); variable *idoexpr(interpreter *interp, const char *line);

@ -1,121 +0,0 @@
#include <parser.h>
#include <builtins.h>
#include "stack.h"
#include <memory.h>
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
extern int rand(void);
int s_put(interpreter *it)
{
char *s = igetarg_string(it, 0);
printf("%s", s);
return 0;
}
int s_type(interpreter *it)
{
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("func");
break;
default:
puts("unknown");
break;
}
return 0;
}
int input(interpreter *it)
{
variable *v = igetarg(it, 0);
v->valtype = STRING;
v->svalue = malloc(128);
unsigned int unused;
getline(&v->svalue, &unused, stdin);
*strchr(v->svalue, '\n') = '\0';
return 0;
}
int concat(interpreter *it)
{
variable *v = igetarg(it, 0);
char *s = igetarg_string(it, 1);
char *new = malloc(strlen(v->svalue) + strlen(s) + 1);
strcpy(new, v->svalue);
strcpy(new + strlen(v->svalue), s);
new[strlen(v->svalue) + strlen(s)] = 0;
v->svalue = new;
return 0;
}
int script_rand(interpreter *it)
{
static variable v;
v.valtype = INTEGER;
unsigned int mod = igetarg_integer(it, 0);
unsigned int val = rand();
INT(&v) = val % mod;
isetstr(&v);
iret(it, &v);
return 0;
}
int line(interpreter *it)
{
(void)it;
return 0;
}
int main(int argc, char **argv)
{
interpreter interp;
if (argc != 2) {
printf("Usage: %s file\n", argv[0]);
return -1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == 0) {
printf("Could not open file: %s\n", argv[1]);
return -1;
}
iinit(&interp);
inew_cfunc(&interp, "print", s_put);
inew_cfunc(&interp, "tp", s_type);
inew_cfunc(&interp, "gets", input);
inew_cfunc(&interp, "concat", concat);
inew_cfunc(&interp, "rand", script_rand);
inew_cfunc(&interp, "line", line);
char *line = 0;
unsigned int size;
int result;
while (getline(&line, &size, fp) != -1) {
*strchr(line, '\n') = '\0';
result = idoline(&interp, line);
if (result != 0)
printf("Error: %d\n", result);
}
fclose(fp);
iend(&interp);
return 0;
}

@ -20,27 +20,19 @@ variable *igetarg(interpreter *interp, uint32_t index)
return interp->stack[interp->stidx - index - 1]; return interp->stack[interp->stidx - index - 1];
} }
char *igetarg_string(interpreter *interp, uint32_t index) const char *igetarg_string(interpreter *interp, uint32_t index)
{ {
if (index >= interp->stidx) if (index >= interp->stidx)
return 0; return 0;
variable *v = igetarg(interp, index); variable *v = igetarg(interp, index);
return v->svalue; return (const char *)v->value.p;
} }
int igetarg_integer(interpreter *interp, uint32_t index) float igetarg_number(interpreter *interp, uint32_t index)
{ {
if (index >= interp->stidx) if (index >= interp->stidx)
return 0; return 0;
variable *v = igetarg(interp, index); variable *v = igetarg(interp, index);
return INT(itoint(v)); return v->value.f;
}
float igetarg_float(interpreter *interp, uint32_t index)
{
if (index >= interp->stidx)
return 0;
variable *v = igetarg(interp, index);
return FLOAT(itofloat(v));
} }

@ -6,10 +6,11 @@
void ipush(interpreter *it, void *v); void ipush(interpreter *it, void *v);
void *ipop(interpreter *it); void *ipop(interpreter *it);
void ipopm(interpreter *it, uint32_t count); void ipopm(interpreter *it, uint32_t count);
variable *igetarg(interpreter *interp, uint32_t index); variable *igetarg(interpreter *interp, uint32_t index);
char *igetarg_string(interpreter *interp, uint32_t index); const char *igetarg_string(interpreter *interp, uint32_t index);
int igetarg_integer(interpreter *interp, uint32_t index); float igetarg_number(interpreter *interp, uint32_t index);
float igetarg_float(interpreter *interp, uint32_t index);
#define igetarg_integer(i, x) (int)igetarg_number(i, x)
#endif // STACK_H_ #endif // STACK_H_

@ -4,12 +4,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <memory.h>
#include <string.h> #include <string.h>
#include <shelpers.h>
extern int atoi(const char *); extern int atoi(const char *);
extern char *str_undef;
extern char *str_func;
char *fixstring(char *s) char *fixstring(char *s)
{ {
char *n = malloc(strlen(s) + 1); char *n = malloc(strlen(s) + 1);
@ -27,105 +25,47 @@ char *fixstring(char *s)
return n; return n;
} }
variable *vmake(uint8_t fromc, uint8_t valtype, void *value) variable *make_varn(variable *v, float value)
{ {
variable *v = (variable *)malloc(sizeof(variable)); if (v == 0)
v = (variable *)malloc(sizeof(variable));
v->used = 0; v->used = 0;
v->fromc = fromc; v->fromc = 0;
v->valtype = valtype; v->valtype = NUMBER;
v->value = 0; v->value.f = value;
v->svalue = 0;
switch (valtype) {
case STRING:
v->svalue = fixstring(value);
free(value);
break;
case INTEGER:
INT(v) = (int32_t)value;
isetstr(v);
break;
case FUNC:
v->value = (uint32_t)value;
v->svalue = str_func;
break;
case EXPR:
v->svalue = value;
break;
}
return v; return v;
} }
variable *vmakef(float value) variable *make_vars(variable *v, const char *value)
{ {
variable *v = (variable *)malloc(sizeof(variable)); if (v == 0)
v = (variable *)malloc(sizeof(variable));
v->used = 0; v->used = 0;
v->fromc = 0; v->fromc = 0;
v->valtype = FLOAT; v->valtype = STRING;
FLOAT(v) = value; v->value.p = (value != 0) ? (uint32_t)fixstring(value) : 0;
fsetstr(v);
return v; return v;
} }
void fsetstr(variable *f) variable *make_varf(variable *v, uint8_t fromc, uint32_t func)
{ {
if (f->svalue == 0 || f->svalue == str_undef) if (v == 0)
f->svalue = (char *)malloc(32); v = (variable *)malloc(sizeof(variable));
snprintf(f->svalue, 32, "%f", FLOAT(f)); v->used = 0;
} v->fromc = fromc;
v->valtype = FUNC;
void isetstr(variable *i) v->value.p = func;
{
if (i->svalue == 0 || i->svalue == str_undef)
i->svalue = (char *)malloc(32);
snprintf(i->svalue, 32, "%d", (int)INT(i));
}
variable *itostring(variable *v)
{
switch (v->valtype) {
case INTEGER:
v->valtype = STRING;
isetstr(v);
break;
case FLOAT:
v->valtype = STRING;
fsetstr(v);
break;
}
return v;
}
variable *itoint(variable *v)
{
switch (v->valtype) {
case STRING:
v->valtype = INTEGER;
INT(v) = atoi(v->svalue);
isetstr(v);
break;
case FLOAT:
v->valtype = INTEGER;
INT(v) = (int32_t)FLOAT(v);
isetstr(v);
break;
}
return v; return v;
} }
variable *itofloat(variable *v) variable *make_vare(variable *v, const char *expr)
{ {
switch (v->valtype) { if (v == 0)
case STRING: v = (variable *)malloc(sizeof(variable));
v->valtype = FLOAT; v->used = 0;
FLOAT(v) = strtof(v->svalue, 0); v->fromc = 0;
fsetstr(v); v->valtype = EXPR;
break; v->value.p = (uint32_t)strclone(expr);
case INTEGER:
v->valtype = FLOAT;
FLOAT(v) = (float)INT(v);
fsetstr(v);
break;
}
return v; return v;
} }

@ -3,33 +3,26 @@
#include <stdint.h> #include <stdint.h>
#define INT(v) (*((int32_t *)&(v)->value))
#define FLOAT(v) (*((float *)&(v)->value))
typedef struct { typedef struct {
uint8_t used :1; uint8_t used :1;
uint8_t fromc :1; uint8_t fromc :1;
uint8_t valtype :4; uint8_t valtype :4;
uint32_t value; union {
char *svalue; float f;
uint32_t p;
} value;
} variable; } variable;
enum valtype { enum valtype {
STRING = 0, STRING = 0,
INTEGER, NUMBER,
FLOAT,
FUNC, FUNC,
EXPR EXPR
}; };
variable *vmake(uint8_t fromc, uint8_t valtype, void *value); variable *make_varn(variable *v, float value);
variable *vmakef(float value); variable *make_vars(variable *v, const char *s);
variable *make_varf(variable *v, uint8_t fromc, uint32_t func);
void isetstr(variable *i); variable *make_vare(variable *v, const char *e);
void fsetstr(variable *f);
variable *itostring(variable *v);
variable *itoint(variable *v);
variable *itofloat(variable *v);
#endif // VARIABLE_H_ #endif // VARIABLE_H_

Loading…
Cancel
Save