]> git.lizzy.rs Git - nothing.git/blob - src/script/repl.c
(#395) Make region print eval errors on stdout
[nothing.git] / src / script / repl.c
1 #include <assert.h>
2 #include <stdbool.h>
3
4 #include "parser.h"
5 #include "interpreter.h"
6 #include "scope.h"
7 #include "gc.h"
8
9 #define REPL_BUFFER_MAX 1024
10
11 static struct EvalResult quit(void *param, Gc *gc, struct Scope *scope, struct Expr args)
12 {
13     assert(scope);
14     (void) args;
15     (void) param;
16
17     exit(0);
18
19     return eval_success(NIL(gc));
20 }
21
22 static void eval_line(Gc *gc, Scope *scope, const char *line)
23 {
24     /* TODO: there is no way to disable REPL debug output */
25     const char *read_iter = line;
26     while (*read_iter != 0) {
27         printf("Before parse:\t");
28         gc_inspect(gc);
29
30         struct ParseResult parse_result = read_expr_from_string(gc, read_iter);
31         if (parse_result.is_error) {
32             print_parse_error(stderr, line, parse_result);
33             return;
34         }
35         printf("After parse:\t");
36         gc_inspect(gc);
37
38         struct EvalResult eval_result = eval(gc, scope, parse_result.expr);
39         printf("After eval:\t");
40         gc_inspect(gc);
41
42         gc_collect(gc, CONS(gc, scope->expr, eval_result.expr));
43         printf("After collect:\t");
44         gc_inspect(gc);
45
46         printf("Scope:\t");
47         print_expr_as_sexpr(stdout, scope->expr);
48         printf("\n");
49
50         if (eval_result.is_error) {
51             fprintf(stderr, "Error:\t");
52             print_expr_as_sexpr(stderr, eval_result.expr);
53             fprintf(stderr, "\n");
54             continue;
55         }
56
57         print_expr_as_sexpr(stderr, eval_result.expr);
58         fprintf(stdout, "\n");
59
60         read_iter = next_token(parse_result.end).begin;
61     }
62 }
63
64 int main(int argc, char *argv[])
65 {
66     (void) argc;
67     (void) argv;
68
69     char buffer[REPL_BUFFER_MAX + 1];
70
71     Gc *gc = create_gc();
72     struct Scope scope = {
73         .expr = CONS(gc, NIL(gc), NIL(gc))
74     };
75
76     set_scope_value(gc, &scope, SYMBOL(gc, "quit"), NATIVE(gc, quit, NULL));
77
78     while (true) {
79         printf("> ");
80
81         if (fgets(buffer, REPL_BUFFER_MAX, stdin) == NULL) {
82             return -1;
83         }
84
85         eval_line(gc, &scope, buffer);
86     }
87
88     destroy_gc(gc);
89
90     return 0;
91 }