]> code.bitgloo.com Git - clyne/interpreter.git/commitdiff
big changes; no ints; things work better
authorClyne Sullivan <tullivan99@gmail.com>
Wed, 7 Mar 2018 20:25:07 +0000 (15:25 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Wed, 7 Mar 2018 20:25:07 +0000 (15:25 -0500)
13 files changed:
Makefile
builtins.c
old/parser.c [deleted file]
old/parser.h [deleted file]
old/variable.h [deleted file]
ops.c
parser.c
parser.h
shell.c [deleted file]
stack.c
stack.h
variable.c
variable.h

index 8bca3c1cb3be9950562593b24b310299cd29ac40..b4a7bfce5dbd29e1ed381356f6d2a93383f1a623 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,13 +7,17 @@ CFLAGS = -Wall -Wextra -Werror -pedantic \
        -Wno-discarded-qualifiers \
        -I. -fsigned-char -fno-builtin -ggdb
 
-all:
-       $(CC) $(CFLAGS) -c shelpers.c
-       $(CC) $(CFLAGS) -c parser.c
-       $(CC) $(CFLAGS) -c builtins.c
-       $(CC) $(CFLAGS) -c stack.c
-       $(CC) $(CFLAGS) -c ops.c
-       $(CC) $(CFLAGS) -c variable.c
-       $(AR) r libinterp.a *.o
-       @rm -f *.o
-       #$(CC) $(CFLAGS) shell.c *.o -o shell
+FILES = $(wildcard *.c)
+OUTFILES = $(patsubst %.c, %.o, $(FILES))
+
+all: $(OUTFILES)
+       @#$(CC) $(CFLAGS) *.o -o shell
+       @$(AR) r libinterp.a *.o
+
+clean:
+       @echo "  CLEAN"
+       @rm -f *.o shell libinterp.a
+
+%.o: %.c
+       @echo "  CC     " $<
+       @$(CC) $(CFLAGS) -c $< -o $@
index b2295c5069a571dac126d26a36ff02bab204afc5..7dba1aa2c4748cfd142dbf267f52e155794384ad 100644 (file)
@@ -3,9 +3,7 @@
 #include "shelpers.h"
 
 #include <memory.h>
-
-extern char *str_func;
-extern char *str_undef;
+#include <string.h>
 
 int ifunc_set(interpreter *it);
 int ifunc_label(interpreter *it);
@@ -42,11 +40,10 @@ int ifunc_set(interpreter *it)
        if (n == 0)
                return -1;
 
+       if (n->valtype == STRING)
+               free((void *)n->value.p);
        n->valtype = v->valtype;
-       n->value = v->value;
-       if (n->svalue != 0 && n->svalue != str_func && n->svalue != str_undef)
-               free(n->svalue);
-       n->svalue = strclone(v->svalue);
+       n->value.p = v->value.p;
        return 0;
 }
 
@@ -58,15 +55,14 @@ int ifunc_label(interpreter *it)
                return -1;
 
        n->valtype = FUNC;
