From cf49088b9977c6b704ec93c30cdd86380f1dee1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20D=C3=B8rum?= Date: Mon, 12 Oct 2020 23:13:20 +0200 Subject: [PATCH 1/4] add simple REPL --- Makefile | 7 +++++-- repl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 repl.c diff --git a/Makefile b/Makefile index 8b6fe1b..9986c9c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ LFLAGS = -lm .PHONY = all clean -all: smoke smoke_pr bench example example2 example3 +all: smoke smoke_pr repl bench example example2 example3 smoke: smoke.c tinyexpr.c @@ -15,6 +15,9 @@ smoke_pr: smoke.c tinyexpr.c $(CC) $(CCFLAGS) -DTE_POW_FROM_RIGHT -DTE_NAT_LOG -o $@ $^ $(LFLAGS) ./$@ +repl: repl.o tinyexpr.o + $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) -lreadline + bench: benchmark.o tinyexpr.o $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) @@ -31,4 +34,4 @@ example3: example3.o tinyexpr.o $(CC) -c $(CCFLAGS) $< -o $@ clean: - rm -f *.o *.exe example example2 example3 bench smoke_pr smoke + rm -f *.o *.exe example example2 example3 bench repl smoke_pr smoke diff --git a/repl.c b/repl.c new file mode 100644 index 0000000..6a29d33 --- /dev/null +++ b/repl.c @@ -0,0 +1,52 @@ +#include "tinyexpr.h" +#include +#include +#include +#include + +static int eval(const char *str) { + int err = 0; + double r = te_interp(str, &err); + if (err != 0) { + printf("Error at position %i\n", err); + return -1; + } else { + printf("%g\n", r); + return 0; + } +} + +static void repl() { + while (1) { + char *line = readline("> "); + if (line == NULL) { + break; + } else if (strcmp(line, "q") == 0 || strcmp(line, "quit") == 0) { + free(line); + break; + } + + if (eval(line) != -1) { + add_history(line); + } + + free(line); + } +} + +int main(int argc, char **argv) { + if (argc == 3 && strcmp(argv[1], "-e") == 0) { + if (eval(argv[2]) == -1) { + return 1; + } else { + return 0; + } + } else if (argc == 1) { + repl(); + return 0; + } else { + printf("Usage: %s\n", argv[0]); + printf(" %s -e \n", argv[0]); + return 1; + } +} From a4f41522fe944c592b11e8e9ee936079a97dda78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20D=C3=B8rum?= Date: Mon, 12 Oct 2020 23:35:59 +0200 Subject: [PATCH 2/4] repl: fgets-based readline alternative --- repl.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/repl.c b/repl.c index 6a29d33..ac03cea 100644 --- a/repl.c +++ b/repl.c @@ -1,8 +1,36 @@ #include "tinyexpr.h" #include #include +#include + +#ifndef NO_READLINE #include #include +#else +static char *readline(const char *prompt) { + fprintf(stderr, "%s", prompt); + char buf[1024]; + char *line = fgets(buf, sizeof(buf), stdin); + if (line == NULL && feof(stdin)) { + return NULL; + } else if (line == NULL) { + perror("fgets"); + return NULL; + } + + size_t len = strlen(line); + if (line[len - 1] == '\n') { + line[len - 1] = '\0'; + len -= 1; + } + + line = malloc(len + 1); + strcpy(line, buf); + return line; +} + +static void add_history(const char *line) {} +#endif static int eval(const char *str) { int err = 0; From 74e451e7be3e2b2894e666af70609df88277d318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20D=C3=B8rum?= Date: Tue, 13 Oct 2020 08:12:32 +0200 Subject: [PATCH 3/4] repl: use fgets by default --- repl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repl.c b/repl.c index ac03cea..021a696 100644 --- a/repl.c +++ b/repl.c @@ -3,7 +3,7 @@ #include #include -#ifndef NO_READLINE +#ifdef USE_READLINE #include #include #else From 7e5358cc52a84564c5f702764af07d25f9a14732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20D=C3=B8rum?= Date: Tue, 13 Oct 2020 19:33:31 +0200 Subject: [PATCH 4/4] add repl-readline target --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 9986c9c..d3db7cf 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,9 @@ smoke_pr: smoke.c tinyexpr.c ./$@ repl: repl.o tinyexpr.o + $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) + +repl-readline: repl-readline.o tinyexpr.o $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) -lreadline bench: benchmark.o tinyexpr.o @@ -30,6 +33,9 @@ example2: example2.o tinyexpr.o example3: example3.o tinyexpr.o $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) +repl-readline.o: repl.c + $(CC) -c -DUSE_READLINE $(CCFLAGS) $< -o $@ + .c.o: $(CC) -c $(CCFLAGS) $< -o $@