| author | Alan
<alan@minerva.local> 2026-05-01 22:20:51 UTC |
| committer | Alan
<alan@minerva.local> 2026-05-01 22:20:51 UTC |
| parent | 22547bfb54299952962df70faf5e71da02b2f870 |
| Makefile | +9 | -7 |
| bootstrap/stage1-compiler.jar | +0 | -0 |
| specs/stage0.md | +20 | -2 |
| specs/stage1.md | +4 | -21 |
| stage1/classfile.lql | +132 | -1 |
| stage1/compiler.lql | +4 | -0 |
| stage1/emit.lql | +7 | -0 |
| stage1/runtime.lql | +704 | -0 |
| test/run.sh | +1 | -1 |
diff --git a/Makefile b/Makefile index 5b2214a..208afd8 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,6 @@ BOOTSTRAP_TEST_DIR := $(BUILD_DIR)/bootstrap-test BOOTSTRAP_DIR := bootstrap BOOTSTRAP_JAR := $(BOOTSTRAP_DIR)/stage1-compiler.jar MAIN_CLASS := com.tailrecursion.larquil.stage0.Stage1Main -RUNTIME_CLASSES := com/tailrecursion/larquil/stage0/IFunction.class com/tailrecursion/larquil/stage0/Symbol.class com/tailrecursion/larquil/stage0/Stage1Main.class .PHONY: all build test clean compile-example run-example stage1-build stage1-test stage1-self-host bootstrap-artifact bootstrap-test @@ -27,7 +26,7 @@ stage1-build: build for f in stage1/core.lql stage1/munge.lql; do \ $(JAVA) -cp $(BOOTSTRAP_JAR) $(MAIN_CLASS) $$f $(STAGE1_DIR); \ done - cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/classfile.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/compiler.lql > $(STAGE1_DIR)/compiler.lql + cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/classfile.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/runtime.lql stage1/compiler.lql > $(STAGE1_DIR)/compiler.lql $(JAVA) -cp $(BOOTSTRAP_JAR) $(MAIN_CLASS) $(STAGE1_DIR)/compiler.lql $(STAGE1_DIR) stage1-test: stage1-build @@ -43,18 +42,21 @@ stage1-self-host: stage1-build bootstrap-artifact: stage1-self-host mkdir -p $(BOOTSTRAP_DIR) - tmp=$$(mktemp -d); \ - (cd $$tmp && jar xf $(abspath $(BOOTSTRAP_JAR)) $(RUNTIME_CLASSES)); \ rm -f $(BOOTSTRAP_JAR); \ - jar --create --file $(BOOTSTRAP_JAR) -C $$tmp . -C $(STAGE3_DIR) .; \ - rm -rf $$tmp + jar --create --file $(BOOTSTRAP_JAR) -C $(STAGE3_DIR) . bootstrap-test: build rm -rf $(BOOTSTRAP_TEST_DIR) mkdir -p $(BOOTSTRAP_TEST_DIR) - cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/classfile.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/compiler.lql > $(BOOTSTRAP_TEST_DIR)/compiler.lql + cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/classfile.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/runtime.lql stage1/compiler.lql > $(BOOTSTRAP_TEST_DIR)/compiler.lql $(JAVA) -cp $(BOOTSTRAP_JAR) $(MAIN_CLASS) $(BOOTSTRAP_TEST_DIR)/compiler.lql $(BOOTSTRAP_TEST_DIR) sh test/run-stage1.sh $(BOOTSTRAP_TEST_DIR) + for c in com/tailrecursion/larquil/stage0/IFunction.class com/tailrecursion/larquil/stage0/Symbol.class com/tailrecursion/larquil/stage0/Stage1Main.class; do \ + jar tf $(BOOTSTRAP_JAR) | grep -qx $$c; \ + done + if javap -classpath $(BOOTSTRAP_JAR) -v com.tailrecursion.larquil.stage0.IFunction com.tailrecursion.larquil.stage0.Symbol com.tailrecursion.larquil.stage0.Stage1Main | grep -E 'SourceFile|Compiled from'; then \ + exit 1; \ + fi compile-example: build rm -rf $(GEN_DIR) diff --git a/bootstrap/stage1-compiler.jar b/bootstrap/stage1-compiler.jar index 275ff03..29389ec 100644 Binary files a/bootstrap/stage1-compiler.jar and b/bootstrap/stage1-compiler.jar differ diff --git a/specs/stage0.md b/specs/stage0.md index 3f80046..89d5eb9 100644 --- a/specs/stage0.md +++ b/specs/stage0.md @@ -148,7 +148,7 @@ There is no general Larquil expression evaluation inside stage 0 function bodies # Compilation Model -For `foo.lql`, the compiler emits: +For `foo.lql`, the source-level class mapping is: - loader class: `com.tailrecursion.larquil.stage0.foo` - one helper function class per named top-level function, for example: @@ -160,11 +160,29 @@ Class files are written under the package path `com/tailrecursion/larquil/stage0 File names and function names are converted to JVM class names with deterministic Clojure-style munging. Path separators are not part of the generated class name. -Stage 0-compatible generated classes depend on these runtime support classes from the bootstrap artifact: +Stage 0-compatible generated classes depend on these runtime support classes: - `IFunction.class` - `Symbol.class` +These runtime classes are reserved names under `com/tailrecursion/larquil/stage0/`. +They are not produced by adding source-level `class` or `interface` forms to Stage 0. + +## Bootstrap Artifact Generation + +The ordinary source mapping above remains limited to loader and helper function classes. +To make the bootstrap artifact self-contained, the compiler may also write reserved runtime and launcher classes into its output directory: + +- `IFunction.class` +- `Symbol.class` +- `Stage1Main.class` + +Those classes are produced by Larquil-compiled generator functions in the compiler. +The generator functions use the Larquil-owned classfile writer and run during compiler output assembly. + +This is a bootstrap mechanism, not a general source-level class-definition feature. +No ordinary `.lql` source form maps directly to `IFunction`, `Symbol`, or `Stage1Main`. + Example loader shape: ```java diff --git a/specs/stage1.md b/specs/stage1.md index 1c44d02..219f789 100644 --- a/specs/stage1.md +++ b/specs/stage1.md @@ -106,24 +106,6 @@ Current temporary support: Replacement: Larquil-shaped list or simple record representation Removal condition: Stage 1 form analysis and instruction lowering agree on the Larquil representation -- Name: `IFunction` - Step: runtime invocation ABI - Reason: generated function classes still implement the Java bootstrap interface - Replacement: Larquil-generated `IFunction.class` - Removal condition: the bootstrap artifact ships an equivalent generated interface - -- Name: `Symbol` - Step: reader/runtime symbol values - Reason: parsed symbols still use the Java runtime class - Replacement: Larquil-generated `Symbol.class` - Removal condition: generated `Symbol` preserves interning, `name`, equality, hash, and string conversion - -- Name: `Stage1Main` - Step: command-line launcher - Reason: Makefile/tests still need a small Java entry point to call the compiler - Replacement: Larquil-generated launcher class - Removal condition: build/test targets invoke the generated launcher without compiling Java sources - - Name: CLI/file bridge Step: Stage 1 entrypoint Reason: Stage 0 source does not yet model `String[] args` and file IO cleanly @@ -639,12 +621,13 @@ Done when: # Current Chunk -The classfile backend is now Larquil-owned: +The bootstrap artifact is now fully Larquil-generated: - `stage1/classfile.lql` owns class records, constant-pool helpers, method records, labels, branch patching, and classfile writing - `stage1/emit.lql` emits through those Larquil records -- the refreshed bootstrap artifact has no references to the removed Java classfile backend +- `stage1/runtime.lql` emits `IFunction`, `Symbol`, and `Stage1Main` as reserved runtime/launcher classes +- `bootstrap-artifact` jars stage3 output directly instead of preserving seeded runtime classes Next best chunk: -- replace the runtime `.class` seeds in `bootstrap/stage1-compiler.jar` with Larquil-generated equivalents +- continue shrinking the host boundary around file IO and command-line entry diff --git a/stage1/classfile.lql b/stage1/classfile.lql index 47005da..c966cc2 100644 --- a/stage1/classfile.lql +++ b/stage1/classfile.lql @@ -232,6 +232,11 @@ (invoke 0) (invoke 2) (pop) + (load-function rec_add) + (load cf) + (lconst 49) + (invoke 2) + (pop) (load-function cp_class) (load cf) (load name) @@ -293,6 +298,21 @@ (checkcast "java/util/ArrayList") (return)) +(function class_access (cf) + (load-function rec_get) + (load cf) + (lconst 6) + (invoke 2) + (return)) + +(function class_set_access (cf access) + (load-function rec_set) + (load cf) + (lconst 6) + (load access) + (invoke 3) + (return)) + (function cp_lookup (cf key) (load-function class_cp_index) (load cf) @@ -688,6 +708,18 @@ (aconst-null) (return)) +(function class_add_abstract_method (cf access name desc) + (load-function class_add_method) + (load cf) + (load-function method_abstract) + (load cf) + (load access) + (load name) + (load desc) + (invoke 4) + (invoke 2) + (return)) + (function writer () (new "java/io/ByteArrayOutputStream") (dup) @@ -957,7 +989,9 @@ (label cp_done) (load-function write_u2) (load w) - (lconst 49) + (load-function class_access) + (load cf) + (invoke 1) (invoke 2) (pop) (load-function write_u2) @@ -1228,6 +1262,72 @@ (load m) (return)) +(function method_abstract (cf access name desc) + (new "java/util/ArrayList") + (dup) + (invokespecial "java/util/ArrayList" "<init>" "()V") + (store m) + (load-function rec_add) + (load m) + (load cf) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load access) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function cp_utf8) + (load cf) + (load name) + (invoke 2) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function cp_utf8) + (load cf) + (load desc) + (invoke 2) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (aconst-null) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load m) + (return)) + (function method_cf (m) (load-function rec_get) (load m) @@ -1552,6 +1652,10 @@ (return)) (function method_write (m w) + (load-function method_code_buffer) + (load m) + (invoke 1) + (jump-if-false write_abstract) (load-function finish_labels) (load m) (invoke 1) @@ -1640,4 +1744,31 @@ (load w) (lconst 0) (invoke 2) + (return) + (label write_abstract) + (load-function write_u2) + (load w) + (load-function method_access) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function method_name_index) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function method_desc_index) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 0) + (invoke 2) (return)) diff --git a/stage1/compiler.lql b/stage1/compiler.lql index eb6274a..baf0114 100644 --- a/stage1/compiler.lql +++ b/stage1/compiler.lql @@ -55,6 +55,10 @@ (return)) (function compile_forms (forms input outdir) + (load-function write_runtime_classes) + (load outdir) + (invoke 1) + (pop) (load-function file_base) (load input) (invoke 1) diff --git a/stage1/emit.lql b/stage1/emit.lql index f464735..f1a7328 100644 --- a/stage1/emit.lql +++ b/stage1/emit.lql @@ -346,6 +346,13 @@ (invoke 2) (return)) +(function emit_ireturn (m) + (load-function emit_u1) + (load m) + (lconst 172) + (invoke 2) + (return)) + (function emit_pop (m) (load-function emit_u1) (load m) diff --git a/stage1/runtime.lql b/stage1/runtime.lql new file mode 100644 index 0000000..f1b6bc9 --- /dev/null +++ b/stage1/runtime.lql @@ -0,0 +1,704 @@ +; Bootstrap runtime and launcher class generators. +; These produce reserved artifact classes by running Larquil-compiled code. + +(function emit_runtime_constructor (cf class_name access) + (load-function method_code) + (load cf) + (load access) + (sconst "<init>") + (sconst "(Ljava/lang/String;)V") + (invoke 4) + (store m) + (load-function method_set_max_locals) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_invokespecial) + (load m) + (sconst "java/lang/Object") + (sconst "<init>") + (sconst "()V") + (invoke 4) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_putfield) + (load m) + (load class_name) + (sconst "name") + (sconst "Ljava/lang/String;") + (invoke 4) + (pop) + (load-function emit_return_void) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_runtime_ifunction () + (load-function class_file) + (sconst "com/tailrecursion/larquil/stage0/IFunction") + (invoke 1) + (store cf) + (load-function class_set_access) + (load cf) + (lconst 1537) + (invoke 2) + (pop) + (load-function class_add_abstract_method) + (load cf) + (lconst 1025) + (sconst "invoke") + (sconst "([Ljava/lang/Object;)Ljava/lang/Object;") + (invoke 4) + (pop) + (load cf) + (return)) + +(function emit_symbol_clinit (cf class_name) + (load-function method_code) + (load cf) + (lconst 8) + (sconst "<clinit>") + (sconst "()V") + (invoke 4) + (store m) + (load-function emit_new) + (load m) + (sconst "java/util/HashMap") + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 89) + (invoke 2) + (pop) + (load-function emit_invokespecial) + (load m) + (sconst "java/util/HashMap") + (sconst "<init>") + (sconst "()V") + (invoke 4) + (pop) + (load-function emit_putstatic) + (load m) + (load class_name) + (sconst "INTERNED") + (sconst "Ljava/util/HashMap;") + (invoke 4) + (pop) + (load-function emit_return_void) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_symbol_intern (cf class_name) + (load-function method_code) + (load cf) + (lconst 9) + (sconst "intern") + (sconst "(Ljava/lang/String;)Lcom/tailrecursion/larquil/stage0/Symbol;") + (invoke 4) + (store m) + (load-function method_set_max_locals) + (load m) + (lconst 3) + (invoke 2) + (pop) + (load-function emit_getstatic) + (load m) + (load class_name) + (sconst "INTERNED") + (sconst "Ljava/util/HashMap;") + (invoke 4) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_invokevirtual) + (load m) + (sconst "java/util/HashMap") + (sconst "get") + (sconst "(Ljava/lang/Object;)Ljava/lang/Object;") + (invoke 4) + (pop) + (load-function emit_checkcast) + (load m) + (load class_name) + (invoke 2) + (pop) + (load-function emit_astore) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_branch) + (load m) + (lconst 198) + (sconst "create") + (invoke 3) + (pop) + (load-function emit_aload) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_areturn) + (load m) + (invoke 1) + (pop) + (load-function emit_label) + (load m) + (sconst "create") + (invoke 2) + (pop) + (load-function emit_new) + (load m) + (load class_name) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 89) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_invokespecial) + (load m) + (load class_name) + (sconst "<init>") + (sconst "(Ljava/lang/String;)V") + (invoke 4) + (pop) + (load-function emit_astore) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function emit_getstatic) + (load m) + (load class_name) + (sconst "INTERNED") + (sconst "Ljava/util/HashMap;") + (invoke 4) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function emit_invokevirtual) + (load m) + (sconst "java/util/HashMap") + (sconst "put") + (sconst "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") + (invoke 4) + (pop) + (load-function emit_pop) + (load m) + (invoke 1) + (pop) + (load-function emit_aload) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function emit_areturn) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_symbol_equals (cf class_name) + (load-function method_code) + (load cf) + (lconst 1) + (sconst "equals") + (sconst "(Ljava/lang/Object;)Z") + (invoke 4) + (store m) + (load-function emit_aload) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_instanceof) + (load m) + (load class_name) + (invoke 2) + (pop) + (load-function emit_branch) + (load m) + (lconst 153) + (sconst "false") + (invoke 3) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_getfield) + (load m) + (load class_name) + (sconst "name") + (sconst "Ljava/lang/String;") + (invoke 4) + (pop) + (load-function emit_aload) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_checkcast) + (load m) + (load class_name) + (invoke 2) + (pop) + (load-function emit_getfield) + (load m) + (load class_name) + (sconst "name") + (sconst "Ljava/lang/String;") + (invoke 4) + (pop) + (load-function emit_invokevirtual) + (load m) + (sconst "java/lang/String") + (sconst "equals") + (sconst "(Ljava/lang/Object;)Z") + (invoke 4) + (pop) + (load-function emit_branch) + (load m) + (lconst 153) + (sconst "false") + (invoke 3) + (pop) + (load-function emit_push_int) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_ireturn) + (load m) + (invoke 1) + (pop) + (load-function emit_label) + (load m) + (sconst "false") + (invoke 2) + (pop) + (load-function emit_push_int) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_ireturn) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_symbol_hash_code (cf class_name) + (load-function method_code) + (load cf) + (lconst 1) + (sconst "hashCode") + (sconst "()I") + (invoke 4) + (store m) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_getfield) + (load m) + (load class_name) + (sconst "name") + (sconst "Ljava/lang/String;") + (invoke 4) + (pop) + (load-function emit_invokevirtual) + (load m) + (sconst "java/lang/String") + (sconst "hashCode") + (sconst "()I") + (invoke 4) + (pop) + (load-function emit_ireturn) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_symbol_to_string (cf class_name) + (load-function method_code) + (load cf) + (lconst 1) + (sconst "toString") + (sconst "()Ljava/lang/String;") + (invoke 4) + (store m) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_getfield) + (load m) + (load class_name) + (sconst "name") + (sconst "Ljava/lang/String;") + (invoke 4) + (pop) + (load-function emit_areturn) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_runtime_symbol () + (sconst "com/tailrecursion/larquil/stage0/Symbol") + (store class_name) + (load-function class_file) + (load class_name) + (invoke 1) + (store cf) + (load-function class_add_field) + (load cf) + (lconst 26) + (sconst "INTERNED") + (sconst "Ljava/util/HashMap;") + (invoke 4) + (pop) + (load-function class_add_field) + (load cf) + (lconst 17) + (sconst "name") + (sconst "Ljava/lang/String;") + (invoke 4) + (pop) + (load-function emit_runtime_constructor) + (load cf) + (load class_name) + (lconst 2) + (invoke 3) + (pop) + (load-function emit_symbol_clinit) + (load cf) + (load class_name) + (invoke 2) + (pop) + (load-function emit_symbol_intern) + (load cf) + (load class_name) + (invoke 2) + (pop) + (load-function emit_symbol_equals) + (load cf) + (load class_name) + (invoke 2) + (pop) + (load-function emit_symbol_hash_code) + (load cf) + (load class_name) + (invoke 2) + (pop) + (load-function emit_symbol_to_string) + (load cf) + (load class_name) + (invoke 2) + (pop) + (load cf) + (return)) + +(function emit_runtime_stage1main_constructor (cf) + (load-function method_code) + (load cf) + (lconst 1) + (sconst "<init>") + (sconst "()V") + (invoke 4) + (store m) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_invokespecial) + (load m) + (sconst "java/lang/Object") + (sconst "<init>") + (sconst "()V") + (invoke 4) + (pop) + (load-function emit_return_void) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_runtime_stage1main_main (cf class_name) + (load-function method_code) + (load cf) + (lconst 9) + (sconst "main") + (sconst "([Ljava/lang/String;)V") + (invoke 4) + (store m) + (load-function method_set_max_locals) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 190) + (invoke 2) + (pop) + (load-function emit_push_int) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function emit_branch) + (load m) + (lconst 159) + (sconst "arity_ok") + (invoke 3) + (pop) + (load-function emit_new) + (load m) + (sconst "java/lang/IllegalArgumentException") + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 89) + (invoke 2) + (pop) + (load-function emit_sconst) + (load m) + (sconst "usage: Stage1Main input.lql outdir") + (invoke 2) + (pop) + (load-function emit_invokespecial) + (load m) + (sconst "java/lang/IllegalArgumentException") + (sconst "<init>") + (sconst "(Ljava/lang/String;)V") + (invoke 4) + (pop) + (load-function emit_u1) + (load m) + (lconst 191) + (invoke 2) + (pop) + (load-function emit_label) + (load m) + (sconst "arity_ok") + (invoke 2) + (pop) + (load-function emit_getstatic) + (load m) + (sconst "com/tailrecursion/larquil/stage0/compiler__compile_file") + (sconst "INSTANCE") + (sconst "Lcom/tailrecursion/larquil/stage0/compiler__compile_file;") + (invoke 4) + (pop) + (load-function emit_push_int) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function emit_anewarray) + (load m) + (sconst "java/lang/Object") + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 89) + (invoke 2) + (pop) + (load-function emit_push_int) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_push_int) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 50) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 83) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 89) + (invoke 2) + (pop) + (load-function emit_push_int) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_aload) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function emit_push_int) + (load m) + (lconst 1) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 50) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 83) + (invoke 2) + (pop) + (load-function emit_invokeinterface) + (load m) + (sconst "com/tailrecursion/larquil/stage0/IFunction") + (sconst "invoke") + (sconst "([Ljava/lang/Object;)Ljava/lang/Object;") + (lconst 2) + (invoke 5) + (pop) + (load-function emit_pop) + (load m) + (invoke 1) + (pop) + (load-function emit_return_void) + (load m) + (invoke 1) + (pop) + (load-function class_add_method) + (load cf) + (load m) + (invoke 2) + (return)) + +(function emit_runtime_stage1main () + (sconst "com/tailrecursion/larquil/stage0/Stage1Main") + (store class_name) + (load-function class_file) + (load class_name) + (invoke 1) + (store cf) + (load-function emit_runtime_stage1main_constructor) + (load cf) + (invoke 1) + (pop) + (load-function emit_runtime_stage1main_main) + (load cf) + (load class_name) + (invoke 2) + (pop) + (load cf) + (return)) + +(function write_runtime_classes (outdir) + (load-function write_class) + (load outdir) + (load-function emit_runtime_ifunction) + (invoke 0) + (invoke 2) + (pop) + (load-function write_class) + (load outdir) + (load-function emit_runtime_symbol) + (invoke 0) + (invoke 2) + (pop) + (load-function write_class) + (load outdir) + (load-function emit_runtime_stage1main) + (invoke 0) + (invoke 2) + (return)) diff --git a/test/run.sh b/test/run.sh index 9177041..74506f2 100755 --- a/test/run.sh +++ b/test/run.sh @@ -106,7 +106,7 @@ ok "stage1 munge class files" aggregate="$OUT/stage1_compiler_src/compiler.lql" mkdir -p "$OUT/stage1_compiler_src" -cat "$ROOT/stage1/core.lql" "$ROOT/stage1/munge.lql" "$ROOT/stage1/forms.lql" "$ROOT/stage1/reader.lql" "$ROOT/stage1/classfile.lql" "$ROOT/stage1/emit.lql" "$ROOT/stage1/instructions.lql" "$ROOT/stage1/backend.lql" "$ROOT/stage1/compiler.lql" > "$aggregate" +cat "$ROOT/stage1/core.lql" "$ROOT/stage1/munge.lql" "$ROOT/stage1/forms.lql" "$ROOT/stage1/reader.lql" "$ROOT/stage1/classfile.lql" "$ROOT/stage1/emit.lql" "$ROOT/stage1/instructions.lql" "$ROOT/stage1/backend.lql" "$ROOT/stage1/runtime.lql" "$ROOT/stage1/compiler.lql" > "$aggregate" compile_ok stage1_compiler "$aggregate" test -f "$OUT/stage1_compiler/com/tailrecursion/larquil/stage0/compiler__is_named_function.class" || fail "stage1 aggregate helper class exists" ok "stage1 aggregate class files"