-       n->value = it->lnidx;
-       n->svalue = str_func;
+       n->value.p = it->lnidx;
        iskip(it);
        return 0;
 }
 
 int ifunc_if(interpreter *it)
 {
-       int v = igetarg_integer(it, 0);
+       int v = igetarg(it, 0)->value.p;
        if (v == 0)
                iskip(it);
        void *tmp = ipop(it);
@@ -94,7 +90,7 @@ int ifunc_do(interpreter *it)
 
 int ifunc_while(interpreter *it)
 {
-       int c = igetarg_integer(it, 0);
+       int c = igetarg(it, 0)->value.p;
        ipop(it);
        int nidx = (int)ipop(it);
        if (c != 0) {
@@ -108,26 +104,21 @@ int ifunc_while(interpreter *it)
 void iret(interpreter *it, variable *v)
 {
        switch (v->valtype) {
-       case INTEGER:
-               inew_integer(it, "RET", INT(v));
-               break;
-       case FLOAT:
-               inew_float(it, "RET", FLOAT(v));
+       case NUMBER:
+               inew_number(it, "RET", v->value.f);
                break;
        case STRING:
-               inew_string(it, "RET", v->svalue);
+               inew_string(it, "RET", (char *)v->value.p);
                break;
        default:
                return;
                break;
        }
        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->value = v->value;
-               char *s = it->ret->svalue;
-               if (s != 0 && s != str_undef)
-                       free(s);
-               it->ret->svalue = strclone(v->svalue);
+               it->ret->value.p = v->value.p;
                it->ret = 0;
        }
 }
diff --git a/old/parser.c b/old/parser.c
deleted file mode 100644 (file)
index 5e94e79..0000000
+++ /dev/null
@@ -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;
-}
-
diff --git a/old/parser.h b/old/parser.h
deleted file mode 100644 (file)
index c6a2b17..0000000
+++ /dev/null
@@ -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_
diff --git a/old/variable.h b/old/variable.h
deleted file mode 100644 (file)
index fd84a6e..0000000
+++ /dev/null
@@ -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_
diff --git a/ops.c b/ops.c
index 34e7986aabe15937db79779f7ee7c4c45af4f61e..cb07093d3c5ae8293639129593f7eaccf6e93d02 100644 (file)
--- a/ops.c
+++ b/ops.c
@@ -32,136 +32,81 @@ operation_t iopfuncs[IOPS_COUNT] = {
 
 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(b);
-               FLOAT(r) = FLOAT(a) + FLOAT(b);
-       }
+       r->value.f = a->value.f + b->value.f;
 }
 
 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);
-       }
+       r->value.f = a->value.f - b->value.f;
 }
 
 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);
-       }
+       r->value.f = a->value.f * b->value.f;
 }
 
 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(b);
-               FLOAT(r) = FLOAT(a) / FLOAT(b);
-       }
+       r->value.f = a->value.f / b->value.f;
 }
 
 void iop_and(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER) {
-               INT(r) = INT(a) & INT(b);
-       }
+       r->value.f = (float)((int)a->value.f & (int)b->value.f);
 }
 
 void iop_or(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER) {
-               INT(r) = INT(a) | INT(b);
-       }
+       r->value.f = (float)((int)a->value.f | (int)b->value.f);
 }
 
 void iop_xor(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER) {
-               INT(r) = INT(a) ^ INT(b);
-       }
+       r->value.f = (float)((int)a->value.f ^ (int)b->value.f);
 }
 
 void iop_shr(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER) {
-               INT(r) = INT(a) >> INT(b);
-       }
+       r->value.f = (float)((int)a->value.f >> (int)b->value.f);
 }
 
 void iop_shl(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER) {
-               INT(r) = INT(a) << INT(b);
-       }
+       r->value.f = (float)((int)a->value.f << (int)b->value.f);
 }
 
 void iop_eq(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) == INT(b);
-       else
-               INT(r) = FLOAT(a) == FLOAT(b);
+       r->value.f = a->value.f == b->value.f;
 }
 
 void iop_lt(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) < INT(b);
-       else
-               INT(r) = FLOAT(a) < FLOAT(b);
+       r->value.f = a->value.f < b->value.f;
 }
 
 void iop_gt(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) > INT(b);
-       else
-               INT(r) = FLOAT(a) > FLOAT(b);
+       r->value.f = a->value.f > b->value.f;
 }
 
 void iop_lte(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) <= INT(b);
-       else
-               INT(r) = FLOAT(a) <= FLOAT(b);
+       r->value.f = a->value.f <= b->value.f;
 }
 
 void iop_gte(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) >= INT(b);
-       else
-               INT(r) = FLOAT(a) >= FLOAT(b);
+       r->value.f = a->value.f >= b->value.f;
 }
 
 void iop_ne(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) != INT(b);
-       else
-               INT(r) = FLOAT(a) != FLOAT(b);
+       r->value.f = a->value.f != b->value.f;
 }
 
 void iop_mod(variable *r, variable *a, variable *b)
 {
-       if (a->valtype == INTEGER && b->valtype == INTEGER)
-               INT(r) = INT(a) % INT(b);
-       else
-               INT(r) = 0;
+       r->value.f = (float)((int)a->value.f % (int)b->value.f);
 }
 
