summaryrefslogtreecommitdiff
path: root/pit/src/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'pit/src/runtime.c')
-rw-r--r--pit/src/runtime.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/pit/src/runtime.c b/pit/src/runtime.c
index ab65d71..429e923 100644
--- a/pit/src/runtime.c
+++ b/pit/src/runtime.c
@@ -163,3 +163,49 @@ void pit_traversal_push_end_code(struct pit_runtime *rt, pit_vec(pit_traversal_e
if (pit_vec_push(pit_traversal_entry)(s, ent) < 0)
pit_error(rt, "traversal overflow");
}
+
+/* check invariants - these should always hold between top-level evaluations! */
+void pit_check_invariants(pit_runtime *rt) {
+ if (rt->saved_bindings->next != 0) {
+ pit_error(rt, "leaked saved_bindings memory! %ld", rt->saved_bindings->next);
+ }
+ if (rt->expr_stack->next != 0) {
+ pit_error(rt, "leaked expr_stack memory! %ld", rt->expr_stack->next);
+ }
+ if (rt->result_stack->next != 0) {
+ pit_error(rt, "leaked result_stack memory! %ld", rt->result_stack->next);
+ }
+ if (rt->compilation_stack->next != 0) {
+ pit_error(rt, "leaked compilation_stack memory! %ld", rt->compilation_stack->next);
+ }
+ if (rt->traversal->next != 0) {
+ pit_error(rt, "leaked traversal memory! %ld", rt->traversal->next);
+ }
+ if (rt->callstack->next != 0) {
+ pit_error(rt, "leaked callstack memory! %ld", rt->callstack->next);
+ }
+}
+
+pit_value pit_load_bytes(pit_runtime *rt, u8 *data, i64 len) {
+ pit_lexer lex;
+ pit_parser parse;
+ bool eof = false;
+ pit_value p = PIT_NIL;
+ pit_value compiled = PIT_NIL;
+ pit_value ret = PIT_NIL;
+ pit_lex_bytes(&lex, (char *) data, len);
+ pit_parser_from_lexer(&parse, &lex);
+ while (p = pit_parse(rt, &parse, &eof), !eof) {
+ pit_check_invariants(rt); if (!pit_value_eq(rt->error, PIT_NIL)) return PIT_NIL;
+ compiled = pit_compile(rt, p);
+ pit_check_invariants(rt); if (!pit_value_eq(rt->error, PIT_NIL)) return PIT_NIL;
+ ret = pit_vm_eval(rt, compiled);
+ pit_check_invariants(rt); if (!pit_value_eq(rt->error, PIT_NIL)) return PIT_NIL;
+ }
+ pit_check_invariants(rt); if (!pit_value_eq(rt->error, PIT_NIL)) return PIT_NIL;
+ return ret;
+}
+pit_value pit_load_cstr(pit_runtime *rt, char *data) {
+ i64 len = (i64) pit_libc_string_strlen(data);
+ return pit_load_bytes(rt, (u8 *) data, len);
+}