From c0cd4e5f199e8567ec3b5e216fbee27837d21bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yaroslav=20de=20la=20Pe=C3=B1a=20Smirnov?= Date: Thu, 20 Jan 2022 02:34:32 +0300 Subject: init --- src/repl.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/repl.c (limited to 'src/repl.c') 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); +} -- cgit v1.2.3