index 56089982bf43c93522f1605905131728218bb362..3311d5c267cc9344138cfbd2d929f5e6a0041222 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -17,9 +17,6 @@
 extern int atoi(const char *);
 extern float strtof(const char *, char **);
 
-char *str_func = "(func)";
-char *str_undef = "(undefined)";
-
 void iinit(interpreter *interp)
 {
        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++) {
                if (it->vars[i].used == 1) {
-                       //char *s = it->vars[i].svalue;
-                       //if (s != 0 && s != str_undef && s != str_func)
-                       //      free(s);
+                       if (it->vars[i].valtype == STRING ||
+                               it->vars[i].valtype == EXPR)
+                               free((void *)it->vars[i].value.p);
                        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->vars);
        free(it->vnames);
        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++) {
                if (!interp->vars[i].used) {
-                       variable *v = &interp->vars[i];
+                       variable *v = make_vars(&interp->vars[i], 0);
                        v->used = 1;
-                       v->fromc = 0;
-                       v->valtype = STRING;
-                       v->value = 0;
-                       v->svalue = str_undef;
-                       char *s = strclone(name);
-                       interp->vnames[i] = s;
+                       interp->vnames[i] = strclone(name);
                        return v;
                } else if (interp->vnames[i] != 0 && !strcmp(interp->vnames[i], name)) {
                        return &interp->vars[i];
@@ -85,51 +93,40 @@ char *interpreter_get_name(interpreter *interp, variable *v)
                if (v == &interp->vars[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);
        if (v != 0) {
                v->valtype = STRING;
-               INT(v) = 0;
-               v->svalue = 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);
+               if (v->value.p != 0)
+                       free((void *)v->value.p);
+               v->value.p = (uint32_t)strclone(value);
        }
        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);
        if (v != 0) {
-               v->valtype = FLOAT;
-               FLOAT(v) = value;
-               fsetstr(v);
+               v->valtype = NUMBER;
+               v->value.f = value;
        }
        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);
        if (v != 0) {
                v->fromc = 1;
                v->valtype = FUNC;
-               v->value = (uint32_t)func;
-               v->svalue = str_func;
+               v->value.p = (uint32_t)func;
        }
+       return v;
 }
 
 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;
                                // TODO string breakdown
                                *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++;
                }
@@ -152,8 +152,10 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
                if (eot(line[end]))
                        return 0;
                *next = end + 1;
-               return vmake(0, EXPR, strnclone(line + 1, end));
-               //return idoexpr(interp, line + 1);
+               char *expr = strnclone(line + 1, end);
+               variable *v = make_vare(0, expr);
+               free(expr);
+               return v;
        } else if (isalpha(line[0])) { // variable/func
                uint32_t end = 1;
                for (; isalnum(line[end]); end++);
@@ -186,9 +188,9 @@ variable *make_var(interpreter *interp, const char *line, uint32_t *next)
                copy[end] = '\0';
                variable *v;
                if (dec)
-                       v = vmakef(strtof(copy, 0));
+                       v = make_varn(0, strtof(copy, 0));
                else
-                       v = vmake(0, INTEGER, (void *)atoi(copy));
+                       v = make_varn(0, (float)atoi(copy));
                free(copy);
                *next = end;
                return v;
@@ -246,7 +248,7 @@ int idoline(interpreter *interp, const char *line)
                goto fail;
        }
 
