From e2283f6c7f5abc60dc7ba7ea59deee94da714da7 Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 8 Oct 2022 11:08:42 +0200 Subject: initial commit --- repl.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 repl.c (limited to 'repl.c') diff --git a/repl.c b/repl.c new file mode 100644 index 0000000..5a22bff --- /dev/null +++ b/repl.c @@ -0,0 +1,98 @@ +#include "pez.h" +#include +#include +#include +#include +#include + +#define CHECK(x) do { \ + if (!(x)) { \ + fprintf(stderr, "%s\n", pez_geterr(cx)); \ + assert(!#x); \ + } \ +} while (0) + +static bool +printtop(PezContext *cx) { + assert(pez_top(cx) >= 2); + return + pez_push(cx, 0) // printf was stored here + && pez_pushstring(cx, "%a", 2) + && pez_push(cx, -3) + && pez_apply(cx, 2) + && (pez_pop(cx), pez_pop(cx), 1); +} + +static void +help(void) +{ + printf("Usage: pez [OPTION]... [FILE] [ARG]...\n" + "With no FILE, enter repl.\n" + "\n" + " -h, --help show this help message\n" + " -db debug: print bytecode\n" + "\n"); +} + +int +main(int argc, char **argv) { + PezContext *cx = pez_new(NULL, NULL); + FILE *fp = NULL; + int i, ret = 0; + + for (i = 1; i < argc; ++i) { + const char *arg = argv[i]; + if (*arg == '-') { + if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) { + help(); + goto Bye; + } else if (arg[1] == 'd') { + pez_debug(cx, arg + 2); + } else { + printf("pez: Invalid option '%s'\n", arg); + help(); + ret = 1; + goto Bye; + } + } else { + fp = fopen(arg, "r"); + if (!fp) { + perror(arg); + ret = 1; + goto Bye; + } + break; + } + } + + if (!fp) { + char *src; + using_history(); + CHECK(pez_pushglobal(cx, "printf")); + + while ((src = readline("> "))) { + add_history(src); + if (!pez_eval_str(cx, "", src)) { + fprintf(stderr, "error: %s\n", pez_geterr(cx)); + } else { + assert(pez_top(cx) == 2); + CHECK(printtop(cx)); + printf("\n"); + } + free(src); + } + } else { + if (!pez_eval_file(cx, argv[i], fp)) { + fprintf(stderr, "error: %s\n", pez_geterr(cx)); + ret = 1; + goto Bye; + } + assert(pez_top(cx) == 1); + } +Bye: + if (fp) { + fclose(fp); + } + pez_del(cx); + return ret; +} -- cgit v1.2.3