diff options
author | Yaroslav de la Peña Smirnov <yps@yaroslavps.com> | 2022-01-20 02:34:32 +0300 |
---|---|---|
committer | Yaroslav de la Peña Smirnov <yps@yaroslavps.com> | 2022-01-20 02:34:32 +0300 |
commit | c0cd4e5f199e8567ec3b5e216fbee27837d21bea (patch) | |
tree | c78eee02932fc6e85413e367d27ec5b5627e1534 /src/repl.c | |
download | cmonkey-c0cd4e5f199e8567ec3b5e216fbee27837d21bea.tar.gz cmonkey-c0cd4e5f199e8567ec3b5e216fbee27837d21bea.zip |
init
Diffstat (limited to 'src/repl.c')
-rw-r--r-- | src/repl.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/repl.c b/src/repl.c new file mode 100644 index 0000000..236d9ec --- /dev/null +++ b/src/repl.c @@ -0,0 +1,67 @@ +#include "repl.h" + +#include "ast.h" +#include "object.h" +#include "token.h" +#include "vector.h" +#include "parser.h" +#include "eval.h" + +#define PROMPT ">> " + +static void +print_parser_errors(FILE *out, struct vector *errors) +{ + size_t i; + char *msg; + vector_foreach(errors, i, msg) { + fprintf(out, "\t%s\n", msg); + } +} + +void +repl_start(FILE *in, FILE *out) +{ + char obuf[2048]; + struct parser *parser = parser_new(); + struct environment *env = environment_new(); + struct vector *history = vector_new(); + for (;;) { + fprintf(out, PROMPT); + char *input = malloc(1024); + if (!fgets(input, 1024, in)) { + if (ferror(in)) { + perror("REPL: can't read"); + free(input); + goto end; + } + fprintf(out, "EOF\n"); + free(input); + goto end; + } + parser_reset(parser, input); + struct program *prog = parser_parse_program(parser); + if (parser->errors->len > 0) { + print_parser_errors(out, parser->errors); + goto skip; + } + struct object *res = eval(env, prog); + if (res) { + fprintf(out, "%s\n", object_sprint(res, obuf)); + object_unref(res); + } + vector_push(history, input); +skip: + node_destroy(prog); + } + +end:; + size_t i; + char *input; + vector_foreach(history, i, input) { + free(input); + } + vector_free(history); + environment_destroy(env); + parser_destroy(parser); +} |