-       if (ops[0]->fromc && ops[0]->value == 0) {
+       if (ops[0]->fromc && ops[0]->value.p == 0) {
                fret = -3;
                goto fail;
        }
@@ -256,14 +258,14 @@ int idoline(interpreter *interp, const char *line)
 
 loop:
        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]) {
                        interp->indent++;
                        goto cont;
                }
        }
        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]) {
                        if (--interp->indent < 0) {
                                fret = -6;
@@ -290,7 +292,7 @@ cont:
        ooffset = 1;
        for (; ops[ooffset] != 0 && ops[ooffset] != (void *)-1; ooffset++) {
                if (ops[ooffset]->valtype == EXPR) {
-                       char *expr = strclone(ops[ooffset]->svalue);
+                       char *expr = strclone((char *)ops[ooffset]->value.p);
                        variable *r = idoexpr(interp, expr);
                        ops[ooffset] = r;
                        free(expr);
@@ -304,7 +306,7 @@ cont:
                for (uint32_t i = ooffset; --i > 0;)
                        ipush(interp, ops[i]);
 
-               int ret = ((func_t)ops[0]->value)(interp);
+               int ret = ((func_t)ops[0]->value.p)(interp);
                if (ret != 0)
                        return ret;
                ipopm(interp, ooffset - 1);
@@ -314,13 +316,10 @@ cont:
                        snprintf(an, 6, "arg%d", (int)(i - 1));
                        switch (ops[i]->valtype) {
                        case STRING:
-                               inew_string(interp, an, ops[i]->svalue);
+                               inew_string(interp, an, (char *)ops[i]->value.p);
                                break;
-                       case INTEGER:
-                               inew_integer(interp, an, INT(ops[i]));
-                               break;
-                       case FLOAT:
-                               inew_float(interp, an, FLOAT(ops[i]));
+                       case NUMBER:
+                               inew_number(interp, an, ops[i]->value.f);
                                break;
                        default:
                                break;
@@ -328,7 +327,7 @@ cont:
                }
 
                ipush(interp, (void *)(interp->lnidx));
-               interp->lnidx = ops[0]->value;
+               interp->lnidx = ops[0]->value.p;
                interp->indent++;
        }
 
@@ -339,7 +338,8 @@ cont:
 
        for (uint32_t i = 1; i < ooffset; 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]);
                }
        }
@@ -431,20 +431,15 @@ variable *idoexpr(interpreter *interp, const char *line)
        // step 2 - do operations
        variable *result = (variable *)calloc(1, sizeof(variable));
        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)
                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) {
-               if (!((variable *)ops[i])->used) {
-                       char *s = ((variable *)ops[i])->svalue;
-                       if (s != 0 && s != str_undef)
-                               free(s);
+               variable *v = (variable *)ops[i];
+               if (!v->used) {
+                       if (v->valtype == STRING || v->valtype == EXPR)
+                               free((void *)v->value.p);
                        free(ops[i]);
                }
        }
index 24c2c89fdfc3d7077b9ea69bf7ce47363b742862..1b821cdb6864763abc5c875c29b27cdb21763481 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -26,10 +26,9 @@ void iend(interpreter *it);
 
 void iskip(interpreter *it);
 
-variable *inew_string(interpreter *, const char *, char *);
-variable *inew_integer(interpreter *, const char *, int32_t);
-variable *inew_float(interpreter *, const char *, float);
-void inew_cfunc(interpreter *, const char *, func_t);
+variable *inew_string(interpreter *, const char *, const char *);
+variable *inew_number(interpreter *, const char *, float);
+variable *inew_cfunc(interpreter *, const char *, func_t);
 
 int idoline(interpreter *, const char *);
 variable *idoexpr(interpreter *interp, const char *line);
diff --git a/shell.c b/shell.c
deleted file mode 100644 (file)
index c5460e7..0000000
--- a/shell.c
+++ /dev/null
@@ -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;
-}
diff --git a/stack.c b/stack.c
index d970bc258a819a1b689611828f43c1f81bd0f568..8ada8ea96c6e85d901d99fa04a7f75fa9e3e78e9 100644 (file)
--- a/stack.c
+++ b/stack.c
@@ -20,27 +20,19 @@ variable *igetarg(interpreter *interp, uint32_t index)
        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)
                return 0;
        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)
                return 0;
        variable *v = igetarg(interp, index);
-       return INT(itoint(v));
-}
-
-float igetarg_float(interpreter *interp, uint32_t index)
-{
-       if (index >= interp->stidx)
-               return 0;
-       variable *v = igetarg(interp, index);
-       return FLOAT(itofloat(v));
+       return v->value.f;
 }
 
diff --git a/stack.h b/stack.h
index d5a7f9610f32a7bba03bf78f369d13f084b19070..18821a18ca9ef3c32fdcc50d6e93cdf1f293da57 100644 (file)
--- a/stack.h
+++ b/stack.h
@@ -6,10 +6,11 @@
 void ipush(interpreter *it, void *v);
 void *ipop(interpreter *it);
 void ipopm(interpreter *it, uint32_t count);
