1 #include "system/stacktrace.h"
3 #include "ebisp/interpreter.h"
4 #include "ebisp/parser.h"
5 #include "ebisp/scope.h"
7 #include "game/level.h"
9 #include "system/str.h"
10 #include "system/line_stream.h"
11 #include "system/log.h"
12 #include "system/log_script.h"
13 #include "system/lt.h"
14 #include "system/nth_alloc.h"
15 #include "ui/console.h"
16 #include "broadcast.h"
23 const char *source_code;
26 static Script *create_script(Broadcast *broadcast, const char *source_code)
28 trace_assert(source_code);
32 Script *script = PUSH_LT(lt, nth_calloc(1, sizeof(Script)), free);
38 script->gc = PUSH_LT(lt, create_gc(), destroy_gc);
39 if (script->gc == NULL) {
43 script->scope = create_scope(script->gc);
44 load_std_library(script->gc, &script->scope);
45 load_log_library(script->gc, &script->scope);
46 broadcast_load_library(broadcast, script->gc, &script->scope);
48 script->source_code = PUSH_LT(
50 string_duplicate(source_code, NULL),
52 if (script->source_code == NULL) {
56 struct ParseResult parse_result =
57 read_all_exprs_from_string(
60 if (parse_result.is_error) {
61 log_fail("Parsing error: %s\n", parse_result.error_message);
65 struct EvalResult eval_result = eval(
69 SYMBOL(script->gc, "begin"),
71 if (eval_result.is_error) {
72 print_expr_as_sexpr(stderr, eval_result.expr);
77 gc_collect(script->gc, script->scope.expr);
82 Script *create_script_from_string(Broadcast *broadcast, const char *source_code)
84 return create_script(broadcast, string_duplicate(source_code, NULL));
87 Script *create_script_from_line_stream(LineStream *line_stream, Broadcast *broadcast)
89 trace_assert(line_stream);
91 const char *line = line_stream_next(line_stream);
97 if (sscanf(line, "%lu", &n) == EOF) {
101 const char *source_code = line_stream_collect_n_lines(line_stream, n);
102 if (source_code == NULL) {
106 return create_script(broadcast, source_code);
109 void destroy_script(Script *script)
111 trace_assert(script);
112 RETURN_LT0(script->lt);
115 const char *script_source_code(const Script *script)
117 return script->source_code;
120 int script_eval(Script *script, const char *source_code)
122 trace_assert(script);
123 trace_assert(source_code);
125 struct ParseResult parse_result = read_expr_from_string(
128 if (parse_result.is_error) {
129 log_fail("Parsing error: %s\n", parse_result.error_message);
133 struct EvalResult eval_result = eval(
137 if (eval_result.is_error) {
138 log_fail("Evaluation error: ");
139 /* TODO(#521): Evalation error is prepended with `[FAIL]` at the end of the message */
140 /* TODO(#486): print_expr_as_sexpr could not be easily integrated with log_fail */
141 print_expr_as_sexpr(stderr, eval_result.expr);
146 gc_collect(script->gc, script->scope.expr);
151 bool script_has_scope_value(const Script *script, const char *name)
156 SYMBOL(script->gc, name)));