From f414175e0cf08e02d65ca09028641ac2adbd0f8e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 20 Feb 2018 22:21:46 -0500 Subject: [PATCH] stdlib independence, fixes for calculator --- Makefile | 1 + builtins.c | 2 +- builtins.h | 2 ++ memory.h | 8 ++++++++ parser.c | 13 ++++++++----- parser.h | 1 + script | 31 ++++++++++++++----------------- shell.c | 44 +++++++++++++++++++++++++++++++++++++++++++- shelpers.c | 2 +- stdlib.c | 21 +++++++++++++++++++++ stdlib.h | 9 +++++++++ variable.c | 26 ++++++++++++++++++++++++-- 12 files changed, 133 insertions(+), 27 deletions(-) create mode 100644 memory.h create mode 100644 stdlib.c create mode 100644 stdlib.h diff --git a/Makefile b/Makefile index 1d66f11..319184f 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ all: $(CC) $(CFLAGS) -c stack.c $(CC) $(CFLAGS) -c ops.c $(CC) $(CFLAGS) -c variable.c + $(CC) $(CFLAGS) -c stdlib.c $(AR) r libinterp.a *.o @rm -f *.o #$(CC) $(CFLAGS) shell.c -o shell -L. -l interp diff --git a/builtins.c b/builtins.c index c77c8b9..44c058e 100644 --- a/builtins.c +++ b/builtins.c @@ -2,7 +2,7 @@ #include "stack.h" #include "shelpers.h" -#include +#include extern char *str_func; extern char *str_undef; diff --git a/builtins.h b/builtins.h index 91c6e8c..0c96452 100644 --- a/builtins.h +++ b/builtins.h @@ -8,6 +8,8 @@ void iload_core(interpreter *it); +int ifunc_ret(interpreter *it); + const func_t indent_up[IUP_COUNT]; const func_t indent_down[IDOWN_COUNT]; diff --git a/memory.h b/memory.h new file mode 100644 index 0000000..546aa2d --- /dev/null +++ b/memory.h @@ -0,0 +1,8 @@ +#ifndef MEMORY_H_ +#define MEMORY_H_ + +void *malloc(unsigned int); +void *calloc(unsigned int, unsigned int); +void free(void *); + +#endif // MEMORY_H_ diff --git a/parser.c b/parser.c index b100123..ed7b16b 100644 --- a/parser.c +++ b/parser.c @@ -7,18 +7,19 @@ #include #include -#include +#include #include #define MAX_VARS 48 #define MAX_STACK 16 #define MAX_LINES 1000 +extern int atoi(const char *); +extern float strtof(const char *, char **); + char *str_func = "(func)"; char *str_undef = "(undefined)"; -variable *idoexpr(interpreter *interp, const char *line); - void iinit(interpreter *interp) { interp->vars = (variable *)malloc(MAX_VARS * sizeof(variable)); @@ -222,7 +223,8 @@ int idoline(interpreter *interp, const char *line) skipblank(line, eol, &offset); continue; } - ops[ooffset] = make_var(interp, line + offset, &next); + variable *v = make_var(interp, line + offset, &next); + ops[ooffset] = v; if (ops[ooffset] == 0) { fret = -4; goto fail; @@ -280,7 +282,8 @@ cont: goto norun; ops = (variable **)malloc(8 * sizeof(variable *)); - memcpy(ops, interp->lines[interp->lnidx], 8 * sizeof(variable *)); + for (uint8_t i = 0; i < 8; i++) + ops[i] = interp->lines[interp->lnidx][i]; uint32_t oldLnidx = interp->lnidx; // eval expressions diff --git a/parser.h b/parser.h index 92a8eb3..24c2c89 100644 --- a/parser.h +++ b/parser.h @@ -32,5 +32,6 @@ variable *inew_float(interpreter *, const char *, float); void inew_cfunc(interpreter *, const char *, func_t); int idoline(interpreter *, const char *); +variable *idoexpr(interpreter *interp, const char *line); #endif // PARSER_H_ diff --git a/script b/script index dac7da5..c3837a3 100644 --- a/script +++ b/script @@ -1,18 +1,15 @@ -func divisible - if (arg1 == 0) - ret 0 - end - ret (arg0 % arg1) -end +set a "Het\n" +set b a +print b -set a 0 -set b 4 -do - set a (a + 1) - divisible a b > i - if (i == 0) - print a - end -while (a < 100) - -print "All done!" +#set a 0 +#do +# print "> " +# gets text +# set input "(" +# concat input text +# concat input ")" +# expr input a +# print a +# print "\n" +#while (1) diff --git a/shell.c b/shell.c index c63b1bc..682213c 100644 --- a/shell.c +++ b/shell.c @@ -1,4 +1,5 @@ #include +#include #include "stack.h" @@ -9,7 +10,7 @@ int s_put(interpreter *it) { char *s = igetarg_string(it, 0); - printf("%s\n", s); + printf("%s", s); return 0; } @@ -36,6 +37,29 @@ int s_type(interpreter *it) 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 quit(interpreter *it) { (void)it; @@ -43,6 +67,21 @@ int quit(interpreter *it) return 0; } +int expr(interpreter *it) +{ + variable *v = igetarg(it, 0); + variable *r = igetarg(it, 1); + int len = strlen(v->svalue); + char *s = malloc(len + 1); + strcpy(s, v->svalue); + s[len] = 0; + variable *q = idoexpr(it, s); + r->valtype = q->valtype; + r->value = q->value; + r->svalue = q->svalue; + return 0; +} + int main(int argc, char **argv) { interpreter interp; @@ -62,6 +101,9 @@ int main(int argc, char **argv) inew_cfunc(&interp, "print", s_put); inew_cfunc(&interp, "tp", s_type); inew_cfunc(&interp, "q", quit); + inew_cfunc(&interp, "gets", input); + inew_cfunc(&interp, "concat", concat); + inew_cfunc(&interp, "expr", expr); char *line = 0; diff --git a/shelpers.c b/shelpers.c index fbde4ab..20ec0cc 100644 --- a/shelpers.c +++ b/shelpers.c @@ -1,6 +1,6 @@ #include "shelpers.h" -#include +#include #include char *strclone(const char *s) diff --git a/stdlib.c b/stdlib.c new file mode 100644 index 0000000..3299d0b --- /dev/null +++ b/stdlib.c @@ -0,0 +1,21 @@ +#include + +char *snprintf(char *buf, unsigned int max, const char *format, ...) +{ + (void)max; + va_list args; + va_start(args, format); + + buf[0] = '0'; + buf[1] = '\0'; + + va_end(args); + return buf; +} + +float strtof(const char *s, char **endptr) +{ + (void)s; + (void)endptr; + return 0.0f; +} diff --git a/stdlib.h b/stdlib.h new file mode 100644 index 0000000..0001edc --- /dev/null +++ b/stdlib.h @@ -0,0 +1,9 @@ +#ifndef STDLIB_H_ +#define STDLIB_H_ + +char *snprintf(char *buf, unsigned int max, const char *format, ...); +float strtof(const char *s, char **endptr); + +extern int atoi(const char *); + +#endif // STDLIB_H_ diff --git a/variable.c b/variable.c index 620a4b6..38b771b 100644 --- a/variable.c +++ b/variable.c @@ -1,12 +1,33 @@ #include "variable.h" #include "parser.h" -#include #include +#include +#include + +extern int atoi(const char *); extern char *str_undef; extern char *str_func; +char *fixstring(char *s) +{ + int len = strlen(s); + char *n = malloc(len + 1); + int i, j; + for (i = 0, j = 0; s[i] != '\0'; i++, j++) { + if (s[i] == '\\') { + if (s[i + 1] == 'n') + n[j] = '\n'; + i++; + } else { + n[j] = s[i]; + } + } + n[j] = '\0'; + return n; +} + variable *vmake(uint8_t fromc, uint8_t valtype, void *value) { variable *v = (variable *)malloc(sizeof(variable)); @@ -18,7 +39,8 @@ variable *vmake(uint8_t fromc, uint8_t valtype, void *value) switch (valtype) { case STRING: v->value = 0; - v->svalue = value; + v->svalue = fixstring(value); + free(value); break; case INTEGER: INT(v) = (int32_t)value;