+
 variable *igetarg(interpreter *interp, uint32_t index);
-char *igetarg_string(interpreter *interp, uint32_t index);
-int igetarg_integer(interpreter *interp, uint32_t index);
-float igetarg_float(interpreter *interp, uint32_t index);
+const char *igetarg_string(interpreter *interp, uint32_t index);
+float igetarg_number(interpreter *interp, uint32_t index);
 
+#define igetarg_integer(i, x) (int)igetarg_number(i, x)
 
 #endif // STACK_H_
index 8b7dc1292e7d48e5587cf7f5c01fcc8b30a86f3b..c170f799660e6ab22702b9ee234d709496aaa155 100644 (file)
@@ -4,12 +4,10 @@
 #include <stdlib.h>
 #include <memory.h>
 #include <string.h>
+#include <shelpers.h>
 
 extern int atoi(const char *);
 
-extern char *str_undef;
-extern char *str_func;
-
 char *fixstring(char *s)
 {
        char *n = malloc(strlen(s) + 1);
@@ -27,105 +25,47 @@ char *fixstring(char *s)
        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->fromc = fromc;
-       v->valtype = valtype;
-       v->value = 0;
-       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;
-       }
+       v->fromc = 0;
+       v->valtype = NUMBER;
+       v->value.f = value;
        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->fromc = 0;
-       v->valtype = FLOAT;
-       FLOAT(v) = value;
-       fsetstr(v);
+       v->valtype = STRING;
+       v->value.p = (value != 0) ? (uint32_t)fixstring(value) : 0;
        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)
-               f->svalue = (char *)malloc(32);
-       snprintf(f->svalue, 32, "%f", FLOAT(f));
-}
-
-void isetstr(variable *i)
-{
-       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;
-       }
+       if (v == 0)
+               v = (variable *)malloc(sizeof(variable));
+       v->used = 0;
+       v->fromc = fromc;
+       v->valtype = FUNC;
+       v->value.p = func;
        return v;
 }
 
-variable *itofloat(variable *v)
+variable *make_vare(variable *v, const char *expr)
 {
-       switch (v->valtype) {
-       case STRING:
-               v->valtype = FLOAT;
-               FLOAT(v) = strtof(v->svalue, 0);
-               fsetstr(v);
-               break;
-       case INTEGER:
-               v->valtype = FLOAT;
-               FLOAT(v) = (float)INT(v);
-               fsetstr(v);
-               break;
-       }
+       if (v == 0)
+               v = (variable *)malloc(sizeof(variable));
+       v->used = 0;
+       v->fromc = 0;
+       v->valtype = EXPR;
+       v->value.p = (uint32_t)strclone(expr);
        return v;
 }
 
index beb8be3fdb86827db496f9144e9c7c3b93f1ec57..b4a7c72172f0cacf00201acfb95f8d30f79e042c 100644 (file)
@@ -3,33 +3,26 @@
 
 #include <stdint.h>
 
-#define INT(v)   (*((int32_t *)&(v)->value))
-#define FLOAT(v) (*((float *)&(v)->value))
-
 typedef struct {
        uint8_t used :1;
        uint8_t fromc :1;
        uint8_t valtype :4;
-       uint32_t value;
-       char *svalue;
+       union {
+               float f;
+               uint32_t p;
+       } value;
 } variable;
 
 enum valtype {
        STRING = 0,
-       INTEGER,
-       FLOAT,
+       NUMBER,
        FUNC,
        EXPR
 };
 
-variable *vmake(uint8_t fromc, uint8_t valtype, void *value);
-variable *vmakef(float value);
-
-void isetstr(variable *i);
-void fsetstr(variable *f);
-
-variable *itostring(variable *v);
-variable *itoint(variable *v);
-variable *itofloat(variable *v);
+variable *make_varn(variable *v, float value);
+variable *make_vars(variable *v, const char *s);
+variable *make_varf(variable *v, uint8_t fromc, uint32_t func);
+variable *make_vare(variable *v, const char *e);
 
 #endif // VARIABLE_H_