1 #include "system/stacktrace.h"
4 #include "ebisp/interpreter.h"
5 #include "ebisp/parser.h"
6 #include "ebisp/scope.h"
8 #include "game/level.h"
9 #include "game/level_script.h"
12 #include "system/line_stream.h"
13 #include "system/log.h"
14 #include "system/log_script.h"
15 #include "system/lt.h"
16 #include "system/nth_alloc.h"
17 #include "ui/console.h"
18 #include "game_script.h"
27 Script *create_script_from_line_stream(LineStream *line_stream, Game *game)
29 trace_assert(line_stream);
36 Script *script = PUSH_LT(lt, nth_alloc(sizeof(Script)), free);
42 script->gc = PUSH_LT(lt, create_gc(), destroy_gc);
43 if (script->gc == NULL) {
47 script->scope = create_scope(script->gc);
49 load_std_library(script->gc, &script->scope);
50 load_log_library(script->gc, &script->scope);
51 load_game_library(script->gc, &script->scope, game);
54 sscanf(line_stream_next(line_stream), "%lu", &n);
56 char *source_code = NULL;
57 for (size_t i = 0; i < n; ++i) {
58 /* TODO(#466): maybe source_code should be constantly replaced in the Lt */
59 source_code = string_append(
61 line_stream_next(line_stream));
63 PUSH_LT(lt, source_code, free);
65 struct ParseResult parse_result =
66 read_all_exprs_from_string(
69 if (parse_result.is_error) {
70 log_fail("Parsing error: %s\n", parse_result.error_message);
74 struct EvalResult eval_result = eval(
78 SYMBOL(script->gc, "begin"),
80 if (eval_result.is_error) {
81 print_expr_as_sexpr(stderr, eval_result.expr);
86 gc_collect(script->gc, script->scope.expr);
88 free(RELEASE_LT(lt, source_code));
93 void destroy_script(Script *script)
96 RETURN_LT0(script->lt);
99 int script_eval(Script *script, const char *source_code)
101 trace_assert(script);
102 trace_assert(source_code);
104 struct ParseResult parse_result = read_expr_from_string(
107 if (parse_result.is_error) {
108 log_fail("Parsing error: %s\n", parse_result.error_message);
112 struct EvalResult eval_result = eval(
116 if (eval_result.is_error) {
117 log_fail("Evaluation error: ");
118 /* TODO(#521): Evalation error is prepended with `[FAIL]` at the end of the message */
119 /* TODO(#486): print_expr_as_sexpr could not be easily integrated with log_fail */
120 print_expr_as_sexpr(stderr, eval_result.expr);
125 gc_collect(script->gc, script->scope.expr);
130 bool script_has_scope_value(const Script *script, const char *name)
135 SYMBOL(script->gc, name)));