← Commit history
refactor(ashvm): consume shared hearth/front lexer and pipeline; drop old lexer, @import and REPL; add run/check commands
lennoxrose committed on Oct 18, 2026 at 00:37 UTC
25 files changed+228−217
hearth/ashvm/Makefilemodified
+13−9@@ -24,13 +24,12 @@ GC ?= 02424
ifeq ($(GC),1)2525
GC_FLAGS = -DASH_GC2626
endif27
-CFLAGS = -Wall -Wextra -std=c11 -O2 -Isrc -I../pyre/src -fopenmp $(GC_FLAGS)28
-LDFLAGS = -lm ../../bin/extensions/pyre/libpyre.a -fopenmp -ldl -lvulkan -lstdc++ $(CUDA_LIBS)27
+CFLAGS = -Wall -Wextra -std=c11 -O2 -Isrc -I../front/src -I../pyre/src -fopenmp $(GC_FLAGS)28
+LDFLAGS = -lm ../../bin/libashfront.a ../../bin/extensions/pyre/libpyre.a -fopenmp -ldl -lvulkan -lstdc++ $(CUDA_LIBS)2929
3030
ASHVM_SRC = \3131
src/app/C/main.c \32
- src/lexer/C/lexer.c \33
- src/lexer/C/lexer_import.c \32
+ src/app/C/repl.c \3433
src/value/C/hashmap.c \3534
src/value/C/value.c \3635
src/vm/C/api.c \@@ -42,12 +41,10 @@ ASHVM_SRC = \4241
src/compiler/C/calls.c \4342
src/compiler/C/constants.c \4443
src/compiler/C/expr.c \45
- src/compiler/C/import_paths.c \4644
src/compiler/C/loop_stack.c \4745
src/compiler/C/state.c \4846
src/compiler/C/stmt.c \4947
src/compiler/C/stmt_control.c \50
- src/compiler/C/stmt_import.c \5148
src/compiler/C/module_state.c \5249
src/compiler/C/prescan.c \5350
src/builtins/C/builtins.c \@@ -67,7 +64,7 @@ ASHVM_OBJ = $(foreach s,$(ASHVM_SRC),$(call obj_of,$(s)))6764
ASHVM_DEP = $(foreach s,$(ASHVM_SRC),$(call dep_of,$(s)))6865
6966
# -MMD -MP: emit a per-object .d file listing the headers it includes, so70
-# editing a shared header (e.g. lexer.h, value.h, chunk.h) correctly67
+# editing a shared header (e.g. value.h, value.h, chunk.h) correctly7168
# triggers a rebuild of every .o that includes it, not just files whose7269
# own .c changed. Without this, make's only dependency is "the .c is newer7370
# than the .o" -- a header-only edit silently produces a binary built from@@ -89,7 +86,14 @@ all: $(BIN)8986
../../bin/extensions/pyre/libpyre.a:9087
$(MAKE) -C ../pyre lib9188
92
-$(BIN): $(ASHVM_OBJ) ../../bin/extensions/pyre/libpyre.a89
+# The shared front end (lexer, parser, type checker, lowering) is the only frontend ashvm has;90
+# front's own Makefile decides whether the library is up to date.91
+../../bin/libashfront.a: FORCE92
+ $(MAKE) -C ../front93
+94
+FORCE:95
+96
+$(BIN): $(ASHVM_OBJ) ../../bin/libashfront.a ../../bin/extensions/pyre/libpyre.a9397
mkdir -p ../../bin9498
$(CC) $(CFLAGS) -o $(BIN) $(ASHVM_OBJ) $(LDFLAGS)9599
@@ -100,4 +104,4 @@ clean:100104
find src -name '*.d' -delete101105
rm -f $(BIN)102106
103
-.PHONY: all clean107
+.PHONY: all clean FORCEhearth/ashvm/src/app/C/main.cmodified
+23−97@@ -1,112 +1,38 @@11
#include <stdio.h>22
#include <stdlib.h>33
#include <string.h>4
-#include <setjmp.h>4
+#include "app/H/repl.h"55
#include "compiler/H/compiler.h"66
#include "vm/H/vm.h"77
#include "diagnostics/H/diagnostics.h"8
+#include "jdriver/H/jdriver.h"89
9
-static char *read_file(const char *path) {10
- FILE *file = fopen(path, "rb");11
- if (!file) { fprintf(stderr, "could not open file: %s\n", path); exit(1); }12
- fseek(file, 0L, SEEK_END);13
- long size = ftell(file);14
- rewind(file);15
- char *buffer = malloc(size + 1);16
- fread(buffer, 1, size, file);17
- buffer[size] = '\0';18
- fclose(file);19
- return buffer;10
+void ashvm_execute_ir(char *ir) {11
+ diagnostics_set_source(ir, "<internal ir>");12
+ vm_run(compile(ir));2013
}2114
22
-static void count_braces(const char *line, int *depth, int *in_string) {23
- for (const char *p = line; *p; p++) {24
- if (*in_string) {25
- if (*p == '\\' && p[1] != '\0') { p++; continue; }26
- if (*p == '"') *in_string = 0;27
- continue;28
- }29
- if (*p == '"') { *in_string = 1; continue; }30
- if (*p == '{') (*depth)++;31
- if (*p == '}') (*depth)--;32
- }33
-}34
-35
-static int is_blank(const char *s) {36
- for (; *s; s++) if (*s != ' ' && *s != '\t' && *s != '\n' && *s != '\r') return 0;37
- return 1;38
-}39
-40
-static jmp_buf repl_recovery;41
-42
-static void run_repl(void) {43
- static Chunk repl_chunk;44
- chunk_init(&repl_chunk);45
- vm_set_repl_recovery(&repl_recovery);46
-47
- printf("Ash REPL (ashvm) -- variables and functions persist between lines.\n");48
- printf("Numeric/string/array/map only (no closures over REPL-level captures across lines).\n");49
- printf("Type 'exit' to quit. Runtime errors are caught automatically; syntax errors will end the session.\n\n");50
-51
- int first_call = 1;52
- char buffer[16384];53
-54
- for (;;) {55
- buffer[0] = '\0';56
- int depth = 0;57
- int in_string = 0;58
- int has_content = 0;59
-60
- for (;;) {61
- printf(depth == 0 ? "ashvm> " : "... ");62
- fflush(stdout);63
-64
- char line[2048];65
- if (!fgets(line, sizeof(line), stdin)) { printf("\n"); return; }66
-67
- if (depth == 0 && !has_content) {68
- char trimmed[2048];69
- strncpy(trimmed, line, sizeof(trimmed) - 1);70
- trimmed[sizeof(trimmed) - 1] = '\0';71
- size_t l = strlen(trimmed);72
- while (l > 0 && (trimmed[l-1] == '\n' || trimmed[l-1] == '\r')) trimmed[--l] = '\0';73
- if (strcmp(trimmed, "exit") == 0) return;74
- }75
-76
- if (!is_blank(line)) has_content = 1;77
- count_braces(line, &depth, &in_string);78
-79
- strncat(buffer, line, sizeof(buffer) - strlen(buffer) - 1);80
-81
- if (depth <= 0) { depth = 0; break; }82
- }83
-84
- if (!has_content) continue;85
-86
- int this_is_first = first_call;87
- first_call = 0;88
-89
- if (setjmp(repl_recovery) != 0) {90
- continue;91
- }92
-93
- int start_offset;94
- compile_repl_line(buffer, &repl_chunk, &start_offset);95
-96
- vm_repl_checkpoint();97
- vm_run_from(&repl_chunk, start_offset, this_is_first);98
- }15
+static int usage(const char *prog) {16
+ fprintf(stderr, "usage: %s interactive REPL\n", prog);17
+ fprintf(stderr, " %s run [--wrap-int] <file.ash> run a program\n", prog);18
+ fprintf(stderr, " %s check <file.ash> type-check without running\n", prog);19
+ return 2;9920
}10021
10122
int main(int argc, char *argv[]) {102
- if (argc < 2) {103
- run_repl();23
+ if (argc < 2) return repl_run();24
+25
+ if (strcmp(argv[1], "run") == 0) {26
+ int wrap_int = argc == 4 && strcmp(argv[2], "--wrap-int") == 0;27
+ if (argc != 3 + wrap_int) return usage(argv[0]);28
+ char *ir = jdriver_compile_file(argv[2 + wrap_int], wrap_int);29
+ if (!ir) return 1;30
+ ashvm_execute_ir(ir);10431
return 0;10532
}106
- char *source = read_file(argv[1]);107
- diagnostics_set_source(source, argv[1]);108
- Chunk *main_chunk = compile(source, argv[1]);109
- vm_run(main_chunk);110
- free(source);111
- return 0;33
+ if (strcmp(argv[1], "check") == 0) {34
+ if (argc != 3) return usage(argv[0]);35
+ return jdriver_check_file(argv[2]);36
+ }37
+ return usage(argv[0]);11238
}hearth/ashvm/src/app/C/repl.cadded
+115−0@@ -0,0 +1,115 @@1
+#define _DEFAULT_SOURCE2
+#include <fcntl.h>3
+#include <stdio.h>4
+#include <stdlib.h>5
+#include <string.h>6
+#include <sys/wait.h>7
+#include <unistd.h>8
+9
+#include "app/H/repl.h"10
+#include "jdriver/H/jdriver.h"11
+#include "jrepl/H/jrepl.h"12
+13
+// Tracks { } nesting across lines, ignoring braces inside string and char literals.14
+static void count_braces(const char *line, int *depth, char *quote) {15
+ for (const char *p = line; *p; p++) {16
+ if (*quote) {17
+ if (*p == '\\' && p[1] != '\0') { p++; continue; }18
+ if (*p == *quote) *quote = 0;19
+ continue;20
+ }21
+ if (*p == '"' || *p == '\'') { *quote = *p; continue; }22
+ if (*p == '/' && p[1] == '/') break;23
+ if (*p == '{') (*depth)++;24
+ if (*p == '}') (*depth)--;25
+ }26
+}27
+28
+static int is_blank(const char *s) {29
+ for (; *s; s++) if (*s != ' ' && *s != '\t' && *s != '\n' && *s != '\r') return 0;30
+ return 1;31
+}32
+33
+// Runs `source` in a child. Everything printed before JREPL_MARKER (the replayed history) is dropped.34
+// Returns 1 when the child compiled and ran to completion.35
+static int run_in_child(const char *source, int quiet) {36
+ int fds[2];37
+ if (pipe(fds) != 0) { perror("pipe"); return 0; }38
+ fflush(stdout);39
+ fflush(stderr);40
+ pid_t pid = fork();41
+ if (pid < 0) { perror("fork"); return 0; }42
+ if (pid == 0) {43
+ close(fds[0]);44
+ dup2(fds[1], 1);45
+ close(fds[1]);46
+ if (quiet) {47
+ int null = open("/dev/null", O_WRONLY);48
+ if (null >= 0) { dup2(null, 2); close(null); }49
+ }50
+ char *ir = jdriver_compile_source("./Repl.ash", source, 0);51
+ if (!ir) exit(1);52
+ ashvm_execute_ir(ir);53
+ exit(0);54
+ }55
+ close(fds[1]);56
+ char *held = NULL;57
+ size_t held_len = 0;58
+ int seen = 0;59
+ char chunk[4096];60
+ ssize_t n;61
+ while ((n = read(fds[0], chunk, sizeof(chunk))) > 0) {62
+ if (seen) { fwrite(chunk, 1, (size_t)n, stdout); continue; }63
+ held = realloc(held, held_len + (size_t)n + 1);64
+ memcpy(held + held_len, chunk, (size_t)n);65
+ held_len += (size_t)n;66
+ held[held_len] = '\0';67
+ char *m = strstr(held, JREPL_MARKER "\n");68
+ if (m) {69
+ m += strlen(JREPL_MARKER "\n");70
+ fwrite(m, 1, held_len - (size_t)(m - held), stdout);71
+ seen = 1;72
+ }73
+ }74
+ close(fds[0]);75
+ free(held);76
+ int status = 0;77
+ waitpid(pid, &status, 0);78
+ fflush(stdout);79
+ return WIFEXITED(status) && WEXITSTATUS(status) == 0;80
+}81
+82
+int repl_run(void) {83
+ JRepl *session = jrepl_new();84
+ printf("Ash REPL (ashvm) -- Java-like Ash. Imports, types, methods and statements persist.\n");85
+ printf("A line without a trailing ';' or '}' is evaluated and printed. Type 'exit' to quit.\n");86
+ printf("State is rebuilt by replaying earlier lines, so file writes and stdin reads repeat.\n\n");87
+88
+ char buffer[16384];89
+ for (;;) {90
+ buffer[0] = '\0';91
+ int depth = 0, has_content = 0;92
+ char quote = 0;93
+ for (;;) {94
+ printf(depth == 0 ? "ashvm> " : "... ");95
+ fflush(stdout);96
+ char line[2048];97
+ if (!fgets(line, sizeof(line), stdin)) { printf("\n"); return 0; }98
+ if (depth == 0 && !has_content && (strcmp(line, "exit\n") == 0 || strcmp(line, "exit") == 0)) return 0;99
+ if (!is_blank(line)) has_content = 1;100
+ count_braces(line, &depth, "e);101
+ strncat(buffer, line, sizeof(buffer) - strlen(buffer) - 1);102
+ if (depth <= 0) break;103
+ }104
+ if (!has_content) continue;105
+106
+ JReplKind kind = jrepl_classify(buffer);107
+ if (kind == JREPL_EXPRESSION) {108
+ // a bare expression is printed; if that does not compile (a void call), run it as a statement109
+ if (run_in_child(jrepl_source(session, buffer, kind, 1), 1)) { jrepl_commit(session, buffer, kind, 1); continue; }110
+ if (run_in_child(jrepl_source(session, buffer, kind, 0), 0)) jrepl_commit(session, buffer, kind, 0);111
+ continue;112
+ }113
+ if (run_in_child(jrepl_source(session, buffer, kind, 0), 0)) jrepl_commit(session, buffer, kind, 0);114
+ }115
+}hearth/ashvm/src/app/D/main.dmodified
+6−3@@ -1,8 +1,11 @@1
-src/app/O/main.o: src/app/C/main.c src/compiler/H/compiler.h \2
- src/vm/H/chunk.h src/value/H/value.h src/vm/H/vm.h \3
- src/diagnostics/H/diagnostics.h1
+src/app/O/main.o: src/app/C/main.c src/app/H/repl.h \2
+ src/compiler/H/compiler.h src/vm/H/chunk.h src/value/H/value.h \3
+ src/vm/H/vm.h src/diagnostics/H/diagnostics.h \4
+ ../front/src/jdriver/H/jdriver.h5
+src/app/H/repl.h:46
src/compiler/H/compiler.h:57
src/vm/H/chunk.h:68
src/value/H/value.h:79
src/vm/H/vm.h:810
src/diagnostics/H/diagnostics.h:11
+../front/src/jdriver/H/jdriver.h:hearth/ashvm/src/app/D/repl.dadded
+5−0@@ -0,0 +1,5 @@1
+src/app/O/repl.o: src/app/C/repl.c src/app/H/repl.h \2
+ ../front/src/jdriver/H/jdriver.h ../front/src/jrepl/H/jrepl.h3
+src/app/H/repl.h:4
+../front/src/jdriver/H/jdriver.h:5
+../front/src/jrepl/H/jrepl.h:hearth/ashvm/src/app/H/repl.hadded
+12−0@@ -0,0 +1,12 @@1
+#ifndef ASH_VM_REPL_H2
+#define ASH_VM_REPL_H3
+4
+// Interactive session for Java-like Ash. Each accepted line is replayed through the shared front5
+// end (hearth/front/src/jrepl) and executed in a child process, so a failing line cannot damage6
+// the session. Returns the process exit status.7
+int repl_run(void);8
+9
+// Compiles the internal IR text from hearth/front and runs it on the VM. Exits on a compile error.10
+void ashvm_execute_ir(char *ir);11
+12
+#endifhearth/ashvm/src/compiler/C/stmt.cmodified
+19−23@@ -5,12 +5,10 @@55
#include "diagnostics/H/diagnostics.h"66
#include "compiler/H/loop_stack.h"77
8
-// statement() is shared between top-level parsing (compile()'s own loop,9
-// and stmt_import.c's parse_imported_file_body()) and here, inside a10
-// forge/given/during/attempt body -- block_depth distinguishes the two so11
-// the "only forge/local at an imported file's top level" guard in12
-// statement() only fires for genuinely top-level statements, never for an13
-// ordinary yield/given/etc. nested inside an imported function's own body.8
+// statement() is shared between top-level parsing (compile()'s own loop) and9
+// here, inside a forge/given/during/attempt body -- block_depth distinguishes10
+// the two so the "only forge/local at the unit's top level" guard in11
+// statement() only fires for genuinely top-level statements.1412
static int block_depth = 0;1513
1614
void block(void) {@@ -281,9 +279,6 @@ static void raise_statement(void) {281279
}282280
283281
void statement(void) {284
- if (current.type == TOKEN_IMPORT) { advance_token(); compile_import_stmt(); return; }285
- imports_close_block();286
-287282
const char *ns; int ns_len;288283
get_import_namespace(&ns, &ns_len);289284
if (ns_len > 0 && block_depth == 0 && current.type != TOKEN_FORGE && current.type != TOKEN_LOCAL) {@@ -324,28 +319,29 @@ void statement(void) {324319
325320
static Chunk main_chunk;326321
327
-Chunk *compile(const char *source, const char *source_path) {322
+// The IR is one unit of top-level `forge` and `local` declarations (see323
+// ir/H/ir_lex.h) that lives in a single module namespace; the program runs by324
+// calling its `start` function. The lowering owns the unit, so there is no325
+// import machinery: only this one namespace exists.326
+#define IR_NAMESPACE "g"327
+328
+Chunk *compile(const char *source) {328329
vm_function_count = 0;329330
local_count = 0;330331
chunk_init(&main_chunk);331332
chunk = &main_chunk;333
+ set_import_namespace(IR_NAMESPACE, (int)strlen(IR_NAMESPACE));332334
prescan_functions(source);333335
lexer_init(source);334336
advance_token();335
- imports_init(source_path);336337
while (current.type != TOKEN_EOF) statement();337338
check_all_functions_defined();339
+ set_import_namespace(NULL, 0);340
+ int start_fn = find_function(IR_NAMESPACE ".start", (int)strlen(IR_NAMESPACE ".start"));341
+ if (start_fn == -1) { fprintf(stderr, "error: program has no entry point\n"); exit(1); }342
+ emit_op(OP_CALL);343
+ emit((uint8_t)start_fn);344
+ emit(0);345
+ emit_op(OP_POP);338346
return &main_chunk;339347
}340
-341
-// Appends compiled bytecode to an EXISTING chunk without resetting locals or342
-// function definitions -- used by the REPL so state persists between lines.343
-Chunk *compile_repl_line(const char *source, Chunk *target_chunk, int *out_start_offset) {344
- chunk = target_chunk;345
- *out_start_offset = chunk->count;346
- prescan_functions(source);347
- lexer_init(source);348
- advance_token();349
- while (current.type != TOKEN_EOF) statement();350
- return chunk;351
-}hearth/ashvm/src/compiler/D/calls.dmodified
+5−4@@ -1,14 +1,15 @@11
src/compiler/O/calls.o: src/compiler/C/calls.c src/compiler/H/internal.h \22
src/compiler/H/state.h src/compiler/H/compiler.h src/vm/H/chunk.h \3
- src/value/H/value.h src/lexer/H/lexer.h src/compiler/H/constants.h \4
- src/compiler/H/module_state.h src/builtins/H/builtins.h \5
- src/diagnostics/H/diagnostics.h src/compiler/H/loop_stack.h3
+ src/value/H/value.h ../front/src/ir/H/ir_lex.h \4
+ src/compiler/H/constants.h src/compiler/H/module_state.h \5
+ src/builtins/H/builtins.h src/diagnostics/H/diagnostics.h \6
+ src/compiler/H/loop_stack.h67
src/compiler/H/internal.h:78
src/compiler/H/state.h:89
src/compiler/H/compiler.h:910
src/vm/H/chunk.h:1011
src/value/H/value.h:11
-src/lexer/H/lexer.h:12
+../front/src/ir/H/ir_lex.h:1213
src/compiler/H/constants.h:1314
src/compiler/H/module_state.h:1415
src/builtins/H/builtins.h:hearth/ashvm/src/compiler/D/constants.dmodified
+2−2@@ -1,14 +1,14 @@11
src/compiler/O/constants.o: src/compiler/C/constants.c \22
src/compiler/H/constants.h src/value/H/value.h src/compiler/H/internal.h \33
src/compiler/H/state.h src/compiler/H/compiler.h src/vm/H/chunk.h \4
- src/lexer/H/lexer.h src/compiler/H/module_state.h \4
+ ../front/src/ir/H/ir_lex.h src/compiler/H/module_state.h \55
src/diagnostics/H/diagnostics.h66
src/compiler/H/constants.h:77
src/value/H/value.h:88
src/compiler/H/internal.h:99
src/compiler/H/state.h:1010
src/compiler/H/compiler.h:1111
src/vm/H/chunk.h:12
-src/lexer/H/lexer.h:12
+../front/src/ir/H/ir_lex.h:1313
src/compiler/H/module_state.h:1414
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/D/expr.dmodified
+4−3@@ -1,13 +1,14 @@11
src/compiler/O/expr.o: src/compiler/C/expr.c src/compiler/H/internal.h \22
src/compiler/H/state.h src/compiler/H/compiler.h src/vm/H/chunk.h \3
- src/value/H/value.h src/lexer/H/lexer.h src/compiler/H/constants.h \4
- src/compiler/H/module_state.h src/diagnostics/H/diagnostics.h3
+ src/value/H/value.h ../front/src/ir/H/ir_lex.h \4
+ src/compiler/H/constants.h src/compiler/H/module_state.h \5
+ src/diagnostics/H/diagnostics.h56
src/compiler/H/internal.h:67
src/compiler/H/state.h:78
src/compiler/H/compiler.h:89
src/vm/H/chunk.h:910
src/value/H/value.h:10
-src/lexer/H/lexer.h:11
+../front/src/ir/H/ir_lex.h:1112
src/compiler/H/constants.h:1213
src/compiler/H/module_state.h:1314
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/D/loop_stack.dmodified
+4−4@@ -1,9 +1,9 @@11
src/compiler/O/loop_stack.o: src/compiler/C/loop_stack.c \2
- src/compiler/H/loop_stack.h src/lexer/H/lexer.h src/compiler/H/state.h \3
- src/compiler/H/compiler.h src/vm/H/chunk.h src/value/H/value.h \4
- src/diagnostics/H/diagnostics.h2
+ src/compiler/H/loop_stack.h ../front/src/ir/H/ir_lex.h \3
+ src/compiler/H/state.h src/compiler/H/compiler.h src/vm/H/chunk.h \4
+ src/value/H/value.h src/diagnostics/H/diagnostics.h55
src/compiler/H/loop_stack.h:6
-src/lexer/H/lexer.h:6
+../front/src/ir/H/ir_lex.h:77
src/compiler/H/state.h:88
src/compiler/H/compiler.h:99
src/vm/H/chunk.h:hearth/ashvm/src/compiler/D/module_state.dmodified
+4−3@@ -1,15 +1,16 @@11
src/compiler/O/module_state.o: src/compiler/C/module_state.c \22
src/compiler/H/module_state.h src/compiler/H/internal.h \33
src/compiler/H/state.h src/compiler/H/compiler.h src/vm/H/chunk.h \4
- src/value/H/value.h src/lexer/H/lexer.h src/compiler/H/constants.h \5
- src/vm/H/state.h src/diagnostics/H/diagnostics.h4
+ src/value/H/value.h ../front/src/ir/H/ir_lex.h \5
+ src/compiler/H/constants.h src/vm/H/state.h \6
+ src/diagnostics/H/diagnostics.h67
src/compiler/H/module_state.h:78
src/compiler/H/internal.h:89
src/compiler/H/state.h:910
src/compiler/H/compiler.h:1011
src/vm/H/chunk.h:1112
src/value/H/value.h:12
-src/lexer/H/lexer.h:13
+../front/src/ir/H/ir_lex.h:1314
src/compiler/H/constants.h:1415
src/vm/H/state.h:1516
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/D/prescan.dmodified
+2−2@@ -1,14 +1,14 @@11
src/compiler/O/prescan.o: src/compiler/C/prescan.c \22
src/compiler/H/internal.h src/compiler/H/state.h \33
src/compiler/H/compiler.h src/vm/H/chunk.h src/value/H/value.h \4
- src/lexer/H/lexer.h src/compiler/H/constants.h \4
+ ../front/src/ir/H/ir_lex.h src/compiler/H/constants.h \55
src/compiler/H/module_state.h src/diagnostics/H/diagnostics.h66
src/compiler/H/internal.h:77
src/compiler/H/state.h:88
src/compiler/H/compiler.h:99
src/vm/H/chunk.h:1010
src/value/H/value.h:11
-src/lexer/H/lexer.h:11
+../front/src/ir/H/ir_lex.h:1212
src/compiler/H/constants.h:1313
src/compiler/H/module_state.h:1414
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/D/state.dmodified
+2−2@@ -1,9 +1,9 @@11
src/compiler/O/state.o: src/compiler/C/state.c src/compiler/H/state.h \22
src/compiler/H/compiler.h src/vm/H/chunk.h src/value/H/value.h \3
- src/lexer/H/lexer.h src/diagnostics/H/diagnostics.h3
+ ../front/src/ir/H/ir_lex.h src/diagnostics/H/diagnostics.h44
src/compiler/H/state.h:55
src/compiler/H/compiler.h:66
src/vm/H/chunk.h:77
src/value/H/value.h:8
-src/lexer/H/lexer.h:8
+../front/src/ir/H/ir_lex.h:99
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/D/stmt.dmodified
+4−4@@ -1,14 +1,14 @@11
src/compiler/O/stmt.o: src/compiler/C/stmt.c src/compiler/H/internal.h \22
src/compiler/H/state.h src/compiler/H/compiler.h src/vm/H/chunk.h \3
- src/value/H/value.h src/lexer/H/lexer.h src/compiler/H/constants.h \4
- src/compiler/H/module_state.h src/diagnostics/H/diagnostics.h \5
- src/compiler/H/loop_stack.h3
+ src/value/H/value.h ../front/src/ir/H/ir_lex.h \4
+ src/compiler/H/constants.h src/compiler/H/module_state.h \5
+ src/diagnostics/H/diagnostics.h src/compiler/H/loop_stack.h66
src/compiler/H/internal.h:77
src/compiler/H/state.h:88
src/compiler/H/compiler.h:99
src/vm/H/chunk.h:1010
src/value/H/value.h:11
-src/lexer/H/lexer.h:11
+../front/src/ir/H/ir_lex.h:1212
src/compiler/H/constants.h:1313
src/compiler/H/module_state.h:1414
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/D/stmt_control.dmodified
+2−2@@ -1,15 +1,15 @@11
src/compiler/O/stmt_control.o: src/compiler/C/stmt_control.c \22
src/compiler/H/internal.h src/compiler/H/state.h \33
src/compiler/H/compiler.h src/vm/H/chunk.h src/value/H/value.h \4
- src/lexer/H/lexer.h src/compiler/H/constants.h \4
+ ../front/src/ir/H/ir_lex.h src/compiler/H/constants.h \55
src/compiler/H/module_state.h src/diagnostics/H/diagnostics.h \66
src/builtins/H/builtins.h src/compiler/H/loop_stack.h77
src/compiler/H/internal.h:88
src/compiler/H/state.h:99
src/compiler/H/compiler.h:1010
src/vm/H/chunk.h:1111
src/value/H/value.h:12
-src/lexer/H/lexer.h:12
+../front/src/ir/H/ir_lex.h:1313
src/compiler/H/constants.h:1414
src/compiler/H/module_state.h:1515
src/diagnostics/H/diagnostics.h:hearth/ashvm/src/compiler/H/compiler.hmodified
+2−2@@ -17,7 +17,7 @@ typedef struct {1717
extern VMFunction vm_functions[MAX_VM_FUNCS];1818
extern int vm_function_count;1919
20
-Chunk *compile(const char *source, const char *source_path);21
-Chunk *compile_repl_line(const char *source, Chunk *target_chunk, int *out_start_offset);20
+// Compiles the internal IR unit produced by hearth/front (jdriver). Exits with a diagnostic on error.21
+Chunk *compile(const char *source);2222
2323
#endifhearth/ashvm/src/compiler/H/internal.hmodified
+0−10@@ -34,11 +34,6 @@ int try_fuse_condition(TokenType terminator);3434
3535
// compiler_stmt.c3636
void block(void);37
-// statement() itself (compiler_stmt.c's dispatcher) also needs to be38
-// callable from compiler_stmt_import.c's parse_imported_file_body(),39
-// which drives the same top-level "while not EOF, parse a statement"40
-// loop for a recursively parsed imported file -- so it's declared here41
-// rather than staying static to compiler_stmt.c.4237
void statement(void);4338
4439
// compiler_stmt_control.c -- the statement kinds involved enough to@@ -50,9 +45,4 @@ void compile_attempt_stmt(void);5045
void compile_during_stmt(void);5146
void compile_each_stmt(void);5247
53
-// compiler_stmt_import.c54
-void compile_import_stmt(void);55
-void imports_close_block(void);56
-void imports_init(const char *entry_file_path);57
-5848
#endifhearth/ashvm/src/compiler/H/loop_stack.hmodified
+1−1@@ -1,6 +1,6 @@11
#ifndef ASH_VM_COMPILER_LOOP_STACK_H22
#define ASH_VM_COMPILER_LOOP_STACK_H3
-#include "lexer/H/lexer.h"3
+#include "ir/H/ir_lex.h"44
55
// stop/next need to know which loop they belong to, and loops nest --66
// they're pure "emit now, patch later" jump bookkeeping (same primitivehearth/ashvm/src/compiler/H/state.hmodified
+1−1@@ -1,7 +1,7 @@11
#ifndef ASH_VM_COMPILER_STATE_H22
#define ASH_VM_COMPILER_STATE_H33
#include "compiler/H/compiler.h"4
-#include "lexer/H/lexer.h"4
+#include "ir/H/ir_lex.h"55
66
// Shared parser/emitter state for compiler_expr.c and compiler_stmt.c --77
// not part of the public API (compiler.h). Mirrors the samehearth/ashvm/src/vm/C/api.cmodified
+0−24@@ -5,15 +5,6 @@55
#include "vm/H/gc.h"66
#include "compiler/H/compiler.h"77
8
-void vm_set_repl_recovery(jmp_buf *jb) {9
- repl_recovery_jmp = jb;10
-}11
-12
-void vm_repl_checkpoint(void) {13
- repl_saved_frame_count = frame_count;14
- repl_saved_stack_top = stack_top;15
-}16
-178
void vm_run(Chunk *main_chunk) {189
stack_top = stack;1910
frame_count = 1;@@ -23,21 +14,6 @@ void vm_run(Chunk *main_chunk) {2314
vm_execute(0);2415
}2516
26
-// Runs bytecode starting at start_offset within the SAME persistent chunk,27
-// used by the REPL: on the first call, resets the stack/frames like vm_run;28
-// on later calls, keeps the existing stack/frames (so variables persist) and29
-// just resumes execution at the newly-appended bytecode's start.30
-void vm_run_from(Chunk *chunk, int start_offset, int is_first_call) {31
- if (is_first_call) {32
- stack_top = stack;33
- frame_count = 1;34
- frames[0].chunk = chunk;35
- frames[0].slots = stack;36
- }37
- frames[0].ip = chunk->code + start_offset;38
- vm_execute(0);39
-}40
-4117
VMValue vm_call_function_sync(int func_idx, VMValue *args, int argc) {4218
for (int i = 0; i < argc; i++) *stack_top++ = args[i];4319
int caller_frame_count = frame_count;hearth/ashvm/src/vm/C/errors.cmodified
+2−12@@ -21,20 +21,15 @@ void vm_runtime_error(const char *fmt, ...) {2121
2222
if (try_depth > 0) {2323
longjmp(try_handlers[try_depth - 1].jmp, 1);24
- } else if (repl_recovery_jmp != NULL) {25
- diagnostics_report("error", error_message, current_pos, current_poslen);26
- frame_count = repl_saved_frame_count;27
- stack_top = repl_saved_stack_top;28
- longjmp(*repl_recovery_jmp, 1);2924
} else {3025
diagnostics_report("error", error_message, current_pos, current_poslen);3126
exit(1);3227
}3328
}3429
3530
// `raise expr;` -- any value (a string is what built-in errors raise; a map36
-// gives a structured error). Mirrors vm_runtime_error's three-way dispatch37
-// (attempt handler / REPL recovery / hard exit) exactly, but hands back31
+// gives a structured error). Mirrors vm_runtime_error's two-way dispatch32
+// (attempt handler / hard exit) exactly, but hands back3833
// the exact raised VMValue via `raised_value` instead of funneling it3934
// through the fixed-size error_message buffer -- see state.h.4035
void vm_raise_value(VMValue msg) {@@ -44,11 +39,6 @@ void vm_raise_value(VMValue msg) {4439
4540
if (try_depth > 0) {4641
longjmp(try_handlers[try_depth - 1].jmp, 1);47
- } else if (repl_recovery_jmp != NULL) {48
- diagnostics_report("error", text, current_pos, current_poslen);49
- frame_count = repl_saved_frame_count;50
- stack_top = repl_saved_stack_top;51
- longjmp(*repl_recovery_jmp, 1);5242
} else {5343
diagnostics_report("error", text, current_pos, current_poslen);5444
exit(1);hearth/ashvm/src/vm/C/state.cmodified
+0−3@@ -14,9 +14,6 @@ char error_message[512];1414
VMValue raised_value;1515
int has_raised_value = 0;1616
17
-jmp_buf *repl_recovery_jmp = NULL;18
-int repl_saved_frame_count;19
-VMValue *repl_saved_stack_top;2017
2118
const char *current_pos = NULL;2219
int current_poslen = 0;hearth/ashvm/src/vm/H/state.hmodified
+0−3@@ -46,9 +46,6 @@ extern char error_message[512];4646
extern VMValue raised_value;4747
extern int has_raised_value;4848
49
-extern jmp_buf *repl_recovery_jmp;50
-extern int repl_saved_frame_count;51
-extern VMValue *repl_saved_stack_top;5249
5350
// Source position of the instruction currently executing, captured once per5451
// DISPATCH() (the single point every instruction passes through) sohearth/ashvm/src/vm/H/vm.hmodified
+0−3@@ -4,9 +4,6 @@44
#include "vm/H/chunk.h"55
66
void vm_run(Chunk *main_chunk);7
-void vm_run_from(Chunk *chunk, int start_offset, int is_first_call);8
-void vm_set_repl_recovery(jmp_buf *jb);9
-void vm_repl_checkpoint(void);107
118
VMValue vm_call_function_sync(int func_idx, VMValue *args, int argc);129
VMValue vm_call_closure_sync(VMClosureObj *c, VMValue *args, int argc);