]> git.lizzy.rs Git - nothing.git/blob - src/ebisp/repl.c
(#458) Implement script ctor
[nothing.git] / src / ebisp / 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 gc_inspect_adapter(void *param, Gc *gc, struct Scope *scope, struct Expr args)
12 {
13     assert(gc);
14     assert(scope);
15     (void) param;
16     (void) args;
17
18     gc_inspect(gc);
19
20     return eval_success(NIL(gc));
21 }
22
23 static struct EvalResult quit(void *param, Gc *gc, struct Scope *scope, struct Expr args)
24 {
25     assert(gc);
26     assert(scope);
27     (void) args;
28     (void) param;
29
30     exit(0);
31
32     return eval_success(NIL(gc));
33 }
34
35 static struct EvalResult get_scope(void *param, Gc *gc, struct Scope *scope, struct Expr args)
36 {
37     assert(gc);
38     assert(scope);
39     (void) param;
40     (void) args;
41
42     return eval_success(scope->expr);
43 }
44
45 static void eval_line(Gc *gc, Scope *scope, const char *line)
46 {
47     /* TODO: eval_line could've been implemented with read_all_exprs_from_string */
48     while (*line != 0) {
49         gc_collect(gc, scope->expr);
50
51         struct ParseResult parse_result = read_expr_from_string(gc, line);
52         if (parse_result.is_error) {
53             print_parse_error(stderr, line, parse_result);
54             return;
55         }
56
57         struct EvalResult eval_result = eval(gc, scope, parse_result.expr);
58         if (eval_result.is_error) {
59             fprintf(stderr, "Error:\t");
60             print_expr_as_sexpr(stderr, eval_result.expr);
61             fprintf(stderr, "\n");
62             return;
63         }
64
65         print_expr_as_sexpr(stderr, eval_result.expr);
66         fprintf(stdout, "\n");
67
68         line = next_token(parse_result.end).begin;
69     }
70 }
71
72 int main(int argc, char *argv[])
73 {
74     (void) argc;
75     (void) argv;
76
77     char buffer[REPL_BUFFER_MAX + 1];
78
79     Gc *gc = create_gc();
80     struct Scope scope = {
81         .expr = CONS(gc, NIL(gc), NIL(gc))
82     };
83
84     set_scope_value(gc, &scope, SYMBOL(gc, "quit"), NATIVE(gc, quit, NULL));
85     set_scope_value(gc, &scope, SYMBOL(gc, "gc-inspect"), NATIVE(gc, gc_inspect_adapter, NULL));
86     set_scope_value(gc, &scope, SYMBOL(gc, "scope"), NATIVE(gc, get_scope, NULL));
87
88     while (true) {
89         printf("> ");
90
91         if (fgets(buffer, REPL_BUFFER_MAX, stdin) == NULL) {
92             return -1;
93         }
94
95         eval_line(gc, &scope, buffer);
96     }
97
98     destroy_gc(gc);
99
100     return 0;
101 }