]> git.lizzy.rs Git - nothing.git/blob - src/game/level/script.c
(#396) introduce script_eval
[nothing.git] / src / game / level / script.c
1 #include <assert.h>
2
3 #include "ebisp/gc.h"
4 #include "ebisp/interpreter.h"
5 #include "ebisp/parser.h"
6 #include "ebisp/scope.h"
7 #include "script.h"
8 #include "str.h"
9 #include "system/error.h"
10 #include "system/line_stream.h"
11 #include "system/lt.h"
12
13 struct Script
14 {
15     Lt *lt;
16     Gc *gc;
17     struct Scope scope;
18 };
19
20 Script *create_script_from_line_stream(LineStream *line_stream)
21 {
22     assert(line_stream);
23
24     Lt *lt = create_lt();
25     if (lt == NULL) {
26         return NULL;
27     }
28
29     Script *script = PUSH_LT(lt, malloc(sizeof(Script)), free);
30     if (script == NULL) {
31         throw_error(ERROR_TYPE_LIBC);
32         RETURN_LT(lt, NULL);
33     }
34     script->lt = lt;
35
36     script->gc = PUSH_LT(lt, create_gc(), destroy_gc);
37     if (script->gc == NULL) {
38         RETURN_LT(lt, NULL);
39     }
40
41     script->scope = create_scope(script->gc);
42
43     size_t n = 0;
44     sscanf(line_stream_next(line_stream), "%lu", &n);
45
46     char *source_code = NULL;
47     for (size_t i = 0; i < n; ++i) {
48         /* TODO(#466): maybe source_code should be constantly replaced in the Lt */
49         source_code = string_append(
50             source_code,
51             line_stream_next(line_stream));
52     }
53     PUSH_LT(lt, source_code, free);
54
55     struct ParseResult parse_result =
56         read_all_exprs_from_string(
57             script->gc,
58             source_code);
59     if (parse_result.is_error) {
60         fprintf(stderr, "Parsing error: %s\n", parse_result.error_message);
61         RETURN_LT(lt, NULL);
62     }
63
64     struct EvalResult eval_result = eval(
65         script->gc,
66         &script->scope,
67         CONS(script->gc,
68              SYMBOL(script->gc, "begin"),
69              parse_result.expr));
70     if (eval_result.is_error) {
71         print_expr_as_sexpr(stderr, eval_result.expr);
72         fprintf(stderr, "\n");
73         RETURN_LT(lt, NULL);
74     }
75
76     gc_collect(script->gc, script->scope.expr);
77
78     free(RELEASE_LT(lt, source_code));
79
80     return script;
81 }
82
83 void destroy_script(Script *script)
84 {
85     assert(script);
86     RETURN_LT0(script->lt);
87 }
88
89 int script_eval(Script *script, const char *source_code)
90 {
91     assert(script);
92     assert(source_code);
93     /* TODO: script_eval is not implemented */
94     return 0;
95 }