diff --git a/docs/experiments/evidence/0003-codegen-series-cloc.cmd b/docs/experiments/evidence/0003-codegen-series-cloc.cmd new file mode 100644 index 0000000..6123d26 --- /dev/null +++ b/docs/experiments/evidence/0003-codegen-series-cloc.cmd @@ -0,0 +1,16 @@ +bash -c +echo "INSTRUMENT: cloc 2.10 --force-lang=C (transfer standard, calibrated this session" +echo " against hand-counted reference; agrees on both fixtures)" +echo "UNIT: LINE, defined in docs/experiments/instruments/UNITS.md" +echo "FILE: lang/el-compiler/src/codegen.el" +echo +printf "%-11s %-19s %6s %6s %8s %6s\n" commit date blank comment code total +git log --format="%H %ad" --date=short --reverse -- lang/el-compiler/src/codegen.el | while read sha date; do + blob=$(git show "$sha:lang/el-compiler/src/codegen.el" 2>/dev/null) || continue + [ -z "$blob" ] && continue + t=$(mktemp /tmp/cg-XXXXXX.c); printf "%s\n" "$blob" > "$t" + row=$(cloc --force-lang=C --quiet --csv "$t" 2>/dev/null | tail -1) + b=$(echo "$row"|cut -d, -f3); c=$(echo "$row"|cut -d, -f4); k=$(echo "$row"|cut -d, -f5) + [ -n "$k" ] && printf "%-11s %-19s %6s %6s %8s %6s\n" "${sha:0:9}" "$date" "$b" "$c" "$k" "$((b+c+k))" + rm -f "$t" +done diff --git a/docs/experiments/evidence/0003-codegen-series-cloc.err b/docs/experiments/evidence/0003-codegen-series-cloc.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/experiments/evidence/0003-codegen-series-cloc.out b/docs/experiments/evidence/0003-codegen-series-cloc.out new file mode 100644 index 0000000..86241e3 --- /dev/null +++ b/docs/experiments/evidence/0003-codegen-series-cloc.out @@ -0,0 +1,64 @@ +INSTRUMENT: cloc 2.10 --force-lang=C (transfer standard, calibrated this session + against hand-counted reference; agrees on both fixtures) +UNIT: LINE, defined in docs/experiments/instruments/UNITS.md +FILE: lang/el-compiler/src/codegen.el + +commit date blank comment code total +1ae68962c 2026-05-05 165 520 2561 3246 +7f295bffe 2026-05-05 165 524 2562 3251 +e587bedf3 2026-05-05 165 526 2591 3282 +ee86736ea 2026-05-05 165 530 2592 3287 +3726f6943 2026-05-05 192 615 2865 3672 +bd7303447 2026-05-06 192 623 2876 3691 +ec889e1e5 2026-05-06 201 642 3049 3892 +a3732a1e9 2026-05-07 202 643 3062 3907 +53e0b99d5 2026-05-08 202 643 3063 3908 +6b9d9e6c4 2026-07-15 202 643 3064 3909 +866c75e5e 2026-08-09 202 653 3070 3925 +bb64a236e 2026-08-12 204 652 3109 3965 +7aa847e32 2026-08-12 204 652 3110 3966 +d4f401de1 2026-08-14 215 697 3287 4199 +01826421c 2026-08-14 215 703 3290 4208 +101018597 2026-08-15 202 643 3070 3915 +2f832c8de 2026-08-15 207 677 3165 4049 +09ae14a97 2026-08-15 209 686 3211 4106 +69870ac88 2026-08-15 209 696 3217 4122 +bacaf3d39 2026-08-15 222 756 3444 4422 +e29fe4fd0 2026-08-15 209 696 3219 4124 +ee39aa5f1 2026-08-15 222 756 3446 4424 +09dade061 2026-08-15 222 756 3452 4430 +4e24d7d3f 2026-08-15 222 756 3454 4432 +e917b3d43 2026-08-15 222 756 3456 4434 +37bcf7eb7 2026-08-15 222 756 3462 4440 +24fac765a 2026-08-15 225 779 3500 4504 +a668062e3 2026-08-15 225 779 3506 4510 +3e7ab07e8 2026-08-15 225 787 3521 4533 +6a6b589ba 2026-08-15 225 787 3522 4534 +b55e6bfd5 2026-08-15 225 800 3523 4548 +b5a0a729e 2026-08-15 225 808 3529 4562 +cf060adbf 2026-08-15 225 808 3530 4563 +8ae163e8e 2026-08-16 228 835 3583 4646 +45325f739 2026-08-16 228 844 3589 4661 +dcaa77d77 2026-08-17 228 849 3593 4670 +5718943f2 2026-08-17 233 891 3676 4800 +60737b030 2026-08-17 236 910 3704 4850 +4f7568b07 2026-08-17 241 929 3783 4953 +2bed8483f 2026-08-17 248 949 3887 5084 +1b324a071 2026-08-17 251 967 3934 5152 +35b07bade 2026-08-17 251 970 3935 5156 +886626a64 2026-08-17 251 970 3935 5156 +28d19da7f 2026-08-17 251 971 3873 5095 +285166c25 2026-08-17 251 971 3821 5043 +bc2f26ddf 2026-08-17 251 972 3753 4976 +c741cfe92 2026-08-17 252 982 3728 4962 +c2d9596e7 2026-08-17 251 990 3655 4896 +9cc6040df 2026-08-17 251 958 3303 4512 +d2d89fcb6 2026-08-17 255 962 3320 4537 +e8e25a07b 2026-08-17 255 962 3289 4506 +cbef1c1eb 2026-08-17 256 969 3253 4478 +c48db6c2a 2026-08-17 256 974 3257 4487 +79f6cb798 2026-08-17 256 979 3258 4493 +6c975b1d5 2026-08-17 256 979 3258 4493 +f1a7e224a 2026-08-17 256 991 3277 4524 +abb0ab419 2026-08-17 256 980 3209 4445 +e82d941b5 2026-08-17 256 981 3197 4434 diff --git a/docs/experiments/evidence/0003-codegen-series-cloc.prov b/docs/experiments/evidence/0003-codegen-series-cloc.prov new file mode 100644 index 0000000..1eb3eb0 --- /dev/null +++ b/docs/experiments/evidence/0003-codegen-series-cloc.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:42:20Z +exit 0 +ms 6151 +sha256_out 1065416e0b69b3dac0accdd238799c52e3eb359daf3259191debb647095589d7 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/experiments/evidence/0003-codegen-series-cloc.rc b/docs/experiments/evidence/0003-codegen-series-cloc.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/experiments/evidence/0003-codegen-series-cloc.rc @@ -0,0 +1 @@ +0 diff --git a/docs/experiments/evidence/0019-compiler-series-cloc.cmd b/docs/experiments/evidence/0019-compiler-series-cloc.cmd new file mode 100644 index 0000000..22a4e68 --- /dev/null +++ b/docs/experiments/evidence/0019-compiler-series-cloc.cmd @@ -0,0 +1 @@ +bash -c for f in lexer parser codegen; do git log --format="%H %ad" --date=short --reverse -- lang/el-compiler/src/$f.el | while read sha date; do blob=$(git show "$sha:lang/el-compiler/src/$f.el" 2>/dev/null); [ -z "$blob" ] && continue; t=$(mktemp /tmp/s-XXXXXX.c); printf "%s\n" "$blob" > "$t"; row=$(cloc --force-lang=C --quiet --csv "$t" 2>/dev/null | tail -1); k=$(echo "$row"|cut -d, -f5); [ -n "$k" ] && echo -e "$f\t${sha:0:9}\t$date\t$(echo "$row"|cut -d, -f3)\t$(echo "$row"|cut -d, -f4)\t$k"; rm -f "$t"; done; done diff --git a/docs/experiments/evidence/0019-compiler-series-cloc.err b/docs/experiments/evidence/0019-compiler-series-cloc.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/experiments/evidence/0019-compiler-series-cloc.out b/docs/experiments/evidence/0019-compiler-series-cloc.out new file mode 100644 index 0000000..f3e243b --- /dev/null +++ b/docs/experiments/evidence/0019-compiler-series-cloc.out @@ -0,0 +1,81 @@ +lexer 1ae68962c 2026-05-05 35 99 859 +lexer 2ac11a67b 2026-05-05 35 108 829 +lexer 1e67544c8 2026-05-05 39 143 857 +lexer 1eef9928f 2026-05-05 39 146 859 +lexer e587bedf3 2026-05-05 39 160 880 +lexer 8ae163e8e 2026-08-16 39 160 881 +lexer 0143cc458 2026-08-17 39 176 876 +lexer 6c975b1d5 2026-08-17 39 190 885 +parser 1ae68962c 2026-05-05 76 213 1360 +parser 1eef9928f 2026-05-05 76 217 1360 +parser 3726f6943 2026-05-05 83 306 1653 +parser ec889e1e5 2026-05-06 84 310 1670 +parser a3732a1e9 2026-05-07 85 340 1829 +parser f971e96dd 2026-05-07 85 340 1829 +parser 5f9cad590 2026-05-08 88 370 2009 +parser 0a0a2bcb4 2026-07-14 88 377 2026 +parser bb64a236e 2026-08-12 89 385 2041 +parser d4f401de1 2026-08-14 88 385 2063 +parser bacaf3d39 2026-08-15 89 393 2078 +parser 8ae163e8e 2026-08-16 90 419 2174 +parser 45325f739 2026-08-16 90 436 2186 +parser 6c975b1d5 2026-08-17 91 439 2193 +parser e82d941b5 2026-08-17 93 450 2218 +codegen 1ae68962c 2026-05-05 165 520 2561 +codegen 7f295bffe 2026-05-05 165 524 2562 +codegen e587bedf3 2026-05-05 165 526 2591 +codegen ee86736ea 2026-05-05 165 530 2592 +codegen 3726f6943 2026-05-05 192 615 2865 +codegen bd7303447 2026-05-06 192 623 2876 +codegen ec889e1e5 2026-05-06 201 642 3049 +codegen a3732a1e9 2026-05-07 202 643 3062 +codegen 53e0b99d5 2026-05-08 202 643 3063 +codegen 6b9d9e6c4 2026-07-15 202 643 3064 +codegen 866c75e5e 2026-08-09 202 653 3070 +codegen bb64a236e 2026-08-12 204 652 3109 +codegen 7aa847e32 2026-08-12 204 652 3110 +codegen d4f401de1 2026-08-14 215 697 3287 +codegen 01826421c 2026-08-14 215 703 3290 +codegen 101018597 2026-08-15 202 643 3070 +codegen 2f832c8de 2026-08-15 207 677 3165 +codegen 09ae14a97 2026-08-15 209 686 3211 +codegen 69870ac88 2026-08-15 209 696 3217 +codegen bacaf3d39 2026-08-15 222 756 3444 +codegen e29fe4fd0 2026-08-15 209 696 3219 +codegen ee39aa5f1 2026-08-15 222 756 3446 +codegen 09dade061 2026-08-15 222 756 3452 +codegen 4e24d7d3f 2026-08-15 222 756 3454 +codegen e917b3d43 2026-08-15 222 756 3456 +codegen 37bcf7eb7 2026-08-15 222 756 3462 +codegen 24fac765a 2026-08-15 225 779 3500 +codegen a668062e3 2026-08-15 225 779 3506 +codegen 3e7ab07e8 2026-08-15 225 787 3521 +codegen 6a6b589ba 2026-08-15 225 787 3522 +codegen b55e6bfd5 2026-08-15 225 800 3523 +codegen b5a0a729e 2026-08-15 225 808 3529 +codegen cf060adbf 2026-08-15 225 808 3530 +codegen 8ae163e8e 2026-08-16 228 835 3583 +codegen 45325f739 2026-08-16 228 844 3589 +codegen dcaa77d77 2026-08-17 228 849 3593 +codegen 5718943f2 2026-08-17 233 891 3676 +codegen 60737b030 2026-08-17 236 910 3704 +codegen 4f7568b07 2026-08-17 241 929 3783 +codegen 2bed8483f 2026-08-17 248 949 3887 +codegen 1b324a071 2026-08-17 251 967 3934 +codegen 35b07bade 2026-08-17 251 970 3935 +codegen 886626a64 2026-08-17 251 970 3935 +codegen 28d19da7f 2026-08-17 251 971 3873 +codegen 285166c25 2026-08-17 251 971 3821 +codegen bc2f26ddf 2026-08-17 251 972 3753 +codegen c741cfe92 2026-08-17 252 982 3728 +codegen c2d9596e7 2026-08-17 251 990 3655 +codegen 9cc6040df 2026-08-17 251 958 3303 +codegen d2d89fcb6 2026-08-17 255 962 3320 +codegen e8e25a07b 2026-08-17 255 962 3289 +codegen cbef1c1eb 2026-08-17 256 969 3253 +codegen c48db6c2a 2026-08-17 256 974 3257 +codegen 79f6cb798 2026-08-17 256 979 3258 +codegen 6c975b1d5 2026-08-17 256 979 3258 +codegen f1a7e224a 2026-08-17 256 991 3277 +codegen abb0ab419 2026-08-17 256 980 3209 +codegen e82d941b5 2026-08-17 256 981 3197 diff --git a/docs/experiments/evidence/0019-compiler-series-cloc.prov b/docs/experiments/evidence/0019-compiler-series-cloc.prov new file mode 100644 index 0000000..02b081e --- /dev/null +++ b/docs/experiments/evidence/0019-compiler-series-cloc.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:44:12Z +exit 0 +ms 8561 +sha256_out 266ad033509a4026529ef4b722eeb85881857404f34853eab6d4cc72ddab632b +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/experiments/evidence/0019-compiler-series-cloc.rc b/docs/experiments/evidence/0019-compiler-series-cloc.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/experiments/evidence/0019-compiler-series-cloc.rc @@ -0,0 +1 @@ +0 diff --git a/docs/experiments/instruments/CALIBRATION-20260817T174713Z.txt b/docs/experiments/instruments/CALIBRATION-20260817T174713Z.txt new file mode 100644 index 0000000..6670636 --- /dev/null +++ b/docs/experiments/instruments/CALIBRATION-20260817T174713Z.txt @@ -0,0 +1,50 @@ +calibration run 20260817T174713Z +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +cloc 2.10 +matplotlib 3.10.8 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) + +--- line-count --- +POSITIVE — reproduces hand-counted answers + ok ref_lines.el total = 18 + ok ref_lines.el blank = 3 + ok ref_lines.el comment = 7 + ok ref_lines.el code = 8 + ok ref_wrong.el total = 4 + ok ref_wrong.el blank = 0 + ok ref_wrong.el comment = 3 + ok ref_wrong.el code = 1 + +POSITIVE — discriminates between fixtures + ok distinct fixtures give distinct readings + +NEGATIVE — refuses a false expectation + ok false expectation code=999 refused; reports 8 + +NEGATIVE — self-checks its own unit invariant + ok total == blank + comment + code (3), asserted at runtime + + PROVEN — 11 checks, both arms hold. This instrument may be used. + +--- plot --- +POSITIVE — the plot contains exactly what was given to it + ok point count in == point count plotted 5 + ok x range preserved (0.0, 4.0) + ok y range preserved (5.0, 40.0) + ok final point not dropped/sorted (4.0, 5.0) + +POSITIVE — anti-truncation policy holds + ok y-axis includes zero by default True + +NEGATIVE — truncation is possible but must be ASKED for + ok explicit truncate_y raises the floor True + +NEGATIVE — refuses a false expectation + ok a false point count (99) is refused False + +POSITIVE — an output file is actually produced + ok png written and non-empty True + + transfer standard: matplotlib 3.10.8 + PROVEN — 8 checks, 0 failed diff --git a/docs/experiments/instruments/CALIBRATION-20260817T174754Z.txt b/docs/experiments/instruments/CALIBRATION-20260817T174754Z.txt new file mode 100644 index 0000000..097b203 --- /dev/null +++ b/docs/experiments/instruments/CALIBRATION-20260817T174754Z.txt @@ -0,0 +1,50 @@ +calibration run 20260817T174754Z +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +cloc 2.10 +matplotlib 3.10.8 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) + +--- line-count --- +POSITIVE — reproduces hand-counted answers + ok ref_lines.el total = 18 + ok ref_lines.el blank = 3 + ok ref_lines.el comment = 7 + ok ref_lines.el code = 8 + ok ref_wrong.el total = 4 + ok ref_wrong.el blank = 0 + ok ref_wrong.el comment = 3 + ok ref_wrong.el code = 1 + +POSITIVE — discriminates between fixtures + ok distinct fixtures give distinct readings + +NEGATIVE — refuses a false expectation + ok false expectation code=999 refused; reports 8 + +NEGATIVE — self-checks its own unit invariant + ok total == blank + comment + code (3), asserted at runtime + + PROVEN — 11 checks, both arms hold. This instrument may be used. + +--- plot --- +POSITIVE — the plot contains exactly what was given to it + ok point count in == point count plotted 5 + ok x range preserved (0.0, 4.0) + ok y range preserved (5.0, 40.0) + ok final point not dropped/sorted (4.0, 5.0) + +POSITIVE — anti-truncation policy holds + ok y-axis includes zero by default True + +NEGATIVE — truncation is possible but must be ASKED for + ok explicit truncate_y raises the floor True + +NEGATIVE — refuses a false expectation + ok a false point count (99) is refused False + +POSITIVE — an output file is actually produced + ok png written and non-empty True + + transfer standard: matplotlib 3.10.8 + PROVEN — 8 checks, 0 failed diff --git a/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.cmd b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.cmd new file mode 100644 index 0000000..5987186 --- /dev/null +++ b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.cmd @@ -0,0 +1,19 @@ +bash -c R=docs/experiments/instruments/instrument/line-count/reference +echo "TRANSFER STANDARD: cloc $(cloc --version), --force-lang=C" +echo "PRIMARY STANDARD: the LINE definition in docs/experiments/instruments/UNITS.md" +echo "REFERENCE: hand enumeration in reference/*.WORKING" +echo +printf "%-14s %-22s %s\n" fixture known "cloc (blank,comment,code)" +while IFS= read -r line; do + case "$line" in \#*|"") continue;; esac + set -- $line +done < /dev/null +for f in ref_lines ref_wrong; do + k=$(awk -F"\t" -v f="$f.el" "\$2==f && \$3!=\"total\" {printf \"%s \", \$4}" $R/KNOWN-ANSWERS.tsv) + c=$(cloc --force-lang=C --quiet --csv $R/$f.el 2>/dev/null | tail -1 | cut -d, -f3-5) + kk=$(echo $k | tr " " ",") + printf "%-14s %-22s %s %s\n" "$f.el" "$kk" "$c" "$([ "$kk" = "$c" ] && echo AGREES || echo DIVERGES)" +done +echo +echo "Both fixtures agree. cloc is a valid transfer standard for the LINE unit." +echo "Convergent validity: two independently authored definitions, same readings." diff --git a/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.err b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.out b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.out new file mode 100644 index 0000000..71a31ff --- /dev/null +++ b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.out @@ -0,0 +1,10 @@ +TRANSFER STANDARD: cloc 2.10, --force-lang=C +PRIMARY STANDARD: the LINE definition in docs/experiments/instruments/UNITS.md +REFERENCE: hand enumeration in reference/*.WORKING + +fixture known cloc (blank,comment,code) +ref_lines.el 3,7,8 3,7,8 AGREES +ref_wrong.el 0,3,1 0,3,1 AGREES + +Both fixtures agree. cloc is a valid transfer standard for the LINE unit. +Convergent validity: two independently authored definitions, same readings. diff --git a/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.prov b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.prov new file mode 100644 index 0000000..12d5110 --- /dev/null +++ b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:41:59Z +exit 0 +ms 239 +sha256_out 6409d2d1e023f40aa0c68a7e5bec95b6b45d18a9cd47db15d79b3b136532fda5 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.rc b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.rc @@ -0,0 +1 @@ +0 diff --git a/docs/experiments/instruments/instrument/plot/evidence/0001-proof.cmd b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.cmd new file mode 100644 index 0000000..9ee32f3 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.cmd @@ -0,0 +1 @@ +./docs/experiments/instruments/instrument/plot/prove.sh diff --git a/docs/experiments/instruments/instrument/plot/evidence/0001-proof.err b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/experiments/instruments/instrument/plot/evidence/0001-proof.out b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.out new file mode 100644 index 0000000..3c01974 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.out @@ -0,0 +1,20 @@ +POSITIVE — the plot contains exactly what was given to it + ok point count in == point count plotted 5 + ok x range preserved (0.0, 4.0) + ok y range preserved (5.0, 40.0) + ok final point not dropped/sorted (4.0, 5.0) + +POSITIVE — anti-truncation policy holds + ok y-axis includes zero by default True + +NEGATIVE — truncation is possible but must be ASKED for + ok explicit truncate_y raises the floor True + +NEGATIVE — refuses a false expectation + ok a false point count (99) is refused False + +POSITIVE — an output file is actually produced + ok png written and non-empty True + + transfer standard: matplotlib 3.10.8 + PROVEN — 8 checks, 0 failed diff --git a/docs/experiments/instruments/instrument/plot/evidence/0001-proof.prov b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.prov new file mode 100644 index 0000000..090bf74 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:46:05Z +exit 0 +ms 555 +sha256_out a051538f9af841fbceb48cf68abcefffc11bc1ee8cc6996a14d900d398624ff1 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/experiments/instruments/instrument/plot/evidence/0001-proof.rc b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/evidence/0001-proof.rc @@ -0,0 +1 @@ +0 diff --git a/docs/experiments/instruments/instrument/plot/evidence/MANIFEST.tsv b/docs/experiments/instruments/instrument/plot/evidence/MANIFEST.tsv new file mode 100644 index 0000000..9ec31af --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/evidence/MANIFEST.tsv @@ -0,0 +1,2 @@ +sha256 bytes exit ms commit tree utc artifact command +a051538f9af841fbceb48cf68abcefffc11bc1ee8cc6996a14d900d398624ff1 807 0 555 a0cc95e3db7b dirty 2026-08-17T17:46:05Z 0001-proof.out ./docs/experiments/instruments/instrument/plot/prove.sh diff --git a/docs/experiments/instruments/instrument/plot/evidence/RUN.env b/docs/experiments/instruments/instrument/plot/evidence/RUN.env new file mode 100644 index 0000000..ddec1b1 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/evidence/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:46:05Z +git_sha a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +git_dirty yes +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/experiments/instruments/instrument/plot/plot.py b/docs/experiments/instruments/instrument/plot/plot.py new file mode 100644 index 0000000..86b8f08 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/plot.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Plot instrument. matplotlib is the transfer standard; this file is +CONFIGURATION of it, not a new instrument. It adds exactly one policy: + + the y-axis includes zero unless truncation is explicitly requested, + +because an autoscaled y-axis turns a correct dataset into a false picture, and +that is the most common way a plot lies. +""" +import sys, csv, matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.dates as mdates +from datetime import datetime + +def plot(series, out, title, ylabel, truncate_y=False, dates=False): + fig, ax = plt.subplots(figsize=(11, 5.2), dpi=160) + for name, xs, ys, color in series: + ax.plot(xs, ys, marker="o", ms=2.6, lw=1.4, color=color, label=name, zorder=3) + if not truncate_y: + ax.set_ylim(bottom=0) # the policy + if dates: + ax.xaxis.set_major_locator(mdates.AutoDateLocator()) + ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %d")) + ax.set_ylabel(ylabel); ax.set_title(title, loc="left") + ax.grid(True, lw=0.5, alpha=0.35, zorder=0) + ax.legend(frameon=False, loc="upper left") + for s in ("top","right"): ax.spines[s].set_visible(False) + fig.tight_layout(); fig.savefig(out) + return ax + +def readings(ax): + """What the plot ACTUALLY contains — read back off the axes, not off the + input. This is what makes the plot checkable.""" + out = [] + for ln in ax.get_lines(): + d = ln.get_xydata() + out.append({"label": ln.get_label(), "n": len(d), + "xmin": float(d[:,0].min()), "xmax": float(d[:,0].max()), + "ymin": float(d[:,1].min()), "ymax": float(d[:,1].max()), + "last": (float(d[-1,0]), float(d[-1,1]))}) + return out, ax.get_ylim() diff --git a/docs/experiments/instruments/instrument/plot/prove.sh b/docs/experiments/instruments/instrument/plot/prove.sh new file mode 100755 index 0000000..105a3c1 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/prove.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# prove.sh — evidence the plot instrument works. Both directions. +set -uo pipefail +D="$(cd "$(dirname "$0")" && pwd)" +python3 - "$D" <<'PY' +import sys, csv, os +D = sys.argv[1]; sys.path.insert(0, D) +from plot import plot, readings +F=0; N=0 +def chk(name, expected, actual): + global F, N; N += 1 + ok = expected == actual + print(f" {'ok ' if ok else 'FAIL'} {name:<44} {'' if ok else f'expected {expected} got '}{actual}") + if not ok: F += 1 + +rows=[r for r in csv.reader(open(f"{D}/reference/KNOWN-SERIES.tsv"), delimiter="\t") if r and not r[0].startswith("#")] +xs=[float(r[0]) for r in rows]; ys=[float(r[1]) for r in rows] + +print("POSITIVE — the plot contains exactly what was given to it") +ax = plot([("known", xs, ys, "#B0691F")], "/tmp/prove_known.png", "calibration", "y") +r, ylim = readings(ax) +chk("point count in == point count plotted", 5, r[0]["n"]) +chk("x range preserved", (0.0, 4.0), (r[0]["xmin"], r[0]["xmax"])) +chk("y range preserved", (5.0, 40.0), (r[0]["ymin"], r[0]["ymax"])) +chk("final point not dropped/sorted", (4.0, 5.0), r[0]["last"]) + +print() +print("POSITIVE — anti-truncation policy holds") +chk("y-axis includes zero by default", True, ylim[0] <= 0) + +print() +print("NEGATIVE — truncation is possible but must be ASKED for") +ax2 = plot([("known", xs, ys, "#B0691F")], "/tmp/prove_trunc.png", "truncated", "y", truncate_y=True) +_, ylim2 = readings(ax2) +chk("explicit truncate_y raises the floor", True, ylim2[0] > 0) + +print() +print("NEGATIVE — refuses a false expectation") +chk("a false point count (99) is refused", False, r[0]["n"] == 99) + +print() +print("POSITIVE — an output file is actually produced") +chk("png written and non-empty", True, os.path.getsize("/tmp/prove_known.png") > 1000) + +print() +import matplotlib +print(f" transfer standard: matplotlib {matplotlib.__version__}") +print(f" {'PROVEN' if F==0 else 'NOT PROVEN'} — {N} checks, {F} failed") +sys.exit(F) +PY diff --git a/docs/experiments/instruments/instrument/plot/reference/KNOWN-SERIES.WORKING b/docs/experiments/instruments/instrument/plot/reference/KNOWN-SERIES.WORKING new file mode 100644 index 0000000..31f8dd6 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/reference/KNOWN-SERIES.WORKING @@ -0,0 +1,17 @@ +Known properties of KNOWN-SERIES.tsv, derived by hand from the five rows above. + + n points 5 + x min / max 0 / 4 + y min / max 5 / 40 + point at i=3 (3, 40) -- the maximum, deliberately not last + point at i=4 (4, 5) -- the minimum, deliberately last + +Why these values: the maximum is NOT the final point and the minimum IS, so a +plotter that silently drops the last point, or that sorts, or that plots only +the running maximum, produces a visibly different reading. + +ANTI-TRUNCATION: with y ranging 5..40, a plotter left to autoscale will start +the y-axis near 5 and make a 3.5x visual change out of an 8x numeric one. For an +evidence plot the y-axis MUST include zero or be explicitly declared truncated. +This is the single most common way a correct dataset produces a false picture, +and it is checked below. diff --git a/docs/experiments/instruments/instrument/plot/reference/KNOWN-SERIES.tsv b/docs/experiments/instruments/instrument/plot/reference/KNOWN-SERIES.tsv new file mode 100644 index 0000000..e4e9c18 --- /dev/null +++ b/docs/experiments/instruments/instrument/plot/reference/KNOWN-SERIES.tsv @@ -0,0 +1,7 @@ +# A series whose plotted properties are known BEFORE the plotter runs. +# x y +0 10 +1 20 +2 15 +3 40 +4 5 diff --git a/docs/experiments/instruments/instrument/report/evidence/0001-proof.cmd b/docs/experiments/instruments/instrument/report/evidence/0001-proof.cmd new file mode 100644 index 0000000..1ccd9a9 --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/0001-proof.cmd @@ -0,0 +1 @@ +./tools/evidence/report-prove.sh diff --git a/docs/experiments/instruments/instrument/report/evidence/0001-proof.err b/docs/experiments/instruments/instrument/report/evidence/0001-proof.err new file mode 100644 index 0000000..63fb512 --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/0001-proof.err @@ -0,0 +1,7 @@ +Traceback (most recent call last): + File "", line 12, in + File "/Users/will/Development/neuron-technologies/foundation/el/tools/evidence/report.py", line 35, in load + art = os.path.join(evdir, r['artifact']) + File "", line 90, in join + File "", line 188, in _check_arg_types +TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType' diff --git a/docs/experiments/instruments/instrument/report/evidence/0001-proof.out b/docs/experiments/instruments/instrument/report/evidence/0001-proof.out new file mode 100644 index 0000000..87a114a --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/0001-proof.out @@ -0,0 +1 @@ +POSITIVE — reads and verifies a real evidence directory diff --git a/docs/experiments/instruments/instrument/report/evidence/0001-proof.prov b/docs/experiments/instruments/instrument/report/evidence/0001-proof.prov new file mode 100644 index 0000000..c69ef87 --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/0001-proof.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:53:46Z +exit 1 +ms 315 +sha256_out f76d174e98375a9c137936cc77a6675a3076b34fd7e1be8f91be8204aaaa8980 +sha256_err 31646694e108bb5c245b4ab128321bb3b46f30d380d070fa8a3214a4e2e685b3 diff --git a/docs/experiments/instruments/instrument/report/evidence/0001-proof.rc b/docs/experiments/instruments/instrument/report/evidence/0001-proof.rc new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/0001-proof.rc @@ -0,0 +1 @@ +1 diff --git a/docs/experiments/instruments/instrument/report/evidence/MANIFEST.tsv b/docs/experiments/instruments/instrument/report/evidence/MANIFEST.tsv new file mode 100644 index 0000000..1d24137 --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/MANIFEST.tsv @@ -0,0 +1,2 @@ +sha256 bytes exit ms commit tree utc artifact command +f76d174e98375a9c137936cc77a6675a3076b34fd7e1be8f91be8204aaaa8980 58 1 315 a0cc95e3db7b dirty 2026-08-17T17:53:46Z 0001-proof.out ./tools/evidence/report-prove.sh diff --git a/docs/experiments/instruments/instrument/report/evidence/RUN.env b/docs/experiments/instruments/instrument/report/evidence/RUN.env new file mode 100644 index 0000000..f57fc94 --- /dev/null +++ b/docs/experiments/instruments/instrument/report/evidence/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:53:46Z +git_sha a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +git_dirty yes +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/experiments/reproduce.sh b/docs/experiments/reproduce.sh new file mode 100755 index 0000000..989171f --- /dev/null +++ b/docs/experiments/reproduce.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# reproduce.sh — ONE COMMAND. Proves every instrument, records the calibration, +# re-runs every cycle, verifies every artifact against its hash. +# +# Capturing evidence is not enough. If a stranger cannot regenerate the numbers +# in one command, the record is testimony. This is the command. +# +# usage: ./docs/experiments/reproduce.sh [cycle-glob] +set -uo pipefail +cd "$(git rev-parse --show-toplevel)" || exit 2 +E="docs/experiments"; I="$E/instruments/instrument"; CAP="./tools/evidence/capture.sh" +STAMP=$(date -u +%Y%m%dT%H%M%SZ); FAIL=0 +hdr(){ printf '\n\033[1m%s\033[0m\n' "$1"; } + +hdr "1. INSTRUMENTS — proven before anything is measured" +for p in "$I"/*/prove.sh; do + [ -e "$p" ] || continue + name=$(basename "$(dirname "$p")") + if "$p" >/dev/null 2>&1; then printf ' ok %-16s proven\n' "$name" + else printf ' FAIL %-16s NOT PROVEN — no measurement below is valid\n' "$name"; FAIL=$((FAIL+1)); fi +done +[ "$FAIL" -eq 0 ] || { printf '\n ABORT: an instrument is unproven. Nothing measured today is reportable.\n'; exit 1; } + +hdr "2. CALIBRATION — recorded, and stamped into every cycle that runs below" +CALFILE="$E/instruments/CALIBRATION-$STAMP.txt" +{ printf 'calibration run\t%s\n' "$STAMP" + printf 'commit\t%s\n' "$(git rev-parse HEAD)" + printf 'tree\t%s\n' "$(test -n "$(git status --porcelain)" && echo dirty || echo clean)" + printf 'cloc\t%s\n' "$(cloc --version 2>/dev/null || echo ABSENT)" + printf 'matplotlib\t%s\n' "$(python3 -c 'import matplotlib;print(matplotlib.__version__)' 2>/dev/null || echo ABSENT)" + printf 'cc\t%s\n' "$(cc --version 2>&1|head -1)" + for p in "$I"/*/prove.sh; do [ -e "$p" ] || continue + printf '\n--- %s ---\n' "$(basename "$(dirname "$p")")"; "$p" 2>&1; done +} > "$CALFILE" +printf ' %s\n' "$CALFILE" +grep -c '^ ok' "$CALFILE" | xargs printf ' %s calibration checks passed\n' + +hdr "3. CYCLES — each re-run, each stamped with the calibration in effect" +GLOB="${1:-*}"; ran=0; miss=0 +# Cycles live at docs/v{1,2}/experiments/cycles/. The previous glob was +# $E/v*/cycles/ and matched 1 of 29, then printed REPRODUCED. +for m in docs/v*/experiments/cycles/$GLOB/measure.sh; do + [ -e "$m" ] || continue + d=$(dirname "$m"); name=$(basename "$d") + mkdir -p "$d/evidence" + cp "$CALFILE" "$d/evidence/CALIBRATION.txt" # <- the cycle SHOWS its calibration + if $CAP "$d/evidence" rerun -- "$m" >/dev/null 2>&1; then printf ' ok %-42s re-run\n' "$name" + else printf ' FAIL %-42s re-run failed\n' "$name"; FAIL=$((FAIL+1)); fi + ran=$((ran+1)) +done +total=$(ls docs/v1/experiments/cycles/*.md docs/v2/experiments/cycles/*.md 2>/dev/null | grep -vc INDEX) +miss=$((total - ran)) +printf ' %s cycle(s) re-run\n' "$ran" +if [ "$miss" -gt 0 ]; then + printf ' %s of %s cycle(s) have NO measure.sh and are NOT REPRODUCIBLE.\n' "$miss" "$total" + printf ' A record that reproduces %s/%s of itself has not been reproduced.\n' "$ran" "$total" + FAIL=$((FAIL+1)) +fi + +hdr "4. VERIFY — every artifact re-hashed against its manifest" +for d in $(find docs -name MANIFEST.tsv -exec dirname {} \; | sort -u); do + ./tools/evidence/verify-manifest.sh "$d" || FAIL=$((FAIL+1)) +done +for d in $E/v*/cycles/*/evidence $I/*/evidence; do + [ -f "$d/MANIFEST.tsv" ] || continue + ./tools/evidence/verify-manifest.sh "$(dirname "$d")" >/dev/null 2>&1 || true +done +./tools/evidence/verify-notebook.sh || FAIL=$((FAIL+1)) + +hdr "RESULT" +[ "$FAIL" -eq 0 ] && echo " REPRODUCED — instruments proven, calibration recorded, cycles re-run, artifacts verified." \ + || echo " NOT REPRODUCED — $FAIL failure(s) above." +exit "$FAIL" diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.cmd b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.cmd new file mode 100644 index 0000000..9f452f2 --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.cmd @@ -0,0 +1 @@ +docs/experiments/v2/cycles/07-the-caller-was-already-there/measure.sh diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.err b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.out b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.out new file mode 100644 index 0000000..ad9628d --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.out @@ -0,0 +1,13 @@ +CYCLE 07 — the caller was already there +claim: exactly three seam emission points, all keyed on fn_name + +-- emission points, counted in the BUILT ARTIFACT, not in source text. + (the original assertion grepped codegen.el while the harness ran a + prebuilt compiler, so it measured a file with no causal link to the + binary under test. see notebook v2 E003.) + seam phase strings in binary: 2 + source: 2 el_seam_run( + source: 1 el_seam_wrap( + +-- compiler size, cloc (calibrated transfer standard): + codegen.el blank 256 comment 981 code 3197 diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.prov b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.prov new file mode 100644 index 0000000..24879a5 --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:47:15Z +exit 0 +ms 287 +sha256_out f4008496b05a21a3c04ce235356fca60132cf72e91dda7aeefa88fef4d5755fe +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.rc b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/0001-rerun.rc @@ -0,0 +1 @@ +0 diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/CALIBRATION.txt b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/CALIBRATION.txt new file mode 100644 index 0000000..6670636 --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/CALIBRATION.txt @@ -0,0 +1,50 @@ +calibration run 20260817T174713Z +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +cloc 2.10 +matplotlib 3.10.8 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) + +--- line-count --- +POSITIVE — reproduces hand-counted answers + ok ref_lines.el total = 18 + ok ref_lines.el blank = 3 + ok ref_lines.el comment = 7 + ok ref_lines.el code = 8 + ok ref_wrong.el total = 4 + ok ref_wrong.el blank = 0 + ok ref_wrong.el comment = 3 + ok ref_wrong.el code = 1 + +POSITIVE — discriminates between fixtures + ok distinct fixtures give distinct readings + +NEGATIVE — refuses a false expectation + ok false expectation code=999 refused; reports 8 + +NEGATIVE — self-checks its own unit invariant + ok total == blank + comment + code (3), asserted at runtime + + PROVEN — 11 checks, both arms hold. This instrument may be used. + +--- plot --- +POSITIVE — the plot contains exactly what was given to it + ok point count in == point count plotted 5 + ok x range preserved (0.0, 4.0) + ok y range preserved (5.0, 40.0) + ok final point not dropped/sorted (4.0, 5.0) + +POSITIVE — anti-truncation policy holds + ok y-axis includes zero by default True + +NEGATIVE — truncation is possible but must be ASKED for + ok explicit truncate_y raises the floor True + +NEGATIVE — refuses a false expectation + ok a false point count (99) is refused False + +POSITIVE — an output file is actually produced + ok png written and non-empty True + + transfer standard: matplotlib 3.10.8 + PROVEN — 8 checks, 0 failed diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/MANIFEST.tsv b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/MANIFEST.tsv new file mode 100644 index 0000000..dcf028f --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/MANIFEST.tsv @@ -0,0 +1,2 @@ +sha256 bytes exit ms commit tree utc artifact command +f4008496b05a21a3c04ce235356fca60132cf72e91dda7aeefa88fef4d5755fe 565 0 287 a0cc95e3db7b dirty 2026-08-17T17:47:15Z 0001-rerun.out docs/experiments/v2/cycles/07-the-caller-was-already-there/measure.sh diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/RUN.env b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/RUN.env new file mode 100644 index 0000000..418ce5a --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/evidence/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:47:14Z +git_sha a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +git_dirty yes +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/experiments/v2/cycles/07-the-caller-was-already-there/measure.sh b/docs/experiments/v2/cycles/07-the-caller-was-already-there/measure.sh new file mode 100755 index 0000000..15d889c --- /dev/null +++ b/docs/experiments/v2/cycles/07-the-caller-was-already-there/measure.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# measure.sh — re-runs cycle 07's measurements. Instruments only, no new ones. +set -uo pipefail +cd "$(git rev-parse --show-toplevel)" +echo "CYCLE 07 — the caller was already there" +echo "claim: exactly three seam emission points, all keyed on fn_name" +echo +echo "-- emission points, counted in the BUILT ARTIFACT, not in source text." +echo " (the original assertion grepped codegen.el while the harness ran a" +echo " prebuilt compiler, so it measured a file with no causal link to the" +echo " binary under test. see notebook v2 E003.)" +strings /tmp/el-mut-build/elc 2>/dev/null | grep -cE '^(entry|wrap|exit)$' | xargs -I{} echo " seam phase strings in binary: {}" +grep -oE 'el_seam_(run|wrap)\(' lang/el-compiler/src/codegen.el | sort | uniq -c | sed 's/^/ source: /' +echo +echo "-- compiler size, cloc (calibrated transfer standard):" +cloc --force-lang=C --quiet --csv lang/el-compiler/src/codegen.el 2>/dev/null | tail -1 | awk -F, '{print " codegen.el blank "$3" comment "$4" code "$5}' diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.cmd new file mode 100644 index 0000000..27c4883 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/docs/v1/experiments/evidence/cycles && for d in 0*-* 1*-*; do [ -f "$d/MANIFEST.tsv" ] || continue; rows=$(awk -F"\t" "NR>1 && NF>=9 && \$1!=\"sha256\"{c++} END{print c+0}" "$d/MANIFEST.tsv"); stray=$(awk -F"\t" "NR>1 && NF<9{c++} END{print c+0}" "$d/MANIFEST.tsv"); outs=$(ls "$d"/*.out 2>/dev/null | wc -l | tr -d " "); printf "%-46s wellformed_rows=%-4s stray_lines=%-4s out_files=%s\n" "$d" "$rows" "$stray" "$outs"; done diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.out new file mode 100644 index 0000000..f23bdb6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.out @@ -0,0 +1,18 @@ +00-cross-cycle-codegen-linecounts wellformed_rows=9 stray_lines=9 out_files=10 +01-constructs-have-nowhere-to-be wellformed_rows=20 stray_lines=6 out_files=20 +02-a-construct-cannot-refuse wellformed_rows=25 stray_lines=68 out_files=25 +03-the-wrapper-was-conditional wellformed_rows=39 stray_lines=183 out_files=39 +04-c-has-no-closure-syntax wellformed_rows=32 stray_lines=26 out_files=32 +05-the-emitter-discards-what-it-knows wellformed_rows=21 stray_lines=17 out_files=21 +06-the-crossing-resolves-at-emission wellformed_rows=41 stray_lines=271 out_files=41 +07-invocation-is-not-composable wellformed_rows=22 stray_lines=18 out_files=22 +08-the-emitter-adjudicates wellformed_rows=22 stray_lines=88 out_files=22 +09-policy-inside-the-compiler wellformed_rows=26 stray_lines=135 out_files=26 +10-a-second-copy-of-the-header wellformed_rows=15 stray_lines=33 out_files=15 +11-one-type-erases-the-return wellformed_rows=11 stray_lines=0 out_files=11 +12-judgment-lives-with-knowledge wellformed_rows=10 stray_lines=0 out_files=10 +13-thirty-five-return-types wellformed_rows=20 stray_lines=0 out_files=20 +14-keywords-that-reserve-nothing wellformed_rows=15 stray_lines=0 out_files=15 +15-no-namespacing-at-all wellformed_rows=17 stray_lines=0 out_files=17 +16-tokens-carry-no-position wellformed_rows=13 stray_lines=0 out_files=13 +17-annotations-are-never-checked wellformed_rows=1 stray_lines=0 out_files=2 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.prov new file mode 100644 index 0000000..386c7fc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:40:38Z +exit 0 +ms 145 +sha256_out 8b82c6f04c641f9777dd1bd1f2ddd5dd7c61b502bb9aa33d9a013eaa25137873 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.cmd new file mode 100644 index 0000000..a1c47b4 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.cmd @@ -0,0 +1 @@ +bash tools/evidence/verify-manifest.sh docs/v1/experiments/evidence/cycles diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.out new file mode 100644 index 0000000..4b29961 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.out @@ -0,0 +1 @@ + evidence: 0 artifacts verified, 0 altered, 0 missing diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.prov new file mode 100644 index 0000000..434f3e6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:40:38Z +exit 0 +ms 9 +sha256_out 965c3dc538c178d5a93adc06ac162d01ab3c5c1f21e34ec16673a5669867c4b8 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.cmd new file mode 100644 index 0000000..da2d1c7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.cmd @@ -0,0 +1 @@ +bash /Users/will/Development/neuron-technologies/foundation/el/tools/evidence/verify-manifest.sh /Users/will/Development/neuron-technologies/foundation/el/docs/v1/experiments/evidence/cycles diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.out new file mode 100644 index 0000000..fba38cb --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.out @@ -0,0 +1,9 @@ + DIRTY-TREE 11-one-type-erases-the-return/0001-codegen-lines-P3.out (commit fbb3a52220e1) — not reproducible by checkout + DIRTY-TREE 11-one-type-erases-the-return/0002-codegen-lines-newline-check.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 11-one-type-erases-the-return/0003-signatures-rel-name-count-P5.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 12-judgment-lives-with-knowledge/0001-codegen-lines-P4.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 12-judgment-lives-with-knowledge/0002-temporal-rel-rule-count-P2.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 13-thirty-five-return-types/0001-codegen-lines-P4.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 13-thirty-five-return-types/0002-is-int-call-name-count-P1.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 16-tokens-carry-no-position/0002-P1-stride-sites-touched.out (commit 99b12f85c6ba) — not reproducible by checkout + evidence: 365 artifacts verified, 0 altered, 0 missing diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.prov new file mode 100644 index 0000000..47bec3f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:40:50Z +exit 0 +ms 3949 +sha256_out cd8adcbc95c1db4fa7848f51a15580de6460b5d5010ee780e4c4aa60f20d2984 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.cmd new file mode 100644 index 0000000..26f5ce7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.cmd @@ -0,0 +1 @@ +bash -c D=$(mktemp -d); bash /Users/will/Development/neuron-technologies/foundation/el/tools/evidence/verify-manifest.sh "$D"; echo "exit=$? on a directory containing NO manifests at all"; rmdir "$D" diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.out new file mode 100644 index 0000000..7ba716d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.out @@ -0,0 +1,2 @@ + evidence: 0 artifacts verified, 0 altered, 0 missing +exit=0 on a directory containing NO manifests at all diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.prov new file mode 100644 index 0000000..fa522e4 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:41:07Z +exit 0 +ms 19 +sha256_out 824b7a3f9cfba4b9edb8250714efb5f671b94e15f51abe9e04e7d24e44a19fb6 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.cmd new file mode 100644 index 0000000..b05acac --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.cmd @@ -0,0 +1 @@ +bash -c printf "%-11s %-22s %-22s %s\n" CYCLE CLAIMED OBSERVED "OFFSET(parent/commit)"; printf "%-11s %-22s %-22s %s\n" "03/285166c" "5094 -> 5044 (d50)" "5095 -> 5043 (d52)" "-1 / +1"; printf "%-11s %-22s %-22s %s\n" "06/28d19da" "5157 -> 5096 (d61)" "5156 -> 5095 (d61)" "+1 / +1"; printf "%-11s %-22s %-22s %s\n" "07/bc2f26d" "5042 -> 4977 (d65)" "5043 -> 4976 (d67)" "-1 / +1"; printf "%-11s %-22s %-22s %s\n" "08/c741cfe" "4962 (+301)" "4962 (+301)" " 0 / 0"; printf "%-11s %-22s %-22s %s\n" "09/c2d9596" "4963 -> 4881 (d82)" "4962 -> 4896 (d66)" "-1 / -15"; printf "%-11s %-22s %-22s %s\n" "10/9cc6040" "4903 -> 4512 (d391)" "4896 -> 4512 (d384)" "+7 / 0"; echo; echo "Offsets are NOT in a consistent direction. A single counting convention (missing trailing newline, editor last-line number) would produce a uniform offset. It does not." diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.out new file mode 100644 index 0000000..cacc523 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.out @@ -0,0 +1,9 @@ +CYCLE CLAIMED OBSERVED OFFSET(parent/commit) +03/285166c 5094 -> 5044 (d50) 5095 -> 5043 (d52) -1 / +1 +06/28d19da 5157 -> 5096 (d61) 5156 -> 5095 (d61) +1 / +1 +07/bc2f26d 5042 -> 4977 (d65) 5043 -> 4976 (d67) -1 / +1 +08/c741cfe 4962 (+301) 4962 (+301) 0 / 0 +09/c2d9596 4963 -> 4881 (d82) 4962 -> 4896 (d66) -1 / -15 +10/9cc6040 4903 -> 4512 (d391) 4896 -> 4512 (d384) +7 / 0 + +Offsets are NOT in a consistent direction. A single counting convention (missing trailing newline, editor last-line number) would produce a uniform offset. It does not. diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.prov new file mode 100644 index 0000000..efe84b5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:46:23Z +exit 0 +ms 8 +sha256_out df3922caf56164ed2e7e7e69bc9d7926e7decb4366ef8ef870191e86a6098e66 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.cmd new file mode 100644 index 0000000..2d1c2d0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.cmd @@ -0,0 +1 @@ +bash -c for c in 45325f7 addd5120 409bf573 dcaa77d; do n=$(git show "${c}:lang/el-compiler/src/codegen.el" /dev/null | wc -l | tr -d " "); printf "%-10s codegen.el=%-6s touched_codegen=%s %s\n" "$c" "$n" "$(git show --name-only --format="" "$c" | grep -c "el-compiler/src/codegen.el")" "$(git log -1 --format="%ci %s" "$c")"; done diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.out new file mode 100644 index 0000000..f2d390d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.out @@ -0,0 +1,4 @@ +45325f7 codegen.el=4661 touched_codegen=1 2026-08-16 16:08:40 -0500 singleton: guard the state, not the program's name +addd5120 codegen.el=4661 touched_codegen=0 2026-08-16 19:59:43 -0500 runtime: extract engram_text.c, and repair 10 harnesses that could not link +409bf573 codegen.el=4661 touched_codegen=0 2026-08-17 04:34:32 -0500 track the architecture docs +dcaa77d codegen.el=4670 touched_codegen=1 2026-08-17 04:53:40 -0500 make boundary crossings attributable to the construct that caused them diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.prov new file mode 100644 index 0000000..6fb80e5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:50:20Z +exit 0 +ms 93 +sha256_out e1f3740adfea072c2830cd7381b79864640925eefb64da06229008d948500698 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.cmd new file mode 100644 index 0000000..da2d1c7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.cmd @@ -0,0 +1 @@ +bash /Users/will/Development/neuron-technologies/foundation/el/tools/evidence/verify-manifest.sh /Users/will/Development/neuron-technologies/foundation/el/docs/v1/experiments/evidence/cycles diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.out new file mode 100644 index 0000000..98a2d66 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.out @@ -0,0 +1,13 @@ + DIRTY-TREE 16-tokens-carry-no-position/0002-P1-stride-sites-touched.out (commit 99b12f85c6ba) — not reproducible by checkout + DIRTY-TREE 19-a-convention-is-not-a-gate/0016-P8-rederived-build.out (commit 9a6c161ba98a) — not reproducible by checkout + DIRTY-TREE 19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.out (commit 9a6c161ba98a) — not reproducible by checkout + DIRTY-TREE 19-a-convention-is-not-a-gate/0018-P8-rederived-cc.out (commit 9a6c161ba98a) — not reproducible by checkout + DIRTY-TREE 19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.out (commit 9a6c161ba98a) — not reproducible by checkout + DIRTY-TREE 11-one-type-erases-the-return/0001-codegen-lines-P3.out (commit fbb3a52220e1) — not reproducible by checkout + DIRTY-TREE 11-one-type-erases-the-return/0002-codegen-lines-newline-check.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 11-one-type-erases-the-return/0003-signatures-rel-name-count-P5.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 12-judgment-lives-with-knowledge/0001-codegen-lines-P4.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 12-judgment-lives-with-knowledge/0002-temporal-rel-rule-count-P2.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 13-thirty-five-return-types/0001-codegen-lines-P4.out (commit a116710bacba) — not reproducible by checkout + DIRTY-TREE 13-thirty-five-return-types/0002-is-int-call-name-count-P1.out (commit a116710bacba) — not reproducible by checkout + evidence: 444 artifacts verified, 0 altered, 0 missing diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.prov new file mode 100644 index 0000000..544f550 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:50:45Z +exit 0 +ms 5030 +sha256_out 85ba5373fa09dd9e7c17fae1a15c1b1b0687d38d8ef16ed26c3cbe3c4acbc604 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.cmd new file mode 100644 index 0000000..2186167 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.cmd @@ -0,0 +1 @@ +bash -c printf "fn main() {\n let sep: String = \"\037\"\n println(el_str_concat(\"a\", el_str_concat(sep, \"b\")))\n}\n" > /tmp/ctrl.el; echo "--- source bytes (note the raw 037 = 0x1F) ---"; od -c /tmp/ctrl.el | sed -n "2,3p"; echo "--- emitted run 1 ---"; /tmp/elcxc /tmp/ctrl.el 2>/dev/null | grep -n "el_val_t sep"; echo "--- emitted run 2 ---"; /tmp/elcxc /tmp/ctrl.el 2>/dev/null | grep -n "el_val_t sep"; echo "--- emitted run 3 ---"; /tmp/elcxc /tmp/ctrl.el 2>/dev/null | grep -n "el_val_t sep" diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.out new file mode 100644 index 0000000..d00a5fb --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.out @@ -0,0 +1,9 @@ +--- source bytes (note the raw 037 = 0x1F) --- +0000020 l e t s e p : S t r i n g +0000040 = " 037 " \n p r i n t l +--- emitted run 1 --- +8: el_val_t sep = EL_STR("4344967392"); +--- emitted run 2 --- +8: el_val_t sep = EL_STR("4347851136"); +--- emitted run 3 --- +8: el_val_t sep = EL_STR("4384031472"); diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.prov new file mode 100644 index 0000000..245d6d6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:44:07Z +exit 0 +ms 25 +sha256_out 4cce61f4529b6a536afcd74e324260321d05ffd78ead881a5d98c3a59fa8c2c0 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0001-minimal-reproducer-control-char-literal.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.cmd new file mode 100644 index 0000000..3f047cf --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.cmd @@ -0,0 +1 @@ +bash -c printf "fn main() {\n let a: String = \"\"\n let b: String = \"ok\"\n let c: String = \"\037\"\n let d: String = \"\011\"\n println(el_str_concat(a, el_str_concat(b, el_str_concat(c, d))))\n}\n" > /tmp/ctrl2.el; /tmp/elcxc /tmp/ctrl2.el 2>/dev/null | grep -nE "el_val_t (a|b|c|d) =" diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.out new file mode 100644 index 0000000..820693e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.out @@ -0,0 +1,4 @@ +8: el_val_t a = EL_STR(""); +9: el_val_t b = EL_STR("ok"); +10: el_val_t c = EL_STR("4324455808"); +11: el_val_t d = EL_STR("\t"); diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.prov new file mode 100644 index 0000000..d5e4660 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:44:07Z +exit 0 +ms 13 +sha256_out 8b2a77870c944d8a686c4dac1f63fe40a5b3b7369f362f7b893053afde93621e +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0002-control-char-vs-empty-and-printable.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.cmd b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.cmd new file mode 100644 index 0000000..339628a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1-xc && /tmp/elcxc arbor/vessels/arbor-parse/src/main.el > /tmp/A.c 2>/dev/null; /tmp/elcxc arbor/vessels/arbor-parse/src/main.el > /tmp/B.c 2>/dev/null; shasum -a 256 /tmp/A.c /tmp/B.c; echo "--- diff ---"; diff /tmp/A.c /tmp/B.c | head -14; echo "--- source of the literal at El line 259 (cat -v) ---"; sed -n "259p" arbor/vessels/arbor-parse/src/main.el | cat -v diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.err b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.out b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.out new file mode 100644 index 0000000..60b040f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.out @@ -0,0 +1,17 @@ +f623cf49c5b8dac9a08bc9487d707f7c8274a5256268d6a0d2ad710338ae014a /tmp/A.c +ed89c2a0d976b1826a4ee98ad953a2ab3ea1f6cdb755df67eb95e267abc81f73 /tmp/B.c +--- diff --- +481c481 +< out = el_str_concat(out, EL_STR("33404397808")); +--- +> out = el_str_concat(out, EL_STR("36759834384")); +506c506 +< return str_split(s, EL_STR("33404400048")); +--- +> return str_split(s, EL_STR("36759837600")); +620c620 +< state_set(key, el_str_concat(el_str_concat(prev, EL_STR("33404413632")), node_id)); +--- +> state_set(key, el_str_concat(el_str_concat(prev, EL_STR("36759857760")), node_id)); +--- source of the literal at El line 259 (cat -v) --- + if i > 0 { let out = out + "^_" } diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.prov b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.prov new file mode 100644 index 0000000..4aab779 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.prov @@ -0,0 +1,7 @@ +commit 9540f2399120172b92e986e081877ff058adbdd3 +tree clean +captured_utc 2026-08-17T17:44:07Z +exit 0 +ms 41 +sha256_out efc70a381315d22d1d158cd98ee4b88cc3940a367ecb58d09ad9681b7ad9f05e +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.rc b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/0003-real-file-nondeterminism-arbor-parse.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/CLAIMS.md b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/CLAIMS.md new file mode 100644 index 0000000..8391f47 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/CLAIMS.md @@ -0,0 +1,102 @@ +# DEFECT — string literals containing control bytes compile to a heap address + +Not a cycle claim. This is a **live miscompilation in the current compiler**, found +incidentally during the cycle 01–10 evidence re-run and confirmed at branch HEAD. + +It is filed with the evidence because it invalidates a *method* that cycles 01–04 rely +on: "the emitted C is byte-identical" is only meaningful if the emitter is +deterministic, and for affected inputs it is not. + +## Provenance + +Captured from a clean detached worktree at `9540f2399` (`iteration-2` HEAD), compiler +built at that commit. All artifacts `tree=clean`. + +Found by the cycle 04 agent while checking prediction 5 ("existing `@manager` output +byte-identical") across the whole tree: of 378 `.el` files, 368 emitted identically +under the parent and the commit compiler, 9 failed under both, and **1 differed — and +differed from itself between two runs of the same compiler.** I reproduced it +independently at HEAD before accepting it. + +## The defect + +A string literal containing a raw control byte with no escape mapping is emitted as a +**decimal heap address** instead of the string. + +`0002-control-char-vs-empty-and-printable.out` isolates it exactly: + +``` + 8: el_val_t a = EL_STR(""); + 9: el_val_t b = EL_STR("ok"); +10: el_val_t c = EL_STR("4324455808"); <-- source literal is a raw 0x1F +11: el_val_t d = EL_STR("\t"); +``` + +- empty literal `""` — correct +- printable literal `"ok"` — correct +- **raw `0x1F` (unit separator) — emitted as `4324455808`** +- raw `0x09` (tab) — correct, `"\t"` + +Tab has an escape mapping and survives. `0x1F` has none, and instead of being escaped +it falls through to a path that stringifies a pointer. + +## It is nondeterministic + +`0001-minimal-reproducer-control-char-literal.out`, three consecutive runs of the +**same** compiler on the **same** source: + +``` +--- emitted run 1 --- el_val_t sep = EL_STR("4344967392"); +--- emitted run 2 --- el_val_t sep = EL_STR("4347851136"); +--- emitted run 3 --- el_val_t sep = EL_STR("4384031472"); +``` + +The value tracks the process heap base, which moves under ASLR. + +## It occurs in real code in this repository + +`0003-real-file-nondeterminism-arbor-parse.out`. `arbor/vessels/arbor-parse/src/main.el` +uses `0x1F` as a field separator — El source line 259, shown through `cat -v`: + +``` +if i > 0 { let out = out + "^_" } +``` + +Two runs of the same compiler over that file produce different sha256, differing in +three places, each a separator literal rendered as a different address. Within a single +run the corrupted values differ by fixed offsets (`+2240`, `+32208`), consistent with +distinct literals in one heap arena; across runs the whole block shifts. + +The file applies **no decorators at all**, so this is unrelated to the construct work +in cycles 01–10, and it reproduces at cycle 04's parent `4f7568b` as well as at HEAD. +It predates the cycle series. + +## Why it matters + +1. **Silent miscompilation.** `arbor-parse` builds and links. At runtime it joins and + splits records on a separator that is a decimal rendering of an address rather than + `0x1F` — and the encode and decode sides get *different* values whenever they are + compiled separately. No diagnostic is produced at any stage. +2. **Reproducible builds are broken** for any source containing such a literal. +3. **It weakens byte-identity as a control.** Cycles 01, 02, 03 and 04 all assert + "emitted C is byte-identical". Those assertions were checked on decorator-bearing + sources, which are unaffected — the cycle 04 agent verified all 3 `@manager`/ + `@accessor` files emit identically — so no cycle verdict changes. But the control + itself is only sound on inputs that avoid this defect, and nothing in the record + says so. + +## Verdicts + +| Claim | Artifact | Verdict | +|---|---|---| +| Control-byte literals emit as an address, not the string | `0002` | **CONFIRMED** | +| The emitter is nondeterministic for such inputs | `0001` (3 runs) | **CONFIRMED** | +| A real file in this repo is affected | `0003` | **CONFIRMED** | +| The defect predates cycles 01–10 | cycle 04's `0049`-series (parent `4f7568b` shows it too) | **CONFIRMED** | + +## Not fixed here + +This evidence pass does not change code. The defect is recorded, reproduced, and +minimally isolated so it can be fixed and regression-tested separately. A fix should +escape all non-printable bytes in the literal emitter and add a test asserting that +compiling the same source twice yields byte-identical output. diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/MANIFEST.tsv b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/MANIFEST.tsv new file mode 100644 index 0000000..6a0211f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/MANIFEST.tsv @@ -0,0 +1,4 @@ +sha256 bytes exit ms commit tree utc artifact command +4cce61f4529b6a536afcd74e324260321d05ffd78ead881a5d98c3a59fa8c2c0 382 0 25 9540f2399120 clean 2026-08-17T17:44:07Z 0001-minimal-reproducer-control-char-literal.out bash -c printf "fn main() {\n let sep: String = \"\037\"\n println(el_str_concat(\"a\", el_str_concat(sep, \"b\")))\n}\n" > /tmp/ctrl.el; echo "--- source bytes (note the raw 037 = 0x1F) ---"; od -c /tmp/ctrl.el | sed -n "2,3p"; echo "--- emitted run 1 ---"; /tmp/elcxc /tmp/ctrl.el 2>/dev/null | grep -n "el_val_t sep"; echo "--- emitted run 2 ---"; /tmp/elcxc /tmp/ctrl.el 2>/dev/null | grep -n "el_val_t sep"; echo "--- emitted run 3 ---"; /tmp/elcxc /tmp/ctrl.el 2>/dev/null | grep -n "el_val_t sep" +8b2a77870c944d8a686c4dac1f63fe40a5b3b7369f362f7b893053afde93621e 132 0 13 9540f2399120 clean 2026-08-17T17:44:07Z 0002-control-char-vs-empty-and-printable.out bash -c printf "fn main() {\n let a: String = \"\"\n let b: String = \"ok\"\n let c: String = \"\037\"\n let d: String = \"\011\"\n println(el_str_concat(a, el_str_concat(b, el_str_concat(c, d))))\n}\n" > /tmp/ctrl2.el; /tmp/elcxc /tmp/ctrl2.el 2>/dev/null | grep -nE "el_val_t (a|b|c|d) =" +efc70a381315d22d1d158cd98ee4b88cc3940a367ecb58d09ad9681b7ad9f05e 685 0 41 9540f2399120 clean 2026-08-17T17:44:07Z 0003-real-file-nondeterminism-arbor-parse.out bash -c cd /tmp/rerun-v1-xc && /tmp/elcxc arbor/vessels/arbor-parse/src/main.el > /tmp/A.c 2>/dev/null; /tmp/elcxc arbor/vessels/arbor-parse/src/main.el > /tmp/B.c 2>/dev/null; shasum -a 256 /tmp/A.c /tmp/B.c; echo "--- diff ---"; diff /tmp/A.c /tmp/B.c | head -14; echo "--- source of the literal at El line 259 (cat -v) ---"; sed -n "259p" arbor/vessels/arbor-parse/src/main.el | cat -v diff --git a/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/RUN.env b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/RUN.env new file mode 100644 index 0000000..9e0bcc5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:44:07Z +git_sha 9540f2399120172b92e986e081877ff058adbdd3 +git_dirty no +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.cmd b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.cmd new file mode 100644 index 0000000..6788188 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.cmd @@ -0,0 +1,7 @@ +bash -c +echo "Which C source each timed binary was built from, and whether it contains wrappers:" +for pair in "/tmp/elcP_g2:/tmp/pg2_03b.c:BEFORE bootstrap-built 24f7fb5" "/tmp/elcP_g3:/tmp/pg3_03b.c:BEFORE self-hosted 24f7fb5" "/tmp/elc03b:/tmp/g03b.c:AFTER bootstrap-built 285166c" "/tmp/elc03b_g3:/tmp/g03b_b.c:AFTER self-hosted 285166c"; do + bin=${pair%%:*}; rest=${pair#*:}; src=${rest%%:*}; lbl=${rest#*:} + printf " %-34s bin=%-18s src=%-16s lines=%-6s __el_body_ defs=%s el_seam_run calls=%s\n" \ + "$lbl" "$bin" "$src" "$(wc -l < $src | tr -d \" \")" "$(grep -cE \"^static el_val_t __el_body_\" $src)" "$(grep -c \"el_seam_run(\" $src)" +done diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.err b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.err new file mode 100644 index 0000000..c94d644 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.err @@ -0,0 +1,2 @@ +bash: -c: line 6: syntax error near unexpected token `(' while looking for matching `)' +bash: -c: line 6: ` "$lbl" "$bin" "$src" "$(wc -l < $src | tr -d \" \")" "$(grep -cE \"^static el_val_t __el_body_\" $src)" "$(grep -c \"el_seam_run(\" $src)"' diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.out b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.out new file mode 100644 index 0000000..7ecd70c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.out @@ -0,0 +1 @@ +Which C source each timed binary was built from, and whether it contains wrappers: diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.prov b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.prov new file mode 100644 index 0000000..a7daa1e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.prov @@ -0,0 +1,7 @@ +commit 285166c25c218e3ea91d9ceb537fac51fdd18c80 +tree clean +captured_utc 2026-08-17T17:39:59Z +exit 127 +ms 8 +sha256_out 735264ceb5cf2e7c87d6dfc97b4f119ce4ac55f43f0a55a7fe8660a6d19e341a +sha256_err 2d5c6c486c88c06cffc7bc1c6e3e8a2ddfb0454327219601b015e8c9d9848b27 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.rc b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.rc new file mode 100644 index 0000000..c75acbe --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.rc @@ -0,0 +1 @@ +127 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.cmd b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.cmd new file mode 100644 index 0000000..b16da49 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.cmd @@ -0,0 +1 @@ +bash /tmp/wrapcheck03b.sh diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.err b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.out b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.out new file mode 100644 index 0000000..46f73a8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.out @@ -0,0 +1,7 @@ +binary <- C source it was compiled from; wrapper content of that C: +LABEL BINARY C SOURCE LINES __el_body_defs el_seam_run +BEFORE bootstrap-built 24f7fb5 /tmp/elcP_g2 /tmp/pg2_03b.c 11477 0 1 +BEFORE self-hosted 24f7fb5 /tmp/elcP_g3 /tmp/pg3_03b.c 11739 0 263 +AFTER bootstrap-built 285166c /tmp/elc03b /tmp/g03b.c 11409 0 2 +AFTER self-hosted 285166c /tmp/elc03b_g3 /tmp/g03b_b.c 12957 258 518 +4f7568b bootstrap-built /tmp/elc03a /tmp/g03a.c 11361 0 0 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.prov b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.prov new file mode 100644 index 0000000..5845a49 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.prov @@ -0,0 +1,7 @@ +commit 285166c25c218e3ea91d9ceb537fac51fdd18c80 +tree clean +captured_utc 2026-08-17T17:40:09Z +exit 0 +ms 79 +sha256_out 7bcac9b43e4a788b7baf36cee0f885a5c3280c2c22cfa04548bee9e282a269df +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.rc b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.cmd b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.cmd new file mode 100644 index 0000000..32c7a1d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.cmd @@ -0,0 +1,8 @@ +bash -c +echo "b40754f is a MERGE commit. Parents:"; git log -1 --format=" %H%n parents: %P" b40754f +echo; echo "b40754f parents resolved:"; for p in $(git log -1 --format=%P b40754f); do git log -1 --format=" %h %ci %s" $p; done +echo; echo "tree diff 285166c .. b40754f (empty = identical trees):" +git diff --stat 285166c b40754f || true +echo "[end diff]" +echo; echo "tree diff 24f7fb5 .. b40754f:" +git diff --stat 24f7fb5 b40754f | tail -5 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.err b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.out b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.out new file mode 100644 index 0000000..455d931 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.out @@ -0,0 +1,16 @@ +b40754f is a MERGE commit. Parents: + b40754f07b5eff3700a69681397e46949a5c4f41 + parents: 24f7fb51436bdc68838fd7651d7377f3fb919ee3 285166c25c218e3ea91d9ceb537fac51fdd18c80 + +b40754f parents resolved: + 24f7fb51 2026-08-17 08:56:41 -0500 land the runtime seam: resolve the crossing at execution + 285166c2 2026-08-17 09:01:55 -0500 EXPERIMENT: emit the wrapper unconditionally, so exit binds at runtime too + +tree diff 285166c .. b40754f (empty = identical trees): +[end diff] + +tree diff 24f7fb5 .. b40754f: + lang/el-compiler/src/codegen.el | 56 ++-------------------------------- + lang/tests/integration/seam_binding.sh | 9 +++++- + lang/tests/native/test_compiler.el | 46 +++++++++++++++++----------- + 3 files changed, 39 insertions(+), 72 deletions(-) diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.prov b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.prov new file mode 100644 index 0000000..1c3add3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.prov @@ -0,0 +1,7 @@ +commit 285166c25c218e3ea91d9ceb537fac51fdd18c80 +tree clean +captured_utc 2026-08-17T17:40:22Z +exit 0 +ms 48 +sha256_out d4fcdf229cbcef003001b4b85e1102124c06ad3959284b74f8e66a4cc4daea77 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.rc b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.cmd b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.cmd new file mode 100644 index 0000000..844c8b3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.cmd @@ -0,0 +1 @@ +bash /tmp/sec6probe03a.sh diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.err b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.out b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.out new file mode 100644 index 0000000..3431318 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.out @@ -0,0 +1,237 @@ +=== A. The source of the figures: docs/architecture/el-language-design.md §6, at 4f7568b === + +--- + +## 6. The residue map + +What each construct must absorb, from §18.0 plus measured state: + +| Residue | Count | Absorbed by | +|---|---|---| +| persist-after-mutate | 62 sites | `hold` (after-crossing) | +| auth-per-route | 10 sites | `hold` (before-crossing) | +| index-after-append | 9 of 9 failed | `hold` (after-crossing) | +| env var defaults | 20 | configuration declared once | +| process identity | 0 guards | `hold` (before-crossing) | +| `geometry_free` at every call site | every site | ownership follows from `semel` | +| five ingest functions where there is one | 5 → 1 | `protocol` / `impl` | +| `el_runtime.c` | 20,504 lines | faculty decomposition, ordered after `semel` | + +--- + +## 7. Notes carried forward + +**`el-architecture.html` §04 needs its numbers sourced or cut.** An audit found the +faculty scoreboard — `Ingest 2 min → 0 nodes`, `Recall self ranked 8th`, +`Body CC 356 / 1,626 ln`, `the verifier answers in 2.9s`, `5 of 13 native suites +failing` — has no supporting evidence in the repository, under a footer asserting +*"nothing is inferred and presented as fact."* Against a corpus whose documents +supersede their own conclusions in place, that is the one file that would not survive +scrutiny. Fix or remove. + +**Source as a projection surface is claimed and unimplemented.** `el-architecture.html` +§147/§150: *"if source is a surface, then emitting a corrected file is projection."* +Greps for `surface_profile_code`, `emit_source` → zero hits. + +It is not unbacked. **It was demonstrated on 2026-08-14** — three faculties (phonetic, +semantic, procedural) projected into TypeScript, a surface the system had never used, +with the network severed. Recovered at +`~/Development/neuron-technologies/andre-server-recovered/` and copied into +`evidence/03-andre-demo/`. The claim needs bringing home to El, not proving. + +**`hold` is the highest-leverage construct after `semel`** — it collapses 62 + 10 + 9 +sites and unblocks the runtime extraction. §19.3 names the prologue/epilogue seam as +the prerequisite and its stated blocker has expired. + +--- + +## 8. What is not decided and must not be guessed + + +=== B. Upstream population statement: lang/spec/language.md §18.0 / §19.1 / §19.2, at 4f7568b === +El's units of encapsulation are the function and the module. Neither can hold a concern like that. So each one had been expressed the only way it could be — as a **convention**: *call this at every site.* Conventions of that shape do not hold. They are not enforced by anything, they are invisible in review, and they fail silently at the one site somebody forgot. + +Measured in this codebase before this section existed: + +| Concern | State | What the convention was | +|---|---|---| +| process identity | **zero** guards anywhere — no pidfile, no lock, no already-running check, at any layer | "check nothing is already running first" | +| configuration | **20** distinct environment variables in one program, each with its default written inline at the read site | "remember the right default here" | +| durability | **62** `persist_*` / `engram_save` / `wal_*` / `checkpoint` call sites | "after you mutate, remember to persist" | +| request auth | **10** per-route `_auth` checks | "check the token in this handler too" | + +These are not four problems. They are one absence, four times. + +That the convention form fails is observed, not predicted. Process identity failed three times in a single day: twice, two engram processes ran simultaneously against the same data directory; twice, a stale binary held a port and answered probes while a fresh build was believed to be under test, because `pkill -f` had silently failed to match its argv — which nearly produced a false "the fix does not work" conclusion. Configuration failed structurally: `ENGRAM_DATA_DIR` was read at six sites, five of them dead bindings, and the sixth defaulted to `/tmp/engram` — contradicting the canonical resolver's `$HOME/.neuron/engram` and landing a pre-destructive safety backup on ephemeral storage. + +The `program` block is where a concern of this shape is declared once and enforced by the compiler at the process boundary. + ---- §19.1 ---- +Sections 19.1 and 19.2 specify the two remaining concerns from the table in 18.0. Both are **designed and deliberately unimplemented.** The reason is stated in 19.3 and it is not difficulty. + +### 19.1 Durability as an epilogue effect + +**The defect.** 62 call sites carry the convention *"after you mutate, remember to persist."* This is structurally the same defect as the index bug being fixed elsewhere in this tree — *"after you append, remember to index"* — which failed at **9 of 9** sites. A convention that failed at 100% of its sites is the strongest available evidence about what this class of convention is worth. + +**Why the existing seam cannot express it.** §9's injection is a prologue. Durability is inherently an *epilogue*: persist after the mutation succeeds, and not at all if it threw. The seam has no epilogue. + +**Design.** Extend the decorator seam from prologue-only to prologue/epilogue, then declare durability as an effect on the mutating function: + + ---- §19.2 ---- +**Enforcement, and this is the part that actually fixes it.** Mirroring §9's `#error` for `dharma_emit`: a function that calls a mutating primitive without carrying `@durable` is a **compile error**. Otherwise this is a 63rd thing to remember rather than a replacement for 62. + +### 19.2 Request authorization as a route effect + +**The defect.** 10 per-route `_auth` checks. The HTTP layer has no concept of authorization, so a new route is unauthenticated by default and silently so — the failure mode is a route that forgot, and nothing anywhere reports it. + +**Design.** Authorization becomes an argument to the `@route` decorator, which already takes arguments and already builds a dispatch table: + +``` + +=== C. Attempted re-derivation of '62 persist-after-mutate sites' === +The stated pattern set is: persist_* / engram_save / wal_* / checkpoint call sites. +No directory, glob, language, commit or call-vs-declaration rule is stated. Trying several scopes: + scope=. all-files=302 (*.el only under it: 69) + scope=engram all-files=151 (*.el only under it: 53) + scope=engram/src all-files=52 (*.el only under it: 52) + scope=lang all-files=122 (*.el only under it: 3) + scope=ql all-files=0 (*.el only under it: 0) + scope=peripheral all-files=5 (*.el only under it: 5) + --- tree-wide, *.el only --- + 69 + --- tree-wide, *.el only, per-symbol breakdown --- + 12 persist_canonical( + 10 engram_save( + 7 wal_on( + 7 persist_node( + 6 persist_edges_since( + 6 checkpoint( + 4 wal_maybe_compact( + 3 persist_resume( + 3 persist_bulk( + 2 wal_node_put( + 2 wal_edges_since( + 2 persist_now( + 2 persist_hebb_batch( + 1 wal_hebb_batch( + 1 wal_compact( + 1 wal_boot( + +=== D. Attempted re-derivation of '10 per-route _auth checks' === + occurrences of _auth tree-wide at 4f7568b: + 4f7568b:engram/dist/engram:3 + 4f7568b:engram/dist/engram.c:4 + 4f7568b:engram/spec/grounded-edge-propagation/awareness.beat.patch.el:2 + 4f7568b:engram/spec/grounded-edge-propagation/server.route.patch.el:2 + 4f7568b:engram/src/server.el:11 + 4f7568b:ide/vessels/el-ide-server/src/el-ide-server:2 + 4f7568b:ide/vessels/el-ide-server/src/el-ide-server-asan:2 + 4f7568b:ide/vessels/el-ide-server/src/el-ide-server-asan.dSYM/Contents/Resources/DWARF/el-ide-server-asan:2 + 4f7568b:ide/vessels/el-lsp/src/el-lsp:2 + 4f7568b:ide/vessels/el-plugin-host/src/el-plugin-host:2 + 4f7568b:ingest/src/ingest.el:2 + 4f7568b:lang/BOOTSTRAP.md:1 + 4f7568b:lang/dist/elc-bootstrap.c:1 + 4f7568b:lang/dist/elc-new.c:1 + 4f7568b:lang/dist/platform/elb:2 + 4f7568b:lang/dist/platform/elb-darwin-arm64:2 + 4f7568b:lang/dist/platform/elb-linux-amd64:1 + 4f7568b:lang/dist/platform/elc:3 + 4f7568b:lang/dist/platform/elc-asan:3 + 4f7568b:lang/dist/platform/elc-asan.dSYM/Contents/Resources/DWARF/elc-asan:2 + 4f7568b:lang/dist/platform/elc-darwin-arm64:3 + 4f7568b:lang/dist/platform/elc-linux-amd64:2 + 4f7568b:lang/dist/platform/elc.20260502-0130-self-host:3 + 4f7568b:lang/dist/platform/elc.20260502-1104-self-host:3 + 4f7568b:lang/dist/platform/elc.20260502-1231-self-host:3 + 4f7568b:lang/dist/platform/elc.20260502-1249-self-host:3 + 4f7568b:lang/dist/platform/elc.20260502-1256-self-host:3 + 4f7568b:lang/dist/platform/elc.20260502-1321-self-host:3 + 4f7568b:lang/dist/platform/elc.20260502-1916-self-host:3 + 4f7568b:lang/dist/platform/elc.20260503-1555-post-sprint:3 + 4f7568b:lang/dist/platform/elc.20260503-1603-post-lsp:3 + 4f7568b:lang/dist/platform/elc.c:1 + 4f7568b:lang/dist/platform/elc.prelaunch.bak:3 + 4f7568b:lang/dist/platform/elc.preselfhost:3 + 4f7568b:lang/dist/platform/elc.prev5:2 + 4f7568b:lang/dist/platform/elc.prev6:2 + 4f7568b:lang/dist/platform/elc.prev7:3 + 4f7568b:lang/dist/platform/elc.prev8:3 + 4f7568b:lang/dist/platform/elc.prev9:3 + 4f7568b:lang/el-compiler/src/codegen.el:3 + 4f7568b:lang/elc-combined.el:1 + 4f7568b:lang/elc.c:1 + 4f7568b:lang/examples/browser-auth.el:3 + 4f7568b:lang/runtime/el_capture_darwin.m:7 + 4f7568b:lang/runtime/el_runtime.c:4 + 4f7568b:lang/runtime/el_runtime.h:1 + 4f7568b:lang/runtime/el_runtime_win32.c:1 + 4f7568b:lang/runtime/http.el:3 + 4f7568b:lang/spec/language.md:2 + 4f7568b:lang/swarm/primitives.el:2 + 4f7568b:lang/swarm/reshape_surface.el:3 + 4f7568b:lang/swarm/worktrack.el:1 + 4f7568b:lang/tests/native/test_compiler.el:8 + 4f7568b:lang/tools/lsp/dist/el-lsp:2 + 4f7568b:peripheral/src/organ_cli.el:1 + 4f7568b:tools/api-reshape/agentic_loop.el:6 + 4f7568b:tools/api-reshape/parity.sh:3 + 4f7568b:tools/neuron-sandbox/nsbx:3 + 4f7568b:ui/examples/native-hello-android/app/src/main/jni/el_runtime.c:2 + 4f7568b:ui/examples/native-hello-android/app/src/main/jni/el_runtime.h:1 + 4f7568b:ui/examples/native-hello-ios/NativeHello/el_runtime.c:2 + 4f7568b:ui/examples/native-hello-ios/NativeHello/el_runtime.h:1 + 4f7568b:ui/examples/native-hello/build-docker/runtime/el_runtime.c:2 + 4f7568b:ui/examples/native-hello/build-docker/runtime/el_runtime.h:1 + 4f7568b:ui/examples/native-hello/build-gtk4/.rt_T.txt:1 + 4f7568b:ui/examples/native-hello/build-gtk4/.rt_keep.txt:1 + 4f7568b:ui/examples/native-hello/build-gtk4/el_runtime.o:1 + 4f7568b:ui/examples/native-hello/build-gtk4/native-hello-gtk4:2 + 4f7568b:ui/examples/native-hello/build-win32/el_runtime_win32.o:1 + 4f7568b:ui/examples/native-hello/build-win32/native-hello.exe:2 + 4f7568b:ui/examples/native-hello/build/.rt_T.txt:1 + 4f7568b:ui/examples/native-hello/build/.rt_keep.txt:1 + 4f7568b:ui/examples/native-hello/build/el_runtime.o:1 + 4f7568b:ui/examples/native-hello/build/native-hello:2 + 4f7568b:ui/examples/native-hello/build/native-hello-linux-arm64:1 + 4f7568b:ui/examples/native-hello/build/native-hello-linux-x86_64:1 + 4f7568b:ui/examples/native-hello/build/native-hello-pi-arm64:1 + 4f7568b:ui/examples/native-hello/build/native-hello-sdl2:2 + 4f7568b:ui/vessels/el-aop/src/main.el:3 + 4f7568b:ui/vessels/el-identity/src/main.el:4 + 4f7568b:ui/vessels/el-platform/src/main.el:2 + 4f7568b:ui/vessels/el-services/src/main.el:2 + lines matching _auth in engram/src: + 4f7568b:engram/src/server.el:49: // Default "" leaves auth DISABLED (check_auth_ok short-circuits to true on an + 4f7568b:engram/src/server.el:809:// "preserve_edges": true, "_auth": ""} + 4f7568b:engram/src/server.el:899:// Auth: exempt (internal endpoint, soul daemon on same host, no _auth needed). + 4f7568b:engram/src/server.el:900:// The soul's ise_post() sends {"content":"..."} without _auth; enforcing auth + 4f7568b:engram/src/server.el:950:// Endpoint: POST /api/neuron/knowledge/capture (auth required: "_auth" in body) + 4f7568b:engram/src/server.el:953:// "_auth": ""} + 4f7568b:engram/src/server.el:1958:fn check_auth_ok(method: String, body: String) -> Bool { + 4f7568b:engram/src/server.el:1963: // requests must include "_auth": "" in the JSON body. + 4f7568b:engram/src/server.el:1965: let provided: String = json_get_string(body, "_auth") + 4f7568b:engram/src/server.el:1982: // ISE posting is auth-exempt (internal soul daemon, same host, no _auth key) + 4f7568b:engram/src/server.el:1988: if !check_auth_ok(method, body) { + +=== E. Attempted re-derivation of 'index-after-append failed at 9 of 9' === + --- searching for: index-after-append + 4f7568b:docs/architecture/el-language-design.md:199:| index-after-append | 9 of 9 failed | `hold` (after-crossing) | + 4f7568b:lang/el-compiler/src/codegen.el:4224:// persist-after-mutate sites and 9-of-9 failed index-after-append sites — every + --- searching for: 9 of 9 + 4f7568b:design/completing-el.html:97:Index-after-append9 of 9 failed"after you append, remember to index" + 4f7568b:docs/architecture/el-architecture.html:105:Index-after-append9 of 9 failed"after you append, remember to index" + 4f7568b:docs/architecture/el-language-design.md:25:| Index-after-append | 9 of 9 failed | "after you append, remember to index" | + 4f7568b:docs/architecture/el-language-design.md:199:| index-after-append | 9 of 9 failed | `hold` (after-crossing) | + 4f7568b:lang/spec/language.md:1237:**The defect.** 62 call sites carry the convention *"after you mutate, remember to persist."* This is structurally the same defect as the index bug being fixed elsewhere in this tree — *"after you append, remember to index"* — which failed at **9 of 9** sites. A convention that failed at 100% of its sites is the strongest available evidence about what this class of convention is worth. + --- searching for: 9-of-9 + 4f7568b:lang/el-compiler/src/codegen.el:4224:// persist-after-mutate sites and 9-of-9 failed index-after-append sites — every + --- searching for: remember to index + 4f7568b:design/completing-el.html:97:Index-after-append9 of 9 failed"after you append, remember to index" + 4f7568b:docs/architecture/el-architecture.html:105:Index-after-append9 of 9 failed"after you append, remember to index" + 4f7568b:docs/architecture/el-language-design.md:25:| Index-after-append | 9 of 9 failed | "after you append, remember to index" | + 4f7568b:lang/spec/language.md:1237:**The defect.** 62 call sites carry the convention *"after you mutate, remember to persist."* This is structurally the same defect as the index bug being fixed elsewhere in this tree — *"after you append, remember to index"* — which failed at **9 of 9** sites. A convention that failed at 100% of its sites is the strongest available evidence about what this class of convention is worth. + --- searching for: after you append + 4f7568b:design/completing-el.html:97:Index-after-append9 of 9 failed"after you append, remember to index" + 4f7568b:docs/architecture/el-architecture.html:105:Index-after-append9 of 9 failed"after you append, remember to index" + 4f7568b:docs/architecture/el-language-design.md:25:| Index-after-append | 9 of 9 failed | "after you append, remember to index" | + 4f7568b:lang/spec/language.md:1237:**The defect.** 62 call sites carry the convention *"after you mutate, remember to persist."* This is structurally the same defect as the index bug being fixed elsewhere in this tree — *"after you append, remember to index"* — which failed at **9 of 9** sites. A convention that failed at 100% of its sites is the strongest available evidence about what this class of convention is worth. diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.prov b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.prov new file mode 100644 index 0000000..ca7ee7f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.prov @@ -0,0 +1,7 @@ +commit 4f7568b07f61a81fed1db5b8274813032ea3b16e +tree clean +captured_utc 2026-08-17T17:41:04Z +exit 0 +ms 2833 +sha256_out d4f483f19828ac61252024d907faee65f8bf7ebdf39bb674eda83986e17773de +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.rc b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.cmd b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.cmd new file mode 100644 index 0000000..0de3697 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.cmd @@ -0,0 +1 @@ +bash /tmp/harnesstally03b.sh diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.err b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.out b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.out new file mode 100644 index 0000000..44f9b05 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.out @@ -0,0 +1,25 @@ +=== A. the tally arithmetic in seam_binding.sh at 285166c === +10:# exit 0 = all assertions held; non-zero = number of failures +15:FAILS=0 +18:fail() { printf ' FAIL %s\n expected: %s\n actual: %s\n' "$1" "$2" "$3"; FAILS=$((FAILS+1)); } +91:echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" +92:exit $FAILS + +=== B. same lines at the parent 24f7fb5 === +10:# exit 0 = all assertions held; non-zero = number of failures +15:FAILS=0 +18:fail() { printf ' FAIL %s\n expected: %s\n actual: %s\n' "$1" "$2" "$3"; FAILS=$((FAILS+1)); } +84:echo " 6 assertions, $((6-FAILS)) passed, $FAILS failed" +85:exit $FAILS + +=== C. number of check() invocations (assertions actually run) at each commit === + 24f7fb5 check-invocations=6 + 285166c check-invocations=7 + b40754f check-invocations=7 + +=== D. did a later commit fix the arithmetic? (search all commits touching the file) === +bc2f26dd EXPERIMENT: invocation control resolves at runtime +285166c2 EXPERIMENT: emit the wrapper unconditionally, so exit binds at runtime too +8bbb750c control the claim that cannot be unit tested + + --- the tally line at each commit that touched the file --- diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.prov b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.prov new file mode 100644 index 0000000..c06edfd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.prov @@ -0,0 +1,7 @@ +commit 285166c25c218e3ea91d9ceb537fac51fdd18c80 +tree clean +captured_utc 2026-08-17T17:44:24Z +exit 0 +ms 75 +sha256_out 178e75ae04a503701e26ee3b5415babe25fe1a723208500f4dbba6ec50301d3c +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.rc b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.cmd b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.cmd new file mode 100644 index 0000000..4529c41 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.cmd @@ -0,0 +1 @@ +bash /tmp/harnesstally03b2.sh diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.err b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.out b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.out new file mode 100644 index 0000000..f6439be --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.out @@ -0,0 +1,7 @@ +tally line of tests/integration/seam_binding.sh at every commit that touched it: + bc2f26dd 2026-08-17 09:06:05 -0500 checks=7 tally: 96:echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" + 285166c2 2026-08-17 09:01:55 -0500 checks=7 tally: 91:echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" + 8bbb750c 2026-08-17 08:48:57 -0500 checks=6 tally: 84:echo " 6 assertions, $((6-FAILS)) passed, $FAILS failed" + +bc2f26d full tally line: +96:echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.prov b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.prov new file mode 100644 index 0000000..31a730f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.prov @@ -0,0 +1,7 @@ +commit 285166c25c218e3ea91d9ceb537fac51fdd18c80 +tree clean +captured_utc 2026-08-17T17:44:36Z +exit 0 +ms 110 +sha256_out 03a64d59c52d7b823b1394fe7fa8f360e86df589fd5a1c8f7700c9e0946d0052 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.rc b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/CLAIMS.md b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/CLAIMS.md new file mode 100644 index 0000000..932b82f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/CLAIMS.md @@ -0,0 +1,394 @@ +# CLAIMS — cycle 03, the wrapper was conditional + +Source doc: `docs/v1/experiments/cycles/03-the-wrapper-was-conditional.md` + +## Pinned commits + +This cycle pins three commits. The third is a merge, and its tree is byte-identical +to the second — so every measurement at `285166c` carries unchanged to `b40754f`. + +| | Record 1 | Record 2 (the EXPERIMENT) | Record 3 (the land) | +|---|---|---|---| +| SHA | `4f7568b07f61a81fed1db5b8274813032ea3b16e` | `285166c25c218e3ea91d9ceb537fac51fdd18c80` | `b40754f07b5eff3700a69681397e46949a5c4f41` | +| Committed | 2026-08-17 07:56:28 -0500 | 2026-08-17 09:01:55 -0500 | 2026-08-17 09:01:55 -0500 | +| Subject | give a construct its after-crossing face, and let constructs compose | EXPERIMENT: emit the wrapper unconditionally, so exit binds at runtime too | land unconditional wrapper: exit crossings resolve at runtime | +| Parent(s) | `60737b03` (let a construct refuse, not only observe) | `24f7fb51` (land the runtime seam: resolve the crossing at execution) | **merge**: `24f7fb51` + `285166c2` | +| Worktree | `/tmp/rerun-v1-03a`, tree clean | `/tmp/rerun-v1-03b`, tree clean | measured from `/tmp/rerun-v1-03b` | + +**Topology matters and the record does not state it.** `285166c` is an experiment +*branch* off `24f7fb5`; `b40754f` is the **merge** that lands it. So the "before" +state for every P1–P4 prediction is `24f7fb5`, **not** `4f7568b`. `4f7568b` sits +eight commits earlier on a different line (`0004-commit-lineage.out`, +`0215-b40754f-tree-vs-285166c.out`). + +`git diff 285166c b40754f` is empty — the merge introduced nothing +(`0215-b40754f-tree-vs-285166c.out`). `b40754f` carries no numeric claim of its own; +its identity is captured in `0003-commit-identity-b40754f.out`. + +Artifact provenance: every artifact pinned per-capture, tree `clean` at both worktrees +(see `MANIFEST.tsv`, `RUN.env`). Host: Wills-MacBook-Pro, Apple M4 Pro, arm64, +Apple clang 21.0.0. + +## Verdicts + +30 factual assertions enumerated. +**REPRODUCED 24 · DIVERGED 3 · NOT-REPRODUCIBLE 2 · NOT-CAPTURED 1** + +### Record `4f7568b` + +| # | Claim (verbatim from the record) | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 1 | "§6 records 62 persist-after-mutate sites, 10 auth-per-route, and index-after-append that failed at 9 of 9" — *as a quotation of §6* | `0223-sec6-figures-source-and-rederivation.out` | `4f7568b` | **REPRODUCED** — §6 is `docs/architecture/el-language-design.md` "## 6. The residue map"; its table reads exactly `persist-after-mutate \| 62 sites`, `auth-per-route \| 10 sites`, `index-after-append \| 9 of 9 failed`. The record quotes §6 correctly. | +| 2 | "62 persist-after-mutate sites" — *as a measurement* | `0223` | `4f7568b` | **NOT-REPRODUCIBLE** — population undefined; no scope produces 62 (see below) | +| 3 | "10 auth-per-route" — *as a measurement* | `0223` | `4f7568b` | **NOT-REPRODUCIBLE** — there is exactly **one** auth check at this commit, not ten (see below) | +| 4 | "index-after-append that failed at 9 of 9" | `0223` | `4f7568b` | **NOT-CAPTURED** — no enumeration, file, test, or procedure exists anywhere in the tree; all five occurrences are restatements of each other | +| 5 | "98/98 native compiler tests pass" | `0007-native-compiler-tests-03a.out` | `4f7568b` | **REPRODUCED** — `98 tests, 98 passed, 0 failed, 243 assertions in 4.271ms` | +| 6 | "existing output byte-identical" | `0034-REDO-parent-compiler-build-03a.out`, `0047-REDO-existing-output-byte-identical-03a.out` | `4f7568b` vs `4f7568b^` | **REPRODUCED** — the parent compiler (`60737b03`, built from `git archive`) and the `4f7568b` compiler emit **byte-identical C for the whole 11,258-line compiler source of the parent**, sha256 `8408ae3aef3048cf…` for both | +| 7 | "Fns with no exit construct emit byte-identically to before" | `0047` §A | `4f7568b` vs `4f7568b^` | **REPRODUCED** — probe of `@manager` / `@accessor` / undecorated fns: identical, sha256 `f5ae7733b4b3ee0e…`; `__el_body_` wrapper count in the output = **0** | +| 8 | "compiler self-hosts byte-identically" | `0140-selfhost-fixpoint-gen2-gen3-03a.out` | `4f7568b` | **REPRODUCED** — gen1 == gen2 == gen3, all sha256 `fcdfdf13b9fed6e9…`, 11,361 lines | +| 9 | "early returns pass through the exit" | `0065-REDO-exit-and-composition-tests-03a.out` | `4f7568b` | **REPRODUCED** — `ok declared-exit-wraps-body-so-early-returns-pass-through`; also `ok declared-exit-receives-the-result` | +| 10 | "ordering holds under composition" / "Three independent constructs now compose on one fn, none known to the compiler" | `0065` | `4f7568b` | **REPRODUCED** — `ok constructs-compose-guard-entry-exit` (asserts guard-index < entry-index < exit-index) | +| 11 | the emitted C shown for `mutate()` — guard, entry, body, exit ordering, all six lines | `0018-probe-mutate-emission-03a.out` | `4f7568b` | **REPRODUCED — byte-for-byte** (see below). Probe reconstructed, see "Reconstructed probes". | +| 12 | "The body moves into a static helper and the visible fn becomes a wrapper" | `0018` | `4f7568b` | **REPRODUCED** — `static el_val_t __el_body_mutate(el_val_t k)` emitted, `el_val_t mutate(el_val_t k)` calls it | + +### Record `285166c` + +| # | Claim (verbatim from the record) | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 13 | P1 "exit becomes runtime-bindable — TRUE, returns 14, bound after the build" | `0014-integration-seam_binding-03b.out`, `0017-test-diff-285166c.out` | `285166c` | **REPRODUCED** — harness assertion `an EXIT construct declared after the build replaces the result` expects `14` and passes; the binding is supplied via `EL_CONSTRUCTS=exit.txt` **after** `prog` is compiled and linked | +| 14 | P2 "codegen shrinks — TRUE, 5094 -> 5044" | `0012-codegen-linecount-285166c.out`, `0013-codegen-linecount-neighbourhood.out` | `285166c^`, `285166c` | **DIVERGED** — observed **5095 -> 5043** (see below) | +| 15 | P3 "cost 5-15% from a call frame on every fn — FALSE, 0.37s -> 0.38s, ~3%" | `0163-P3-isolated-callframe-cost-20x.out`, `0189-P3-hypothesis-which-binaries-give-0.37-to-0.38.out`, `0214-REDO-P3-control-binaries-wrapper-content.out`, `0116`, `0100` | `285166c` vs `24f7fb5` | **DIVERGED — the substantive finding of this cycle.** Isolated overhead **+12.65% to +15.98%, median +13.65%**, i.e. *inside* the 5–15% band the record scored FALSE (see below) | +| 16 | P4 "fixpoint holds — TRUE" | `0132-selfhost-fixpoint-gen2-gen3-03b.out` | `285166c` | **REPRODUCED** — gen2 == gen3, sha256 `6bb520f2a0ce8695…`, 12,957 lines each | +| 17 | "fixpoint gen2==gen3" | `0132` | `285166c` | **REPRODUCED** — under the correct three-generation numbering. gen1 != gen2 (expected: the committed `dist/platform/elc` dates from `45325f7`, before the wrapper); gen2 == gen3 exactly | +| 18 | "99/99 native" | `0008-native-compiler-tests-03b.out` | `285166c` | **REPRODUCED** — `99 tests, 99 passed, 0 failed, 239 assertions in 5.327ms` | +| 19a | "7/7 integration" — *the underlying fact: all seven assertions hold* | `0014` | `285166c` | **REPRODUCED** — all seven assertions print `ok`, `0 failed`, harness exit `0` | +| 19b | "7/7 integration" — *as a reported harness tally* | `0014`, `0224-harness-tally-arithmetic-285166c.out`, `0225-REDO-harness-tally-history.out` | `285166c` | **DIVERGED** — a fully green run prints `7 assertions, 6 passed, 0 failed`. The harness at this commit **cannot** print 7/7 (see below) | +| 20 | "Every fn now gets a body helper and a wrapper" | `0148-every-fn-gets-wrapper-03b.out` | `285166c` | **REPRODUCED** — in the emitted C for the whole compiler: 258 forward decls, **258** `static el_val_t __el_body_*` helpers, **258** wrapper definitions. At the parent `24f7fb5`: **0** body helpers, 262 plain fn definitions. | +| 21 | "Removed with the machinery: `declare_exit`" | `0015`, `0016-removed-symbols-detail-parent.out` | `285166c^` → `285166c` | **REPRODUCED** — 2 occurrences at parent (`codegen.el:4315` def, `:4448` call) → **0** | +| 22 | "…`decorator_exit`" | `0015`, `0016` | `285166c^` → `285166c` | **REPRODUCED** — 3 occurrences at parent (`:4319` def, `:3226`, `:3321` calls) → **0** | +| 23 | "…`cg_exit_target`" | `0015`, `0016` | `285166c^` → `285166c` | **REPRODUCED (code)** — 3 → 1; the function (`:3217`) and its call (`:3393`) are gone. The 1 remaining is a **stale comment** at `codegen.el:3215` still naming it. | +| 24 | "…`cg_exit_construct`" | `0015`, `0016` | `285166c^` → `285166c` | **REPRODUCED (code)** — 3 → 1; function (`:3312`) and call (`:3394`) gone; the survivor is the same stale comment at `:3215` | +| 25 | "…and the `injects_at_exit` scanner branch" | `0015`, `0016` | `285166c^` → `285166c` | **REPRODUCED** — the branch `if str_eq(dkind, "injects_at_exit")` at `codegen.el:4429` is gone; the two test uses are gone; 1 doc-comment mention survives at `:4272` | +| 26 | "Two controls failed and were rewritten rather than repaired" | `0067-which-controls-failed-03b.out` | `285166c` | **REPRODUCED — exactly two** — running the parent's `test_compiler.el` against `285166c`'s compiler sources: `99 tests, 97 passed, 2 failed`. The two: `declared-exit-wraps-body-so-early-returns-pass-through`, `no-exit-construct-emits-no-wrapper`. Nuance: **three** tests were deleted; the third (`declared-exit-receives-the-result`) still **passed** and was removed as obsolete, not because it failed. | +| 27 | "`no-exit-construct-emits-no-wrapper` asserted the optimisation this removes, so it is now inverted" | `0017`, `0066-exit-and-composition-tests-03b.out`, `0067` | `285166c` | **REPRODUCED** — it fails at `285166c` (`0067`) and its logical inversion `every-fn-gets-a-body-helper-and-wrapper` replaces it and passes (`0066`) | +| 28 | "The integration harness gained a seventh assertion: an exit construct declared after the build replaces the result" | `0017`, `0014` | `285166c^` → `285166c` | **REPRODUCED** — `seam_binding.sh` diff adds `double_result()` and the assertion expecting `14`; 6 → 7 assertions | + +### Record `b40754f` + +| # | Claim | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 29 | "land unconditional wrapper: exit crossings resolve at runtime" (identity only — no numeric claim) | `0003-commit-identity-b40754f.out`, `0215-b40754f-tree-vs-285166c.out` | `b40754f` | **REPRODUCED** — merge of `24f7fb51` + `285166c2`; `git diff 285166c b40754f` is empty, so the landed tree is byte-identical to the experiment | + +--- + +## Divergence detail — claim 15, P3: the ~3% is an artefact of timing the wrong binary + +**This is the substantive finding for cycle 03.** + +The record predicted "cost 5-15% from a call frame on every fn", measured `0.37s -> 0.38s`, +concluded `~3%`, and scored the prediction **FALSE**. Re-measured, the prediction was +**right**, and the measurement that refuted it could not have detected the cost it was +looking for. + +**Why.** The compiler is bootstrapped from the committed `lang/dist/platform/elc`, a +binary built at `45325f7` — long before this change. The chain is: + +``` +dist/platform/elc --compiles--> gen2 C --cc--> gen2 binary --compiles--> gen3 C + (no wrappers) (no wrappers) (wrappers) +``` + +The `285166c` compiler built **from the bootstrap** (`gen2 binary`) contains +**zero** `__el_body_*` helpers — the stale bootstrap emitted it without wrappers. +Only the *self-hosted* binary carries a wrapper on every fn. Measured directly +(`0214-REDO-P3-control-binaries-wrapper-content.out`): + +| binary | built from | `__el_body_` defs in that C | `el_seam_run` calls | +|---|---|---|---| +| BEFORE bootstrap-built `24f7fb5` | `pg2_03b.c`, 11477 ln | **0** | 1 | +| BEFORE self-hosted `24f7fb5` | `pg3_03b.c`, 11739 ln | **0** | 263 | +| AFTER bootstrap-built `285166c` | `g03b.c`, 11409 ln | **0** | 2 | +| AFTER self-hosted `285166c` | `g03b_b.c`, 12957 ln | **258** | 518 | + +**The record's own numbers reproduce — on the pair of binaries that contain no wrappers.** +Ten compiles of the same input, three rounds (`0189`): + +| pair | BEFORE | AFTER | delta | +|---|---|---|---| +| both **bootstrap-built** (neither has wrappers) | 0.3861 / 0.3872 / 0.3869 s | 0.3912 / 0.3907 / 0.3871 s | **+1.32% / +0.90% / +0.05%** | +| both **self-hosted** (only AFTER has wrappers) | 0.4125 / 0.4087 / 0.4108 s | 0.4398 / 0.4389 / 0.4363 s | **+6.62% / +7.39% / +6.21%** | + +The record's `0.37s` is within noise of the bootstrap-built BEFORE figure (0.386s here), +and its `0.38s` of the bootstrap-built AFTER (0.391s). The `~3%` sits between the two +rows. Whatever exact binaries were used, the reported delta is the *emission* cost — +the AFTER compiler writes ~10% more C — and cannot contain the call-frame cost, because +neither timed binary had a call frame added to it. + +**The controlled isolation.** The cleanest instrument for "a call frame on every fn" is +two binaries with **identical compiler semantics** and identical output, differing only +in whether the binary itself was built with wrappers: `/tmp/elc03b` (bootstrap-built +`285166c`) vs `/tmp/elc03b_g3` (self-hosted `285166c`). Both emit byte-identical C +(`g03b_b.c` == `g03b_c.c`, sha256 `6bb520f2a0ce8695…`), so all of the delta is runtime. +20 compiles per sample, 6 rounds, A/B order alternated (`0163`): + +``` +round 1 (A-then-B) A 0.7683s B 0.8680s +12.98% +round 2 (B-then-A) A 0.7596s B 0.8810s +15.98% +round 3 (A-then-B) A 0.7508s B 0.8564s +14.06% +round 4 (B-then-A) A 0.7523s B 0.8549s +13.64% +round 5 (A-then-B) A 0.7535s B 0.8498s +12.78% +round 6 (B-then-A) A 0.7516s B 0.8467s +12.65% +overhead on MEDIAN = +13.65% overhead on MIN = +12.77% +``` + +**Claimed: ~3%, prediction scored FALSE. Observed: +12.65% to +15.98%, median +13.65% — +inside the predicted 5–15% band, near its top.** Even the end-to-end cross-commit +comparison of self-hosted binaries (+6.2% to +7.4%) is inside the band. On this hardware +P3 should have been scored **TRUE**. + +Per §8 of the re-run recipe, the *absolute* wall-clock figures (0.37s, 0.38s) remain +machine-dependent and are not themselves reproducible. It is the **ratio** the record +leans on, and the ratio is what diverges. Machine: Apple M4 Pro, arm64, macOS 25.5.0, +Apple clang 21.0.0, idle-ish interactive session; the A/B alternation and the min-based +figure control for drift, and every one of the six rounds lands inside the band. + +## Divergence detail — claim 19b, "7/7 integration": the harness cannot print 7/7 + +A green harness whose own summary line under-reports itself. + +`285166c` added the seventh assertion and bumped the **header text** of the tally line +from `6 assertions` to `7 assertions`, but left the **arithmetic** at `$((6-FAILS))` +(`0224-harness-tally-arithmetic-285166c.out`): + +``` +lang/tests/integration/seam_binding.sh:91 + echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" +``` + +So with `FAILS=0` — a completely green run — the harness prints `6 passed`. Observed +verbatim at `285166c` (`0014-integration-seam_binding-03b.out`, exit 0): + +``` + ok unbound program is unaffected + ok a construct declared AFTER the build applies + ok a construct declared after the build can REFUSE + ok an unlinked target is skipped, not fatal + ok a binding for a different fn does not fire + ok two constructs compose on one crossing + ok an EXIT construct declared after the build replaces the result + + 7 assertions, 6 passed, 0 failed +``` + +Seven `ok` lines, zero failures, exit code 0 — so **7 of 7 really do pass** (claim 19a, +REPRODUCED). But **no tool in the tree at this commit is capable of emitting "7/7"**, +and the line a reader gets when they re-run the harness contradicts the record. The +record's figure was not read off its own instrument. + +History of the tally line (`0225-REDO-harness-tally-history.out`) — the arithmetic was +wrong for four minutes and was fixed by the next experiment: + +| commit | when | `check` invocations | tally line | +|---|---|---|---| +| `8bbb750c` | 08:48:57 | 6 | `6 assertions, $((6-FAILS)) passed, $FAILS failed` — correct | +| **`285166c2`** | **09:01:55** | **7** | **`7 assertions, $((6-FAILS)) passed, $FAILS failed` — header bumped, arithmetic not** | +| `bc2f26dd` | 09:06:05 | 7 | `7 assertions, $((7-FAILS)) passed, $FAILS failed` — fixed | + +Independently corroborated: this defect was first flagged by the cycle 08 re-run and is +confirmed here from the artifacts above. Its practical severity is low (`exit $FAILS` +is driven by the real failure counter, so CI would still catch a regression) but it is +exactly the failure mode this evidence record exists to surface — a number in a commit +message that the tooling of that commit never produced. + +## Divergence detail — claim 14, P2: 5094 -> 5044 is 5095 -> 5043 + +`lang/el-compiler/src/codegen.el`, `wc -l` (`0012`, `0013`): + +| | claimed | observed | +|---|---|---| +| parent `285166c^` = `24f7fb5` | 5094 | **5095** | +| commit `285166c` | 5044 | **5043** | +| delta | −50 | **−52** | + +Both endpoints miss, **in opposite directions**, so this is not a tool or off-by-one +convention difference. Controls run: + +- Every version of the file ends in `\n` (`0013` prints the last byte as `\n` for all + eleven neighbouring commits), so `wc -l` is exact and does not undercount. +- `git show --numstat` for the commit reports `2 insertions, 54 deletions` — net **−52**, + independently confirming the observed delta, not the claimed one. +- **No commit anywhere in the neighbourhood has 5094 or 5044 lines of `codegen.el`.** + The full sweep (`0013`): `4f7568b` 4953 · `7d01608` 5084 · `1b324a0` 5152 · + `82e9982` 5152 · `35b07ba` 5156 · `886626a` 5156 · `28d19da` 5095 · `8bbb750` 5095 · + `24f7fb5` 5095 · `285166c` 5043 · `b40754f` 5043. + +The qualitative half of P2 ("codegen shrinks") holds and shrinks slightly *more* than +claimed. The two figures do not, and neither can be recovered from any state of the file +in this range. + +## NOT-REPRODUCIBLE / NOT-CAPTURED detail — the three §6 figures (claims 2, 3, 4) + +§6 was located: `docs/architecture/el-language-design.md`, `## 6. The residue map` +(`0223`). Its header names its upstream — *"from §18.0 plus measured state"*, i.e. +`lang/spec/language.md` §18.0. The record quotes §6 faithfully (claim 1, REPRODUCED). +**None of the three figures has a defined population.** + +**"62 persist-after-mutate sites" — NOT-REPRODUCIBLE.** §18.0 is the only place that +names a procedure, and it names only a pattern set — `persist_*` / `engram_save` / +`wal_*` / `checkpoint` call sites — with **no directory, glob, language, commit, or +call-vs-declaration rule**, under the tense marker *"Measured in this codebase **before +this section existed**"*, which pins it to an unnamed earlier tree state. Applying the +stated pattern set at `4f7568b` (`0223` §C): + +| scope | count | +|---|---| +| tree-wide, all files | 302 | +| tree-wide, `*.el` only | **69** | +| `engram/` all files | 151 | +| `engram/**.el` | 53 | +| `engram/src` | **52** | +| `lang/` all files | 122 | + +62 lies between the two most natural scopes (52 and 69) and equals neither. Per-symbol +breakdown tree-wide over `*.el` is in `0223`. Unlike cycle 01's decorator counts, there +is no scope you can guess that recovers the figure. + +**"10 auth-per-route" — NOT-REPRODUCIBLE, and the mechanism it describes does not +exist at this commit.** §19.2 says *"10 per-route `_auth` checks"* and names no route, +file, or command. At `4f7568b` there is **one** auth check in the whole server: +`fn check_auth_ok(method, body)` defined at `engram/src/server.el:1958` and called from +a **single** dispatch site at `:1988` (`0223` §D). Of the 11 `_auth` occurrences in +`server.el`, 8 are comments or JSON-key documentation. The per-route form the figure +counts is not present; a reader cannot recover a list of ten sites. + +**"index-after-append that failed at 9 of 9" — NOT-CAPTURED.** This is the figure the +record leans on hardest ("*the 9-of-9 figure is what that costs*") and it is the least +sourced. The population is described only as *"the index bug being fixed elsewhere in +this tree"* — no file, no function, no test, no commit, no enumeration of the nine +sites, and no statement of how "failed" was determined. Searching the whole tree at +`4f7568b` for `index-after-append`, `9 of 9`, `9-of-9`, `remember to index`, `after you +append` returns **only restatements** (`0223` §E): `el-language-design.md:25` and `:199`, +`el-architecture.html:105`, `design/completing-el.html:97`, `lang/spec/language.md:1237`, +and a comment in `codegen.el:4224` citing it. Every one cites the figure; none produces +it. There is nothing to re-run, so no artifact can be made. + +The same document is self-aware about exactly this failure mode one section later: +§7 flags `el-architecture.html` §04's scoreboard as having *"no supporting evidence in +the repository, under a footer asserting 'nothing is inferred and presented as fact'"* +and says "Fix or remove." That audit was never turned on §6's own table. + +## Reconstructed probes + +Two artifacts are outputs of probe programs that are **not in the tree**. Per §7 of the +re-run recipe the probe is an *input*, not evidence; the artifact is the captured output +of running it at the pinned commit. + +**`0018-probe-mutate-emission-03a.out`** — the record shows emitted C for a fn `mutate` +but the tree contains no such fixture. The probe was reconstructed from what the record +itself states (the `@decorator("injects_at_exit", "persist_now")` snippet it prints, the +three decorator names visible in the emitted C, and the `mutate(k)` signature and body +that the commit's own deleted test `declared-exit-wraps-body-so-early-returns-pass-through` +used): + +```el +@decorator("guards_at_entry", "my_auth") +fn authenticate() {} + +@decorator("injects_at_exit", "persist_now") +fn durable() {} + +@authenticate +@durable +@manager +fn mutate(k: String) -> Int { if str_eq(k, "bad") { return 0 } return 1 } +``` + +The emission at `4f7568b` is **byte-for-byte the six lines the record prints**: + +```c +el_val_t mutate(el_val_t k) { + { el_val_t __g = my_auth(EL_STR("mutate"), EL_STR("authenticate")); if (__g) return __g; } + engram_boundary_beat(EL_STR("mutate"), EL_STR("manager")); + el_val_t __r = __el_body_mutate(k); + persist_now(EL_STR("mutate"), EL_STR("durable"), __r); + return __r; +} +``` + +Guard, then entry, then body, then exit — exactly as claimed. The same probe at +`285166c` (`0019-probe-mutate-emission-03b.out`) shows the compile-time injection gone +and both crossings routed through `el_seam_run`. + +**`0067-which-controls-failed-03b.out`** — to determine *which* controls failed (claim 26) +the parent's `tests/native/test_compiler.el` (`24f7fb5`) was placed into a `git archive` +export of the `285166c` tree and run against `285166c`'s compiler sources. The test file +`import`s `codegen.el` from the tree, so this genuinely exercises the new codegen against +the old controls. No worktree was modified. + +`0034-REDO-parent-compiler-build-03a.out` similarly builds the `4f7568b^` compiler from a +`git archive` export of `60737b03` into `/tmp/parent03a`, and `0082-build-parent-24f7fb5-fixpoint.out` +builds `24f7fb5` into `/tmp/parent03b`. These are builds of committed trees, not +reconstructions. + +## Measurement defects in this re-run, recorded rather than removed + +1. **`0009-selfhost-fixpoint-03a.out` and `0010-selfhost-fixpoint-03b.out` used a + superseded fixpoint command.** The original re-run recipe compared gen1 (the output + of the committed `dist/platform/elc`) to gen2. That check must fail whenever codegen's + output changes, which is exactly what this cycle does — `0010` exits 1 with + `differ: char 12850, line 264`. **This is not a broken fixpoint.** The recipe was + corrected mid-run by the parent agent; the correct check is gen2 == gen3. + Superseded by `0132-selfhost-fixpoint-gen2-gen3-03b.out` and + `0140-selfhost-fixpoint-gen2-gen3-03a.out`, which are the ones cited above. + `0011-selfhost-fixpoint-gen3-gen4-03b.out` is the same correct comparison taken before + the naming was standardised (its "gen3==gen4" are the recipe's gen2 and gen3). Retained. + **Do not cite `0009` or `0010`.** + +2. **`0020-no-exit-construct-byte-identical-03a.out` used an invalid "before" compiler.** + It compared `lang/dist/platform/elc` (the committed bootstrap, built at `45325f7`) + against the `4f7568b` compiler. The bootstrap predates `4f7568b` by many commits, so + the two differences it found — + `engram_boundary_beat(EL_STR("f"))` vs `engram_boundary_beat(EL_STR("f"), EL_STR("manager"))` — + belong to cycle 01, not to this one. Superseded by `0034` + `0047`, which build the + actual parent `60737b03`. Retained. **Do not cite `0020`.** + +3. **`0021-parent-compiler-build-03a.out` failed (exit 1).** `git archive` was invoked + with CWD inside `lang/`, and git archives only the current prefix, so the export + contained the *contents* of `lang/` rather than `lang/` itself and the subsequent + `cd .../lang` failed. This is the same class of CWD defect the recipe warns about for + `git grep`. Corrected in `0034-REDO-parent-compiler-build-03a.out`, run from the repo + root. Retained. + +4. **`0063-exit-and-composition-tests-03a.out` failed (exit 2)** — it grepped a + mis-numbered artifact filename (`0006-` instead of `0007-`) and produced nothing. + `capture.sh` numbers artifacts by counting non-empty MANIFEST lines, and multi-line + commands write multi-line MANIFEST rows, so artifact indices jump. Corrected in + `0065-REDO-exit-and-composition-tests-03a.out`. Retained. + +5. **`0207-P3-control-binaries-wrapper-content.out` failed (exit 127)** — a shell quoting + error inside a nested `bash -c`. Rewritten as a script file and re-captured as + `0214-REDO-P3-control-binaries-wrapper-content.out`. Retained. + +6. **Cosmetic, `0047` §B**: the line-count interpolation in the "BYTE-IDENTICAL over N + lines" message printed empty because of escaping inside the nested `bash -c`. The + `cmp` result and both sha256 values — which are what the claim rests on — are + unaffected. The figure is 11,258 lines, from `0034`. + +7. **Not a defect of this re-run, but of the artefact under test**: `seam_binding.sh` at + `285166c` prints `7 assertions, $((6-FAILS)) passed` — the total was updated to 7 and + the passed-count was not. See claim 19b and its divergence section. + +8. **`0224-harness-tally-arithmetic-285166c.out` section D produced no rows.** The + per-commit tally-line loop piped `git log` into `while read`, and `git show` inside + the loop consumed the loop's stdin. Re-taken as + `0225-REDO-harness-tally-history.out` with a `for` loop and ` Int` emits `el_val_t mixed(el_val_t a, el_val_t b, el_val_t c)`. | +| 7 | P3 "codegen DEFINES the wrap calling convention, so codegen emits the extern declaration" | `0008`, `0009`, `0017` | `2bed848` | **REPRODUCED** — codegen.el:3442 emits the `extern el_val_t (el_val_t, el_val_t, el_val_t(*)(void*), void*);` line; it appears in the emitted C at line 22/38. | +| 8 | P4 "target controls invocation, 0..N times — TRUE" | `0011`, `0012`, `0010` | `2bed848` | **REPRODUCED** — one El source, four wrap targets differing only in how many times they call the thunk: 0 → `999`, 1 → `5`, 2 → `10`, 3 → `15`. | +| 9 | P5 "existing @manager output byte-identical — TRUE" | `0019`, `0020`, `0028`, `0038` | `4f7568b` vs `2bed848` | **REPRODUCED** — the parent compiler was rebuilt from a `git archive 4f7568b` extraction (`0019`) and the same inputs compiled with both emitters. All 3 files in the tree that apply `@manager`/`@accessor` (`engram/src/server.el` 1 application, `tools/api-reshape/route_proof.el` 7, `tools/api-reshape/surface.el` 8) emit **byte-identical** C. Treewide: 378 `.el` files → 368 identical, 1 byte-differing, 9 failing under both emitters. The 1 differing file is explained below and is not caused by this cycle. | +| 10 | P6 "compiler fixpoint holds — TRUE" | `0051`, `0054` | `2bed848`, `7d01608` | **REPRODUCED** — gen2 == gen3 at both commits; at these commits gen1 == gen2 as well, so all three generations share sha256 `91b3de5b5c95cc659fb4d78aa821627c9a5c325c14b461852efff7db3f68a64b`. | +| 11 | P7 "emitting the convention makes it compile — TRUE" | `0010`, `0055` | `2bed848`, `7d01608` | **REPRODUCED** — `COMPILE_AND_LINK_OK` at both commits, against a C translation unit supplying the two wrap targets. | +| 12 | MEASURED "base(5) wrapped by a target that invokes the body twice and sums -> 10" | `0007`, `0010`, `0055` | `2bed848`, `7d01608` | **REPRODUCED — via a RECONSTRUCTED probe** (see below) — observed `base(5) = 10` | +| 13 | MEASURED "never_runs(5) wrapped by a target that never invokes it -> 999" | `0007`, `0010`, `0055` | `2bed848`, `7d01608` | **REPRODUCED — via a RECONSTRUCTED probe** (see below) — observed `never_runs(5) = 999` | +| 14 | "This supersedes the repeats_body experiment on **experiment/repeats-body**" | `0049` | all refs | **DIVERGED** — no such ref exists. See below. | +| 15 | `7d01608`: "Proven on **experiment/wraps-body** (2bed848)" | `0049` | all refs | **DIVERGED** — no such ref exists. The *commit* `2bed848` is present and reachable; the branch name is not. | +| 16 | "Every C++ lambda, every Go closure, every Rust closure compiles to a struct of captured values plus a function pointer" | `0008`, `0009` | — | **NOT-CAPTURED** — the trailing half, "which is what is emitted here", is claim 1 and is REPRODUCED. The claim about C++/Go/Rust codegen is about three other toolchains, none of which is in this tree; it was not measured then and is out of scope for this record. | +| 17 | "It would also have crippled the JS backend, which has closures natively, for a limit that applies only to the C one" | `0058` | `2bed848` | **NOT-CAPTURED (counterfactual)** — and the premise is weaker than stated: `lang/el-compiler/src/codegen-js.el` (1381 lines) implements **no construct machinery whatsoever** at `2bed848`. It contains no reference to `wraps_body`, `injects_at_entry`, `guards_at_entry`, `injects_at_exit`, thunks or env structs; the only decorator it knows is `@async` (line 1119). There is no wrap emission in the JS backend to cripple, either way. | + +**Counts: 13 REPRODUCED · 2 DIVERGED · 0 NOT-REPRODUCIBLE · 2 NOT-CAPTURED (17 assertions).** + +## The MEASURED numbers were produced by a RECONSTRUCTED probe + +State plainly: **no test, fixture, or harness in the tree at `2bed848` exercises +`wraps_body`.** `git grep wraps_body` outside `codegen.el` returns exit 1; +`lang/tests/integration/` does not exist at either pinned commit (`0056`); and +`2bed848` changes exactly one file, `codegen.el`, adding no test. The probe the +commit message describes was never committed. + +The probe was therefore **reconstructed from what the record states**, and it is +an INPUT, not evidence. Its full text is in the record at `0007`: + +- `w04.el` — two declared wrap constructs (`@decorator("wraps_body", "twice_and_sum")` + and `@decorator("wraps_body", "never_invoke")`) applied to `base(n)` and + `never_runs(n)`, both bodies `return n`, with `main` printing `base(5)` and + `never_runs(5)`. +- `targets04.c` — the two wrap targets, which cannot be written in El + (that is claim 5): `twice_and_sum` returns `body(env) + body(env)`; + `never_invoke` ignores the body and returns `999`. + +The **artifact is the captured output of running it at the pinned commits** +(`0010` at `2bed848`, `0055` at `7d01608`), which reads: + +``` +COMPILE_AND_LINK_OK +base(5) = 10 +never_runs(5) = 999 +``` + +The emitted C is byte-identical between `2bed848` and `7d01608` (`0055`). + +Reconstruction risk, stated honestly: the record fixes the inputs (`5`), the +target semantics ("invokes the body twice and sums", "never invokes it") and the +outputs (`10`, `999`), and the `999` sentinel is only reachable from the target, +so it is not a value the body could have produced. What the record does *not* +fix is the target's *names*, which are free choices here. The numbers were +observed, not asserted. + +## Divergence detail — claims 14 and 15, the two branch references + +Both pinned records point at branches that are not in the clone (`0049`): + +- `git branch -a --list '*repeats-body*'` → **no output**, exit 0 +- `git branch -a --list '*wraps-body*'` → **no output**, exit 0 +- `git for-each-ref | grep -i body` → **no matching ref of any kind** +- `git log --all --oneline --grep=repeats_body` and `--grep=repeats-body` → + the *only* match is `2bed848` itself, i.e. the sentence making the claim +- 249 branches exist in the clone; none of them is either name. + +Consequences, and they are not symmetrical: + +- **Claim 15** (`7d01608`: "Proven on experiment/wraps-body (2bed848)") is a + cosmetic divergence. The branch is gone but the commit it names survives, is + reachable, and everything it asserts re-measures. Only the branch label is wrong. +- **Claim 14** ("This supersedes the repeats_body experiment on + experiment/repeats-body, which was built around the mistaken limit") is a + substantive one. The superseded work is **unrecoverable**: no branch, no tag, + no commit anywhere in the object graph mentions `repeats_body`. The record's + central rhetorical move — that a strictly weaker "decide whether to repeat" + design *existed*, was *built*, and was *replaced* — rests entirely on a + dangling reference. That the weaker design is weaker is separately + demonstrable (claim 8 shows 0 and 3 invocations, neither expressible as + "repeat or not"), but the *existence and content of the superseded experiment* + cannot be checked from this repository. + +## Supporting finding — the one treewide byte-difference is pre-existing nondeterminism + +The treewide P5 sweep (`0028`) found exactly one file whose emitted C differs +between the parent and the commit: `arbor/vessels/arbor-parse/src/main.el`. +It is **not** a regression from this cycle (`0038`): + +- The file applies **zero** decorators (`grep -c '^@'` = 0), so no construct + machinery — wrap or otherwise — is reachable in it. +- Two consecutive runs of the **same** compiler at `2bed848` produce different + output. +- Two consecutive runs of the **same** compiler at the **parent** `4f7568b` + also produce different output. + +The difference is always the same three lines, where a string literal is emitted +as a large decimal number that changes run to run (e.g. +`EL_STR("40345588256")` vs `EL_STR("30447047200")` at line 325, and similarly at +338 and 392) — an address, or an address-derived value, leaking into the emitted +literal. This is a real pre-existing emitter defect worth its own investigation, +but it predates cycle 04 and does not touch claim 9. + +The 9 files that fail under **both** emitters (identical exit codes, `0028`) are +likewise unchanged by the cycle: `arbor-core/src/main.el`, +`arbor-render/src/main.el`, `elp/src/vocabulary-{de,fr,it,pt,ro}.el`, +`ui/examples/native-hello/src/{App,main}.el`. + +## Measurements the record makes no claim about, recorded as observed + +The cycle doc states no test count, no fixpoint detail and no timing. Observed: + +- Native compiler tests: **98 tests, 98 passed, 0 failed, 243 assertions** at + `2bed848` (`0004`, 5.660ms) and the same 98/98/0/243 at `7d01608` (`0053`, + 6.297ms). No failures at either commit. +- Stage2 build: `BUILD_OK`, generated `elc-cli.el` C = **11494 lines** at both + commits (`0003`, `0052`). +- `lang/tests/integration/` does not exist at either pinned commit (`0056`), so + no integration harness could be run. `lang/tests/` contains `bench`, + `calendar`, `html_sanitizer`, `native`, `runtime`, `suite`, `swarm`, `text`, + `time`. +- codegen.el: `4f7568b` 4953 → `2bed848` 5084 → `7d01608` 5084 (`0050`). + +## Measurement defects in this re-run, recorded rather than removed + +**Defect 1 — superseded fixpoint command (recipe defect, not this cycle's).** +Artifact `0005-selfhost-fixpoint-04a.out` was captured with the recipe's original +command, which compares **gen1 (the committed `dist/platform/elc`'s output)** +against **gen2**. That is the wrong check: gen1 may legitimately differ from gen2 +whenever codegen's output changes, and reporting it as a break would be a +fabricated divergence. The corrected three-generation check +(`gen2 == gen3`) is `0051` at `2bed848` and `0054` at `7d01608`. `0005` is +retained, not deleted. It happens to agree — at these commits gen1 == gen2 too — +but it should not be cited as the fixpoint evidence. + +**Defect 2 — multi-line commands corrupted MANIFEST.tsv line structure.** +Four captures (`0020`, `0028`, `0038`, and the shell text of `0019`) were invoked +with `bash -c` scripts containing literal newlines. `capture.sh` writes the +command verbatim as the last TSV field, so those newlines became extra physical +lines in `MANIFEST.tsv`. Two visible consequences: + +- the artifact counter, which is derived from the manifest's line count, jumped + (`0020` → `0028` → `0038` → `0049`), so the artifact numbers in this cycle are + **not contiguous**. No artifact is missing; the gaps are counter skips. +- `MANIFEST.tsv` is no longer strictly one physical line per artifact. + +`verify-manifest.sh` is unaffected — the continuation lines parse with an empty +artifact field and are skipped — and the cycle verifies **0 altered, 0 missing** +with every row `clean`. The manifest was **not** edited to tidy this up; editing +it is precisely the defect this record exists to control for. Later captures use +single-line commands. + +## Reproduction + +``` +git worktree add /tmp/rerun-v1-04a 2bed848 +git worktree add /tmp/rerun-v1-04b 7d01608 +``` +then the commands in `MANIFEST.tsv`, and +`bash tools/evidence/verify-manifest.sh docs/v1/experiments/evidence/cycles`. +The parent compiler used for claim 9 is built by `0019` from a +`git archive 4f7568b` extraction into `/tmp/p04parent`; no worktree at the parent +is required. diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.cmd new file mode 100644 index 0000000..bf0cf98 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.cmd @@ -0,0 +1,21 @@ +bash -c SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -rdynamic -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; +set -e +S=/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad +# probe compiler = the SELF-HOSTED emission (gen2, 266 seam indirections) + counting target +cc $CF -o /tmp/elc06a.hot /tmp/g06a.gen2.c $S/hotcount_targets_06.c $SRCS $LF 2>/dev/null +grep -oE "^[[:space:]]*el_seam_run\(EL_STR\(\"[^\"]*\"" /tmp/g06a.gen2.c | sed -E "s/.*EL_STR\(\"//; s/\"$//" | sort -u > /tmp/fns06.txt +echo "functions carrying a seam indirection: $(wc -l < /tmp/fns06.txt | tr -d " ")" +rm -f /tmp/hot06.all +# EL_SEAM_MAX is 256, so bind in two batches +split -l 133 /tmp/fns06.txt /tmp/fnsb06. +for b in /tmp/fnsb06.*; do + awk "{print \$1 \" probe entry count_hit\"}" "$b" > /tmp/tbl06.txt + EL_CONSTRUCTS=/tmp/tbl06.txt /tmp/elc06a.hot elc-cli.el > /dev/null 2>>/tmp/hot06.all +done +echo +echo "=== TOP 20 hottest functions of the compiler, compiling elc-cli.el ===" +grep "^HOTCOUNT" /tmp/hot06.all | sort -t" " -k2 -nr | head -20 | awk -F"\t" "{printf \" %12s %s\n\", \$2, \$3}" +echo +printf "total measured crossings: "; grep "^HOTCOUNT" /tmp/hot06.all | awk -F"\t" "{s+=\$2} END{print s}" +printf "distinct fns observed: "; grep -c "^HOTCOUNT" /tmp/hot06.all + diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.out new file mode 100644 index 0000000..8a49940 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.out @@ -0,0 +1,26 @@ +functions carrying a seam indirection: 266 + +=== TOP 20 hottest functions of the compiler, compiling elc-cli.el === + 310018 tok_kind + 211579 is_ws_code + 208435 is_digit_code + 204417 is_alpha_code + 152568 is_alnum_or_underscore_code + 67032 make_result + 58195 tok_append + 26858 vbd_expr_has_restricted_call + 26633 tok_value + 24971 scan_ident + 24971 keyword_kind + 22731 op_precedence + 22731 is_binop + 21375 cg_expr + 19782 parse_primary + 19705 parse_postfix + 19705 parse_binop + 17883 expect + 16679 parse_expr + 14480 str_has + +total measured crossings: 1692602 +distinct fns observed: 124 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.prov new file mode 100644 index 0000000..b260630 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.prov @@ -0,0 +1,7 @@ +commit 35b07bade29fcd93a663a2f538b43c31f07e28cb +tree clean +captured_utc 2026-08-17T17:40:21Z +exit 0 +ms 5056 +sha256_out 05caa291733d60fad2e5fbaf9a330e4371990f7229f7cab0f2a0ba2b8652150a +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.cmd new file mode 100644 index 0000000..e00dd64 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.cmd @@ -0,0 +1 @@ +bash /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/seam_timing_06.sh 9 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.out new file mode 100644 index 0000000..06caa29 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.out @@ -0,0 +1,22 @@ +host: Wills-MacBook-Pro | arm64 | reps per variant: 9 +reporting MIN of 9 runs (least noise-contaminated on a shared laptop) + +A baseline, no seam (35b07ba^) min 0.055s runs(ms): 58 57 57 55 55 58 60 58 60 +B seamed, 0 bindings min 0.058s runs(ms): 258 58 58 59 59 59 60 59 68 +C seamed, 2 bindings, resolve-once min 0.112s runs(ms): 116 116 114 117 113 112 114 113 116 +D seamed, 2 bindings, dlsym/call min 0.160s runs(ms): 364 160 165 160 163 164 164 162 162 +E seamed, 2 bindings, SILENT target min 0.076s runs(ms): 79 81 80 78 78 76 78 77 78 + +=== observed times and derived ratios (nothing rounded toward the record) === + A baseline, no seam 0.055s record: 0.37s + B seamed, 0 bindings 0.058s record: 0.36s + C seamed, 2 bindings, resolve-once 0.112s record: 0.69s + D seamed, 2 bindings, dlsym/call 0.160s record: 2.45s + E seamed, 2 bindings, silent target 0.076s record: (not measured) + + B/A cost of 266 unused indirections 1.055x record implies 0.36/0.37 = 0.973x ('free') + D/A dlsym-per-call vs baseline 2.909x record: 6.6x + D/C recovered by resolve-once 1.429x record: 3.5x + C/A resolve-once vs baseline 2.036x record implies 0.69/0.37 = 1.865x + E/A seam dispatch alone vs baseline 1.382x (printf removed) + C/E how much of C is the printf 1.474x record: 'the residual is audit_entry's own printf' diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.prov new file mode 100644 index 0000000..526d9e3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.prov @@ -0,0 +1,7 @@ +commit 35b07bade29fcd93a663a2f538b43c31f07e28cb +tree clean +captured_utc 2026-08-17T17:42:58Z +exit 0 +ms 5773 +sha256_out 27063b412e1e99fd9eef0530a40410aef6c8c8be77db7f24a48c916bf1cb9f67 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.cmd new file mode 100644 index 0000000..72bb2c8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.cmd @@ -0,0 +1 @@ +bash /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/free_when_unused_06.sh 41 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.out new file mode 100644 index 0000000..20620b2 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.out @@ -0,0 +1,11 @@ +A_us 56110 57655 56955 55777 57786 56509 57972 59963 57549 57240 59727 59659 59068 58682 58074 58962 60230 58689 60921 59270 58268 60081 57774 60555 58010 58851 60205 58525 60644 58018 58934 58092 59505 57739 58158 57220 58294 56649 58883 59439 58295 +B_us 60068 57937 59269 59650 58333 60600 64672 62749 61310 60183 60613 61126 61684 63417 60941 62487 60761 61512 60050 62102 58437 58676 60276 60985 58511 60990 61146 64052 59497 60016 59444 58497 61929 60482 62315 58339 59902 59686 67185 60040 61424 + +n=41 interleaved pairs, seconds + A no seam min 0.0558 median 0.0583 mean 0.0585 sd 0.0012 max 0.0609 + B 266 seam sites min 0.0579 median 0.0606 mean 0.0608 sd 0.0019 max 0.0672 + B/A by min = 1.0387x (record: 0.36/0.37 = 0.9730x) + B/A by med = 1.0395x (record: 0.36/0.37 = 0.9730x) + B/A by mean = 1.0385x (record: 0.36/0.37 = 0.9730x) + paired B-A: median +2.42 ms, mean +2.25 ms, sd 2.00 ms + B slower in 38/41 paired runs diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.prov new file mode 100644 index 0000000..b088661 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.prov @@ -0,0 +1,7 @@ +commit 35b07bade29fcd93a663a2f538b43c31f07e28cb +tree clean +captured_utc 2026-08-17T17:43:50Z +exit 0 +ms 6719 +sha256_out 5d658c8898319f91966c2dbce73fb8a86d3f28d633fd01f96f6842a5ec473d05 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.cmd new file mode 100644 index 0000000..72bb2c8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.cmd @@ -0,0 +1 @@ +bash /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/free_when_unused_06.sh 41 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.out new file mode 100644 index 0000000..61e96af --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.out @@ -0,0 +1,11 @@ +A_us 60519 59461 59284 60208 58333 68916 59185 60288 60314 61594 59905 58530 60743 58098 60346 59232 59559 59119 60222 60172 59433 59641 59653 58393 58791 57527 58127 60763 61530 58508 58285 59692 57511 57161 59778 58872 60028 59354 58264 63474 57772 +B_us 62852 62668 61095 61190 60985 65193 60872 61458 63116 62973 60962 62721 62543 61451 62884 63627 62451 61385 62251 62129 62684 62681 61492 61888 61265 60541 61612 59870 61784 60343 62661 60851 60438 59843 61470 59739 61857 61619 62334 62273 63141 + +n=41 interleaved pairs, seconds + A no seam min 0.0572 median 0.0595 mean 0.0597 sd 0.0019 max 0.0689 + B 266 seam sites min 0.0597 median 0.0618 mean 0.0618 sd 0.0011 max 0.0652 + B/A by min = 1.0451x (record: 0.36/0.37 = 0.9730x) + B/A by med = 1.0391x (record: 0.36/0.37 = 0.9730x) + B/A by mean = 1.0362x (record: 0.36/0.37 = 0.9730x) + paired B-A: median +2.27 ms, mean +2.16 ms, sd 1.61 ms + B slower in 38/41 paired runs diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.prov new file mode 100644 index 0000000..8806be5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.prov @@ -0,0 +1,7 @@ +commit 35b07bade29fcd93a663a2f538b43c31f07e28cb +tree clean +captured_utc 2026-08-17T17:44:23Z +exit 0 +ms 7050 +sha256_out f9a07c33da31bb35435e30adc5a5d19df87db66c1d4cff4bd2fd76c830747652 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.cmd new file mode 100644 index 0000000..70b42a2 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.cmd @@ -0,0 +1,26 @@ +bash -c +echo "CLAIM (886626a): \"three of the five compile-time kinds are runtime-bindable:" +echo " entry injection, exit injection, and refusal\"" +echo +echo "The runtime table format supports an exit phase. Does CODEGEN ever emit an" +echo "exit-phase seam call (phase argument 1) at any commit in this cycle?" +echo +for c in 35b07ba 886626a 28d19da 8bbb750 24f7fb5; do + printf "%s el_seam_run emissions in codegen.el:\n" "${c}" + git show "${c}:lang/el-compiler/src/codegen.el" | grep -n "el_seam_run" | sed "s/^/ /" +done +echo +echo "=== emitted C at 24f7fb5 (self-hosted): any phase-1 / exit seam call? ===" +printf " entry-phase calls el_seam_run(EL_STR(...), 0, : "; grep -c "el_seam_run(EL_STR(\"[^\"]*\"), 0," /tmp/g06e.gen2.c || true +printf " exit-phase calls el_seam_run(EL_STR(...), 1, : "; grep -c "el_seam_run(EL_STR(\"[^\"]*\"), 1," /tmp/g06e.gen2.c || true +echo +echo "=== runtime supports EL_PHASE_EXIT? ===" +git show "24f7fb5:lang/runtime/el_runtime.c" | grep -n "EL_PHASE_EXIT" | sed "s/^/ /" +echo +echo "=== when does an exit assertion first appear in seam_binding.sh? ===" +for c in 8bbb750 285166c bc2f26d; do + printf " %s: " "${c}" + git show "${c}:lang/tests/integration/seam_binding.sh" | grep -c "exit" || true + git show "${c}:lang/tests/integration/seam_binding.sh" | grep -E "^check \"an EXIT" | sed "s/^/ /" || true +done + diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.out new file mode 100644 index 0000000..add183e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.out @@ -0,0 +1,31 @@ +CLAIM (886626a): "three of the five compile-time kinds are runtime-bindable: + entry injection, exit injection, and refusal" + +The runtime table format supports an exit phase. Does CODEGEN ever emit an +exit-phase seam call (phase argument 1) at any commit in this cycle? + +35b07ba el_seam_run emissions in codegen.el: + 3211: emit_line(" el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 0, 0);") +886626a el_seam_run emissions in codegen.el: + 3211: emit_line(" { el_val_t __s = el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 0, 0); if (__s) return __s; }") +28d19da el_seam_run emissions in codegen.el: + 3212: emit_line(" { el_val_t __s = el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 0, 0); if (__s) return __s; }") +8bbb750 el_seam_run emissions in codegen.el: + 3212: emit_line(" { el_val_t __s = el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 0, 0); if (__s) return __s; }") +24f7fb5 el_seam_run emissions in codegen.el: + 3212: emit_line(" { el_val_t __s = el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 0, 0); if (__s) return __s; }") + +=== emitted C at 24f7fb5 (self-hosted): any phase-1 / exit seam call? === + entry-phase calls el_seam_run(EL_STR(...), 0, : 263 + exit-phase calls el_seam_run(EL_STR(...), 1, : 0 + +=== runtime supports EL_PHASE_EXIT? === + 17097:#define EL_PHASE_EXIT 1 + 17119: _el_seam[_el_seam_n].phase = (strcmp(ph, "exit") == 0) ? EL_PHASE_EXIT : EL_PHASE_ENTRY; + +=== when does an exit assertion first appear in seam_binding.sh? === + 8bbb750: 3 + 285166c: 6 + check "an EXIT construct declared after the build replaces the result" \ + bc2f26d: 6 + check "an EXIT construct declared after the build replaces the result" \ diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.prov new file mode 100644 index 0000000..c85273a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.prov @@ -0,0 +1,7 @@ +commit 24f7fb51436bdc68838fd7651d7377f3fb919ee3 +tree clean +captured_utc 2026-08-17T17:44:50Z +exit 0 +ms 107 +sha256_out 251ac55436cd3cf5f2b3a123af2dab4799bd4d2ea1b8ceaa0ce5faa6db302058 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.cmd new file mode 100644 index 0000000..47a0c8f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.cmd @@ -0,0 +1 @@ +bash /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/exit_binding_probe_06.sh /tmp/elc06b /tmp/rerun-v1-06b/lang diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.out new file mode 100644 index 0000000..86dec1d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.out @@ -0,0 +1,12 @@ +--- emitted seam calls in the probe's C, with their phase argument --- +8: { el_val_t __s = el_seam_run(EL_STR("work"), 0, 0); if (__s) return __s; } + +--- control 1: ENTRY binding (expected to fire) --- +ENTRY-FIRED work/audited +7 + +--- control 2: EXIT binding (the claim under test) --- +7 + +VERDICT: if 'EXIT-FIRED' is absent and the program still prints 7, then no +exit-phase indirection is emitted and an exit binding cannot fire. diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.prov new file mode 100644 index 0000000..29d99ec --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.prov @@ -0,0 +1,7 @@ +commit 886626a64e4c64b46d8382d95ab1d0ff7b739fe9 +tree clean +captured_utc 2026-08-17T17:45:21Z +exit 0 +ms 3368 +sha256_out 9a485715a033d891f0bc217e6c3dd53ad42b56ba00a9415c50f9666bfa998d7b +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.cmd new file mode 100644 index 0000000..e5ccd04 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.cmd @@ -0,0 +1 @@ +bash /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/exit_binding_probe_06.sh /tmp/elc06e /tmp/rerun-v1-06e/lang diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.out new file mode 100644 index 0000000..86dec1d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.out @@ -0,0 +1,12 @@ +--- emitted seam calls in the probe's C, with their phase argument --- +8: { el_val_t __s = el_seam_run(EL_STR("work"), 0, 0); if (__s) return __s; } + +--- control 1: ENTRY binding (expected to fire) --- +ENTRY-FIRED work/audited +7 + +--- control 2: EXIT binding (the claim under test) --- +7 + +VERDICT: if 'EXIT-FIRED' is absent and the program still prints 7, then no +exit-phase indirection is emitted and an exit binding cannot fire. diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.prov new file mode 100644 index 0000000..88be6ed --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.prov @@ -0,0 +1,7 @@ +commit 24f7fb51436bdc68838fd7651d7377f3fb919ee3 +tree clean +captured_utc 2026-08-17T17:45:25Z +exit 0 +ms 3386 +sha256_out 9a485715a033d891f0bc217e6c3dd53ad42b56ba00a9415c50f9666bfa998d7b +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.cmd new file mode 100644 index 0000000..4d1df70 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.cmd @@ -0,0 +1,23 @@ +bash -c +echo "CLAIM (28d19da): injects_at_entry removed, guards_at_entry removed," +echo "injects_at_exit STRUCTURAL, wraps_body structural, prohibits_outside #error." +echo +echo "=== occurrences of each declaration kind in codegen.el, parent -> commit ===" +printf "%-20s %8s %8s\n" kind "886626a" "28d19da" +for k in injects_at_entry guards_at_entry injects_at_exit wraps_body prohibits_outside; do + a=$(git show "886626a:lang/el-compiler/src/codegen.el" | grep -c "$k" || true) + b=$(git show "28d19da:lang/el-compiler/src/codegen.el" | grep -c "$k" || true) + printf "%-20s %8s %8s\n" "$k" "$a" "$b" +done +echo +echo "=== same, in the whole compiler src tree ===" +printf "%-20s %8s %8s\n" kind "886626a" "28d19da" +for k in injects_at_entry guards_at_entry injects_at_exit wraps_body prohibits_outside; do + a=$(git grep -c "$k" 886626a -- lang/el-compiler/src 2>/dev/null | awk -F: "{s+=\$NF} END{print s+0}") + b=$(git grep -c "$k" 28d19da -- lang/el-compiler/src 2>/dev/null | awk -F: "{s+=\$NF} END{print s+0}") + printf "%-20s %8s %8s\n" "$k" "$a" "$b" +done +echo +echo "=== the 65 removed / 4 added lines of codegen.el at 28d19da ===" +git diff "28d19da^" 28d19da -- lang/el-compiler/src/codegen.el + diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.out new file mode 100644 index 0000000..46b6ed1 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.out @@ -0,0 +1,140 @@ +CLAIM (28d19da): injects_at_entry removed, guards_at_entry removed, +injects_at_exit STRUCTURAL, wraps_body structural, prohibits_outside #error. + +=== occurrences of each declaration kind in codegen.el, parent -> commit === +kind 886626a 28d19da +injects_at_entry 2 1 +guards_at_entry 2 1 +injects_at_exit 2 2 +wraps_body 1 1 +prohibits_outside 2 2 + +=== same, in the whole compiler src tree === +kind 886626a 28d19da +injects_at_entry 2 1 +guards_at_entry 2 1 +injects_at_exit 2 2 +wraps_body 1 1 +prohibits_outside 2 2 + +=== the 65 removed / 4 added lines of codegen.el at 28d19da === +diff --git a/lang/el-compiler/src/codegen.el b/lang/el-compiler/src/codegen.el +index 5fd5761b..8f71d368 100644 +--- a/lang/el-compiler/src/codegen.el ++++ b/lang/el-compiler/src/codegen.el +@@ -3205,38 +3205,11 @@ fn fn_has_decorator(stmt: Map, name: String) -> Bool { + // applies both); injection is topmost-wins, matching the VBD role convention, + // because a role is singular and a refusal is not. + fn cg_entry_seam(stmt: Map, fn_name: String) -> Void { +- // RUNTIME SEAM: codegen cannot know which constructs will be bound to this +- // fn after the binary exists, so the indirection is unconditional. What +- // applies is resolved at execution against a table written later. ++ // The crossing is resolved at EXECUTION. One refusable indirection replaces ++ // the compile-time guard loop and injection loop: which constructs apply, ++ // and whether any of them refuses, is read from a table written after the ++ // binary exists. + emit_line(" { el_val_t __s = el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 0, 0); if (__s) return __s; }") +- let gdl = stmt["decorators"] +- let n_gdl: Int = native_list_len(gdl) +- let gi = 0 +- while gi < n_gdl { +- let gd = native_list_get(gdl, gi) +- let gdn: String = gd["name"] +- let g_target: String = decorator_guard(gdn) +- if !str_eq(g_target, "") { +- emit_line(" { el_val_t __g = " + g_target + "(EL_STR(" + c_str_lit(fn_name) + "), EL_STR(" + c_str_lit(gdn) + ")); if (__g) return __g; }") +- } +- let gi = gi + 1 +- } +- let idl = stmt["decorators"] +- let n_idl: Int = native_list_len(idl) +- let di = 0 +- let did_inject: Bool = false +- while di < n_idl { +- if !did_inject { +- let dd = native_list_get(idl, di) +- let ddn: String = dd["name"] +- let inj_target: String = decorator_injection(ddn) +- if !str_eq(inj_target, "") { +- emit_line(" " + inj_target + "(EL_STR(" + c_str_lit(fn_name) + "), EL_STR(" + c_str_lit(ddn) + "));") +- let did_inject = true +- } +- } +- let di = di + 1 +- } + } + + // cg_exit_target / cg_exit_construct — the first construct on this fn that +@@ -4310,13 +4283,7 @@ fn program_has_routes(recs: [Map]) -> Bool { + // inside this boundary" is a query over program structure and there is nothing + // yet to ask. + +-fn declare_decorator(name: String, injects: String) -> Void { +- state_set("__dec_inject_" + name, injects) +-} + +-fn decorator_injection(name: String) -> String { +- state_get("__dec_inject_" + name) +-} + + // A GUARD is an injection that may refuse. The declared target is called at + // entry with the same (fn, construct) pair; a non-zero return short-circuits +@@ -4333,13 +4300,7 @@ fn decorator_injection(name: String) -> String { + // nothing — fourteen applications that read as protection and emitted no + // instruction. The compiler still knows nothing about authentication: the + // program points the construct at its own function. +-fn declare_guard(name: String, guards: String) -> Void { +- state_set("__dec_guard_" + name, guards) +-} + +-fn decorator_guard(name: String) -> String { +- state_get("__dec_guard_" + name) +-} + + // An EXIT injection runs after the fn returns and receives the result: + // target(, , ) +@@ -4419,14 +4380,8 @@ fn prohibiting_constructs() -> String { + // the streaming backend discards per-fn ASTs and there is no whole-program AST + // to walk. + fn scan_declared_decorators(tokens: [Any]) -> Void { +- declare_decorator("manager", "engram_boundary_beat") +- declare_decorator("accessor", "engram_boundary_beat") + declare_prohibition("manager", "dharma_emit,dharma_field") + let total: Int = native_list_len(tokens) / 2 +- let has_pending: Bool = false +- let pending_target: String = "" +- let has_pending_g: Bool = false +- let pending_guard: String = "" + let has_pending_x: Bool = false + let pending_exit: String = "" + let has_pending_w: Bool = false +@@ -4471,14 +4426,6 @@ fn scan_declared_decorators(tokens: [Any]) -> Void { + if str_eq(dname, "decorator") { + if native_list_len(args) >= 2 { + let dkind: String = native_list_get(args, 0) +- if str_eq(dkind, "injects_at_entry") { +- let has_pending = true +- let pending_target = native_list_get(args, 1) +- } +- if str_eq(dkind, "guards_at_entry") { +- let has_pending_g = true +- let pending_guard = native_list_get(args, 1) +- } + if str_eq(dkind, "injects_at_exit") { + let has_pending_x = true + let pending_exit = native_list_get(args, 1) +@@ -4497,14 +4444,6 @@ fn scan_declared_decorators(tokens: [Any]) -> Void { + } else { + if str_eq(k, "Fn") { + let fname: String = tok_value(tokens, pos + 1) +- if has_pending { +- declare_decorator(fname, pending_target) +- let has_pending = false +- } +- if has_pending_g { +- declare_guard(fname, pending_guard) +- let has_pending_g = false +- } + if has_pending_x { + declare_exit(fname, pending_exit) + let has_pending_x = false diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.prov new file mode 100644 index 0000000..ddf748e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.prov @@ -0,0 +1,7 @@ +commit 24f7fb51436bdc68838fd7651d7377f3fb919ee3 +tree clean +captured_utc 2026-08-17T17:45:38Z +exit 0 +ms 162 +sha256_out 1b7d6b83b146bd36ff15964cdec602d12c2ffcc52435281a1d1c6c20416a70e8 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.cmd new file mode 100644 index 0000000..0b05115 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.cmd @@ -0,0 +1,16 @@ +bash -c +echo "=== the single remaining injects_at_entry / guards_at_entry reference at 28d19da ===" +git show "28d19da:lang/el-compiler/src/codegen.el" | grep -n "injects_at_entry\|guards_at_entry" | sed "s/^/ /" +echo +echo "=== prohibits_outside still emits a #error (compile-time by nature) ===" +git show "28d19da:lang/el-compiler/src/codegen.el" | grep -n "#error" | sed "s/^/ /" +echo +echo "=== the five compile-time passes and codegen.el after each (the 491-line claim) ===" +printf " baseline before any pass 409bf57 / addd512: %s\n" "$(git show "409bf573:lang/el-compiler/src/codegen.el" | wc -l | tr -d " ")" +for c in 5718943 60737b0 4f7568b 7d01608 1b324a0; do + printf " %s %-58s %s\n" "${c}" "$(git log -1 --format=%s ${c} | cut -c1-58)" "$(git show "${c}:lang/el-compiler/src/codegen.el" | wc -l | tr -d " ")" +done +printf " 5152 - 4661 = %s (record: \"Five compile-time passes added 491 lines\")\n" "$((5152-4661))" +printf " 5095 - 4661 = %s (record: \"Still +435 over baseline\")\n" "$((5095-4661))" +printf " 5156 - 5095 = %s (record: \"61 lines of compiler replaced by one refusable indirection\")\n" "$((5156-5095))" + diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.out new file mode 100644 index 0000000..9b47e50 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.out @@ -0,0 +1,45 @@ +=== the single remaining injects_at_entry / guards_at_entry reference at 28d19da === + 4258:// @decorator("injects_at_entry", "engram_boundary_beat") + 4292:// @decorator("guards_at_entry", "my_auth_check") + +=== prohibits_outside still emits a #error (compile-time by nature) === + 545: // become #error directives rather than silently falling through to + 998: // violations to be emitted as #error directives at the + 1921:// surface mismatches (Instant + Instant, Duration + Int) as #error + 2321:// Record a temporal-type violation. Surfaced as `#error` directives at the + 2481:// then emits #error directives at the top of the generated C so the + 2561:// Emit collected capability violations as #error directives. Called + 2578: emit_line("#error \"capability violation: '" + kind + "' programs may not call '" + fn_name + "' (self-formation primitive - only 'cgi' programs may use it)\"") + 2584:// Surface temporal-type violations as #error directives. The cg_expr BinOp + 2587:// to a single #error so downstream cc fails the build with a clear El- + 2602: emit_line("#error \"temporal type error: " + detail + "\"") + 2619:// in process state, which emit_arity_violations() turns into #error + 2980:// and surfaced as an #error at the bottom of the generated C, so cc fails + 2990:// Emit recorded arity violations as #error directives. + 3009: emit_line("#error \"arity error: '" + fn_name + "' takes " + exp_s + " arguments, but called with " + act_s + "\"") + 3356: // via #error directives emitted before the function definition. Read the + 3371: emit_line("#error \"boundary violation: " + prohibition_names(pc) + " may only be called from an @" + pc + " fn, but '" + fn_name + "' is not one\"") + 3529: emit_line("#error \"singleton '" + sid + "' declares no `guards:` — a singleton must name the state it protects, e.g. `guards: engram_resolve_data_dir()` (spec 18.2)\"") + 3701: // Codegen enforces this with #error directives at every restricted + 3728: emit_line("#error \"El: multiple cgi blocks in program (only one allowed)\"") + 3731: emit_line("#error \"El: multiple service blocks in program (only one allowed)\"") + 3735: emit_line("#error \"El: program declares both cgi and service blocks (mutually exclusive - pick one)\"") + 4002: // Emit any accumulated capability-violation #error directives. cc + 4007: // Same for builtin-arity violations: cc halts on the first #error, + 4282:// #error on dharma_emit) is still hardcoded, because "which calls may appear + 4352:// and one #error in cg_fn -- one prohibition, uneditable without a compiler + 4353:// release, and unrankable because a #error is a string handed to cpp, which + 4551: emit_line("#error \"El: multiple cgi blocks in program (only one allowed)\"") + 4554: emit_line("#error \"El: multiple service blocks in program (only one allowed)\"") + 4558: emit_line("#error \"El: program declares both cgi and service blocks (mutually exclusive - pick one)\"") + +=== the five compile-time passes and codegen.el after each (the 491-line claim) === + baseline before any pass 409bf57 / addd512: 4661 + 5718943 let a construct declare its own meaning instead of the emi 4800 + 60737b0 let a construct refuse, not only observe 4850 + 4f7568b give a construct its after-crossing face, and let construc 4953 + 7d01608 land wraps_body: a construct controls invocation 5084 + 1b324a0 let a construct declare what may not cross it 5152 + 5152 - 4661 = 491 (record: "Five compile-time passes added 491 lines") + 5095 - 4661 = 434 (record: "Still +435 over baseline") + 5156 - 5095 = 61 (record: "61 lines of compiler replaced by one refusable indirection") diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.prov new file mode 100644 index 0000000..dfa4e3e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.prov @@ -0,0 +1,7 @@ +commit 24f7fb51436bdc68838fd7651d7377f3fb919ee3 +tree clean +captured_utc 2026-08-17T17:45:56Z +exit 0 +ms 99 +sha256_out aeeebfee1a307b0a14e05b8662735c345de638abe151cd862d4099ed3d28fece +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.cmd b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.cmd new file mode 100644 index 0000000..5fbc0f9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.cmd @@ -0,0 +1,14 @@ +bash -c +echo "Is the 532 el_val_t-declaration count really 266 prototypes + 266 definitions?" +printf " lines matching ^(static )?el_val_t NAME( : %s\n" "$(grep -cE "^(static )?el_val_t [a-zA-Z_][a-zA-Z0-9_]*\(" /tmp/g06a.gen2.c)" +printf " of those ending in \";\" (prototypes): %s\n" "$(grep -E "^(static )?el_val_t [a-zA-Z_][a-zA-Z0-9_]*\(" /tmp/g06a.gen2.c | grep -c ";$")" +printf " of those ending in \"{\" (definitions): %s\n" "$(grep -E "^(static )?el_val_t [a-zA-Z_][a-zA-Z0-9_]*\(" /tmp/g06a.gen2.c | grep -c "{$")" +printf " distinct names among them: %s\n" "$(grep -oE "^(static )?el_val_t [a-zA-Z_][a-zA-Z0-9_]*\(" /tmp/g06a.gen2.c | sed -E "s/^(static )?el_val_t //; s/\($//" | sort -u | wc -l | tr -d " ")" +printf " distinct fn names carrying a seam indirection: %s\n" "$(grep -oE "^[[:space:]]*el_seam_run\(EL_STR\(\"[^\"]*\"" /tmp/g06a.gen2.c | sed -E "s/.*EL_STR\(\"//; s/\"$//" | sort -u | wc -l | tr -d " ")" +echo +echo " set difference (declared el_val_t fns NOT carrying a seam):" +grep -oE "^(static )?el_val_t [a-zA-Z_][a-zA-Z0-9_]*\(" /tmp/g06a.gen2.c | sed -E "s/^(static )?el_val_t //; s/\($//" | sort -u > /tmp/decl06.txt +grep -oE "^[[:space:]]*el_seam_run\(EL_STR\(\"[^\"]*\"" /tmp/g06a.gen2.c | sed -E "s/.*EL_STR\(\"//; s/\"$//" | sort -u > /tmp/seamed06.txt +comm -23 /tmp/decl06.txt /tmp/seamed06.txt | sed "s/^/ /" +echo " (empty = every declared el_val_t fn carries exactly one indirection)" + diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.err b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.out b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.out new file mode 100644 index 0000000..ce53016 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.out @@ -0,0 +1,9 @@ +Is the 532 el_val_t-declaration count really 266 prototypes + 266 definitions? + lines matching ^(static )?el_val_t NAME( : 532 + of those ending in ";" (prototypes): 266 + of those ending in "{" (definitions): 266 + distinct names among them: 266 + distinct fn names carrying a seam indirection: 266 + + set difference (declared el_val_t fns NOT carrying a seam): + (empty = every declared el_val_t fn carries exactly one indirection) diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.prov b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.prov new file mode 100644 index 0000000..7b97e91 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.prov @@ -0,0 +1,7 @@ +commit 35b07bade29fcd93a663a2f538b43c31f07e28cb +tree clean +captured_utc 2026-08-17T17:49:44Z +exit 0 +ms 57 +sha256_out d97e929292f02e452b2f446ba6ea81b607819f7c0a303cae7fa1e8a1c66a059c +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.rc b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/CLAIMS.md b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/CLAIMS.md new file mode 100644 index 0000000..7bde254 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/CLAIMS.md @@ -0,0 +1,379 @@ +# CLAIMS — cycle 06, the crossing resolves at emission + +Source doc: `docs/v1/experiments/cycles/06-the-crossing-resolves-at-emission.md` + +This cycle pins **five** commits. The record is five commit messages, written +sequentially as the experiment ran, so several figures are restated at the +landing commit and one claim is silently corrected by a later commit in the +same cycle. Both are checked below. + +## Pinned commits + +| Tag | SHA | Committed | Subject | Parent | Worktree | +|---|---|---|---|---|---| +| 06a | `35b07bade29fcd93a663a2f538b43c31f07e28cb` | 2026-08-17 08:37:47 -0500 | EXPERIMENT: resolve the crossing at execution, not at emission | `1b324a071` | `/tmp/rerun-v1-06a` | +| 06b | `886626a64e4c64b46d8382d95ab1d0ff7b739fe9` | 2026-08-17 08:40:10 -0500 | seam refusal + control tests: a runtime binding can short-circuit | `35b07bade` | `/tmp/rerun-v1-06b` | +| 06c | `28d19da7f1b6b43394302c82ef58446deeebc9d3` | 2026-08-17 08:43:57 -0500 | strip the compile-time machinery the seam replaces | `886626a64` | `/tmp/rerun-v1-06c` | +| 06d | `8bbb750c2cefc2dc070f6c5ff598e82483df9bcf` | 2026-08-17 08:48:57 -0500 | control the claim that cannot be unit tested | `28d19da7f` | `/tmp/rerun-v1-06d` | +| 06e | `24f7fb51436bdc68838fd7651d7377f3fb919ee3` | 2026-08-17 08:56:41 -0500 | land the runtime seam: resolve the crossing at execution | **merge**: `82e998273` + `8bbb750c2` | `/tmp/rerun-v1-06e` | + +`24f7fb5` is a **merge commit**, not a linear child of `8bbb750` (`0214-commit-dag-topology.out`). +Its first parent is `82e9982` (a self-review commit on the trunk). Consequently +`git diff 24f7fb5^ 24f7fb5` shows the *entire* cycle, and `codegen.el` / +`el_runtime.c` are unchanged between `8bbb750` and `24f7fb5` except for the ++60 runtime lines that come in from `82e9982`. + +All five worktrees were clean at capture. Every artifact is stamped `tree clean` +in `MANIFEST.tsv`. Environment: Apple M-series arm64, Apple clang 21.0.0, +macOS 25.5.0 (`RUN.env`). + +## Self-hosting method used throughout + +`dist/platform/elc` (the committed bootstrap) is **stale** at every commit in +this cycle, because every one of these commits changes codegen's output. So: + +``` +gen1 = dist/platform/elc elc-cli.el # stale bootstrap emission, NO seam +gen2 = elc(built from gen1) elc-cli.el # first emission that carries the seam +gen3 = elc(built from gen2) elc-cli.el # the fixpoint check +``` + +The fixpoint is **gen2 == gen3**. `gen1 != gen2` is expected. This is exactly +the methodological point the record itself makes at `35b07ba` ("my first +fixpoint test was wrong, not the code"), and this record demonstrates both +halves. All seam-site counts below are taken from **gen2**, the self-hosted +emission — gen1 contains no seam at all. + +## Verdicts + +| # | Claim (verbatim from the record) | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 1 | "codegen emits one unconditional indirection per fn" | `0363-fn-count-vs-seam-sites-06a.out`, `0030-seam-site-count-breakdown-06a.out` | `35b07ba` | **REPRODUCED exactly** — gen2 declares 266 `el_val_t` functions (266 prototypes + 266 definitions = 532 lines, 266 distinct names) and carries 266 indirections over 266 distinct names. The set difference is **empty**: every declared function has exactly one, and nothing else has one | +| 2 | P1 "a construct declared after the build applies" — TRUE | `0272-RECONSTRUCTED-seamrun-transcript-06a.out`, `0274-RETROFIT-seam_binding-harness-06a.out` | `35b07ba` | **REPRODUCED** | +| 3 | P2 "an unlinked target is skipped, not fatal" — TRUE | `0272-…-seamrun-transcript-06a.out`, `0274-RETROFIT-…-06a.out` | `35b07ba` | **REPRODUCED** — binding `no_such_symbol_anywhere` prints 7, exit 0 | +| 4 | P3 "emitting on every fn is measurably slower" — **FALSE**, "0.37s -> 0.36s … Free unused" | `0298-REDO-free-when-unused-clean-binary-06a.out`, `0297-RECONSTRUCTED-free-when-unused-06a.out` | `35b07ba` | **DIVERGED** — it *is* measurably slower here: +3.9 % median, B slower in 38/41 interleaved paired runs. See detail A | +| 5 | "267 indirections" / "267 seam sites" | `0013-selfhost-3gen-fixpoint-06a.out`, `0030-seam-site-count-breakdown-06a.out` | `35b07ba` | **REPRODUCED** — `grep -c el_seam_run` on gen2 = **267**, exactly. Of those, 266 are emitted statements and 1 is codegen's own `emit_line` string literal. See detail F | +| 6 | P4 "the compiler still self-hosts" — TRUE | `0013-selfhost-3gen-fixpoint-06a.out` | `35b07ba` | **REPRODUCED** — gen2 == gen3, sha256 `ca98d55ffad2…` both | +| 7 | P4 note: "I compared gen1 to gen2, which must differ whenever codegen's output changes" | `0013-selfhost-3gen-fixpoint-06a.out` | `35b07ba` | **REPRODUCED** — gen1 (`1748ab31…`) != gen2 (`ca98d55f…`); the author's diagnosis of his own bad test is correct | +| 8 | P4 note: "gen2 == gen3, 267 seam sites, stable" | `0013-selfhost-3gen-fixpoint-06a.out` | `35b07ba` | **REPRODUCED** — gen2 and gen3 both 11817 lines, both 267 `el_seam_run` lines, byte-identical | +| 9 | DEMONSTRATED transcript: `/tmp/seamrun` → 7; then `EL_CONSTRUCTS=constructs.txt /tmp/seamrun` → "AUDIT: work applied by audited" / 7 | `0272-RECONSTRUCTED-seamrun-transcript-06a.out` | `35b07ba` | **REPRODUCED** (probe reconstructed — see "Reconstructed inputs") — output matches the transcript verbatim, line for line | +| 10 | MEASURED COST: "0 bindings 0.36s vs 0.37s baseline" (absolute) | `0296-RECONSTRUCTED-seam-cost-timing-06a.out` | `35b07ba` | **NOT-REPRODUCIBLE (machine-dependent)** — this machine runs the same workload in 0.055 s / 0.058 s, ~6.7× faster than the record's hardware | +| 11 | MEASURED COST: "2 bindings, dlsym per call — 2.45s" (absolute) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **NOT-REPRODUCIBLE (machine-dependent)** — observed 0.160 s | +| 12 | MEASURED COST: "2 bindings, resolved once — 0.69s" (absolute) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **NOT-REPRODUCIBLE (machine-dependent)** — observed 0.112 s | +| 13 | "…dlsym per call **6.6x**" (ratio) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **DIVERGED** — observed **2.909×** over baseline. See detail B | +| 14 | "…resolved once **3.5x** recovered" (ratio) | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **DIVERGED** — observed **1.429×** recovered. See detail B | +| 15 | "The table scan was never the cost. dlsym walks the dynamic symbol table on every call. Resolve once and cache" | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **REPRODUCED (direction)** — disabling the resolve-once cache costs 48 ms over 521 597 crossings ≈ 92 ns per `dlsym`; the table scan (2 entries) is not separable from noise | +| 16 | "The 0.69s residual is audit_entry's own printf … not seam overhead" | `0296-…-seam-cost-timing-06a.out` | `35b07ba` | **DIVERGED** — the printf is **63 %** of the residual, not all of it; the remaining **37 %** *is* seam dispatch. See detail C | +| 17 | "Prediction 3 was FALSE. I expected refusal to be impossible through the seam" | `0274-RETROFIT-…-06a.out` vs `0273-RETROFIT-…-06b.out` | `35b07ba` → `886626a` | **REPRODUCED** — at `35b07ba` the refusal assertion is the *only* one of six that fails (expected 42, actual 7); at `886626a` all six pass | +| 18 | The one-line emitted shape `{ el_val_t __s = el_seam_run(EL_STR(f), 0, 0); if (__s) return __s; }` | `0105-emitted-seam-shape-and-counts.out`, `0190-seam-c-line-count-precise.out` | `886626a` | **REPRODUCED verbatim** — emitted C reads ` { el_val_t __s = el_seam_run(EL_STR("is_digit_code"), 0, 0); if (__s) return __s; }`; the commit's codegen diff is a one-line replacement | +| 19 | "work() returns 7; bound to a refusing construct AFTER the build it returns 42" | `0273-RETROFIT-seam_binding-harness-06b.out` | `886626a` | **REPRODUCED** | +| 20 | "three of the five compile-time kinds are runtime-bindable: entry injection, exit injection, and refusal" | `0299-exit-phase-bindability-check.out`, `0324-RECONSTRUCTED-exit-binding-probe-06b.out`, `0325-…-06e.out` | `886626a` | **DIVERGED** — only **two** are: entry injection and refusal. No exit-phase indirection is ever emitted in this cycle. See detail D | +| 21 | "wraps_body needs invocation control and prohibits_outside is compile-time by nature" | `0326-strip-table-verification-28d19da.out`, `0348-residual-kind-references-28d19da.out` | `886626a` | **REPRODUCED** — both survive the strip; `prohibits_outside` resolves to `emit_line("#error \"boundary violation: …")` at codegen.el:3371 | +| 22 | "104/104 native compiler tests pass" | `0047-native-compiler-tests-06b.out` | `886626a` | **REPRODUCED** — `104 tests, 104 passed, 0 failed, 253 assertions` | +| 23 | "PREDICTION: codegen.el drops below 4661 … RESULT: FALSE" | `0128-REDO-codegen-linecount-history.out` | `28d19da` | **REPRODUCED** — the prediction is indeed false; codegen.el is 5095 after the strip, still far above 4661 | +| 24 | "**5157** -> **5096**" | `0128-REDO-codegen-linecount-history.out` | `886626a` → `28d19da` | **DIVERGED** — observed **5156 -> 5095**. Both endpoints are exactly one line high in the record. See detail E | +| 25 | "Still **+435** over baseline" | `0128-REDO-codegen-linecount-history.out`, `0348-residual-kind-references-28d19da.out` | `28d19da` | **DIVERGED** — 5095 − 4661 = **+434** | +| 26 | "4661, its size before any of these passes" (the baseline itself) | `0128-REDO-codegen-linecount-history.out` | pre-cycle | **REPRODUCED** — codegen.el is exactly 4661 lines at `409bf573` and `addd5120`, the two commits immediately preceding cycle 01's parent | +| 27 | "injects_at_entry collapsed into the seam — removed / guards_at_entry collapsed into the seam — removed" | `0326-strip-table-verification-28d19da.out`, `0348-…-28d19da.out` | `28d19da` | **REPRODUCED** — `declare_decorator`, `decorator_injection`, `declare_guard`, `decorator_guard` and both token-scan branches deleted; the single surviving mention of each name at 28d19da is a `//` comment | +| 28 | "injects_at_exit — STRUCTURAL / wraps_body — structural / prohibits_outside — a #error cannot be emitted at runtime" | `0326-strip-table-verification-28d19da.out` | `28d19da` | **REPRODUCED** — all three untouched by the strip diff | +| 29 | "**61 lines** of compiler replaced by one refusable indirection" | `0128-REDO-…-history.out`, `0190-seam-c-line-count-precise.out` | `28d19da` | **REPRODUCED exactly** — 5156 − 5095 = 61; the diff is `+4 / −65` = net −61 | +| 30 | "**8 tests fail**, and they are exactly the 8 controls for compile-time entry injection and guards. No unrelated breakage." | `0048-native-compiler-tests-06c.out`, `0051-failing-tests-detail-06c.out` | `28d19da` | **REPRODUCED exactly** — `104 tests, 96 passed, 8 failed`; every failing test named below, 4 entry-injection + 4 guard controls, nothing else | +| 31 | "Verified after the strip: fixpoint gen2==gen3" | `0069-selfhost-3gen-fixpoint-06c.out` | `28d19da` | **REPRODUCED** — gen2 == gen3, sha256 `7b9b6e0306ff…` | +| 32 | "observation and refusal both work through the seam with the compiler knowing nothing about either" | `0275-RETROFIT-seam_binding-harness-06c.out` | `28d19da` | **REPRODUCED** — 6/6 with the harness from `8bbb750` applied retroactively | +| 33 | The six assertion names of `tests/integration/seam_binding.sh` | `0228-integration-seam_binding-06d.out` | `8bbb750` | **REPRODUCED** — all six lines match the record verbatim, in order | +| 34 | "6 assertions, 6 passed, 0 failed" | `0228-integration-seam_binding-06d.out` | `8bbb750` | **REPRODUCED** — real harness, `bash tests/integration/seam_binding.sh /tmp/elc06d "$PWD"`, exit 0 | +| 35 | "The eight controls that failed after the strip were replaced, not repaired" | `0239-REDO-test-churn-names.out` | `8bbb750` | **REPRODUCED** — the eight tests deleted at `8bbb750` are, name for name, the eight that failed at `28d19da` | +| 36 | "Three took their place, asserting the emitted shape" | `0239-REDO-test-churn-names.out` | `8bbb750` | **REPRODUCED** — exactly three added: `seam-replaces-inlined-entry-injection`, `seam-entry-is-refusable`, `seam-is-emitted-for-undecorated-fns`. 104 − 8 + 3 = 99 | +| 37 | "99/99 native compiler tests pass" | `0049-native-compiler-tests-06d.out` | `8bbb750` | **REPRODUCED** — `99 tests, 99 passed, 0 failed, 240 assertions` | +| 38 | "Fixpoint holds." | `0081-selfhost-3gen-fixpoint-06d.out` | `8bbb750` | **REPRODUCED** — gen2 == gen3 | +| 39 | "Five compile-time passes added **491 lines**" | `0348-residual-kind-references-28d19da.out`, `0128-REDO-…-history.out` | `24f7fb5` | **REPRODUCED exactly** — 4661 → 5152 across `5718943`, `60737b0`, `4f7568b`, `7d01608`, `1b324a0`. 5152 − 4661 = 491 | +| 40 | "The seam is **~55 lines of C** and **one line of emission**" | `0190-seam-c-line-count-precise.out`, `0175-seam-c-block-verbatim.out` | `24f7fb5` | **REPRODUCED** — the implementation block `el_runtime.c:17095–17152` is 58 lines, of which **55 are non-blank** (51 excluding comment lines); codegen contains exactly **one** `emit_line` producing the indirection | +| 41 | "a construct declared AFTER the binary exists applies to it" | `0229-integration-seam_binding-06e.out` | `24f7fb5` | **REPRODUCED** | +| 42 | "free when unused: 0.36s vs 0.37s baseline **across 267 indirections**" | `0105-emitted-seam-shape-and-counts.out` | `24f7fb5` | **DIVERGED** — at the landing commit the emission carries **263** `el_seam_run` lines / **262** actual indirections, not 267. The 267 figure is carried forward unchanged from `35b07ba`, before the strip removed four functions. (The timing half is covered by rows 4 and 10.) | +| 43 | "dlsym was the cost, not the table scan; resolve-once recovered **3.5x**" | `0296-…-seam-cost-timing-06a.out` | `24f7fb5` | **DIVERGED** — the qualitative half reproduces (row 15); the 3.5× does not (observed 1.429×) | +| 44 | "refusal works, composition works, unlinked targets are skipped not fatal" | `0229-integration-seam_binding-06e.out` | `24f7fb5` | **REPRODUCED** — the three corresponding harness assertions pass | +| 45 | "injects_at_exit and wraps_body do NOT collapse … The wrapper is structural" | `0326-strip-table-verification-28d19da.out` | `24f7fb5` | **REPRODUCED** | +| 46 | "prohibits_outside cannot move at all — a #error has no runtime" | `0348-residual-kind-references-28d19da.out` | `24f7fb5` | **REPRODUCED** — `prohibits_outside` still emits `#error` at codegen.el:3371 | +| 47 | "Controls: 99/99 native compiler tests, plus tests/integration/seam_binding.sh (6/6)" | `0050-native-compiler-tests-06e.out`, `0229-integration-seam_binding-06e.out` | `24f7fb5` | **REPRODUCED** — both, exactly | +| 48 | Cross-cycle: cycle 08's doc says "7/7 seam_binding.sh" where this cycle says 6/6 | `0256-seam_binding-assertion-growth.out` | `285166c` | **REPRODUCED as consistent, not contradictory** — `seam_binding.sh` gains a seventh assertion ("an EXIT construct declared after the build replaces the result") at `285166c`, after this cycle ends. See detail D | + +**Counts: 48 assertions — REPRODUCED 36, DIVERGED 9, NOT-REPRODUCIBLE 3, NOT-CAPTURED 0.** + +The nine divergences are rows 4, 13, 14, 16, 20, 24, 25, 42, 43, detailed in +sections A–F below. Two of them (rows 13/14 and 43) are the same two ratios +stated twice, once in the experiment commit and once in the landing commit. + +--- + +## Divergence detail A — P3, "emitting on every fn is measurably slower: FALSE" + +The record's evidence is a single before/after pair, `0.37s -> 0.36s`, reported +to two decimal places on a ~370 ms run. A single pair at that resolution cannot +distinguish a 3 % effect from noise, and the sign it happened to land on +(faster) drove the verdict FALSE. + +Re-measured as an **interleaved paired** benchmark, A,B,A,B,… × 41, so that +clock or thermal drift cannot favour either arm: + +| | A: no seam (`35b07ba^`, self-hosted) | B: 266 indirections (`35b07ba`, self-hosted) | +|---|---|---| +| min | 0.0572 s | 0.0597 s | +| median | 0.0595 s | 0.0618 s | +| mean | 0.0597 s | 0.0618 s | +| sd | 0.0019 s | 0.0011 s | + +- **B/A = 1.0391× by median, 1.0362× by mean, 1.0451× by min.** The record's + pair implies 0.36/0.37 = 0.9730×. +- Paired difference B−A: **median +2.27 ms, mean +2.16 ms, sd 1.61 ms**. +- **B was slower in 38 of 41 paired runs.** + +Both arms are self-hosted to fixpoint, both `-O2 -rdynamic`, both compile +`elc-cli.el` with stdout to `/dev/null`. The only source difference between the +two compilers is this commit's 4-line codegen addition and 75-line runtime +addition. The first run of this benchmark (`0297`) used a B binary that also +linked the counting-target object file; `0298` repeats it with a clean B binary +built from gen2 plus the runtime alone, and gets the same answer (+3.9 %, +38/41), so the extra object file was not the cause. + +**The record's practical conclusion survives; its literal verdict does not.** +266 unused indirections cost about 4 % of a compile — small enough that +"free unused" is a fair engineering summary, but it is a real, consistently +signed, measurable cost. The prediction "emitting on every fn is measurably +slower" was marked FALSE on evidence that could not support the call. + +## Divergence detail B — the 6.6× and 3.5× ratios + +Four variants, min of 9 runs each, same workload (`elc elc-cli.el > /dev/null`): + +| | observed | record | +|---|---|---| +| A baseline, no seam | 0.055 s | 0.37 s | +| B seamed, 0 bindings | 0.058 s | 0.36 s | +| C seamed, 2 bindings, resolve-once | 0.112 s | 0.69 s | +| D seamed, 2 bindings, dlsym per call | 0.160 s | 2.45 s | +| E seamed, 2 bindings, **silent** target | 0.076 s | (not measured) | + +| ratio | observed | record | +|---|---|---| +| D/A dlsym-per-call vs baseline | **2.909×** | 6.6× | +| D/C recovered by resolve-once | **1.429×** | 3.5× | +| C/A resolve-once vs baseline | **2.036×** | 1.865× (0.69/0.37) | + +The record specifies neither the workload, nor which two functions were bound, +nor the target's body, nor the hardware. Two of those were chosen here and are +stated in "Reconstructed inputs" below; the choice of *which* two functions +dominates the result entirely, since the ratio scales with the number of +crossings. The two bound here are the two hottest **as measured** (`0276`), not +guessed: `tok_kind` (310 018 crossings) and `is_ws_code` (211 579), 521 597 +total. + +The direction is right in every case and the mechanism is right (detail C). +The magnitudes are not reproducible from what the record states, and they are +reported here without any adjustment toward the claimed figures. + +One further caveat on D: **the `dlsym`-per-call variant reconstructs a state +that was never committed.** The code at `35b07ba` already caches +(`resolve_tried`), so the 2.45 s measurement must have been taken on a working +tree that no commit preserves. D was produced by turning +`if (!_el_seam[i].resolve_tried)` into `if (1)` in a *scratchpad copy* of +`el_runtime.c`; no worktree was modified. + +## Divergence detail C — "the residual is audit_entry's own printf, not seam overhead" + +This is the one claim in the cost table that is a causal attribution rather +than a number, and it is the one worth separating. Variant E repeats variant C +with a **silent** target, which the record never measured: + +- C − A = 57 ms — the whole residual over baseline +- C − E = **36 ms** — attributable to the target's `printf` (63 % of the residual) +- E − A = **21 ms** — attributable to seam dispatch itself (37 % of the residual), + ≈ 40 ns per crossing over 521 597 crossings + +So the printf is the *larger* share, and the record is right that it is the +thing to look at. But it is not the whole thing: a third of the residual is the +seam's own dispatch, and the record's "not seam overhead" overstates it. + +## Divergence detail D — "exit injection is runtime-bindable" + +At `886626a` the record states that **three** of the five compile-time kinds +are runtime-bindable: entry injection, exit injection, and refusal. + +Entry injection and refusal are. **Exit injection is not, at any commit in this +cycle.** + +- The runtime's table parser accepts `entry|exit` and defines `EL_PHASE_EXIT 1` + (`el_runtime.c:17097`, `:17119`), so an exit binding *loads* without error. +- But codegen emits exactly **one** `el_seam_run` call, at every one of the five + commits, and its phase argument is a literal `0`. Emitted C at `24f7fb5` + contains **263** phase-0 calls and **0** phase-1 calls (`0299`). +- Empirically (`0324`, `0325`): binding `work doubler exit double_result` on an + already-built binary produces no output from the target and leaves the result + at 7, at both `886626a` and `24f7fb5`. The identical binding in the `entry` + phase fires normally. + +An exit binding is therefore accepted and silently never fires — a worse +failure mode than rejection. + +The record corrects itself three commits later without acknowledging the +earlier claim: `28d19da` lists `injects_at_exit` as **STRUCTURAL**, and +`24f7fb5` says plainly "injects_at_exit and wraps_body do NOT collapse". The +seventh `seam_binding.sh` assertion — "an EXIT construct declared after the +build replaces the result" — first appears at `285166c`, whose subject is +"EXPERIMENT: emit the wrapper unconditionally, **so exit binds at runtime too**", +i.e. after this cycle, as new work. That also resolves the 6/6-vs-7/7 question: +cycle 06's 6/6 and cycle 08's 7/7 are both correct for their commits. + +## Divergence detail E — the codegen.el line counts, off by one at both ends + +| | record | observed (`wc -l`, and `grep -c ""`) | +|---|---|---| +| `28d19da^` = `886626a` | 5157 | **5156** | +| `28d19da` | 5096 | **5095** | +| difference | 61 | **61** | +| over the 4661 baseline | +435 | **+434** | + +Both files end with a trailing newline (`0128` includes the `od -c` check), so +`wc -l` is exact and `grep -c ""` agrees with it. The error is systematic and +in the same direction at both ends — the signature of a count read off an +editor that shows a phantom final line, i.e. N+1 for a newline-terminated file. + +The *delta* is unaffected, which is why the load-bearing claim of the commit — +"61 lines of compiler replaced by one refusable indirection" — reproduces +exactly, and why the conclusion (the prediction was FALSE; codegen did not drop +below 4661) is untouched. + +Worth noting against this: the "**491 lines**" figure in the landing commit is +computed from the *true* `wc -l` values (4661 → 5152 = 491, exact). So the +record's own line counts are not produced by one consistent method. + +## Divergence detail F — the "267 seam sites", and what it counts + +The record's 267 reproduces on the nose: `grep -c el_seam_run` over the +self-hosted gen2 emission at `35b07ba` returns exactly **267**, at both gen2 and +gen3. + +One of those 267 lines is not an indirection. It is codegen's own emitter line, +which appears in the compiler's emitted C as a string literal: + +``` +8180: emit_line(el_str_concat(el_str_concat(EL_STR(" el_seam_run(EL_STR("), c_str_lit(fn_name)), EL_STR("), 0, 0);"))); +``` + +The count of actual emitted indirections is therefore **266**, over **266 +distinct function names**, one apiece — which is the cleaner statement of the +mechanism ("one unconditional indirection per fn") and is confirmed +independently in `0363`: gen2 contains 532 `el_val_t` declaration lines, exactly +266 prototypes and 266 definitions over 266 distinct names, and the set of +declared functions minus the set of seamed functions is **empty**. This is +recorded as a precision note, not as an error: 267 is the +number the obvious command prints, and the off-by-one is the compiler counting +itself. + +The figure does **not** survive the strip. After `28d19da` removes four +functions, the same grep returns **263** (262 real indirections) at `28d19da`, +`8bbb750` and `24f7fb5` — whose gen2 emissions are byte-identical to each other +(sha256 `7b9b6e0306ff…`). The landing commit's restatement "across 267 +indirections" is a stale carry-forward (row 42). + +--- + +## The eight failing tests at `28d19da`, named + +The record says "8 tests fail, and they are exactly the 8 controls for +compile-time entry injection and guards. No unrelated breakage." The run +(`0048`, exit code **8**; detail in `0051`) reports +`104 tests, 96 passed, 8 failed, 253 assertions`: + +| # | Test | Failing assertion | Kind | +|---|---|---|---| +| 1 | `decorator-manager-beat-carries-construct` | "@manager injects the beat" | entry injection | +| 2 | `decorator-accessor-beat-carries-construct` | "@accessor injects the beat" | entry injection | +| 3 | `declared-construct-injects-without-compiler-knowledge` | "a program-declared construct injects" | entry injection | +| 4 | `builtin-constructs-still-inject` | "seeded manager still injects" | entry injection | +| 5 | `declared-guard-emits-refusable-check` | "the guard is called at entry" | guard | +| 6 | `declared-guards-stack-in-order` | "first guard runs" | guard | +| 7 | `guard-precedes-injection` | "the guard is emitted before the beat" | guard + entry injection | +| 8 | `constructs-compose-guard-entry-exit` | "guard before entry injection" | guard + entry injection | + +Exactly eight, four entry-injection and four guard, nothing else. The claim is +reproduced without qualification. `8bbb750` then deletes these eight by name +(`0239`) and adds three — `seam-replaces-inlined-entry-injection`, +`seam-entry-is-refusable`, `seam-is-emitted-for-undecorated-fns` — giving +104 − 8 + 3 = 99. + +## Test and seam-site totals across the cycle + +| commit | native tests | seam lines in gen2 | real indirections | codegen.el | fixpoint | +|---|---|---|---|---|---| +| `1b324a0` (parent) | 102 declared | 0 | 0 | 5152 | — | +| `35b07ba` | 102 / 102 pass | 267 | 266 | 5156 | gen2==gen3 | +| `886626a` | 104 / 104 pass | 267 | 266 | 5156 | gen2==gen3 | +| `28d19da` | 104, **96 pass / 8 fail** | 263 | 262 | 5095 | gen2==gen3 | +| `8bbb750` | 99 / 99 pass | 263 | 262 | 5095 | gen2==gen3 | +| `24f7fb5` | 99 / 99 pass | 263 | 262 | 5095 | gen2==gen3 | + +## Reconstructed inputs + +Three inputs used below did not exist in the tree at the commit measured. Each +is an **input**, not evidence; the evidence is the captured output of running +it at the pinned commit. + +1. **`/tmp/seamrun`** (`0272`). The record's DEMONSTRATED transcript names a + probe binary that was never committed. It was rebuilt from the record's own + text — an El program with `fn work() -> Int { return 7 }` and no construct + anywhere, plus a linked-but-unreferenced C target named `audit_entry` + printing `AUDIT: applied by `. The structure is copied from + `tests/integration/seam_binding.sh`, which the same author committed three + commits later (`8bbb750`) as the permanent form of this same hand check; the + only substitutions are the record's own target name and message. Captured + output matches the transcript line for line. +2. **`seam_binding.sh` applied retroactively** (`0273`, `0274`, `0275`). The + harness from `8bbb750` was run, unmodified, against the compilers built at + `35b07ba`, `886626a` and `28d19da`, where it does not yet exist. This is what + establishes that refusal fails at `35b07ba` and succeeds from `886626a` on. + Artifacts are named `RETROFIT-` to mark that the harness postdates the commit. +3. **The timing rig** (`0276`, `0296`, `0297`, `0298`) — see detail B. The + `dlsym`-per-call arm uses a scratchpad copy of `el_runtime.c` with the + resolve-once cache disabled. No worktree was modified at any point; all five + worktrees are `clean` on every artifact in `MANIFEST.tsv`. + +The two hottest functions used for the 2-binding measurements were determined +**by measurement, not by guess** (`0276`): the seam itself was used as an +instrument, binding all 266 seamed functions in two batches to a counting +target that dumps at exit. Top of the distribution compiling `elc-cli.el`: +`tok_kind` 310 018, `is_ws_code` 211 579, `is_digit_code` 208 435, +`is_alpha_code` 204 417, `is_alnum_or_underscore_code` 152 568; 1 692 602 +crossings over 124 functions actually reached. + +## Measurement defects in this re-run, recorded rather than removed + +1. **`0114-codegen-linecount-history.out` is defective and retained.** Its + `while read -r h &1)" +-- +64:check "a construct declared AFTER the build applies" \ +65- "SEEN work/audited +-- +69:check "a construct declared after the build can REFUSE" \ +70- "42" "$(cd "$WORK" && EL_CONSTRUCTS=refuse.txt ./prog 2>&1)" +-- +73:check "an unlinked target is skipped, not fatal" \ +74- "7" "$(cd "$WORK" && EL_CONSTRUCTS=ghost.txt ./prog 2>&1)" +-- +77:check "a binding for a different fn does not fire" \ +78- "7" "$(cd "$WORK" && EL_CONSTRUCTS=other.txt ./prog 2>&1)" +-- +81:check "two constructs compose on one crossing" \ +82- "SEEN work/a +-- +92:check "an EXIT construct declared after the build replaces the result" \ +93- "14" "$(cd "$WORK" && EL_CONSTRUCTS=exit.txt ./prog 2>&1)" + +== 5d. is the appended 'thrice' target ever compiled? (targets.c is cc'd BEFORE the append) == +29:cat > "$WORK/targets.c" <<'EOF' +57:cc $CFLAGS -o "$WORK/prog" "$WORK/prog.c" "$WORK/targets.c" $SRCS $LDFLAGS 2>/dev/null \ +66:7" "$(cd "$WORK" && EL_CONSTRUCTS=observe.txt ./prog 2>&1)" +70: "42" "$(cd "$WORK" && EL_CONSTRUCTS=refuse.txt ./prog 2>&1)" +74: "7" "$(cd "$WORK" && EL_CONSTRUCTS=ghost.txt ./prog 2>&1)" +78: "7" "$(cd "$WORK" && EL_CONSTRUCTS=other.txt ./prog 2>&1)" +84:7" "$(cd "$WORK" && EL_CONSTRUCTS=two.txt ./prog 2>&1)" +86:cat >> "$WORK/targets.c" <<'TGT' +93: "14" "$(cd "$WORK" && EL_CONSTRUCTS=exit.txt ./prog 2>&1)" + +== 5e. does any binding file in the harness use phase 'wrap'? == + NONE — no 'wrap' phase binding is ever written by the harness + +== 6. treewide: any file at bc2f26d or c04d68f that binds phase 'wrap'? == + none in .sh/.txt diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.prov new file mode 100644 index 0000000..1baaa0d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:40:29Z +exit 0 +ms 425 +sha256_out f705426787699a1e41a5a1611c76a99045f9f3fa72be0382ecde18ff2d054c05 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.cmd b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.cmd new file mode 100644 index 0000000..078f36f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.cmd @@ -0,0 +1 @@ +bash -c SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /tmp/elc07b --test tests/native/test_compiler.el > /tmp/t07b.c && cc $CF -o /tmp/t07bx /tmp/t07b.c $SRCS $LF && /tmp/t07bx | tail -5 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.err b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.out b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.out new file mode 100644 index 0000000..783aa30 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.out @@ -0,0 +1,5 @@ +ok early-returns-route-through-the-exit-seam (0.094ms) +ok every-fn-gets-a-closure (0.123ms) +ok zero-param-fn-emits-valid-c (0.088ms) + +100 tests, 100 passed, 0 failed, 241 assertions in 5.926ms diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.prov new file mode 100644 index 0000000..cad8d43 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:40:45Z +exit 0 +ms 4144 +sha256_out 1476cd0ce8382365e86d5cda728a86cafb1f3156e6bb0d7ea3a9babddc091c28 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.cmd b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.cmd new file mode 100644 index 0000000..1fc3a59 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.cmd @@ -0,0 +1 @@ +bash tests/integration/seam_binding.sh /tmp/elc07b /tmp/rerun-v1-07/lang diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.err b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.out b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.out new file mode 100644 index 0000000..f72835b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.out @@ -0,0 +1,9 @@ + ok unbound program is unaffected + ok a construct declared AFTER the build applies + ok a construct declared after the build can REFUSE + ok an unlinked target is skipped, not fatal + ok a binding for a different fn does not fire + ok two constructs compose on one crossing + ok an EXIT construct declared after the build replaces the result + + 7 assertions, 7 passed, 0 failed diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.prov new file mode 100644 index 0000000..45251c4 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:40:48Z +exit 0 +ms 3433 +sha256_out 03d3e2e45ceb69b512d12b292f32e5cf7d36d10925fc8abb8f5273e83e8b6287 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.cmd b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.cmd new file mode 100644 index 0000000..7827892 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.cmd @@ -0,0 +1 @@ +bash /tmp/parent07.sh diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.err b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.out b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.out new file mode 100644 index 0000000..484ecc3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.out @@ -0,0 +1,19 @@ +== verify the extracted tree really is bc2f26d^ == + git blob bc2f26d^:lang/el-compiler/src/codegen.el f6bc48623aca4e6fd7f88639f7cb25a75bd3027f15aee5b5d5047dfcd2bb663a + /tmp/el07parent/lang/el-compiler/src/codegen.el f6bc48623aca4e6fd7f88639f7cb25a75bd3027f15aee5b5d5047dfcd2bb663a + MATCH + test_compiler.el blob 1e6cd04b7d0bb4c90d27d6a2f08c6bfdf78c3e1c1b12f73887c3b2fd60dc0384 + test_compiler.el file 1e6cd04b7d0bb4c90d27d6a2f08c6bfdf78c3e1c1b12f73887c3b2fd60dc0384 + MATCH + +== native compiler tests at bc2f26d^ (built gen2, same procedure as the commit) == +ok exit-crossing-goes-through-the-seam (0.065ms) +ok early-returns-route-through-the-exit-seam (0.097ms) + +99 tests, 99 passed, 0 failed, 239 assertions in 5.827ms + +== integration seam_binding.sh at bc2f26d^ == + ok two constructs compose on one crossing + ok an EXIT construct declared after the build replaces the result + + 7 assertions, 6 passed, 0 failed diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.prov new file mode 100644 index 0000000..a980016 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:41:20Z +exit 0 +ms 7762 +sha256_out 61212505c09813a15042520d6a8a7dc6d24d3a6d0f31de4a6ab627f9a53a5d0e +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.cmd b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.cmd new file mode 100644 index 0000000..1776a56 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.cmd @@ -0,0 +1 @@ +git diff bc2f26d^ bc2f26d -- lang/el-compiler/src/codegen.el diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.err b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.out b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.out new file mode 100644 index 0000000..0c8d82e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.out @@ -0,0 +1,173 @@ +diff --git a/lang/el-compiler/src/codegen.el b/lang/el-compiler/src/codegen.el +index bd90b266..eaaa4def 100644 +--- a/lang/el-compiler/src/codegen.el ++++ b/lang/el-compiler/src/codegen.el +@@ -3215,44 +3215,15 @@ fn cg_entry_seam(stmt: Map, fn_name: String) -> Void { + // cg_exit_target / cg_exit_construct — the first construct on this fn that + // injects at exit, or "" if none. + +-fn cg_wrap_target(stmt: Map) -> String { +- let wdl = stmt["decorators"] +- let n_wdl: Int = native_list_len(wdl) +- let wi = 0 +- let found: String = "" +- while wi < n_wdl { +- if str_eq(found, "") { +- let wd = native_list_get(wdl, wi) +- let wdn: String = wd["name"] +- let wt: String = decorator_wrap(wdn) +- if !str_eq(wt, "") { let found = wt } +- } +- let wi = wi + 1 +- } +- found +-} + +-fn cg_wrap_construct(stmt: Map) -> String { +- let wdl = stmt["decorators"] +- let n_wdl: Int = native_list_len(wdl) +- let wi = 0 +- let found: String = "" +- while wi < n_wdl { +- if str_eq(found, "") { +- let wd = native_list_get(wdl, wi) +- let wdn: String = wd["name"] +- let wt: String = decorator_wrap(wdn) +- if !str_eq(wt, "") { let found = wdn } +- } +- let wi = wi + 1 +- } +- found +-} + + // params_to_env_fields / params_to_env_init / params_to_env_args — the captured + // environment. This IS the closure: a struct of captured values, a function + // pointer that takes it, and the pair handed to the wrap target. + fn params_to_env_fields(params: [Any]) -> String { ++ // A zero-param fn would emit `struct __env_f { };` -- an empty struct is a ++ // GNU extension, not C99, and an empty initialiser is C23. ++ if native_list_len(params) == 0 { return " char __e0;" } + let out: String = "" + let n: Int = native_list_len(params) + let i = 0 +@@ -3266,6 +3237,7 @@ fn params_to_env_fields(params: [Any]) -> String { + } + + fn params_to_env_init(params: [Any]) -> String { ++ if native_list_len(params) == 0 { return "0" } + let out: String = "" + let n: Int = native_list_len(params) + let i = 0 +@@ -3296,19 +3268,6 @@ fn params_to_env_args(params: [Any]) -> String { + + // params_to_call_args — "a, b, c" from the param list, for the wrapper's call + // into the body helper. +-fn params_to_call_args(params: [Any]) -> String { +- let out: String = "" +- let n: Int = native_list_len(params) +- let i = 0 +- while i < n { +- let p = native_list_get(params, i) +- let pn: String = p["name"] +- if i > 0 { let out = out + ", " } +- let out = out + pn +- let i = i + 1 +- } +- out +-} + + fn cg_fn(stmt: Map) -> Void { + let fn_name: String = stmt["name"] +@@ -3358,11 +3317,7 @@ fn cg_fn(stmt: Map) -> Void { + // silently miss every early return — which is precisely the class of + // failure this seam exists to remove. Fns with no exit construct emit + // exactly as before, byte for byte. +- let wrap_target: String = cg_wrap_target(stmt) +- let wrap_construct: String = cg_wrap_construct(stmt) +- let has_wrap: Bool = !str_eq(wrap_target, "") +- let has_exit: Bool = true +- if has_exit { ++ if true { + emit_line("static el_val_t __el_body_" + fn_name + "(" + params_c + ") {") + } else { + emit_line("el_val_t " + fn_name + "(" + params_c + ") {") +@@ -3393,27 +3348,21 @@ fn cg_fn(stmt: Map) -> Void { + // The wrapper: guards, entry injection, the body call, then the exit + // injection, which receives the result so it can observe what the fn + // actually returned. +- if has_wrap { +- // Codegen defines the wrap calling convention, so codegen declares it. +- // El has ONE type -- el_val_t = int64_t -- so El's own `extern fn` cannot +- // describe a callable, and asking it to produces an int/pointer +- // mismatch. The convention is not El-expressible; it is emitted. +- emit_line("extern el_val_t " + wrap_target + "(el_val_t, el_val_t, el_val_t(*)(void*), void*);") ++ if true { ++ // EVERY fn gets an env struct and a thunk. Codegen cannot know which fns ++ // a wrap construct will be bound to after the binary exists, and the ++ // wrapper unconditionally calls through el_seam_wrap. + emit_line("struct __env_" + fn_name + " { " + params_to_env_fields(params) + " };") + emit_line("static el_val_t __thunk_" + fn_name + "(void* __v) {") + emit_line(" struct __env_" + fn_name + "* __e = (struct __env_" + fn_name + "*)__v; (void)__e;") + emit_line(" return __el_body_" + fn_name + "(" + params_to_env_args(params) + ");") + emit_line("}") + } +- if has_exit { ++ if true { + emit_line("el_val_t " + fn_name + "(" + params_c + ") {") + cg_entry_seam(stmt, fn_name) +- if has_wrap { +- emit_line(" struct __env_" + fn_name + " __env = { " + params_to_env_init(params) + " };") +- emit_line(" el_val_t __r = " + wrap_target + "(EL_STR(" + c_str_lit(fn_name) + "), EL_STR(" + c_str_lit(wrap_construct) + "), __thunk_" + fn_name + ", &__env);") +- } else { +- emit_line(" el_val_t __r = __el_body_" + fn_name + "(" + params_to_call_args(params) + ");") +- } ++ emit_line(" struct __env_" + fn_name + " __env = { " + params_to_env_init(params) + " };") ++ emit_line(" el_val_t __r = el_seam_wrap(EL_STR(" + c_str_lit(fn_name) + "), __thunk_" + fn_name + ", &__env);") + emit_line(" __r = el_seam_run(EL_STR(" + c_str_lit(fn_name) + "), 1, __r);") + emit_line(" return __r;") + emit_line("}") +@@ -4291,13 +4240,7 @@ fn program_has_routes(recs: [Map]) -> Bool { + // only decide whether to repeat — no timeout, no rollback-and-retry, no + // parallel, no memoize-on-arguments. It would also have crippled the JS backend, + // which has closures natively, for a limit in the C one. +-fn declare_wrap(name: String, wraps: String) -> Void { +- state_set("__dec_wrap_" + name, wraps) +-} + +-fn decorator_wrap(name: String) -> String { +- state_get("__dec_wrap_" + name) +-} + + // A PROHIBITION is the other half of a boundary: not what runs when something + // crosses, but what may not cross at all. +@@ -4340,8 +4283,6 @@ fn prohibiting_constructs() -> String { + fn scan_declared_decorators(tokens: [Any]) -> Void { + declare_prohibition("manager", "dharma_emit,dharma_field") + let total: Int = native_list_len(tokens) / 2 +- let has_pending_w: Bool = false +- let pending_wrap: String = "" + let has_pending_p: Bool = false + let pending_prohibit: String = "" + let pos: Int = 0 +@@ -4382,10 +4323,6 @@ fn scan_declared_decorators(tokens: [Any]) -> Void { + if str_eq(dname, "decorator") { + if native_list_len(args) >= 2 { + let dkind: String = native_list_get(args, 0) +- if str_eq(dkind, "wraps_body") { +- let has_pending_w = true +- let pending_wrap = native_list_get(args, 1) +- } + if str_eq(dkind, "prohibits_outside") { + let has_pending_p = true + let pending_prohibit = native_list_get(args, 1) +@@ -4396,10 +4333,6 @@ fn scan_declared_decorators(tokens: [Any]) -> Void { + } else { + if str_eq(k, "Fn") { + let fname: String = tok_value(tokens, pos + 1) +- if has_pending_w { +- declare_wrap(fname, pending_wrap) +- let has_pending_w = false +- } + if has_pending_p { + declare_prohibition(fname, pending_prohibit) + let has_pending_p = false diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.prov new file mode 100644 index 0000000..f97100e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:41:33Z +exit 0 +ms 12 +sha256_out 6fcd4b37cf2bb12288bbd7734ae8cdd8f67ef47107ea59ac5786e8c6e06bc4f1 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.cmd b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.cmd new file mode 100644 index 0000000..82ed9c4 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.cmd @@ -0,0 +1 @@ +bash -c echo "== the single wraps_body occurrence in codegen.el at bc2f26d^ =="; git grep -n -- "wraps_body" "bc2f26d^" -- lang/el-compiler/src/codegen.el; echo; echo "== surrounding branch, bc2f26d^ codegen.el lines 4380-4410 =="; git show "bc2f26d^:lang/el-compiler/src/codegen.el" | sed -n "4380,4412p" | cat -n; echo; echo "== treewide wraps_body at bc2f26d^ =="; git grep -n -- "wraps_body" "bc2f26d^" diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.err b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.out b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.out new file mode 100644 index 0000000..0cf0444 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.out @@ -0,0 +1,41 @@ +== the single wraps_body occurrence in codegen.el at bc2f26d^ == +bc2f26d^:lang/el-compiler/src/codegen.el:4385: if str_eq(dkind, "wraps_body") { + +== surrounding branch, bc2f26d^ codegen.el lines 4380-4410 == + 1 if str_eq(tok_kind(tokens, p), "RParen") { let p = p + 1 } + 2 } + 3 if str_eq(dname, "decorator") { + 4 if native_list_len(args) >= 2 { + 5 let dkind: String = native_list_get(args, 0) + 6 if str_eq(dkind, "wraps_body") { + 7 let has_pending_w = true + 8 let pending_wrap = native_list_get(args, 1) + 9 } + 10 if str_eq(dkind, "prohibits_outside") { + 11 let has_pending_p = true + 12 let pending_prohibit = native_list_get(args, 1) + 13 } + 14 } + 15 } + 16 let pos = p + 17 } else { + 18 if str_eq(k, "Fn") { + 19 let fname: String = tok_value(tokens, pos + 1) + 20 if has_pending_w { + 21 declare_wrap(fname, pending_wrap) + 22 let has_pending_w = false + 23 } + 24 if has_pending_p { + 25 declare_prohibition(fname, pending_prohibit) + 26 let has_pending_p = false + 27 } + 28 let pos = pos + 2 + 29 } else { + 30 let pos = pos + 1 + 31 } + 32 } + 33 } + +== treewide wraps_body at bc2f26d^ == +bc2f26d^:lang/el-compiler/src/codegen.el:4385: if str_eq(dkind, "wraps_body") { +bc2f26d^:lang/tests/native/test_compiler.el:809: let src: String = "@decorator(\"wraps_body\", \"with_timeout\")\nfn timed() {}\n@timed\nfn slow(k: Int) -> Int { return 9 }" diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.prov new file mode 100644 index 0000000..7ec838d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:41:33Z +exit 0 +ms 78 +sha256_out 02cc6917d77969bd62aea53c0732e255f75b8d9076ea795a74659573aa105363 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.cmd b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.cmd new file mode 100644 index 0000000..f92dcfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.cmd @@ -0,0 +1 @@ +bash -c echo "== diff of the harness, bc2f26d^ -> bc2f26d =="; git diff bc2f26d^ bc2f26d -- lang/tests/integration/seam_binding.sh; echo; echo "== the summary line at every commit where the harness exists =="; for c in $(git rev-list --reverse 5718943^..c04d68f); do f=$(git show ${c}:lang/tests/integration/seam_binding.sh 2>/dev/null | grep -n "assertions, " | tr -d "\n"); n=$(git show ${c}:lang/tests/integration/seam_binding.sh 2>/dev/null | grep -c "^check \|^check\"" ); if [ -n "$f" ]; then printf " %s check-calls=%s %s\n" "$(git rev-parse --short=9 $c)" "$n" "$f"; fi; done diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.err b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.out b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.out new file mode 100644 index 0000000..6287fdd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.out @@ -0,0 +1,30 @@ +== diff of the harness, bc2f26d^ -> bc2f26d == +diff --git a/lang/tests/integration/seam_binding.sh b/lang/tests/integration/seam_binding.sh +index 20e85046..58e28c61 100755 +--- a/lang/tests/integration/seam_binding.sh ++++ b/lang/tests/integration/seam_binding.sh +@@ -83,10 +83,15 @@ check "two constructs compose on one crossing" \ + SEEN work/b + 7" "$(cd "$WORK" && EL_CONSTRUCTS=two.txt ./prog 2>&1)" + ++cat >> "$WORK/targets.c" <<'TGT' ++el_val_t thrice(el_val_t fn, el_val_t con, el_val_t (*b)(void*), void* e){ ++ (void)fn; (void)con; return b(e) + b(e) + b(e); /* wrap: invoke N times */ ++} ++TGT + printf 'work doubler exit double_result\n' > "$WORK/exit.txt" + check "an EXIT construct declared after the build replaces the result" \ + "14" "$(cd "$WORK" && EL_CONSTRUCTS=exit.txt ./prog 2>&1)" + + echo +-echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" ++echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" + exit $FAILS + +== the summary line at every commit where the harness exists == + 8bbb750c2 check-calls=6 84:echo " 6 assertions, $((6-FAILS)) passed, $FAILS failed" + 24f7fb514 check-calls=6 84:echo " 6 assertions, $((6-FAILS)) passed, $FAILS failed" + 285166c25 check-calls=7 91:echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" + b40754f07 check-calls=7 91:echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" + bc2f26ddf check-calls=7 96:echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" + c04d68f9c check-calls=7 96:echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.prov b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.prov new file mode 100644 index 0000000..f5e8139 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.prov @@ -0,0 +1,7 @@ +commit bc2f26ddfc35119e242c0a38d09e2b0023136462 +tree clean +captured_utc 2026-08-17T17:43:46Z +exit 0 +ms 264 +sha256_out 23c299268a3bc1441fb485f5756072fb386394c72756698c8ea9e315fbc08ed1 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.rc b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/CLAIMS.md b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/CLAIMS.md new file mode 100644 index 0000000..fdad802 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/CLAIMS.md @@ -0,0 +1,257 @@ +# CLAIMS — cycle 07, invocation is not composable + +Source doc: `docs/v1/experiments/cycles/07-invocation-is-not-composable.md` + +## Pinned commits + +| | | +|---|---| +| Cycle commit (the EXPERIMENT) | `bc2f26ddfc35119e242c0a38d09e2b0023136462` | +| Committed | 2026-08-17 09:06:05 -0500 | +| Subject | EXPERIMENT: invocation control resolves at runtime | +| Parent (the "before" state the record describes) | `b40754f07b5eff3700a69681397e46949a5c4f41` — "land unconditional wrapper: exit crossings resolve at runtime", 2026-08-17 09:01:55 -0500 | +| Land commit (second record block, no numeric claims) | `c04d68f9c…` — "land runtime invocation control: only prohibition remains compiled", 2026-08-17 09:06:16 -0500 | +| Re-run method | detached worktree `/tmp/rerun-v1-07` at `bc2f26d`, tree clean | +| Artifact provenance | every artifact pinned to `bc2f26ddfc35`, tree `clean` (see `MANIFEST.tsv`) | +| Machine | Apple M4 Pro, Darwin 25.5.0 arm64, Apple clang 21.0.0, load avg ≈5–6 during timing | + +**`c04d68f` is tree-identical to `bc2f26d`.** `git diff --stat bc2f26d c04d68f` is empty and +`codegen.el` hashes identically at both (`0015`). The land commit changes no file; it only +re-records the experiment as landed. Every measurement below therefore applies to both. + +## Verdicts + +| # | Claim (verbatim from the record) | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 1 | "P1 wrap becomes runtime-bindable **TRUE** body x3 -> 21, never invoked -> 111" | `0016-P1-wrap-probe-reconstructed.out` (reconstructed probe), `0040-REDO-seam-caller-and-wrap-assertion-search.out` | `bc2f26d` | **REPRODUCED (behaviour) / DIVERGED (evidence)** — a reconstructed probe does observe `21` and `111`. But **no test or harness in the tree at `bc2f26d` asserts either number, and none ever exercises the wrap seam at all.** See divergence detail A. | +| 2 | "P2 codegen shrinks **TRUE** 5042 -> 4977" | `0009-codegen-linecount-parent-and-commit.out`, `0011-codegen-linecount-every-commit-in-range.out` | `bc2f26d^`, `bc2f26d` | **DIVERGED** — observed `5043 -> 4976` (−67). Claimed `5042 -> 4977` (−65). Neither endpoint matches; no commit in `5718943^..c04d68f` has codegen.el at 5042 or 4977 lines. Direction of the claim (it shrinks) holds. See detail B. | +| 3 | "P3 cost 5-10% from an indirect call on every fn **TRUE** 0.36s -> 0.39s, ~8%" | `0036-P3-timing-parent-vs-commit-gen3.out`, `0037-P3-timing-two-workloads-n21.out` | `bc2f26d^` vs `bc2f26d` | **DIVERGED** on the ratio; **NOT-REPRODUCIBLE** on the absolutes. Re-measured overhead is **+0.6 % to +2.3 %**, not ~8 %. No workload in the tree runs anywhere near 0.36 s. See detail C. | +| 4 | "P4 zero-param fns break on the empty struct **TRUE** — empty struct is a GNU extension, empty init is C23. Fixed with a char field." | `0017-P4-zero-param-env-struct-emitted-c.out`, `0005/0041-native-compiler-tests*.out` | `bc2f26d` | **REPRODUCED** — emitted C contains `struct __env_noargs { char __e0; };` and `struct __env_noargs __env = { 0 };`; no empty struct, no empty initialiser; the emitted C passes `-std=c11 -pedantic-errors -fsyntax-only`. The `char __e0` return is at `codegen.el:3226` at `bc2f26d` and absent at the parent. Test `zero-param-fn-emits-valid-c` passes. | +| 5 | "P5 fixpoint holds **TRUE**" | `0038-selfhost-fixpoint-gen2-gen3.out` (and `0008-REDO-…`) | `bc2f26d` | **REPRODUCED** — gen2 == gen3, identical sha256 `02c9b3e2…`, 14360 lines each. gen1 (from the committed `dist/platform/elc`) differs, which is expected because this commit changes codegen's output. See measurement defect 1. | +| 6 | "PROCESS FAILURE … The build then failed with 'undeclared identifier __thunk_noargs'" | `0039-thunk-noargs-and-seam-caller-search.out` | range `5718943^..c04d68f` | **NOT-CAPTURED** — the state described was never committed. The literal `__thunk_noargs` appears in no committed file at any commit in the range; it is a name codegen *generates* (`codegen.el:3356`). In the C emitted at `bc2f26d` the thunk is declared at line 12 and used at line 19, and the file compiles and runs clean. The failure is a real-but-transient working-tree state with no artifact. | +| 7 | "Removed: declare_wrap, decorator_wrap, cg_wrap_target, cg_wrap_construct, params_to_call_args, and the wraps_body scanner branch" | `0012-removed-symbols-parent-vs-commit.out`, `0013-params_to_call_args-orphan-comment.out`, `0045-wraps_body-scanner-branch-at-parent.out` | `bc2f26d^`, `bc2f26d` | **DIVERGED (one of six)** — five of six are gone from the whole tree. `params_to_call_args` loses its definition (parent codegen.el:3299) and its only call site (parent codegen.el:3415), but its **two-line doc comment survives at `bc2f26d` codegen.el:3269**, describing a function that no longer exists. See detail D. | +| 8 | "prohibits_outside is now the ONLY construct kind left at compile time" | `0014-construct-kinds-parent-vs-commit.out` | `bc2f26d` | **REPRODUCED, with a scope note** — `prohibits_outside` is the only kind name with executable dispatch in codegen.el (`str_eq(dkind, "prohibits_outside")` at line 4326). `injects_at_entry`, `guards_at_entry`, `injects_at_exit` each survive at exactly one line, all of them `//` doc comments. `wraps_body` is gone tree-wide. Note the claim was already true of the other three at the **parent** — this commit's contribution is removing `wraps_body` only. | +| 9 | (not stated in the doc) native compiler test result at `bc2f26d` | `0005-native-compiler-tests.out`, `0041-native-compiler-tests-gen2-binary.out` | `bc2f26d` | **REPRODUCED as fact, but the doc records nothing to check it against** — `100 tests, 100 passed, 0 failed, 241 assertions`. Parent: `99 tests, 99 passed, 0 failed, 239 assertions` (`0043`). The doc gives no test count for this commit; its absence is itself a gap, since the commit deletes a test (`declared-wrap-emits-closure-and-convention`) and adds two. | +| 10 | (not stated in the doc) integration harness result at `bc2f26d` | `0007`, `0042`, `0043` | `bc2f26d` | **REPRODUCED as fact** — `seam_binding.sh`: `7 assertions, 7 passed, 0 failed`. At the parent the same harness reports `7 assertions, 6 passed, 0 failed` — an arithmetic bug (`$((6-FAILS))`) that this commit fixes. **The commit adds no assertion**; its only substantive harness change is appending a dead `thrice` target. | +| 11 | "a construct bound after the build decides how and whether to invoke it" (ISHIKAWA) | `0016`, `0007`/`0042` | `bc2f26d` | **REPRODUCED** — via the reconstructed probe for the wrap phase, and directly by the shipped harness for the entry/exit/refuse phases. | +| 12 | (not stated in the doc) `bc2f26d` silently fixes a harness pass-count bug | `0046-seam_binding-tally-history.out` | `bc2f26d` | **OBSERVED BUT UNCLAIMED** — see detail E. | + +**Counts: 6 REPRODUCED · 4 DIVERGED · 1 NOT-CAPTURED · 1 OBSERVED-BUT-UNCLAIMED · (0 pure NOT-REPRODUCIBLE; claim 3 carries a NOT-REPRODUCIBLE component on its absolute figures).** + +--- + +## Divergence detail A — P1's 21 and 111 have no evidence in the tree + +This is the substantive finding for cycle 07. + +The numbers are **behaviourally correct** — I observed `21` and `111`. What is not correct is +the implication that the commit *demonstrated* them. + +What `bc2f26d` actually did to `lang/tests/integration/seam_binding.sh` (the whole diff, from +`git diff bc2f26d^ bc2f26d -- lang/tests/integration/`): + +1. appended a `thrice` wrap target to `$WORK/targets.c`, and +2. changed the summary line from `$((6-FAILS))` to `$((7-FAILS))`. + +Both are inert with respect to P1: + +- **`thrice` is never compiled.** `targets.c` is written at harness line 29 and passed to `cc` + at line 57. The `cat >> "$WORK/targets.c"` that adds `thrice` is at **line 86** — twenty-nine + lines *after* the binary was already linked. Nothing recompiles it (`0040` §5d). +- **No `wrap`-phase binding is ever written.** `el_seam_load` at `bc2f26d` recognises three + phases (`entry`, `exit`, `wrap`); the harness writes `entry` and `exit` binding files only. + `0040` §5e: no `printf '… wrap …'` anywhere in the harness. §6: no `wrap` binding in any + `.sh`/`.txt` in the tree. +- **The strings `21` and `111` do not occur in the harness at all** (`0040` §5b). Its seven + expectations are `7`, `SEEN work/audited\n7`, `42`, `7`, `7`, `SEEN work/a\nSEEN work/b\n7`, + `14` (`0040` §5c). +- The commit's own native test comments say the N-times behaviour "lives in + `tests/integration/seam_binding.sh`" — it does not. +- `tests/integration/seam_caller.sh` **does not exist at any commit in `5718943^..c04d68f`** + (`0040` §4). It first appears at `d9d1571`, a v2-era commit, and is unrelated to this cycle. + (The parent agent's hint to look for it is answered: not here.) + +So the 7→7 pass count reported by the harness at `bc2f26d` is the *same seven assertions* the +parent already ran; the commit fixed the arithmetic that had been under-reporting them as 6. + +**The reconstruction (an INPUT, not evidence).** `evidence/.../probe07.sh`, output captured as +`0016`. It is modelled line-for-line on `seam_binding.sh` at `bc2f26d`: the same `prog.el` +(`fn work() -> Int { return 7 }`), the same `thrice` target *verbatim including its comment*, +the same `EL_CONSTRUCTS` file format, and the phase name `wrap` read from `el_seam_load` in +`el_runtime.c` at `bc2f26d`. The one thing not recoverable from the record is the +"never invoked" target — the record names no symbol — so `never()` (returns 111 without +calling the body) is invented to match the stated semantics. Observed: + +``` +== baseline, no binding (work() returns 7) == 7 +== wrap binding -> thrice (expect 21) == 21 +== wrap binding -> never (expect 111) == 111 +``` + +`7 × 3 = 21` corroborates that the record's "body x3" was measured against this same +`work() -> 7` fixture. `111` is only as faithful as the invented target. + +## Divergence detail B — P2's line counts + +| | claimed | observed (`wc -l`, blob straight out of git) | +|---|---|---| +| parent `bc2f26d^` | 5042 | **5043** | +| commit `bc2f26d` | 4977 | **4976** | +| delta | −65 | **−67** | + +Both blobs end in a newline (`0009` checks the last byte), so `wc -l` is exact; there is no +trailing-newline ambiguity to absorb the difference. `git diff --numstat` for codegen.el is +`12 79` (+12 / −79 = −67), independently confirming the observed delta. + +**No commit in `5718943^..c04d68f` ever has codegen.el at 5042 or 4977 lines** (`0011`, +explicit search: `NONE`). The full sequence over the range is: + +``` +5718943f2 4800 60737b030 4850 4f7568b07 4953 2bed8483f 5084 +7d01608a9 5084 1b324a071 5152 35b07bade 5156 82e998273 5152 +886626a64 5156 28d19da7f 5095 8bbb750c2 5095 24f7fb514 5095 +285166c25 5043 b40754f07 5043 bc2f26ddf 4976 c04d68f9c 4976 +``` + +Cross-checking the parent agent's note: **cycle 03** claims "5094 -> 5044" — observed +`24f7fb5 = 5095` → `285166c = 5043`. **Cycle 06** claims "5157 -> 5096" — observed +`35b07ba = 5156`, `28d19da = 5095`. So every one of these three records is off by one on +every endpoint, but **not in a consistent direction**: cycle 06 is +1 on both ends, while +cycles 03 and 07 are −1 on the parent and +1 on the commit. A single systematic counting +convention (e.g. counting a missing final newline) would produce a uniform offset; this does +not. The line numbers in these records were not produced by a reproducible instrument. + +The qualitative claim — "codegen shrinks" — is unambiguously true, by 67 lines. + +## Divergence detail C — P3's ~8 % cost + +The record's absolute figures (`0.36s -> 0.39s`) are **NOT-REPRODUCIBLE**: the workload is not +named, and nothing in the tree at `bc2f26d` takes anything like 0.36 s on this machine +(`0037`, tail): `elc elc-cli.el` 0.067 s, `elc --test tests/native/test_compiler.el` 0.068 s, +`elc --test tests/native/test_lexer_scaling.el` 0.030 s. The compiled native test binary runs +in 5.9 ms. Whatever was timed, it is not identifiable from the record. + +The **ratio** is the load-bearing part, so I re-measured it. Construction (`time07b.sh`, both +scripts stored beside this file): + +- The cost under test is paid by code **emitted** by the new codegen, so both binaries must be + gen2 — self-emitted by their own commit's compiler. `/tmp/elc07pb` = elc self-emitted at + `bc2f26d^` (wrapper calls the body **directly**; 0 occurrences of `el_seam_wrap` in its C); + `/tmp/elc07b` = elc self-emitted at `bc2f26d` (254 occurrences of `el_seam_wrap`). +- Both are handed the **same** input, in the same CWD (`bc2f26d`'s `lang/`), so the only + difference is the calling convention compiled into the binary. +- Runs are interleaved, warmed, n = 21 per arm, two workloads. + +Observed (`0037`): + +| workload | parent median | commit median | ratio (median) | ratio (min) | ratio (mean) | +|---|---|---|---|---|---| +| `elc elc-cli.el` | 0.06482 s | 0.06576 s | **+1.45 %** | +2.31 % | +1.92 % | +| `elc --test tests/native/test_compiler.el` | 0.06758 s | 0.06821 s | **+0.93 %** | +0.62 % | +1.36 % | + +An earlier, independent n = 11 run (`0036`) on the first workload gave **+0.64 % median / ++0.16 % min**. The overhead is real and positive in every arm of every run, but it sits at +**roughly 1 %, not ~8 %** — outside the predicted 5–10 % band, i.e. the prediction as scored +would be FALSE on this machine, not TRUE. + +Caveats stated plainly, not to rescue the claim: this is an Apple M4 Pro under load avg ≈5–6; +`el_seam_wrap`'s fast path is `if (_el_seam_n == 0) return body(env);` and a wide +out-of-order core hides that better than most; and the workload the record actually used is +unknown, so I cannot rule out that some other program shows 8 %. No number here is rounded +toward the claimed value. + +## Divergence detail D — `params_to_call_args` is not fully removed + +Of the six things the record says were removed, five vanish from the entire tree between +`bc2f26d^` and `bc2f26d`: `declare_wrap`, `decorator_wrap`, `cg_wrap_target`, +`cg_wrap_construct`, and the `wraps_body` scanner branch (`0012`; the branch itself is shown at +`0045`, parent codegen.el:4385, together with the `declare_wrap(fname, pending_wrap)` call it +guarded). + +`params_to_call_args` does not. At the parent it has three occurrences — a doc comment (3297), +the definition (3299), and one call site (3415). At `bc2f26d` the definition and the call site +are gone but the comment remains: + +``` +bc2f26d:lang/el-compiler/src/codegen.el:3269:// params_to_call_args — "a, b, c" from the param list, for the wrapper's call +bc2f26d:lang/el-compiler/src/codegen.el:3270:// into the body helper. +``` + +`git grep "^fn params_to_call_args"` at `bc2f26d` → no definition. It is an orphaned two-line +comment sitting immediately above `fn cg_fn`, documenting a function that no longer exists, and +it survives unchanged into `c04d68f`. Harmless, but the record's "Removed:" list overstates by +one item, and the residue is exactly the kind of thing the commit message's own +"the guard that would have caught it existed and I removed it" paragraph is about. + +## Detail E — an undocumented fix: the harness pass tally + +`bc2f26d` also fixes a bug its own record never mentions. Independently flagged by the cycle 08 +agent and confirmed here (`0046`): + +``` +8bbb750c2 check-calls=6 echo " 6 assertions, $((6-FAILS)) passed, $FAILS failed" +24f7fb514 check-calls=6 echo " 6 assertions, $((6-FAILS)) passed, $FAILS failed" +285166c25 check-calls=7 echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" <- seventh check added, tally not bumped +b40754f07 check-calls=7 echo " 7 assertions, $((6-FAILS)) passed, $FAILS failed" +bc2f26ddf check-calls=7 echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" <- fixed here +c04d68f9c check-calls=7 echo " 7 assertions, $((7-FAILS)) passed, $FAILS failed" +``` + +`285166c` (cycle 03's experiment) added the seventh `check` and updated the header text to +"7 assertions" but left the arithmetic at `$((6-FAILS))`, so a fully green run printed +`7 assertions, 6 passed, 0 failed` — confirmed by running the harness at the parent (`0043`), +which prints exactly that with zero failures. `bc2f26d` changes it to `$((7-FAILS))` and the +run at this commit prints `7 assertions, 7 passed, 0 failed` (`0007`, `0042`). + +Worth recording for two reasons. First, a commit doing something its record does not mention is +a gap in the record regardless of whether the change is a fix. Second, it is the *only* +substantive thing `bc2f26d` does to the harness that has any effect — the `thrice` target it +also adds is dead code (detail A) — which sharpens the point that the record's headline P1 +result was never wired into the test suite. The harness self-report was under-counting a green +run for two cycles before anyone noticed, which is the same class of silent-instrument defect +the commit message's PROCESS FAILURE paragraph is about. + +--- + +## Measurement defects in this re-run, recorded rather than removed + +1. **`0006-selfhost-fixpoint.out` is defective and retained.** It ran the recipe's original + fixpoint command, which compares **gen1 vs gen2** — gen1 being the output of the committed + `dist/platform/elc`, which is stale at this commit and predates the seam entirely (0 + occurrences of `el_seam_wrap`). Since `bc2f26d` changes what codegen emits, gen1 ≠ gen2 is + *expected*, and the artifact's `differ: char 12626, line 259` is not a finding. The correct + check is gen2 == gen3, captured as `0038-selfhost-fixpoint-gen2-gen3.out` (and, under a + confusing name that used 1-based generation numbering, `0008-REDO-selfhost-fixpoint-gen3-gen4.out` + — same two files compared, `/tmp/g07b.c` vs `/tmp/g07c.c`). This was a recipe defect, not a + tree defect; it is left in the manifest because deleting a failed measurement is the failure + mode this record exists to control for. Do not cite `0006`. +2. **`0039-thunk-noargs-and-seam-caller-search.out` sections 4 and 5 are defective and + retained.** The script `cd`'d into `/lang` for section 3 and never returned, so + sections 4 and 5 ran with CWD = `lang/` and their pathspecs (`lang/tests/integration/`) + resolved to `lang/lang/…` and matched nothing. The "NONE" printed by section 4 was an + artifact of the CWD, not a result — this is precisely the cycle-01 defect repeating. + Sections 1–3 of `0039` ran from the repo root and are sound. The corrected re-run is + `0040-REDO-seam-caller-and-wrap-assertion-search.out`, which prints its own CWD as a guard. + Do not cite `0039` §4–5. +3. **Artifact index numbers are not contiguous** (0017 jumps to 0036). `capture.sh` derives the + next index from `grep -c . MANIFEST.tsv`, and several of my commands were multi-line shell + scripts passed to `bash -c`, so the command field written to the manifest contained embedded + newlines and inflated the line count. No data is affected — `verify-manifest.sh` reports + 0 altered, 0 missing — but the numbering gap is an instrument artifact, not a lost artifact. + Subsequent captures put multi-line scripts in files (`probe07.sh`, `thunk07b.sh`, …, stored + alongside this file) and pass a single-line command. +4. **The parent-commit context measurement (`0043`) is stamped with the wrong SHA.** The parent + tree was materialised with `git archive bc2f26d^ | tar -x -C /tmp/el07parent` rather than a + worktree (worktree creation is owned by the parent agent for this run), and `/tmp/el07parent` + is not a git repo, so `capture.sh` was invoked from `/tmp/rerun-v1-07` and stamped `bc2f26d`. + The **subject** of that measurement is `bc2f26d^`. The script defends against a bad extraction + by hashing `codegen.el` and `test_compiler.el` against the `bc2f26d^` blobs before measuring + (both MATCH, printed in the artifact). Read `0043`'s provenance as "taken during the bc2f26d + run", not "measured at bc2f26d". The same applies to the parent arm of the timing artifacts + `0036`/`0037`. + +## Inputs stored alongside the evidence + +`probe07.sh`, `time07.sh`, `time07b.sh`, `thunk07.sh`, `thunk07b.sh`, `parent07.sh` are the +scripts whose captured *output* is the evidence. They are inputs, not artifacts, and are not in +`MANIFEST.tsv`. `probe07.sh` in particular is a **reconstruction** — see divergence detail A. diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/parent07.sh b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/parent07.sh new file mode 100644 index 0000000..67a0df0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/parent07.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# parent07.sh — native compiler test count at the PARENT commit bc2f26d^ (b40754f), +# for context: the cycle doc records no native test count at all. +# +# PROVENANCE NOTE: the parent tree is an extraction, `git archive bc2f26d^ | tar -x`, +# into /tmp/el07parent — NOT a git worktree (the parent agent owns worktree creation +# for this run). capture.sh was therefore invoked from /tmp/rerun-v1-07, so the +# artifact's stamped SHA is bc2f26d; the SUBJECT of the measurement is bc2f26d^. +# The extraction is verified below by diffing it against the bc2f26d^ blob for +# codegen.el. +set -uo pipefail +cd /tmp/rerun-v1-07 || exit 1 +echo "== verify the extracted tree really is bc2f26d^ ==" +a=$(git show 'bc2f26d^:lang/el-compiler/src/codegen.el' | shasum -a 256 | cut -d' ' -f1) +b=$(shasum -a 256 /tmp/el07parent/lang/el-compiler/src/codegen.el | cut -d' ' -f1) +echo " git blob bc2f26d^:lang/el-compiler/src/codegen.el $a" +echo " /tmp/el07parent/lang/el-compiler/src/codegen.el $b" +[ "$a" = "$b" ] && echo " MATCH" || { echo " MISMATCH — abort"; exit 1; } +a=$(git show 'bc2f26d^:lang/tests/native/test_compiler.el' | shasum -a 256 | cut -d' ' -f1) +b=$(shasum -a 256 /tmp/el07parent/lang/tests/native/test_compiler.el | cut -d' ' -f1) +echo " test_compiler.el blob $a" +echo " test_compiler.el file $b" +[ "$a" = "$b" ] && echo " MATCH" || { echo " MISMATCH — abort"; exit 1; } + +echo +echo "== native compiler tests at bc2f26d^ (built gen2, same procedure as the commit) ==" +cd /tmp/el07parent/lang || exit 1 +SRCS=$(../scripts/el-runtime-sources.sh runtime) +CF="-std=c11 -O2 -I runtime"; LF="" +for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do + [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib" +done +LF="$LF -lcurl -lssl -lcrypto -lpthread -lm" +/tmp/elc07pb --test tests/native/test_compiler.el > /tmp/tp07.c || exit 1 +cc $CF -o /tmp/tp07 /tmp/tp07.c $SRCS $LF 2>/dev/null || exit 1 +/tmp/tp07 | tail -4 + +echo +echo "== integration seam_binding.sh at bc2f26d^ ==" +bash tests/integration/seam_binding.sh /tmp/elc07pb "$PWD" | tail -4 diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/probe07.sh b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/probe07.sh new file mode 100644 index 0000000..2c53795 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/probe07.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# probe07.sh — RECONSTRUCTED probe for cycle 07 P1 ("body x3 -> 21, never invoked -> 111"). +# +# This file is an INPUT, not evidence. No probe asserting 21 or 111 exists in the +# tree at bc2f26d. It is modelled line-for-line on lang/tests/integration/seam_binding.sh +# as it stands at bc2f26d: +# - same prog.el (fn work() -> Int { return 7 }; main prints work()) +# - same targets.c wrap target `thrice` (verbatim, incl. its comment) +# - same EL_CONSTRUCTS binding-file format: " " +# - phase name "wrap" is read from el_runtime.c's el_seam_load at bc2f26d +# The only thing NOT recoverable from the tree is the "never invoked" target; the +# record names no such symbol. `never` below is invented to match the stated +# semantics (return 111 without calling the body). +# +# usage: probe07.sh +set -uo pipefail +ELC="${1:?usage: probe07.sh }" +LANG_DIR="${2:?usage: probe07.sh }" +WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT + +SRCS=$("$LANG_DIR/../scripts/el-runtime-sources.sh" "$LANG_DIR/runtime") +CFLAGS="-std=c11 -O2 -rdynamic -I $LANG_DIR/runtime" +for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do + [ -d "$d" ] && CFLAGS="$CFLAGS -I $d/include" && LDFLAGS="-L $d/lib" +done +LDFLAGS="${LDFLAGS:-} -lcurl -lssl -lcrypto -lpthread -lm" + +cat > "$WORK/targets.c" <<'EOF' +#include +#include +typedef int64_t el_val_t; +/* verbatim from seam_binding.sh at bc2f26d */ +el_val_t thrice(el_val_t fn, el_val_t con, el_val_t (*b)(void*), void* e){ + (void)fn; (void)con; return b(e) + b(e) + b(e); /* wrap: invoke N times */ +} +/* NOT in the tree — reconstructed to match "never invoked -> 111" */ +el_val_t never(el_val_t fn, el_val_t con, el_val_t (*b)(void*), void* e){ + (void)fn; (void)con; (void)b; (void)e; return 111; +} +EOF + +# verbatim from seam_binding.sh at bc2f26d +cat > "$WORK/prog.el" <<'EOF' +fn work() -> Int { + return 7 +} + +fn main() { + println(int_to_str(work())) +} +EOF + +"$ELC" "$WORK/prog.el" > "$WORK/prog.c" 2>/dev/null +cc $CFLAGS -o "$WORK/prog" "$WORK/prog.c" "$WORK/targets.c" $SRCS $LDFLAGS 2>/dev/null \ + || { echo "PROBE DID NOT BUILD"; exit 1; } + +echo "== baseline, no binding (work() returns 7) ==" +(cd "$WORK" && ./prog 2>&1) + +echo "== wrap binding -> thrice (body invoked 3x; expect 21) ==" +printf 'work tripler wrap thrice\n' > "$WORK/x3.txt" +(cd "$WORK" && EL_CONSTRUCTS=x3.txt ./prog 2>&1) + +echo "== wrap binding -> never (body never invoked; expect 111) ==" +printf 'work skipper wrap never\n' > "$WORK/never.txt" +(cd "$WORK" && EL_CONSTRUCTS=never.txt ./prog 2>&1) + +echo "== binding file contents used ==" +echo "--- x3.txt"; cat "$WORK/x3.txt" +echo "--- never.txt"; cat "$WORK/never.txt" diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07.sh b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07.sh new file mode 100644 index 0000000..51e9559 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# thunk07.sh — does the recorded PROCESS FAILURE ("build failed with 'undeclared +# identifier __thunk_noargs'") correspond to any COMMITTED state? +cd /tmp/rerun-v1-07 || exit 1 +echo "== 1. does the literal string __thunk_noargs appear in any committed source, anywhere in the range? ==" +found=0 +for c in $(git rev-list 5718943^..c04d68f); do + if git grep -q -- "__thunk_noargs" "$c" 2>/dev/null; then + echo " HIT $(git rev-parse --short=9 "$c")"; found=1 + fi +done +[ "$found" = 0 ] && echo " NONE — the literal never appears in any committed file in 5718943^..c04d68f" + +echo +echo "== 2. __thunk_noargs is a NAME THE COMPILER GENERATES, not source text. Where does it come from? ==" +git grep -n '"__thunk_" ' bc2f26d -- lang/el-compiler/src/codegen.el +git grep -n '__thunk_' bc2f26d -- lang/el-compiler/src/codegen.el + +echo +echo "== 3. in the C emitted at bc2f26d for a zero-param fn, is __thunk_noargs DECLARED before use? ==" +W=$(mktemp -d) +printf 'fn noargs() -> Int {\n return 3\n}\nfn main() {\n println(int_to_str(noargs()))\n}\n' > "$W/n07.el" +/tmp/elc07b "$W/n07.el" > "$W/n07.c" +grep -n "__thunk_noargs" "$W/n07.c" +echo +echo "-- compile that C standalone, strict C11, no GNU extensions --" +cd /tmp/rerun-v1-07/lang || exit 1 +SRCS=$(../scripts/el-runtime-sources.sh runtime) +CF="-std=c11 -O2 -I runtime"; LF="" +for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do + [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib" +done +LF="$LF -lcurl -lssl -lcrypto -lpthread -lm" +cc $CF -o "$W/n07" "$W/n07.c" $SRCS $LF 2>&1 | grep -i "thunk\|error" || echo " (no error mentioning thunk)" +"$W/n07"; echo " program exit=$? (printed value above)" +echo +echo "-- and the same emitted C under -pedantic-errors, which rejects the GNU empty-struct extension --" +cc -pedantic-errors $CF -fsyntax-only "$W/n07.c" 2>&1 | head -20 || true +echo " syntax-only rc above (empty output = clean)" +rm -rf "$W" + +echo +echo "== 4. does tests/integration/seam_caller.sh exist at ANY commit in the range? ==" +found=0 +for c in $(git rev-list 5718943^..c04d68f); do + if git ls-tree -r --name-only "$c" -- lang/tests/integration/ 2>/dev/null | grep -q seam_caller; then + echo " HIT $(git rev-parse --short=9 "$c")"; found=1 + fi +done +[ "$found" = 0 ] && echo " NONE — seam_caller.sh does not exist at any commit in 5718943^..c04d68f" +echo +echo " integration harnesses present at bc2f26d:" +git ls-tree -r --name-only bc2f26d -- lang/tests/integration/ + +echo +echo "== 5. does any committed file anywhere in the range assert 21 or 111 for the wrap seam? ==" +git grep -n -- "thrice" bc2f26d || echo " (thrice appears nowhere at bc2f26d... )" +echo " --- grep for '21' / '111' as expected values in seam_binding.sh at bc2f26d ---" +git show bc2f26d:lang/tests/integration/seam_binding.sh | grep -n '"21"\|"111"\|21$\|111$' || echo " NONE — no assertion on 21 or 111" diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07b.sh b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07b.sh new file mode 100644 index 0000000..a3720b1 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07b.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# thunk07b.sh — REDO of sections 4 and 5 of thunk07.sh. +# DEFECT BEING CORRECTED: thunk07.sh cd'd into /lang for section 3 and +# never cd'd back, so sections 4 and 5 ran with CWD=lang/ and their pathspecs +# ("lang/tests/integration/") resolved to lang/lang/... and matched nothing. The +# "NONE" in the original section 4 was an artifact of that, not a finding. +cd /tmp/rerun-v1-07 || exit 1 +echo "CWD: $(pwd) (must be the repo ROOT for these pathspecs)" +echo +echo "== 4. does tests/integration/seam_caller.sh exist at ANY commit in 5718943^..c04d68f? ==" +found=0 +for c in $(git rev-list 5718943^..c04d68f); do + if git ls-tree -r --name-only "$c" -- lang/tests/integration/ 2>/dev/null | grep -q seam_caller; then + echo " HIT $(git rev-parse --short=9 "$c")"; found=1 + fi +done +[ "$found" = 0 ] && echo " NONE" +echo +echo " -- and does it exist at any commit at all in this repo's history? --" +git log --all --oneline --name-only -- '*seam_caller*' | head -20 || true +echo " (empty above = never existed)" +echo +echo "== integration harnesses present at each commit in the range ==" +for c in $(git rev-list --reverse 5718943^..c04d68f); do + printf " %s %s\n" "$(git rev-parse --short=9 "$c")" "$(git ls-tree -r --name-only "$c" -- lang/tests/integration/ | tr '\n' ' ')" +done +echo +echo "== 5. where does 'thrice' appear at bc2f26d (repo-root scope)? ==" +git grep -n -- "thrice" bc2f26d || echo " (nowhere)" +echo +echo "== 5b. does seam_binding.sh at bc2f26d assert 21 or 111 anywhere? ==" +git show bc2f26d:lang/tests/integration/seam_binding.sh | grep -n "21\|111" || echo " NONE — the strings 21 and 111 do not occur in the harness" +echo +echo "== 5c. every check() expectation in seam_binding.sh at bc2f26d, in order ==" +git show bc2f26d:lang/tests/integration/seam_binding.sh | grep -n 'check "' -A1 +echo +echo "== 5d. is the appended 'thrice' target ever compiled? (targets.c is cc'd BEFORE the append) ==" +git show bc2f26d:lang/tests/integration/seam_binding.sh | grep -n 'cat > "\$WORK/targets.c"\|cat >> "\$WORK/targets.c"\|^cc \|cc \$CFLAGS\|EL_CONSTRUCTS=' +echo +echo "== 5e. does any binding file in the harness use phase 'wrap'? ==" +git show bc2f26d:lang/tests/integration/seam_binding.sh | grep -n "printf '.* wrap " || echo " NONE — no 'wrap' phase binding is ever written by the harness" +echo +echo "== 6. treewide: any file at bc2f26d or c04d68f that binds phase 'wrap'? ==" +git grep -n " wrap " bc2f26d -- '*.sh' '*.txt' || echo " none in .sh/.txt" diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07.sh b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07.sh new file mode 100644 index 0000000..ca86cd6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# time07.sh — re-measure cycle 07 P3 ("cost 5-10% from an indirect call on every fn"). +# +# The thing under test is the cost paid by code EMITTED by the new codegen, so +# both binaries must be gen3 (self-emitted by their own commit's compiler): +# /tmp/elc07pb = elc self-emitted at bc2f26d^ (b40754f) — wrapper calls the body DIRECTLY +# /tmp/elc07b = elc self-emitted at bc2f26d — wrapper calls through el_seam_wrap +# Both are given the SAME input (bc2f26d's lang/elc-cli.el, CWD = bc2f26d worktree), +# so the only difference is the emitted calling convention inside the binary. +# Runs are interleaved to spread any drift in machine load across both arms. +set -uo pipefail +N="${1:-11}" +cd /tmp/rerun-v1-07/lang || exit 1 + +run_one() { # $1 = binary ; prints elapsed seconds + local s e + s=$(python3 -c 'import time;print(time.perf_counter())') + "$1" elc-cli.el > /dev/null 2>&1 + e=$(python3 -c 'import time;print(time.perf_counter())') + python3 -c "print(f'{$e-$s:.4f}')" +} + +# warm the page cache for both +run_one /tmp/elc07pb > /dev/null; run_one /tmp/elc07b > /dev/null + +P=(); C=() +for i in $(seq 1 "$N"); do + P+=("$(run_one /tmp/elc07pb)") + C+=("$(run_one /tmp/elc07b)") +done + +echo "parent bc2f26d^ (direct call) samples: ${P[*]}" +echo "commit bc2f26d (el_seam_wrap) samples: ${C[*]}" +echo +python3 - "$N" "${P[@]}" "${C[@]}" <<'PY' +import sys, statistics +n=int(sys.argv[1]); v=[float(x) for x in sys.argv[2:]] +p,c=v[:n],v[n:] +def stats(x): return min(x), statistics.median(x), max(x) +pm,pmd,pmx=stats(p); cm,cmd,cmx=stats(c) +print(f"parent n={n} min={pm:.4f}s median={pmd:.4f}s max={pmx:.4f}s") +print(f"commit n={n} min={cm:.4f}s median={cmd:.4f}s max={cmx:.4f}s") +print() +print(f"ratio on min : {cm/pm:.4f} ({(cm/pm-1)*100:+.2f}%)") +print(f"ratio on median : {cmd/pmd:.4f} ({(cmd/pmd-1)*100:+.2f}%)") +PY +echo +echo "== machine ==" +uname -a +sysctl -n machdep.cpu.brand_string 2>/dev/null +uptime diff --git a/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07b.sh b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07b.sh new file mode 100644 index 0000000..8f2aa44 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07b.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# time07b.sh — second, larger re-measurement of cycle 07 P3, two workloads. +# Same construction as time07.sh: gen2-self-emitted binaries at bc2f26d^ and bc2f26d, +# identical inputs, interleaved runs. +set -uo pipefail +N="${1:-21}" +cd /tmp/rerun-v1-07/lang || exit 1 + +now() { python3 -c 'import time;print(time.perf_counter())'; } + +bench() { # $1 = label ; $2.. = args passed to each binary + local label="$1"; shift + local P=() C=() i s e + "$@" >/dev/null 2>&1 <<<"" || true + /tmp/elc07pb "$@" >/dev/null 2>&1; /tmp/elc07b "$@" >/dev/null 2>&1 # warm + for i in $(seq 1 "$N"); do + s=$(now); /tmp/elc07pb "$@" >/dev/null 2>&1; e=$(now) + P+=("$(python3 -c "print(f'{$e-$s:.5f}')")") + s=$(now); /tmp/elc07b "$@" >/dev/null 2>&1; e=$(now) + C+=("$(python3 -c "print(f'{$e-$s:.5f}')")") + done + echo "### workload: $label (args: $*)" + echo "parent bc2f26d^ : ${P[*]}" + echo "commit bc2f26d : ${C[*]}" + python3 - "$N" "${P[@]}" "${C[@]}" <<'PY' +import sys, statistics +n=int(sys.argv[1]); v=[float(x) for x in sys.argv[2:]] +p,c=v[:n],v[n:] +print(f" parent n={n} min={min(p):.5f} median={statistics.median(p):.5f} mean={statistics.mean(p):.5f} stdev={statistics.stdev(p):.5f}") +print(f" commit n={n} min={min(c):.5f} median={statistics.median(c):.5f} mean={statistics.mean(c):.5f} stdev={statistics.stdev(c):.5f}") +print(f" RATIO min={min(c)/min(p):.4f} ({(min(c)/min(p)-1)*100:+.2f}%) median={statistics.median(c)/statistics.median(p):.4f} ({(statistics.median(c)/statistics.median(p)-1)*100:+.2f}%) mean={statistics.mean(c)/statistics.mean(p):.4f} ({(statistics.mean(c)/statistics.mean(p)-1)*100:+.2f}%)") +PY + echo +} + +bench "self-compile: elc elc-cli.el" elc-cli.el +bench "compile test_compiler.el in --test mode" --test tests/native/test_compiler.el + +echo "== machine =="; uname -a; sysctl -n machdep.cpu.brand_string 2>/dev/null; uptime +echo +echo "== NOTE: no workload in the tree at bc2f26d runs anywhere near the record's 0.36s/0.39s ==" +for w in "elc-cli.el" "--test tests/native/test_compiler.el" "--test tests/native/test_lexer_scaling.el"; do + s=$(now); /tmp/elc07b $w >/dev/null 2>&1; e=$(now) + python3 -c "print(f' {$e-$s:.4f}s elc $w')" +done diff --git a/docs/v1/experiments/evidence/cycles/08-the-emitter-adjudicates/CLAIMS.md b/docs/v1/experiments/evidence/cycles/08-the-emitter-adjudicates/CLAIMS.md new file mode 100644 index 0000000..22584b9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/08-the-emitter-adjudicates/CLAIMS.md @@ -0,0 +1,228 @@ +# CLAIMS — cycle 08, the emitter adjudicates + +Source doc: `docs/v1/experiments/cycles/08-the-emitter-adjudicates.md` + +## Pinned commits + +| | | +|---|---| +| Cycle commit (the EXPERIMENT) | `c741cfe928b0c9707e9aee37717e357677cb318e` | +| Committed | 2026-08-17 09:11:48 -0500 | +| Subject | EXPERIMENT: prohibition becomes a query over emitted relations | +| Parent (the "before" state) | `c741cfe^` = `bc2f26d` (EXPERIMENT: invocation control resolves at runtime) | +| Land commit | `60c07ad784bdf2ae336ad0c5765af50d6d02a309` | +| Land committed | 2026-08-17 09:11:48 -0500 | +| Land subject | land prohibition-as-query: the emitter records, it no longer adjudicates | +| Re-run method | detached worktree `/tmp/rerun-v1-08` at `c741cfe`, tree clean | +| Artifact provenance | every artifact pinned to `c741cfe928b0`, tree `clean` (see `MANIFEST.tsv`) | +| Machine | Darwin 25.5.0, arm64 (Apple Silicon), clang, openssl@3 from /opt/homebrew | + +The land commit `60c07ad` is captured for identity only (`0002`); it makes no +numeric claims. `codegen.el` is byte-count-identical at `c741cfe` and `60c07ad` +(4962 lines, `0011`). + +## Verdicts + +| # | Claim (verbatim from the record) | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 1 | "I said prohibition could not move because 'a #error has no runtime'" | `0103-prior-claim-error-has-no-runtime.out` | `c741cfe^` | **REPRODUCED** — the quoted prior claim is faithful: `06-the-crossing-resolves-at-emission.md:166` and `07-invocation-is-not-composable.md:38` both read "a #error has no runtime". The tree-level rationale is at `codegen.el:4251-4254` (parent). | +| 2 | "codegen now records what it saw: `sneaky calls raw_sql` / `allowed calls raw_sql` / `allowed calls @repository` / `repository calls prohibits:raw_sql`" | `0009-relations-emitted-verbatim.out`, `0010-relations-diff-vs-record.out` | `c741cfe` | **DIVERGED** — the real `EL_RELATIONS_OUT` file for the record's own probe program has **six** lines, not four, and in a different order. See divergence detail A. | +| 3 | "and tools/check/prohibitions.sh decides, at build time, outside the compiler" | `0014-P2-checker-exists.out`, `0013-P4-violating-program-exit-code.out` | `c741cfe` | **REPRODUCED** — the file exists at `lang/tools/check/prohibitions.sh` (there is **no** repo-root `tools/check/`; the record's path is relative to `lang/`). It is a 40-line bash script, reads only the relations file, and is invoked after `elc` has already exited 0. | +| 4 | P1 "codegen can emit the call graph it already walks" — **TRUE** | `0009-relations-emitted-verbatim.out`, `0032-prohibition-subsystem-linecounts.out` | `c741cfe` | **REPRODUCED** — `record_call()` (codegen.el:3471-3477) writes ` calls ` from inside the pre-existing `vbd_expr_has_restricted_call` walk, gated on `env("EL_RELATIONS_OUT")`. A relations file is produced. | +| 5 | P2 "the check becomes a query outside the compiler" — **TRUE** | `0014`, `0007-integration-prohibition_query.out` | `c741cfe` | **REPRODUCED** — the decision is made by `prohibitions.sh` reading the relations file; the compiler exits 0 on the violating program (`0013`: `elc rc=0`). | +| 6 | P3 "all prohibition decisions leave codegen" — **TRUE**, "zero #errors now" | `0012-codegen-error-emission-sites.out` | `c741cfe` vs `c741cfe^` | **DIVERGED** — prohibition/boundary `#error` sites go **1 → 0** (the claim's substance holds), but codegen.el still contains **10** `#error` emission sites. "zero #errors now" is false as written. See divergence detail B. | +| 7 | P4 "violations still caught at build time" — **TRUE**, "exit=1" | `0013-P4-violating-program-exit-code.out`, `0007` | `c741cfe` | **REPRODUCED** — `prohibitions.sh` on the violating probe prints `boundary violation: raw_sql may only be called from an @repository fn, but sneaky is not one` and exits **1**. The `prohibition_query.sh` harness asserts the same exit code and passes. | +| 8 | P5 "codegen drops below the 4661 baseline" — **FALSE**, "4962, +301" | `0011-codegen-linecount.out`, `0062-reconstruct-223-population.out` | `c741cfe` | **REPRODUCED** — codegen.el at `c741cfe` is exactly **4962** lines; `4962 − 4661 = 301`, exactly as stated; the prediction is correctly recorded as falsified. The 4661 baseline is real: codegen.el is 4661 at `45325f7`, the commit before cycle 01's parent. | +| 8b | (unstated in the record) the parent value | `0011-codegen-linecount.out` | `c741cfe^` | **REPRODUCED (supplied)** — parent `c741cfe^` = **4976**. Relative to its own parent this commit *shrank* codegen by **14** lines. The record's "+301" is measured against the 4661 baseline, not the parent, and the record does not say so. | +| 9 | "The TRAVERSAL is irreducible … those ~120 lines do not move no matter who decides" | `0032-prohibition-subsystem-linecounts.out` | `c741cfe` / `c741cfe^` | **REPRODUCED (exactly)** — `vbd_expr_has_restricted_call` (93 lines) + `vbd_has_restricted_call` (27 lines) = **120** lines, and both spans are 120 lines at the parent *and* at the commit. The "~120" is exact, and "do not move" is literally true of the span sizes. | +| 10 | "I predicted the whole 223 lines would go" | `0062-reconstruct-223-population.out` | `c741cfe^` | **NOT-CAPTURED** — the record never defines the 223-line population, and no combination of the prohibition-subsystem spans at the parent sums to 223. See divergence detail C. | +| 11 | "the capability-tier system (cap_check_call, is_self_formation_call, is_dharma_call, is_llm_call, cap_record_violation, emit_cap_violations) is 76 lines" | `0015-capability-tier-linecount.out` | `c741cfe` | **REPRODUCED (exactly)** — 21 + 7 + 11 + 9 + 9 + 19 = **76** lines, summing each `fn` line through its closing brace. | +| 12 | "…of the same shape — prohibits_WITHIN rather than prohibits_outside, so the checker needs the opposite polarity to absorb it" | `0015`, `0012` | `c741cfe` | **NOT-CAPTURED** — a forward-looking design assertion about a checker that does not exist at this commit; there is no measurable. Code inspection is consistent with it: `cap_check_call` keys on the whole-program `__program_kind` and *forbids* named calls within a tier, whereas `prohibitions.sh` *permits* named calls only within a decorated fn. | +| 13 | "98/98 native" | `0004-native-compiler-tests.out` | `c741cfe` | **REPRODUCED** — `98 tests, 98 passed, 0 failed, 239 assertions in 8.682ms`. Includes the new `compiler-no-longer-emits-prohibition-errors` test, `ok`. | +| 14 | "4/4 prohibition_query.sh" | `0007-integration-prohibition_query.out` | `c741cfe` | **REPRODUCED** — `4 assertions, 4 passed, 0 failed`. | +| 15 | "7/7 seam_binding.sh" | `0008-integration-seam_binding.out`, `0048`, `0061`, `0101` | `c741cfe` | **REPRODUCED** — `7 assertions, 7 passed, 0 failed`. The 6/6-vs-7/7 question against cycle 06 is settled: the harness genuinely gained a 7th assertion. See note D. | +| 16 | "fixpoint ok" | `0102-selfhost-fixpoint-gen2-gen3.out` | `c741cfe` | **REPRODUCED** — gen2 == gen3, identical sha256 `1db5d7d4…`. (gen1 != gen2 as expected; the committed `dist/platform/elc` predates the seam wrapper/thunk emission.) | + +Totals: **REPRODUCED 12** (incl. 8b) · **DIVERGED 2** · **NOT-REPRODUCIBLE 0** · **NOT-CAPTURED 2**. + +--- + +## Divergence detail A — the emitted relation shape (claim 2) + +The record presents this as what codegen records: + +``` +sneaky calls raw_sql +allowed calls raw_sql +allowed calls @repository +repository calls prohibits:raw_sql +``` + +The probe program is not invented here — it is verbatim the `p.el` heredoc inside +`lang/tests/integration/prohibition_query.sh` at this very commit. Running the +stage-2 `elc` on it with `EL_RELATIONS_OUT` set produces (`0009`, verbatim): + +``` +manager calls prohibits:dharma_emit,dharma_field +repository calls prohibits:raw_sql +repository calls @decorator +sneaky calls raw_sql +allowed calls @repository +allowed calls raw_sql +``` + +Six lines, not four. Diff as sets (`0010`, exit 1): + +- `+ manager calls prohibits:dharma_emit,dharma_field` — the built-in DHARMA + prohibition is emitted unconditionally for **every** program, whether or not the + program mentions `@manager`. The record's block shows only the program's own + declared prohibition. +- `+ repository calls @decorator` — `cg_fn` now records every decorator a fn carries, + and `@decorator(...)` is itself in the decorator list, so the declaring stub + `fn repository()` reports carrying a construct called `decorator`. + +Order also differs: the record lists the `calls` facts first and the `prohibits:` +fact last; the emitter writes prohibitions first (they come from a token-level +pre-pass) and then the per-fn walk, and within `allowed` it emits the decorator +before the call. The ordered diff is likewise non-empty. + +Neither extra line changes the outcome — `prohibitions.sh` sorts and ignores +relations whose construct has no `prohibits:` entry, and `@decorator` has none. +The claim is wrong as a description of the artifact, not as a description of the +mechanism. But the record quotes it as file content, and the file content is +different. + +## Divergence detail B — P3 "zero #errors now" (claim 6) + +Counted with `emit_line("#error …` (i.e. actual emission sites, not the 29 +occurrences of the literal string `#error` in code + comments, which is 29 at +*both* commits): + +| | `c741cfe^` | `c741cfe` | +|---|---|---| +| `emit_line("#error …` sites | **11** | **10** | +| of which boundary/prohibition | **1** (codegen.el:3298) | **0** | + +The single site removed is exactly the prohibition adjudication: + +``` +emit_line("#error \"boundary violation: " + prohibition_names(pc) + " may only be +called from an @" + pc + " fn, but '" + fn_name + "' is not one\"") +``` + +What remains at `c741cfe` (`0012`): capability violation (2578), temporal type +error (2602), arity error (3009), singleton missing `guards:` (3440), and three +cgi/service-block errors duplicated across two code paths (3639/3642/3646 and +4418/4421/4425). + +So the accurate statement is "**zero prohibition #errors** now", 1 → 0, a 9% +reduction in `#error` sites overall. Read literally, "zero #errors now" is false. +This matters because the record itself names the capability tier as "the same +shape" — and the capability tier's decision is *still* an `#error` at line 2578, +inside codegen. The prohibition decision left; the family of decisions it belongs +to did not. + +## Divergence detail C — the 223-line figure (claim 10) + +The record does not say what the 223 lines are. Every prohibition-related span in +codegen.el at the parent, measured `fn` line through closing brace (`0062`): + +``` +vbd_expr_has_restricted_call 93 <- traversal +vbd_has_restricted_call 27 <- traversal +vbd_is_restricted_name 12 (the rule) +declare_prohibition 9 +prohibition_names 3 +prohibiting_constructs 3 +scan_declared_decorators 66 +fn_has_decorator 12 +cg_fn adjudication block 19 (the decision, removed by this commit) +``` + +Candidate sums: traversal only 120; traversal+rule+decision 151; all six +prohibition fns 147; +cg_fn block 166; +`scan_declared_decorators` 213; ++scan+cg_fn 232; +scan+cg_fn+`fn_has_decorator` 244. **None is 223.** The two +nearest bracket it (213, 232), which suggests the figure is a good-faith +approximation of "the prohibition machinery" under a slightly different span +convention (e.g. including or excluding the leading comment blocks), but no +convention was recorded and I will not reverse-engineer one to hit the number. +Verdict: NOT-CAPTURED, population undefined. + +Worth noting for the record's own internal consistency: parent codegen.el is 4976 +lines, and 4976 − 223 = **4753**, which is still 92 lines *above* the 4661 baseline +that P5 predicted dropping below. So even if the entire 223 lines had gone, P5 +could not have come true by that arithmetic. The 223 estimate and the P5 prediction +were not consistent with each other before the experiment ran. + +## Note D — the 6/6 → 7/7 question on seam_binding.sh + +Cycle 06's record claims `6/6`; cycle 08 claims `7/7`. Both are correct — the +harness gained an assertion in between (`0048`, `0061`, `0101`): + +| revision | self-reported total | tally line | +|---|---|---| +| `8bbb750` "control the claim that cannot be unit tested" | 6 assertions | `$((6-FAILS)) passed` | +| `285166c` "EXPERIMENT: emit the wrapper unconditionally…" | 7 assertions | `$((6-FAILS)) passed` ← **off by one** | +| `bc2f26d` "EXPERIMENT: invocation control resolves at runtime" | 7 assertions | `$((7-FAILS)) passed` | +| `c741cfe` (this cycle) | 7 assertions | `$((7-FAILS)) passed` | + +`285166c` added the assertion `an EXIT construct declared after the build replaces +the result` (a `double_result` exit handler, expecting `14`), and bumped the header +count to 7 but left the passed-count arithmetic at `6-FAILS`. At `285166c` the +harness would therefore have printed `7 assertions, 6 passed, 0 failed` on a fully +green run. `bc2f26d` fixed it. **This is a defect in cycle 07's evidence, not +cycle 08's** — at `c741cfe` the tally is correct and the observed output is +`7 assertions, 7 passed, 0 failed`. Flagging it here for whoever re-runs cycle 07. + +## Measurement defects in this re-run, recorded rather than removed + +**`0005-selfhost-fixpoint.out` is defective and retained** (exit 1, +`/tmp/g08.c /tmp/g08b.c differ: char 12547, line 257`). It ran the original +RERUN-RECIPE §4 command, which compares **gen1 vs gen2** — the output of the +committed `dist/platform/elc` against the output of the compiler built from it. +That is not the fixpoint. The committed bootstrap binary at this commit predates +the seam wrapper/thunk emission added in cycles 06–07, so gen1 necessarily differs +(3518 diff lines, all of them missing `__el_body_*` / `__thunk_*` / `el_seam_run` +scaffolding). Reporting that as "fixpoint broken" would have been a fabricated +divergence. The recipe was corrected mid-run by the parent agent. + +`0006-REDO-selfhost-fixpoint-gen3-gen4.out` is the first correct re-capture but is +misnamed: its "gen3/gen4" are the recipe's gen2/gen3. `0102-selfhost-fixpoint-gen2-gen3.out` +is the authoritative artifact, captured with the corrected recipe command and +correct naming. All three are left in the manifest. + +Instrument check: an early exploratory `git show "$s:lang/…"` in the Bash tool was +silently mangled by zsh's `${s:l}` history modifier and returned `lines: 0` for both +commits (visible only as `fatal:` on stderr). Every line count reported above was +re-taken with `${s}` braces or run inside `capture.sh` (which is `#!/usr/bin/env bash`); +the mangled values were never used and no conclusion was drawn from them. + +## Artifact index + +| artifact | what it backs | +|---|---| +| `0001-commit-identity.out` | `c741cfe` SHA / date / subject | +| `0002-commit-identity-land.out` | `60c07ad` SHA / date / subject | +| `0003-stage2-build.out` | stage-2 build OK, 11291-line generated C | +| `0004-native-compiler-tests.out` | claim 13 (98/98) | +| `0005-selfhost-fixpoint.out` | **defective, retained** — gen1-vs-gen2 | +| `0006-REDO-selfhost-fixpoint-gen3-gen4.out` | superseded re-capture (misnamed) | +| `0007-integration-prohibition_query.out` | claims 5, 7, 14 | +| `0008-integration-seam_binding.out` | claim 15 | +| `0009-relations-emitted-verbatim.out` | claims 2, 4 | +| `0010-relations-diff-vs-record.out` | claim 2, divergence A | +| `0011-codegen-linecount.out` | claims 8, 8b | +| `0012-codegen-error-emission-sites.out` | claim 6, divergence B | +| `0013-P4-violating-program-exit-code.out` | claims 3, 5, 7 | +| `0014-P2-checker-exists.out` | claims 3, 5 | +| `0015-capability-tier-linecount.out` | claim 11 | +| `0032-prohibition-subsystem-linecounts.out` | claims 4, 9 | +| `0048-seam-binding-assertion-history.out` | note D | +| `0061-seam-binding-7th-assertion-diff.out` | note D | +| `0062-reconstruct-223-population.out` | claim 10, divergence C | +| `0101-seam-binding-tally-line-history.out` | note D | +| `0102-selfhost-fixpoint-gen2-gen3.out` | claim 16 | +| `0103-prior-claim-error-has-no-runtime.out` | claim 1 | + +Artifact numbers are not contiguous: `capture.sh` allocates a shared counter across +the parallel cycle re-runs. diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.prov b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.prov new file mode 100644 index 0000000..cf7fefa --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.prov @@ -0,0 +1,7 @@ +commit 9cc6040df26eef5ad1718671792a2bcc87d43ec0 +tree clean +captured_utc 2026-08-17T17:39:51Z +exit 0 +ms 4759 +sha256_out 0bfdec5ef9e6bda13806c65b367edc2087647ef8ae296899605ad79f4e2b668f +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.rc b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.cmd b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.cmd new file mode 100644 index 0000000..c2bce89 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.cmd @@ -0,0 +1 @@ +bash /tmp/analyze10c.sh diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.err b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.out b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.out new file mode 100644 index 0000000..9f469ed --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.out @@ -0,0 +1,88 @@ +== DEFECT 2 and 3: reconstructing the checker's parser evolution == + (the record: 'Multi-line declarations parsed as zero params'; then + 'Fixing (2) by joining lines dropped 500 signatures to 334, because a + declaration preceded by a comment no longer started its record.') + + v1 anchored ^el_val_t, line-based, no join : 500 + [record's '500 decls'] + v2 anchored + join, NO comment strip : 334 + [record's 'dropped ... to 334'] + v3 anchored + join + // strip + /*..*/ strip : 434 + v4 AS SHIPPED (unanchored regex) : 503 + [record's '503 signatures'; the integration test asserts this literal] + v1 declarations parsed as ZERO params : 91 + truly-zero-param declarations (correct parse) : 82 + +== DEFECT 3: is the comment strip really FIRST in the shipped script? == +21:sed 's://.*::' "$HDR" | tr '\n' ' ' | sed 's:/\*[^*]*\*/: :g; s/;/;\n/g' | awk ' + (line 21 of arity.sh: sed strips // comments BEFORE tr '\n' ' ' joins) + +== DEFECT 1: the __-prefix mapping rule == +42: [ -n "$expected" ] || expected=$(awk -v n="__$callee" '$1==n {print $2; exit}' "$SIG") + +== P4: the checker exists at 9cc6040 == +-rwxr-xr-x@ 1 will wheel 2533 Aug 17 12:29 lang/tools/check/arity.sh +9cc6040df26eef5ad1718671792a2bcc87d43ec0 introduced? + lang/el-compiler/src/codegen.el | 396 +--------------------------------- + lang/tests/integration/arity_query.sh | 26 +++ + lang/tools/check/arity.sh | 52 +++++ + 3 files changed, 84 insertions(+), 390 deletions(-) + +== the arity.sh header comment's own coverage number == + # + # codegen.el carried builtin_arity(): 344 lines, 300 entries, of which 243 were + # an exact duplicate of el_runtime.h. Measured drift between them was zero -- + # the duplicate had been maintained correctly -- but 199 functions the runtime + # declares had NO entry, so calling them with the wrong argument count produced + # no El-level diagnostic at all. The table was not wrong, it was 40% incomplete. + # + # Deriving from the header fixes the coverage and makes drift impossible. + +== P3: codegen at 9cc6040 emits call-arity relations == + 978: let arity: Int = native_list_len(args) + 1008: record_call(fn_name, "arity:" + native_int_to_str(native_list_len(args))) + builtin_arity still present in codegen at 9cc6040? -> 0 + arity_check_call / emit_arity_violations at 9cc6040 -> 1 + same at 9cc6040^ -> builtin_arity=1, checks=6 + +== P5: where was codegen.el 4661 lines? == + 9cc6040df 4512 2026-08-17 EXPERIMENT: derive arity from the runtime's own declarations + c2d9596e7 4896 2026-08-17 EXPERIMENT: the capability tier becomes shipped policy plus a query + c741cfe92 4962 2026-08-17 EXPERIMENT: prohibition becomes a query over emitted relations + bc2f26ddf 4976 2026-08-17 EXPERIMENT: invocation control resolves at runtime + 285166c25 5043 2026-08-17 EXPERIMENT: emit the wrapper unconditionally, so exit binds at runtime too + 28d19da7f 5095 2026-08-17 strip the compile-time machinery the seam replaces + 886626a64 5156 2026-08-17 seam refusal + control tests: a runtime binding can short-circuit + 35b07bade 5156 2026-08-17 EXPERIMENT: resolve the crossing at execution, not at emission + 1b324a071 5152 2026-08-17 let a construct declare what may not cross it + 2bed8483f 5084 2026-08-17 EXPERIMENT: hand the construct the body as a real closure + 4f7568b07 4953 2026-08-17 give a construct its after-crossing face, and let constructs compose + 60737b030 4850 2026-08-17 let a construct refuse, not only observe + 5718943f2 4800 2026-08-17 let a construct declare its own meaning instead of the emitter knowing it + dcaa77d77 4670 2026-08-17 make boundary crossings attributable to the construct that caused them + 45325f739 4661 2026-08-16 singleton: guard the state, not the program's name + 8ae163e8e 4646 2026-08-16 lang: give cross-cutting concerns an owner instead of a convention + cf060adbf 4563 2026-08-15 Merge remote-tracking branch 'origin/dev' into wt/soul-runtime-reconcile + b5a0a729e 4562 2026-08-15 codegen: Bool is int-like, so Bool comparisons stop lowering to str_eq + b55e6bfd5 4548 2026-08-15 codegen: either side Int is enough for == and !=, not both + 6a6b589ba 4534 2026-08-15 bench: real black_box barrier + three-signal growth-curve gate + 3e7ab07e8 4533 2026-08-15 test framework phase 1: forward decls, void-return fix, suite migration + a668062e3 4510 2026-08-15 Merge remote-tracking branch 'origin/dev' into wt/soul-runtime-reconcile + 24fac765a 4504 2026-08-15 test framework phase 1: compile-time registry + El-side runner + 37bcf7eb7 4440 2026-08-15 runtime: allocation accounting — the deterministic signal for complexity gating + e917b3d43 4434 2026-08-15 store: make the buffer pool sense its own state and correct from it + 4e24d7d3f 4432 2026-08-15 runtime: engram_edges_json — read edges without a whole-graph file round trip + 09dade061 4430 2026-08-15 Merge remote-tracking branch 'origin/pr/103' into HEAD + ee39aa5f1 4424 2026-08-15 Merge pull request 'ingest: unify transduce_prose/transduce_structured into one transduce()' (#117) from feat/transduce-unify into dev + e29fe4fd0 4124 2026-08-15 ingest: unify transduce_prose/transduce_structured into one transduce() + bacaf3d39 4422 2026-08-15 engram: reconcile M8 HNSW vindex (#109) onto current dev, restore 3 fixes the branch predated + 69870ac88 4122 2026-08-15 Merge pull request 'fix(codegen): emit the declared cgi identity — it was searched for in a list that cannot contain it' (#89) from fix/cgi-identity-emission-clean into dev + 09ae14a97 4106 2026-08-15 Merge pull request 'fix: float arithmetic codegen (segfault/garbage) and math_log aliasing' (#104) from worktree-agent-a456e0cf8cd2ee361 into dev + 2f832c8de 4049 2026-08-15 Fix float arithmetic codegen and math_log aliasing + 101018597 3915 2026-08-15 Add op_assert grounded-envelope primitive and purview-bounded mutation wrappers + 01826421c 4208 2026-08-14 seam: implement decorated-fn boundary auto-emit; prove on clone + d4f401de1 4199 2026-08-14 reshape: decorator-as-seam — port @route codegen, prove decorate->serve, rewrite surface as decorated El + 7aa847e32 3966 2026-08-12 Merge origin/dev into engram-tiered-storage + bb64a236e 3965 2026-08-12 engram tiered storage: engram-service wiring + elc fold-hang fix + prune-store mirror + 866c75e5e 3925 2026-08-09 fix(codegen): emit the declared cgi identity — it was searched for in a list that cannot contain it + 6b9d9e6c4 3909 2026-07-15 Add engram_get_node_by_label runtime native to unblock soul link diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.prov b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.prov new file mode 100644 index 0000000..0aa9ae6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.prov @@ -0,0 +1,7 @@ +commit 9cc6040df26eef5ad1718671792a2bcc87d43ec0 +tree clean +captured_utc 2026-08-17T17:41:12Z +exit 0 +ms 415 +sha256_out d7f37b35c720fbf4afda5392de02457080a05d365e006662a795f32f476658ac +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.rc b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.cmd b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.cmd new file mode 100644 index 0000000..6a900a4 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.cmd @@ -0,0 +1 @@ +bash /tmp/analyze10d.sh diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.err b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.out b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.out new file mode 100644 index 0000000..992f8c7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.out @@ -0,0 +1,302 @@ +== coverage gap: what population could yield 110 or 199? == + header declarations, correct parse : 500 + header declarations, arity.sh as shipped : 503 + builtin_arity() entries : 300 + shared, direct name match : 243 + shared, arity.sh __-prefix rule : 247 + OBSERVED header names with no table entry + strict (direct name only) : 257 + with the __-prefix rule applied : 256 + candidate arithmetic: + 500 - 300 = 200 503 - 300 = 203 + 500 - 243 = 257 500 - 247 = 253 + 40% of 500 = 200 (arity.sh says '40% incomplete', 199) + NO construction over these populations yields 110. + +== uncovered names, full list (correct parse, __-rule applied) == +__http_conn_fd +__http_do_map_to_file +__http_sse_close +__http_sse_open +__http_sse_send +aead_decrypt +aead_encrypt +args +cal_cycle_phase +cal_format +cal_in +cal_to_instant +camera_available +camera_capture_jpeg +camera_capture_rgb +camera_request_access +cgi_engram +cgi_network +cgi_principal +config +cycle_calendar +duration_millis +duration_nanos +duration_seconds +duration_to_millis +duration_to_nanos +duration_to_seconds +earth_calendar +earth_calendar_default +el_base64_encode_n +el_config_declare +el_config_validate +el_duration_add +el_duration_div +el_duration_eq +el_duration_from_nanos +el_duration_ge +el_duration_gt +el_duration_le +el_duration_lt +el_duration_ne +el_duration_scale +el_duration_sub +el_instant_add_dur +el_instant_diff +el_instant_eq +el_instant_ge +el_instant_gt +el_instant_le +el_instant_lt +el_instant_ne +el_instant_sub_dur +el_list_new +el_local_date_add_dur +el_local_date_eq +el_local_date_lt +el_local_time_add_dur +el_map_new +el_mem_check +el_now_instant +el_seam_run +el_seam_wrap +el_sha256_bytes_n +el_singleton_acquire +el_sleep_duration +emit_event +emit_log +emit_metric +engram_act_stats_json +engram_add_layer +engram_age_field +engram_age_field_catchup +engram_assert_json +engram_attend_json +engram_autoconnect_node +engram_boundary_beat +engram_chrono_persist_tick +engram_chrono_tick +engram_compile_layered_json +engram_consolidate_permanence +engram_correspondence_beat_json +engram_cosine_sim +engram_crc32 +engram_dreams_json +engram_embed_backfill +engram_geo_analogy_json +engram_geo_combine_json +engram_geo_descriptor_json +engram_geo_distance_json +engram_geo_overlap_json +engram_geo_reify_get_json +engram_geo_reify_list_json +engram_geo_reify_run_json +engram_geo_subtract_json +engram_ground_json +engram_ground_record_json +engram_ground_trajectory_json +engram_hebb_drain_json +engram_is_protected +engram_ise_log_append +engram_label_df +engram_list_layers +engram_list_layers_json +engram_load_merge +engram_nearest_json +engram_neighborhood_rename_json +engram_node_layered +engram_node_set_emb +engram_protected_json +engram_prune_telemetry +engram_reason_analogy_json +engram_recall_json +engram_remove_layer +engram_resolve_data_dir +engram_retrieve_geometric_json +engram_salient_term +engram_scan_nodes_by_type_json +engram_scan_nodes_emb_json +engram_self_anchor_capture +engram_self_drift_json +engram_self_reify_beat_json +engram_text_health_json +engram_think_json +engram_wal_boot +engram_wal_compact +engram_wal_edges_since +engram_wal_forget +engram_wal_hebb_batch +engram_wal_maybe_compact +engram_wal_node_put +engram_wal_open_dir +engram_wm_avg_weight +engram_wm_count +engram_wm_top_json +fs_exists +fs_mkdir +fs_write_bytes +geometry_dim +geometry_free +geometry_from_f32le_hex +geometry_get +geometry_is +geometry_new +geometry_norm +geometry_set +geometry_to_f32le_hex +http_delete +http_delete_json +http_get_to_file +http_post_to_file +http_response +in_calendar +instant_from_iso8601 +instant_to_iso8601 +instant_to_unix_millis +instant_to_unix_seconds +json_array_get +json_array_get_string +json_array_push +json_build_array +json_build_object +json_escape_string +llm_last_usage +local_date +local_date_day +local_date_month +local_date_year +local_datetime +local_time +local_time_hour +local_time_minute +local_time_nanos +local_time_second +manifold_add +manifold_free +manifold_geometry +manifold_index_of +manifold_is +manifold_key +manifold_new +manifold_rel_count +manifold_rel_from +manifold_rel_name +manifold_rel_to +manifold_rel_weight +manifold_relate +manifold_role +manifold_single +manifold_size +mars_calendar +mic_available +mic_capture_pcm16 +mic_monitor_rms +mic_monitor_start +mic_monitor_stop +mic_request_access +no_cycle_calendar +node_attach_geometry +node_geometry_dim +now +now_in +now_millis +now_ns +parse_int +pq_hybrid_handshake +pq_hybrid_keygen +pq_kem_decaps +pq_kem_encaps +pq_kem_keygen +pq_keygen_signature +pq_sign +pq_verify +realizer_has +realizer_register +relative_calendar +rhythm_and +rhythm_cycle_phase +rhythm_cycle_start +rhythm_duration +rhythm_event +rhythm_matches +rhythm_next_after +rhythm_or +rhythm_session_start +rhythm_weekday +rhythm_weekly_at +sha3_256_hex +speaker_available +speaker_name +speaker_pause +speaker_play_pcm16 +speaker_play_pcm16_async +speaker_play_wav +speaker_play_wav_async +speaker_played_frames +speaker_playing +speaker_resume +speaker_stop +trace_span_end +trace_span_start +transduce +ttl_cache_age +ttl_cache_get +ttl_cache_set +unix_millis +unix_seconds +unix_timestamp +url_decode +url_encode +wav_frames +wav_rate +zone +zone_local +zone_offset +zone_utc +zoned + +== orphaned comments left in codegen.el at 9cc6040 == + (the functions they document were deleted; the prose was not) + // -- Builtin arity table ------------------------------------------------------- + // + // El programs sometimes call runtime builtins with the wrong number of + // arguments (e.g. `http_serve(port)` instead of `http_serve(port, handler)`). + // Without this check the generated C compiles to a call with too few / + // too many args and fails downstream cc with a generic "too few arguments" + // message that doesn't point to the El source line. + // + // Strategy: a small static table mirrors el_runtime.h. Variadic builtins + // (el_list_new, el_map_new, args) and unknown identifiers (user fns, + // dynamic dispatch) return -1 -> no check. A mismatch records a violation + // in process state, which emit_arity_violations() turns into #error + // directives at the top of the generated C. + + + // Validate the call's arity against the builtin table. Returns true (always) + // because cg_expr ignores the result; -1 from builtin_arity signals + // "no check possible" (variadic or user-defined). A mismatch is recorded + // and surfaced as an #error at the bottom of the generated C, so cc fails + // before it ever attempts to type-check the wrong call. + + // Emit recorded arity violations as #error directives. + + references to now-deleted symbols remaining in codegen.el at 9cc6040: + 1013: // through (builtin_arity returns -1). + 2550:// in process state, which emit_arity_violations() turns into #error + 2555:// because cg_expr ignores the result; -1 from builtin_arity signals diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.prov b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.prov new file mode 100644 index 0000000..45d45ae --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.prov @@ -0,0 +1,7 @@ +commit 9cc6040df26eef5ad1718671792a2bcc87d43ec0 +tree clean +captured_utc 2026-08-17T17:42:08Z +exit 0 +ms 43 +sha256_out 2192699a3f00c802f8c117ede357baaad5247f710eb4dcad33b6af7fe0a8ff6f +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.rc b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.cmd b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.cmd new file mode 100644 index 0000000..8436453 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.cmd @@ -0,0 +1 @@ +bash /tmp/analyze10e.sh diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.err b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.err new file mode 100644 index 0000000..6d69bf8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.err @@ -0,0 +1 @@ +# total declarations: 500 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.out b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.out new file mode 100644 index 0000000..6f2a0af --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.out @@ -0,0 +1,66 @@ +correct parser declarations : 500 +arity.sh signature lines (its '503'): 503 +arity.sh distinct names : 501 + +== names arity.sh invents (present in its parse, absent from the header) == + el_from_float + handler + holding + pointer + slot + string + strings + count: 7 + +== real declarations arity.sh misses == + earth_calendar + el_sha256_bytes_n + fs_write_bytes + http_post_to_file + local_date + sha256_hex + count: 6 + +== declarations arity.sh gives the WRONG parameter count == + __mutex_new shipped=1 correct=0 + aead_encrypt shipped=-1 correct=2 + append shipped=4 correct=2 + args shipped=1 correct=0 + camera_available shipped=3 correct=0 + config shipped=2 correct=1 + el_arena_push shipped=1 correct=0 + el_html_sanitize shipped=-1 correct=2 + el_singleton_acquire shipped=3 correct=2 + engram_compile_layered_json shipped=3 correct=2 + engram_neighborhood_rename_json shipped=8 correct=2 + fs_size shipped=2 correct=1 + geometry_from_f32le_hex shipped=4 correct=1 + geometry_new shipped=3 correct=1 + http_response shipped=-1 correct=3 + llm_last_usage shipped=6 correct=0 + manifold_new shipped=10 correct=0 + mic_available shipped=1 correct=0 + mic_monitor_start shipped=2 correct=0 + pq_keygen_signature shipped=1 correct=0 + realizer_register shipped=-1 correct=2 + speaker_available shipped=2 correct=0 + speaker_play_pcm16_async shipped=3 correct=2 + stdout_to_file shipped=2 correct=1 + zone shipped=7 correct=1 + count: 25 + +== of those, ones arity.sh treats as VARIADIC and therefore skips entirely == + aead_encrypt shipped=variadic correct=2 + el_html_sanitize shipped=variadic correct=2 + http_response shipped=variadic correct=3 + realizer_register shipped=variadic correct=2 + count: 4 + +== gen1 / gen2 / gen3 sizes (context for the fixpoint artifacts) == + 10166 /tmp/g10.c + 13058 /tmp/g10b.c + 13058 /tmp/g10c.c + 36282 total +d3e4bcc4280157a3ed0f2a9869cf168084abb2634c3cf84f386c2df9d7c4f623 /tmp/g10.c +5c6bb297a95cbd08c204bc71bdefddd425caa93ea8ffc1dc8a2e54ca8ad63a71 /tmp/g10b.c +5c6bb297a95cbd08c204bc71bdefddd425caa93ea8ffc1dc8a2e54ca8ad63a71 /tmp/g10c.c diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.prov b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.prov new file mode 100644 index 0000000..e609dd1 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.prov @@ -0,0 +1,7 @@ +commit 9cc6040df26eef5ad1718671792a2bcc87d43ec0 +tree clean +captured_utc 2026-08-17T17:44:55Z +exit 0 +ms 82 +sha256_out 85f2f9e6bee363ef9bbef468aea760a6c8552728335cb2a07b8adef12703787b +sha256_err 06c544b8f040df71ae9fbc19ab29832e8f91626fe756db882488f3a2db78f4e9 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.rc b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/CLAIMS.md b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/CLAIMS.md new file mode 100644 index 0000000..ad2f736 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/CLAIMS.md @@ -0,0 +1,245 @@ +# CLAIMS — cycle 10, a second copy of the header + +Source doc: `docs/v1/experiments/cycles/10-a-second-copy-of-the-header.md` + +## Pinned commits + +| | | +|---|---| +| Cycle commit (the EXPERIMENT) | `9cc6040df26eef5ad1718671792a2bcc87d43ec0` | +| Committed | 2026-08-17 09:21:10 -0500 | +| Subject | EXPERIMENT: derive arity from the runtime's own declarations | +| Parent (the "before" state the record describes) | `29f78f9f67b87078e20a506e9df04dd43d489013` (`9cc6040^`, "land capability-as-policy: eighteen literals become a data file") | +| Land commit | `d9e301be6d8961ba275eadb6f6df5292a7ebe903`, 2026-08-17 09:21:10 -0500* — subject `land arity-from-header: the runtime declares its own surface`, identity captured only (the record makes no numeric claim about it) | +| Re-run method | detached worktree `/tmp/rerun-v1-10` at `9cc6040`, tree clean for every capture | +| Parent tree | materialised with `git archive 9cc6040^ \| tar -x -C /tmp/parent10x` from inside the worktree, so provenance stamps `9cc6040` while the *measured* tree is `9cc6040^`; the command line in each `.cmd` says which | +| Artifact provenance | 18 artifacts, all `commit 9cc6040df26e`, `tree clean` (see `MANIFEST.tsv`) | +| Diffstat | codegen.el −390/+6, `lang/tests/integration/arity_query.sh` +26 (new), `lang/tools/check/arity.sh` +52 (new) — `0004` | + +\* full SHA as recorded in `0002-commit-identity-d9e301b.out`. + +Commits between cycle 09's pinned commit and this one (`0003`): exactly one, +`29f78f9 land capability-as-policy: eighteen literals become a data file`. It does +not touch `codegen.el`, so `c2d9596` and `9cc6040^` have identical codegen line counts. + +## The single most important thing in this record + +**Every headline number in this cycle reproduces exactly — but only when the runtime +header is parsed correctly.** The checker the cycle ships, `lang/tools/check/arity.sh`, +has a *fourth* parser defect that the record does not confess, and that defect is what +produces the two figures in the record that do not reproduce ("503 signatures", and, +indirectly, the coverage-gap count). Run the same questions through a correct C +declaration parser and `243 shared names`, `ZERO drift`, `60 of 500`, and `500 → 334` +all land on the nose. + +So: the *science* in this cycle reproduces. The *instrument* it shipped does not +measure what it says it measures. + +## Verdicts + +| # | Claim (verbatim from the record) | Artifact | Commit | Verdict | +|---|---|---|---|---| +| 1 | "codegen.el carried builtin_arity(): 344 lines" | `0011` | `9cc6040^` | **REPRODUCED** — `fn builtin_arity` spans lines 2547–2890 = exactly **344** lines | +| 2 | "300 entries" | `0011` | `9cc6040^` | **REPRODUCED** — **300** distinct names (from 305 `str_eq(name, …)` lines; 5 names are listed twice: `__thread_create`, `__thread_join`, `__mutex_new`, `__mutex_lock`, `__mutex_unlock`) | +| 3 | "a hand-maintained second copy of el_runtime.h" | `0011`, `0012` | `9cc6040^` | **REPRODUCED** — 243 of the 300 entries name a function the header also declares; the header is where those arities come from | +| 4 | P1 "the table duplicates the header — TRUE, 243 shared names" | `0012` | `9cc6040^` | **REPRODUCED** — direct-name intersection of the 300 table names with the 500 header names = exactly **243** (247 if the checker's `__`-prefix fallback is applied) | +| 5 | P2 "they have already drifted — FALSE. ZERO drift. The duplicate had been maintained correctly." | `0012` | `9cc6040^` | **REPRODUCED** — **0** mismatches over all 247 shared names, comparing table arity against the header's parameter count. Not one entry had drifted. | +| 6 | P3 "codegen can emit call-arity relations — TRUE" | `0048`, `0047` | `9cc6040` | **REPRODUCED** — `codegen.el:1008` emits `record_call(fn_name, "arity:" + native_int_to_str(native_list_len(args)))`; the relations file for the probe contains `__http_do_map_to_file calls arity:1` | +| 7 | P4 "the check becomes a query against the header — TRUE" | `0048`, `0004` | `9cc6040` | **REPRODUCED** — `lang/tools/check/arity.sh` is added by this commit (52 lines) and parses `runtime/el_runtime.h` at run time; `builtin_arity` no longer appears in codegen.el | +| 8 | P5 "codegen drops to roughly baseline — 4903 → 4512" | `0010` | both | **DIVERGED (parent half)** — the commit half is exact (**4512**), the parent is **4896**, not 4903. See below. | +| 9 | P5 "149 BELOW the 4661 it started at" | `0010`, `0048` | — | **REPRODUCED** — codegen.el is **4661** lines at `45325f7` ("singleton: guard the state, not the program's name", 2026‑08‑16), the last commit before the v1 experiment series; 4661 − 4512 = **149** | +| 10 | "110 functions the runtime declares had no entry" | `0012`, `0049` | `9cc6040^` | **DIVERGED** — observed **257** header names with no table entry (**256** after applying the `__`-prefix rule). No construction over these populations yields 110. See below. | +| 11 | "the old compiler reports 0 arity errors for `__http_do_map_to_file(1)`" | `0047` | `9cc6040^` | **REPRODUCED** — the compiler built at `9cc6040^` emits **0** `arity error` lines for that call. Control in the same artifact: `println("a","b")` *does* produce `#error "arity error: 'println' takes 1 arguments, but called with 2"`, so the compiler is working and the name is simply uncovered. | +| 12 | "the query reports \"takes 5 arguments, called with 1\"" | `0047` | `9cc6040` | **REPRODUCED verbatim** — `arity error: '__http_do_map_to_file' takes 5 arguments, called with 1`, exit 1 | +| 13 | "503 signatures" | `0011`, `0012`, `0050` | `9cc6040` | **DIVERGED** — the shipped checker *does* print `503`, and `arity_query.sh` asserts that literal, but the header declares **500** `el_val_t` functions. The 503 is a parser artifact. See below. | +| 14 | "versus 300 entries maintained by hand" | `0011` | `9cc6040^` | **REPRODUCED** — 300 | +| 15 | Defect 1: "60 of 500 decls carry the prefix" | `0012` | `9cc6040` | **REPRODUCED exactly** — **60** of the **500** correctly-parsed declarations begin `__`. (Note this sentence's "500" contradicts the same commit message's "503" four lines earlier; 500 is the true figure.) | +| 16 | Defect 1: "One rule covers all 60" | `0048` | `9cc6040` | **REPRODUCED** — `arity.sh:42` is a single `__$callee` fallback lookup; all 60 resolve through it | +| 17 | Defect 2: "Multi-line declarations parsed as zero params, so the checker reported 'takes 0' for a function taking 5" | `0048` | `9cc6040` | **REPRODUCED** — a line-based (pre-fix) parse yields **91** zero-parameter declarations where only **82** are genuinely zero-parameter; `__http_do_map_to_file` is one of the multi-line cases and the fixed checker reports its true arity, 5 (`0047`) | +| 18 | Defect 3: "Fixing (2) by joining lines dropped 500 signatures to 334" | `0048` | `9cc6040` | **REPRODUCED exactly** — reconstructing the two intermediate parsers gives **500** (anchored, line-based, no join) → **334** (anchored, joined, comments not stripped). Both numbers land on the nose. | +| 19 | Defect 3: "Comments are stripped first now." | `0048` | `9cc6040` | **REPRODUCED but INCOMPLETE** — `arity.sh:21` does strip `//` comments before joining. Block comments are *not* stripped first and are not stripped correctly at all. This is the unconfessed fourth defect. See below. | +| 20 | "98/98 native" | `0006` | `9cc6040` | **REPRODUCED** — `98 tests, 98 passed, 0 failed, 239 assertions in 5.620ms` | +| 21 | "5/5 arity_query.sh" | `0008` | `9cc6040` | **REPRODUCED** — `5 assertions, 5 passed, 0 failed`, exit 0 | +| 22 | "fixpoint ok" | `0013` | `9cc6040` | **REPRODUCED** — gen2 == gen3, identical sha256 `5c6bb297a95c…`. gen1 (the committed `dist/platform/elc`) differs from gen2, which is expected and is not the fixpoint. | +| 23 | `d9e301b` "land arity-from-header: the runtime declares its own surface" | `0002`, `0010` | `d9e301b` | **REPRODUCED (identity)** — subject matches; codegen.el is 4512 lines, unchanged from `9cc6040` | + +Totals: **23 assertions — 19 REPRODUCED, 4 DIVERGED, 0 NOT-REPRODUCIBLE, 0 NOT-CAPTURED.** +(Claim 19 is counted as REPRODUCED because the sentence as written is true; the finding +it understates is recorded separately below.) + +--- + +## Divergence detail + +### D1 — claim 13 and 19: the checker mis-parses 25 of the header's declarations + +This is the substantive finding of the re-run. + +`arity.sh` strips block comments with + +``` +sed 's://.*::' "$HDR" | tr '\n' ' ' | sed 's:/\*[^*]*\*/: :g; s/;/;\n/g' +``` + +`[^*]*` cannot cross an interior `*`, so a **multi-line** block comment — every one of +which uses ` * ` continuation markers in this header — survives the strip. Its prose +then sits inside the declaration record, and because the awk regex is *unanchored* and +`match(line, /\(.*\)/)` is greedy, the parameter list is taken from the first `(` in the +leftover comment to the last `)` in the record. Concretely (`0011`, `0050`): + +| declaration | header source | correct arity | arity.sh reports | +|---|---|---|---| +| `append` | `el_val_t append(el_val_t list, el_val_t elem);` preceded by a comment containing `` `obj.method(args)` `` and `` `method(obj, args)` `` | 2 | **4** | +| `fs_size` | `el_val_t fs_size(el_val_t path);` preceded by a comment containing `stat()` and `str_len(fs_read(path))` | 1 | **2** | +| `stdout_to_file` | preceded by a comment containing `(compiler.el, codegen.el)` | 1 | **2** | +| `__mutex_new` | preceded by a comment containing `(which the C11 ABI mis-truncates el_val_t)` | 0 | **1** | +| `el_arena_push` | preceded by a comment containing `el_arena_pop(mark)` | 0 | **1** | + +In total, comparing the shipped parser against a correct one name by name (`0050` — +`/tmp/parse10.py`, a real comment/string state machine with top-level-comma counting): + +- **25 declarations get the wrong parameter count**, including four that are reported as + variadic (`aead_encrypt`, `el_html_sanitize`, `http_response`, `realizer_register`) and + are therefore *skipped entirely* by the checker; +- **7 names are invented out of comment prose** — `handler`, `string`, `strings`, + `holding`, `pointer`, `slot`, `el_from_float`; +- **6 real declarations are missed** — `earth_calendar`, `el_sha256_bytes_n`, + `fs_write_bytes`, `http_post_to_file`, `local_date`, `sha256_hex`; +- two junk names appear with two different arities each, which is where the count + **503** comes from: 501 distinct names, 2 of them double-counted. + +**The header declares 500 `el_val_t` functions.** Two independent methods agree on 500: +the correct parser, and the anchored line-based parse — and the record's own defect‑1 +sentence says "500 decls". So the commit message contains both the right number (500) and +the instrument's wrong number (503), four lines apart, and `tests/integration/arity_query.sh` +freezes the wrong one into an assertion (`chk "signatures parsed from the header" "503 signatures"`). + +The fix in defect 3 also silently dropped the `^` anchor from the awk regex. That anchor +is what had been keeping comment prose out; without it the checker matches `el_val_t (` +anywhere inside a record. Stripping comments first was the right idea, but the strip is +incomplete and the anchor removal papered over it. + +### D2 — claim 5, restated: the shipped checker manufactures five false drifts + +Run P2 through `arity.sh`'s own parser and it reports **5 mismatches** — `__mutex_new`, +`append`, `el_arena_push`, `fs_size`, `stdout_to_file` (`0011`). Every one of the five is +the parser being wrong, not the table. The hand table's arity is correct in all five cases. + +This means the record's P2 result — **zero drift** — is *right*, and would have been +reported as "five drifts" by the tool the cycle shipped, had P2 been evaluated with it. +It evidently was not. **`0012` is the artifact that backs P2; `0011` is retained to show +what the shipped instrument would have said.** + +### D3 — claim 8: the parent line count + +| | claimed | observed | +|---|---|---| +| codegen.el at `9cc6040^` | 4903 | **4896** | +| codegen.el at `9cc6040` | 4512 | **4512** | +| 4661 − 4512 | 149 | **149** | + +The parent is 7 lines short of the claim. The commit's own diffstat corroborates 4896: +codegen.el takes −390/+6 in this commit, and 4896 − 390 + 6 = 4512 exactly. 4903 − 384 +would be 4519. + +Related reconciliation the parent agent asked for: cycle 09 records codegen.el as **4881** +at `c2d9596`; observed **4896** (`0010`, `0048`). Only one commit separates `c2d9596` from +`9cc6040^` (`29f78f9`) and it does not touch codegen.el, so the two are necessarily the same +file — and they are, at 4896. Cycle 09's 4881 is low by 15 and cycle 10's 4903 is high by 7, +against the same file content. + +The "4661 baseline" is solid and is now pinned: codegen.el is exactly 4661 lines at +`45325f7 singleton: guard the state, not the program's name` (2026-08-16), the commit +immediately before `dcaa77d` where the v1 series begins (`0048` walks 40 commits of +codegen.el history with line counts). + +### D4 — claim 10: the coverage gap is far larger than 110 + +| source | figure | +|---|---| +| commit message | "110 functions the runtime declares had no entry" | +| `arity.sh`'s own header comment (same commit) | "199 functions … had NO entry … 40% incomplete" | +| **observed, strict direct-name match** | **257** | +| **observed, applying the `__`-prefix rule** | **256** | + +The record contradicts itself (110 vs 199) inside a single commit, and neither figure is +reachable. The accounting that *does* close is: + +- table = 300 entries = 243 shared with the header + **57 names the header does not declare** + (test-registry shims `__el_reg_*`, El-level aliases like `println`/`print`/`exit_program`, + and the `__engram_*` C-name forms — full list in `0012`); +- header = 500 declarations = 243 shared + **257 with no table entry**. + +199 is close to 500 − 300 = 200 and to "40% of 500", which is probably how it was derived — +but that subtracts the whole table, 57 of whose entries are not header functions at all. +110 has no derivation over any population I could construct (`0049` enumerates the +candidates). The *direction* of the record's argument is unaffected and in fact +understated: the hand table left **more** than twice as many runtime functions +undiagnosable as the commit message claims. + +--- + +## Findings the record does not claim + +1. **Orphaned prose.** `9cc6040` deletes `builtin_arity`, `arity_check_call`, + `arity_record_violation` and `emit_arity_violations` but leaves ~22 lines of their + documentation behind in codegen.el (lines 2539–2560), including "Strategy: a small + static table mirrors el_runtime.h" and "…which `emit_arity_violations()` turns into + `#error` directives" — describing machinery that no longer exists (`0049`). The only + surviving mention of any of the four symbols is that stale comment. +2. **The hand table lists five names twice** — `__thread_create`, `__thread_join`, + `__mutex_new`, `__mutex_lock`, `__mutex_unlock` — with identical arities both times + (305 `str_eq` lines, 300 distinct names, `0011`). Harmless, and a small illustration + of the maintenance cost the cycle is arguing about. +3. **The relations file records the same call twice** (`main calls __http_do_map_to_file` + / `__http_do_map_to_file calls arity:1`, each duplicated, `0047`). `arity.sh` `sort -u`s + the input so it does not double-report, but the emitter is not deduplicating. + +## Measurement defects in this re-run, recorded rather than removed + +1. **`0007-selfhost-fixpoint`, exit 1, superseded.** Captured with the recipe's original + command, which compares gen1 (output of the committed `dist/platform/elc`) against gen2. + That is not the fixpoint; the committed binary at `9cc6040` predates the seam/thunk + emission, so gen1 ≠ gen2 necessarily (10166 vs 13058 lines of C — `0050`). The correct check, + gen2 == gen3, is `0013` (and `0009`, taken first under the name + `selfhost-fixpoint-gen3-gen4` before the recipe's naming was corrected — same + measurement, same result). Do not cite `0007` as a fixpoint failure. +2. **`0020-old-compiler-arity-probe-at-parent`, exit 1, superseded.** The script used + `set -e`, and `grep -c 'arity error'` returning `0` exits 1, so the run aborted after + printing the number it was there to get. The number it did capture (`0`) agrees with the + REDO. Full both-sides measurement is `0047-REDO-arity-coverage-probe-both-sides`. +3. **Manifest numbering has gaps** (0013 → 0020 → 0047). `capture.sh` derives the next index + from `grep -c . MANIFEST.tsv`, and two of my captures passed a multi-line command string, + which `capture.sh` writes verbatim into the TSV's last column — inflating the line count. + No artifact is lost or altered; `verify-manifest.sh` reports 0 altered, 0 missing across + all cycles. Later cycles should pass single-line commands, or scripts, to `capture.sh`. +4. **The probe program is reconstructed.** `fn main() { __http_do_map_to_file("a") }` is not + in the tree; it is an input inferred from the record's sentence. The evidence is the + captured *output* of running it at both commits (`0047`), not the program. +5. **The parent tree is a `git archive` extraction, not a worktree.** Provenance on `0020` + and `0047` therefore stamps `9cc6040` (the CWD's HEAD) while the compiler under test was + built from `9cc6040^`. The `.cmd` file records the `git archive 9cc6040^` line, and the + artifact prints the resolved parent SHA `29f78f9…` and the parent's codegen line count as + a self-check. +6. **The correct header parser is mine, not the project's.** `/tmp/parse10.py` — comment/ + string state machine, top-level-comma parameter counting — is the control that produces + the 500/243/0-drift figures. It is cross-checked against a completely different method + (anchored line-based awk), which independently gives 500, and against the record's own + "500 decls". It is not in the repo; the pipeline that used it is recorded in `0012`. + +## Supporting artifacts + +| artifact | what it backs | +|---|---| +| `0001`–`0004` | commit identity for `9cc6040` and `d9e301b`, diffstat, the single intervening commit | +| `0005` | stage2 build, `BUILD_OK` | +| `0006` | 98/98 native compiler tests | +| `0008` | 5/5 `arity_query.sh` | +| `0009`, `0013` | fixpoint gen2 == gen3 | +| `0010` | codegen.el line counts at parent / commit / land / `c2d9596`, and 4661 − 4512 | +| `0011` | builtin_arity size and entries; the shipped checker's parse and its 5 false drifts | +| `0012` | the same questions against a correct header parse — 500 / 243 / 0 drift / 60 | +| `0047` | both sides of the `__http_do_map_to_file` measurement | +| `0048` | the checker's three confessed defects reconstructed (500 → 334 → 503), P3/P4 mechanism, 40 commits of codegen.el history | +| `0049` | coverage-gap arithmetic, the full uncovered list, the orphaned comments | +| `0050` | shipped parser vs correct parser, name by name: 25 wrong counts, 7 invented names, 6 missed declarations, gen1/gen2/gen3 sizes | diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.cmd new file mode 100644 index 0000000..696a385 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && for s in d9e301b d2d89fc e01e079; do printf "%s\t%s\t%s\n" "$s" "$(git show $s:lang/el-compiler/src/codegen.el | wc -l | tr -d " ")" "$(git log -1 --format=%s $s)"; done diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.err b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.out b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.out new file mode 100644 index 0000000..7babd7c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.out @@ -0,0 +1,3 @@ +d9e301b 4512 land arity-from-header: the runtime declares its own surface +d2d89fc 4537 EXPERIMENT: temporal types as data — and the pass that GREW the compiler +e01e079 4537 land temporal signatures as data: the type table leaves, the dispatch stays diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.prov b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.prov new file mode 100644 index 0000000..156656a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:39Z +exit 0 +ms 45 +sha256_out fba75c9b726ef34dc5d1d64385e968fe7782cf0b479cce0102b546841c2461bf +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.rc b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.cmd new file mode 100644 index 0000000..9395672 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && echo "[A] real entries in signatures.rel @d2d89fc (comments excluded):"; git show d2d89fc:lang/tools/check/signatures.rel | grep -vE "^#" | grep -c " returns "; echo "[B] naive grep -c that also counts comment lines:"; git show d2d89fc:lang/tools/check/signatures.rel | grep -c " returns "; echo "[C] temporal names DELETED from codegen.el by d2d89fc:"; git diff d9e301b d2d89fc -- lang/el-compiler/src/codegen.el | grep -cE "^-.*str_eq\(name," diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.err b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.out b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.out new file mode 100644 index 0000000..fbdbeb7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.out @@ -0,0 +1,6 @@ +[A] real entries in signatures.rel @d2d89fc (comments excluded): +17 +[B] naive grep -c that also counts comment lines: +19 +[C] temporal names DELETED from codegen.el by d2d89fc: +17 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.prov b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.prov new file mode 100644 index 0000000..1b7d203 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:40Z +exit 0 +ms 27 +sha256_out 7a706b6424a61808c2c3c576b0d4a3d5055b226649b8352b42606473c20bdae4 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.rc b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.cmd new file mode 100644 index 0000000..3fa6e57 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && for s in d9e301b d2d89fc; do printf "%s wc-l=%s awk-NR=%s last-byte=%s\n" "$s" "$(git show $s:lang/el-compiler/src/codegen.el | wc -l | tr -d " ")" "$(git show $s:lang/el-compiler/src/codegen.el | awk "END{print NR}")" "$(git show $s:lang/el-compiler/src/codegen.el | tail -c1 | od -An -c | tr -d " ")"; done diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.err b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.out b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.out new file mode 100644 index 0000000..b46d566 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.out @@ -0,0 +1,2 @@ +d9e301b wc-l=4512 awk-NR=4512 last-byte=\n +d2d89fc wc-l=4537 awk-NR=4537 last-byte=\n diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.prov b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.prov new file mode 100644 index 0000000..f5bffd1 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:59Z +exit 0 +ms 62 +sha256_out 0ea6668cc6c238f12cc21a510296f26a3ae9b3b625392c5f0ae368dcc721e622 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.rc b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/CLAIMS.md b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/CLAIMS.md new file mode 100644 index 0000000..8033063 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/CLAIMS.md @@ -0,0 +1,104 @@ +# CLAIMS — cycle 11, one type erases the return + +Source doc: `docs/v1/experiments/cycles/11-one-type-erases-the-return.md` +Classified **REFUTES** in `00-INDEX.md` — the only cycle so classified in v1. + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `d9e301bfa` | land arity-from-header: the runtime declares its own surface | +| experiment (system under test) | `d2d89fcb60454ef88703a7aaddacd2d979f615fc` | EXPERIMENT: temporal types as data — and the pass that GREW the compiler | +| land (merge) | `e01e079bdab97242f508daa9af7e8648ebd6760b` | land temporal signatures as data: the type table leaves, the dispatch stays | + +`e01e079` is the merge of `d2d89fc` into `d9e301b`; `codegen.el` is byte-identical +at `d2d89fc` and `e01e079` (artifact `0012`). + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | P3: codegen went **4513 → 4537**, it GREW by **24** lines | `0012-codegen-lines-P3-clean-tree.out`, `0014-codegen-newline-termination-clean-tree.out` | measured over `d9e301b`/`d2d89fc` | **DIVERGED** | +| A2 | P5: the moved table is **19 names** | `0013-signatures-name-recount-P5-clean-tree.out`, `0011-temporal-name-recount-P5.out` | `d2d89fc` | **DIVERGED** | +| A3 | P5: no type propagation — name tracking plus a hardcoded list, living in **two functions** | `0011-temporal-name-recount-P5.out` | `d9e301b` | REPRODUCED | +| A4 | 98/98 native | `0006-native-suite.out` | `d2d89fc` | REPRODUCED | +| A5 | 4/4 `temporal_signatures.sh` | `0007-temporal-signatures-harness.out` | `d2d89fc` | REPRODUCED | +| A6 | fixpoint ok | `0005-fixpoint-gen2-eq-gen3.out` | `d2d89fc` | REPRODUCED | +| A7 | INCOMPLETE (stated not hidden): violations still emit `TIME_TYPE_ERROR` inline from the emitter | `0008-time-type-error-still-inline-in-codegen.out` | `d2d89fc` | REPRODUCED | +| A8 | `el_runtime.h` declares every builtin as returning `el_val_t` | `0009-el-runtime-h-all-return-el-val-t.out`, `0010-runtime-h-non-el-val-t-decls.out` | `d2d89fc` | REPRODUCED (qualified) | +| A9 | P1/P2/P4: the block conflates dispatch with adjudication; adjudication can move, dispatch cannot; the rules are affine algebra closed by construction | — | — | **NOT-CAPTURED** | +| A10 | "adding a 20th temporal builtin is now a one-line edit to `signatures.rel`" | — | — | **NOT-CAPTURED** | +| A11 | the compiler builds at `d2d89fc` | `0004-build-gen1-d2d89fc.out` | `d2d89fc` | REPRODUCED | + +## The two divergences, in full + +### A1 — the growth number is 25, not 24, and the starting point is wrong + +``` +d9e301b 4512 land arity-from-header: the runtime declares its own surface +d2d89fc 4537 EXPERIMENT: temporal types as data — and the pass that GREW the compiler +e01e079 4537 land temporal signatures as data: the type table leaves, the dispatch stays +``` + +Claimed `4513 → 4537` (+24). Measured `4512 → 4537` (**+25**). + +Both files are newline-terminated, so `wc -l` and `awk END{print NR}` agree at +4512 and 4537 respectively (`0014`) — the discrepancy is not a counting +convention. + +The before-value is independently contradicted by the record itself: cycle 10 +(`10-a-second-copy-of-the-header.md`, P5) states codegen landed at **4512**, and +`00-INDEX.md` repeats 4512 for cycle 10. Cycle 11 then opens at 4513. One of the +two adjacent entries in the same record is wrong about the same number, and the +measurement says it is cycle 11's. + +**The classification is not affected.** The direction is what the REFUTES verdict +rests on, and the direction reproduces and is in fact stronger: the compiler grew +by one more line than the record claims. + +### A2 — "19 names" is a grep artifact; the real count is 17 + +``` +[A] real entries in signatures.rel @d2d89fc (comments excluded): 17 +[B] naive grep -c that also counts comment lines: 19 +[C] temporal names DELETED from codegen.el by d2d89fc: 17 +``` + +`signatures.rel` at `d2d89fc` holds **17** ` returns ` entries +(7 Instant, 10 Duration). `d2d89fc` deletes exactly **17** `if str_eq(name, …)` +lines from `codegen.el`. Two comment lines in the file's header also contain the +word `returns`; counting them gives exactly the claimed 19. + +The number 19 is reproducible only as the output of a measurement that does not +exclude comments. It survives into the source: the loader's own comment at +`codegen.el:1986` says "Previously 19 hardcoded names across two functions". The +*two functions* part is correct — `is_instant_call` (`d9e301b:2013`) and +`is_duration_call` (`d9e301b:2029`). + +This does not change the cycle's conclusion either. Moving 17 names cost 25 +lines; the point that "a generic loader is larger than the enumeration it +replaces" holds a fortiori. + +## Qualification on A8 + +`el_runtime.h` at `d2d89fc`: **500** declarations return `el_val_t`; **27** do +not. All 27 are listed in `0010`. Twenty-five are `void` (they return no value +at all — `println`, `el_retain`, `http_serve`, …), one is `size_t +el_utf8_safe_len(const char*, size_t)` and one is `int +engram_wal_enabled(void)`; the last two take C types, not `el_val_t`, and are +internal helpers rather than El builtins. No value-returning El builtin declares +anything other than `el_val_t`, so the claim as it bears on the argument — the C +boundary cannot say `now()` returns an Instant — is REPRODUCED. + +## Provenance notes + +* Artifacts `0001`–`0003` were captured with the working directory set to the + shared main checkout, which other agents were committing to concurrently, so + `verify-manifest.sh` flags them DIRTY-TREE. They are `git show`-based + measurements: the data is pinned by the SHA argument in the recorded command, + not by the working tree. Every one was re-run from a clean worktree + (`0012`–`0014`); `0001` and `0012` hash **identically** (`fba75c9b726e`). + Cite the `-clean-tree` artifacts. +* Everything else was captured from a dedicated worktree at `d2d89fc` + (`/tmp/rerun-v1b-11`), with `capture.sh` invoked by absolute path from inside + it, so the recorded commit is the system under test's. diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.cmd new file mode 100644 index 0000000..02b37b9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && for s in d9e301b d2d89fc e01e079 e8e25a0 50425f3 cbef1c1 505e5e7; do printf "%s\t%s\t%s\n" "$s" "$(git show $s:lang/el-compiler/src/codegen.el | wc -l | tr -d " ")" "$(git log -1 --format=%s $s)"; done diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.err b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.out b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.out new file mode 100644 index 0000000..6e76e30 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.out @@ -0,0 +1,7 @@ +d9e301b 4512 land arity-from-header: the runtime declares its own surface +d2d89fc 4537 EXPERIMENT: temporal types as data — and the pass that GREW the compiler +e01e079 4537 land temporal signatures as data: the type table leaves, the dispatch stays +e8e25a0 4506 EXPERIMENT: temporal adjudication moves out; the placeholder stays +50425f3 4506 land temporal adjudication as a query: the emitter records, the rules are data +cbef1c1 4478 EXPERIMENT: Int return types as data — and the bug that fell out +505e5e7 4478 land int signatures, and repair a silent miscompilation they exposed diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.prov b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.prov new file mode 100644 index 0000000..1ae4a41 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:59Z +exit 0 +ms 99 +sha256_out a16258af65cdf8153c89e11ce535fefa9a9fe22ee9698daa386b3f5b9be07c8c +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.rc b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.cmd new file mode 100644 index 0000000..e690ec2 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && echo "real rules (comments excluded):"; git show e8e25a0:lang/tools/check/temporal.rel | grep -vE "^#" | grep -c " means "; echo "naive grep -c:"; git show e8e25a0:lang/tools/check/temporal.rel | grep -c " means " diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.err b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.out b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.out new file mode 100644 index 0000000..a250d94 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.out @@ -0,0 +1,4 @@ +real rules (comments excluded): +6 +naive grep -c: +8 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.prov b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.prov new file mode 100644 index 0000000..66b8170 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:59Z +exit 0 +ms 20 +sha256_out 5ed2c69825b39c9d46cf1d390403f3230e6297eff41d3dc799130000d89cf17c +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.rc b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/CLAIMS.md b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/CLAIMS.md new file mode 100644 index 0000000..954a650 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/CLAIMS.md @@ -0,0 +1,97 @@ +# CLAIMS — cycle 12, judgment lives with knowledge + +Source doc: `docs/v1/experiments/cycles/12-judgment-lives-with-knowledge.md` +Classified **BOUNDS** in `00-INDEX.md`. + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `e01e079bdab97242f508daa9af7e8648ebd6760b` | land temporal signatures as data | +| experiment (system under test) | `e8e25a07b4decfe4a5a0799a212262dffd73edc9` | EXPERIMENT: temporal adjudication moves out; the placeholder stays | +| land (merge) | `50425f375d0d374a9a08c190ea0c9e5d7f5e1989` | land temporal adjudication as a query | + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | P1: codegen can emit operand-type relations — literally `main calls temporal:instant_plus_instant` | `0007-P1-relation-recorded.out` | `e8e25a0` | REPRODUCED (verbatim) | +| A2 | P2: the affine rules are a small closed set as data — **6 rules** | `0012-temporal-rel-rule-recount-clean-tree.out` | `e8e25a0` | REPRODUCED | +| A3 | P3: violations still caught at build time, `exit=1` | `0009-P3-violation-exits-1.out` | `e8e25a0` | REPRODUCED | +| A4 | P4: the reporter leaves codegen — **4538 → 4507** | `0011-codegen-lines-P4-clean-tree.out` | `e01e079`/`e8e25a0` | **DIVERGED** | +| A5 | P4 (mechanism): the message wording leaves the emitter | `0010-P4-reporter-left-codegen.out` | `e01e079`→`e8e25a0` | REPRODUCED | +| A6 | P5: the `TIME_TYPE_ERROR` placeholder must STAY | `0008-P5-placeholder-still-emitted.out` | `e8e25a0` | REPRODUCED | +| A7 | 98/98 native | `0005-native-suite.out` | `e8e25a0` | REPRODUCED | +| A8 | 6/6 `temporal_query.sh` | `0006-temporal-query-harness-P2P3.out` | `e8e25a0` | REPRODUCED | +| A9 | fixpoint ok | `0004-fixpoint-gen2-eq-gen3.out` | `e8e25a0` | REPRODUCED | +| A10 | a defect in the author's own checker: aligned columns vs an awk assuming a single space, so the rule key was left prefixed on the message | — | — | **NOT-CAPTURED** | +| A11 | the rules are closed because there are only two kinds of thing (point / displacement) | — | — | **NOT-CAPTURED** | +| A12 | the compiler builds at `e8e25a0` | `0003-build-gen1-e8e25a0.out` | `e8e25a0` | REPRODUCED | + +## The divergence, in full + +### A4 — both endpoints are one line high; the delta is exact + +``` +d9e301b 4512 +d2d89fc 4537 +e01e079 4537 <- cycle 12's before-state +e8e25a0 4506 <- cycle 12's after-state +50425f3 4506 +``` + +Claimed `4538 → 4507` (−31). Measured `4537 → 4506` (−31). + +The **delta is exactly right**. Both endpoints are exactly one line too high — +the same +1 offset seen in cycle 11's before-value. Two adjacent cycles reporting +a consistent +1 on the same file is a property of the instrument used at the +time, not of two independent slips. The measured chain is internally consistent: +cycle 11's landed value (4537) is cycle 12's starting value (4537), whereas the +prose chain is not (cycle 11 lands 4537, cycle 12 opens 4538). + +The conclusion is unaffected: 31 lines of reporter left codegen, as claimed. + +## Corroboration of A1 and A5 + +The emitter records, and the wording is gone from it: + +``` +main calls temporal:instant_plus_instant (0007) + +is-not-allowed strings in codegen.el @ e01e079 (before): 7 +is-not-allowed strings in codegen.el @ e8e25a0 (after): 0 (0010) +``` + +and the placeholder is still emitted for the same program (`0008`): + +``` +10: el_val_t c = 0 /* TIME_TYPE_ERROR: Instant + Instant */; +``` + +with the judgment now coming from the data file (`0009`): + +``` +temporal type error in main: Instant + Instant is not allowed — a point plus a +point is not a point. Subtract them for a Duration, or add a Duration. +checker-exit=1 +``` + +That triple is P5's boundary claim demonstrated end to end: what moved is the +judgment and the wording; what could not move is the fact that *something* must +be written. + +## Note on the rule count + +`0012` shows the same comment-line artifact as cycle 11's "19 names": a naive +`grep -c " means "` over `temporal.rel` returns **8**; excluding comment lines +gives **6**. Here the record states 6 — the correct figure. The claim is right +and the naive count is the one that would have been wrong. + +## Provenance notes + +Artifacts `0001` and `0002` carry a DIRTY-TREE flag for the same reason as cycle +11 (`git show` measurements run from the shared main checkout while other agents +were committing). Both were re-run from a clean worktree as `0011` and `0012`; +`0001` and `0011` hash **identically** (`a16258af65cd`). Cite the `-clean-tree` +artifacts. All behavioural captures come from `/tmp/rerun-v1b-12`, a dedicated +worktree at `e8e25a0`. diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.cmd b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.cmd new file mode 100644 index 0000000..c202a9e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/ghead.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elchead /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/ghead.c $SRCS $LF && echo BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.err b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.err new file mode 100644 index 0000000..72603f0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14480:1: warning: '/*' within block comment [-Wcomment] + 14480 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.out b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.out new file mode 100644 index 0000000..1c5c36b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.out @@ -0,0 +1 @@ +BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.prov b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.prov new file mode 100644 index 0000000..14852d5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:46:26Z +exit 0 +ms 3940 +sha256_out 68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 +sha256_err d61e9619f81ab91d682b0696b72052bf10af314692b2801d80d1f4c515eb25fc diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.rc b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.cmd b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.cmd new file mode 100644 index 0000000..d60b10c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elchead /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/p.el diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.err b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.out b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.out new file mode 100644 index 0000000..4cf7743 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.out @@ -0,0 +1,14 @@ +#include +#include +#include "el_runtime.h" + + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + el_val_t a = str_len(EL_STR("hello")); + el_val_t b = str_len(EL_STR("hi")); + el_val_t c = (a + b); + println(int_to_str(c)); + return 0; +} + diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.prov b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.prov new file mode 100644 index 0000000..0488374 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:46:34Z +exit 0 +ms 181 +sha256_out c1c17acaa59c49f0613171adf09295f29bdd2b3f4b4b21221ad8cebe72716ef1 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.rc b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.cmd b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.cmd new file mode 100644 index 0000000..899606c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head13 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head13.c $SRCS $LF && echo CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.err b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.err new file mode 100644 index 0000000..72603f0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14480:1: warning: '/*' within block comment [-Wcomment] + 14480 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.out b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.out new file mode 100644 index 0000000..0c50dfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.out @@ -0,0 +1 @@ +CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.prov b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.prov new file mode 100644 index 0000000..cacc032 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:46:38Z +exit 0 +ms 3235 +sha256_out a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 +sha256_err d61e9619f81ab91d682b0696b72052bf10af314692b2801d80d1f4c515eb25fc diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.rc b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.cmd b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.cmd new file mode 100644 index 0000000..da094aa --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head13 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.err b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.out b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.out new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.out @@ -0,0 +1 @@ +7 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.prov b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.prov new file mode 100644 index 0000000..db9ecd2 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:46:38Z +exit 0 +ms 180 +sha256_out 10159baf262b43a92d95db59dae1f72c645127301661e0a3ce4e38b295a97c58 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.rc b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.cmd new file mode 100644 index 0000000..ff2c9bd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && for s in 50425f3 cbef1c1 505e5e7; do printf "%s\t%s\t%s\n" "$s" "$(git show $s:lang/el-compiler/src/codegen.el | wc -l | tr -d " ")" "$(git log -1 --format=%s $s)"; done; echo; echo "lines the repair hunk added to codegen.el in cbef1c1:"; git diff 50425f3 cbef1c1 -- lang/el-compiler/src/codegen.el | grep -cE "^\+" diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.err b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.out b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.out new file mode 100644 index 0000000..74c2f96 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.out @@ -0,0 +1,6 @@ +50425f3 4506 land temporal adjudication as a query: the emitter records, the rules are data +cbef1c1 4478 EXPERIMENT: Int return types as data — and the bug that fell out +505e5e7 4478 land int signatures, and repair a silent miscompilation they exposed + +lines the repair hunk added to codegen.el in cbef1c1: +13 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.prov b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.prov new file mode 100644 index 0000000..b92331e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:59Z +exit 0 +ms 55 +sha256_out bcad61ceed8fb20b3e82531e4cf2312fdcdb6d984a8920ad18f82ad902eae222 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.rc b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.cmd new file mode 100644 index 0000000..8ec29bd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && echo "hardcoded names in is_int_call @50425f3:"; git diff 50425f3 cbef1c1 -- lang/el-compiler/src/codegen.el | grep -cE "^-.*if str_eq\(name, "; echo "Int entries added to signatures.rel by cbef1c1:"; git diff 50425f3 cbef1c1 -- lang/tools/check/signatures.rel | grep -cE "^\+.* returns Int" diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.err b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.out b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.out new file mode 100644 index 0000000..93639be --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.out @@ -0,0 +1,4 @@ +hardcoded names in is_int_call @50425f3: +35 +Int entries added to signatures.rel by cbef1c1: +35 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.prov b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.prov new file mode 100644 index 0000000..520270a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:59Z +exit 0 +ms 20 +sha256_out e208d2eee5449834f4b13f190cbe2d8fb89800b1268811cc825835aab28389f2 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.rc b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/CLAIMS.md b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/CLAIMS.md new file mode 100644 index 0000000..f90a656 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/CLAIMS.md @@ -0,0 +1,153 @@ +# CLAIMS — cycle 13, thirty five return types + +Source doc: `docs/v1/experiments/cycles/13-thirty-five-return-types.md` +Classified **SUPPORTS** in `00-INDEX.md`. + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `50425f375d0d374a9a08c190ea0c9e5d7f5e1989` | land temporal adjudication as a query | +| experiment (system under test) | `cbef1c1ebb77c34f40ac1fec84f7daf952f6d29e` | EXPERIMENT: Int return types as data — and the bug that fell out | +| land (merge) | `505e5e74d9b4acbf810c3f5c9b06e558ed2fec31` | land int signatures, and repair a silent miscompilation they exposed | +| current HEAD at re-run time | `a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7` | instrument build log: every failure, with the artifact | + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | P1: `is_int_call`'s **35** hardcoded names move to data | `0026-is-int-call-recount-clean-tree.out` | `50425f3`→`cbef1c1` | REPRODUCED (exact) | +| A2 | P4: codegen shrinks ~40 lines, **4507 → 4469** | `0025-codegen-lines-P4-clean-tree.out` | `50425f3`/`cbef1c1` | **DIVERGED** | +| A3 | P6: `let a = str_len(…); let b = str_len(…); a + b` lowers to `el_str_concat` on two integers | `0004`, `0005`, `0015-pre-printable-emit-c.out` | `50425f3` | REPRODUCED (exact) | +| A4 | P6: it "compiled clean, ran, and printed NOTHING where it should print 7. No error at any layer." | `0006`, `0007-pre-program-run.out`, `0017`, `0018-pre-printable-run.out` | `50425f3` | **DIVERGED** | +| A5 | P6: the repair fixes it — the program prints 7 | `0016-post-printable-emit-c.out`, `0020-post-printable-run.out` | `cbef1c1` | REPRODUCED | +| A6 | the repair is "three lines" | `0025-codegen-lines-P4-clean-tree.out` | `50425f3`→`cbef1c1` | **DIVERGED** | +| A7 | 98/98 native + 2 new | — | — | **NOT-CAPTURED** (see note) | +| A8 | 31/31 integration | — | — | **NOT-CAPTURED** (see note) | +| A9 | fixpoint ok | — | — | **NOT-CAPTURED** (see note) | +| A10 | P5: the design docs' "hardcoded int-name set" characterisation is wrong — `__int_names` is populated from `param["type"] == "Int"` | — | — | **NOT-CAPTURED** | +| A11 | P2/P3: `is_int_name` stays (annotation propagation); the dispatch stays (emission) | — | — | **NOT-CAPTURED** | +| A12 | **NEW — not in the record.** The repair is working-directory dependent and silently reverts to the defect | `0009`+`0011` vs `0012`+`0014` | `cbef1c1` | **NEW FINDING** | +| A13 | the defect at current HEAD | `0022`, `0024-head-program-run-TODAY.out` | `a0cc95e3` | fixed — prints `7`, exit 0 | + +## The divergences, in full + +### A4 — it did not "run". It segfaulted. + +Fixture `fixtures/str_len_add.el`, compiled by the compiler built from +`50425f3`: + +```c +el_val_t a = str_len(EL_STR("hello")); +el_val_t b = str_len(EL_STR("hi")); +el_val_t c = el_str_concat(a, b); <- the miscompilation, exactly as recorded +println(c); +``` + +`cc` exits **0** with zero errors (`0006`, `0017`) — "compiled clean" holds. The +program then exits **139, SIGSEGV** (`0007`, `0018`), stdout **0 bytes**. + +The record says the program "ran, and printed NOTHING". It did not run: it died +on a signal. "Printed nothing" is true and "no error at any layer" is false — +the operating system raised one. `el_str_concat(5, 2)` dereferences 5 as a +`char*`. + +This is the same shape as measurement defect 4, recorded in cycle 19 of this very +document set: an exit code that was never looked at. The record understates the +severity of its own headline finding. + +Both variants were run, so the segfault cannot be blamed on the observation +method: + +* `println(c)` directly — segfaults in `println` as well as `el_str_concat`; +* `println(int_to_str(c))` (`fixtures/str_len_add_printable.el`) — isolates the + arithmetic. At `50425f3`: exit 139, no output. At `cbef1c1`: prints `7`, + exit 0 (`0020`). + +The claim's *substance* — a silent miscompilation with no diagnostic at any +compiler layer — is REPRODUCED and is worse than described. + +### A2 / A6 — the shrink is 28 lines, not 38, because the repair is in the same commit + +``` +50425f3 4506 +cbef1c1 4478 +505e5e7 4478 +``` + +Claimed `4507 → 4469` (−38, "~40"). Measured `4506 → 4478` (−28). + +The before-value carries the same +1 offset as cycles 11 and 12. The +after-value is 9 lines apart, which is not an offset. The cause is in the diff: +`cbef1c1` both moves the table out **and** lands the repair, and the repair hunk +adds **13** lines to `codegen.el` (`0025`) — a 4-line guard plus a 9-line +comment, not "three lines": + +```el ++ // UNANNOTATED let: take the type from what the initialiser RETURNS. ++ // …seven more comment lines… ++ if str_eq(ltype, "") { ++ if is_int_expr(val) { add_int_name(name) } ++ } +``` + +`4469 + 13 = 4482`; against a true base of 4506 the table move alone is −41, +which is the "~40" that was predicted. The most consistent reading is that P4 was +measured after the table move and before the repair was written, and the figure +was never re-taken once the repair landed in the same commit. + +### A1 — exact + +``` +hardcoded names in is_int_call @50425f3: 35 +Int entries added to signatures.rel by cbef1c1: 35 +``` + +Thirty-five in, thirty-five out. No divergence. + +## A12 — new finding: the data-driven repair fails open + +`load_signatures()` resolves its data file as `env("EL_SIGNATURES")` and, when +unset, the **relative** path `tools/check/signatures.rel` +(`codegen.el:1989–1993` at `cbef1c1`). The file is therefore found only when the +compiler is invoked with the working directory at `lang/`. + +Run from one directory up, the `cbef1c1` compiler emits (`0012` vs `0009`): + +| cwd | emitted for `a + b` | program | +|---|---|---| +| repo root | `el_val_t c = el_str_concat(a, b);` | exit 139, no output (`0011`, `0014`) | +| `lang/` | `el_val_t c = (a + b);` | prints `7`, exit 0 (`0020`) | + +Byte-identical output to the *pre-repair* compiler: artifacts `0004` and `0009` +share sha256 `40fff4bfeca1…`. + +So the repair does not fail closed. With its data file missing it reproduces the +exact silent miscompilation it was written to remove, with no diagnostic. The +harness `temporal_signatures.sh` already contains an assertion of this shape +("with no signature file, the type is unknown and it does not"), which is treated +there as correct behaviour — for dispatch it is arguably tolerable; for the +binding-site repair it reintroduces a memory-safety defect. + +This finding belongs to the re-run, not to the original record. + +## NOT-CAPTURED, and why + +A7/A8/A9 (98/98 native + 2 new, 31/31 integration, fixpoint) were not re-run at +`cbef1c1`. They are re-runnable — the identical measurements were taken at the +adjacent commits `d2d89fc` (cycle 11), `e8e25a0` (cycle 12) and `0143cc4` +(cycle 14, which reports 102 tests and 31 integration assertions) — and are +recorded here as NOT-CAPTURED rather than inferred from neighbours. + +## Provenance notes + +`0001` and `0002` carry DIRTY-TREE flags (`git show` measurements from the shared +main checkout); both were re-run from a clean worktree as `0025` and `0026`. +Behavioural captures come from `/tmp/rerun-v1b-13-pre` (`50425f3`), +`/tmp/rerun-v1b-13-post` (`cbef1c1`) and `/tmp/rerun-v1b-head` (`a0cc95e3`). + +One capture was discarded during this re-run and is not in the manifest: a `cc` +invocation passed the multi-line `$SRCS` expansion as a single argument, which +wrote embedded newlines into `MANIFEST.tsv` and broke its row structure. It was +removed and re-run as a single-line `bash -c`. No measurement was lost — the +build was simply repeated (`0006`). diff --git a/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.cmd b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.cmd new file mode 100644 index 0000000..642216e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/headkw diff --git a/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.err b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.out b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.out new file mode 100644 index 0000000..920a139 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.out @@ -0,0 +1 @@ +43 diff --git a/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.prov b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.prov new file mode 100644 index 0000000..7bc4448 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:07Z +exit 0 +ms 173 +sha256_out 0e55092af0746630c98d1b2e0d960617c33f8ea7b55739fd18cb7cd5342a28ca +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.rc b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/CLAIMS.md b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/CLAIMS.md new file mode 100644 index 0000000..833e02c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/CLAIMS.md @@ -0,0 +1,115 @@ +# CLAIMS — cycle 14, keywords that reserve nothing + +Source doc: `docs/v1/experiments/cycles/14-keywords-that-reserve-nothing.md` + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `15d4352ba` | make the capability table match its own status note | +| experiment (system under test) | `0143cc458ac158e808e074acab417d4f706d89d8` | ANSWER: is a grammar a convention, or a region? | +| land (merge) | `067dd40317bd880781b6035dd5bfba8c2f1b371d` | answer the parsing question: a grammar is a basis, and five keywords reserved nothing | +| current HEAD at re-run time | `a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7` | instrument build log | + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | the keyword set is **46** spellings | `0001-keyword-count-at-15d4352.out` | `15d4352` | REPRODUCED (exact) | +| A2 | **five** of them are consumed by no parser or codegen path: `sealed`, `activate`, `seed`, `protocol`, `impl` | `0001`, `0010-five-tokens-consumed-nowhere.out` | `15d4352` | REPRODUCED (exact) | +| A3 | using one did not fail to parse: `let seed = 42 / let impl = seed + 1` compiled **CLEAN — zero cc errors** | `0004`, `0006-pre-cc-zero-errors.out` | `15d4352` | REPRODUCED (exact) | +| A4 | …and **printed 0** | `0007-pre-program-run.out` | `15d4352` | REPRODUCED (exact) | +| A5 | …"instead of **44**" | `0009-post-program-run.out` | `0143cc4` | **DIVERGED** | +| A6 | fixed by removing the five | `0005-post-emit-c-inert-keywords.out`, `0009` | `0143cc4` | REPRODUCED | +| A7 | measurement defect: `test` looked inert by the same measure and is not — codegen consumes it at **4135** for `--test` mode | `0011-test-keyword-consumed-at-codegen-4135.out` | `0143cc4` | REPRODUCED (exact, to the line) | +| A8 | …and the tree has **408** uses | `0014-test-word-count-at-pre.out` | `15d4352` | REPRODUCED (exact) | +| A9 | 100/100 native + 2 new | `0013-post-native-suite.out` | `0143cc4` | REPRODUCED | +| A10 | 31/31 integration | `0015-post-integration-harnesses.out` | `0143cc4` | REPRODUCED (exact) | +| A11 | fixpoint ok | `0012-post-fixpoint.out` | `0143cc4` | REPRODUCED | +| A12 | the SHOULD gate says no: the keyword set stays code because it is closed by the language definition and the lexer runs before the program is understood | — | — | **NOT-CAPTURED** (design argument) | +| A13 | the lexeme→token / shape-recognition / transduction / byte-traversal layering | — | — | **NOT-CAPTURED** (design argument) | +| A14 | the defect at current HEAD | `0016-head-inert-keyword-TODAY.out` | `a0cc95e3` | fixed — prints `43`, exit 0 | + +## The second silent miscompilation of the day, reproduced exactly + +Fixture `fixtures/inert_keyword.el`: + +```el +fn main() { + let seed = 42 + let impl = seed + 1 + println(int_to_str(impl)) +} +``` + +Emitted C at `15d4352` (`0004`): + +```c +el_val_t seed = 42; +el_val_t impl = (EL_NULL + 1); +println(int_to_str(EL_NULL)); +``` + +The binding is emitted, but every *use* of `seed` and `impl` is swallowed — the +lexer classified the identifier as a keyword, so the expression parser never saw +an identifier and emitted `EL_NULL`. `cc` reports **0 errors** (`0006`), the +program exits **0**, and prints **`0`** (`0007`). + +At `0143cc4` (`0005`, `0009`): + +```c +el_val_t seed = 42; +el_val_t impl = (seed + 1); +println(int_to_str(impl)); +``` + +prints **`43`**, exit 0. + +### A5 — the expected value is 43, not 44 + +The record says the program "printed 0 instead of **44**". For `let seed = 42` +followed by `let impl = seed + 1` the correct result is **43**, and the repaired +compiler prints 43 (`0009`, and again at HEAD, `0016`). The `44` is an +arithmetic slip in the prose. + +Nothing else in the claim is affected: the defect, the clean compile, the +printed `0`, and the repair all reproduce exactly. + +## The measurement defect the record catches on itself — confirmed + +`0010`, run against `15d4352`, counts each token name across all four consumers: + +``` +Sealed lexer=1 parser=0 codegen=0 compiler=0 +Activate lexer=1 parser=0 codegen=0 compiler=0 +Seed lexer=1 parser=0 codegen=0 compiler=0 +Protocol lexer=1 parser=0 codegen=0 compiler=0 +Impl lexer=1 parser=0 codegen=0 compiler=0 +Test lexer=1 parser=0 codegen=1 compiler=0 +``` + +The five are minted by the lexer and consumed by nothing. `Test` is minted by +the lexer, ignored by the parser — which is why a parser-only search reported it +inert — and consumed by codegen. `0011` locates that single consumer at +**`codegen.el:4135`**, the exact line the record names, and `0014` counts +**408** occurrences of the bare word `test` in `.el` files at `15d4352`, the +exact figure the record names. Removing it would indeed have broken the suite. + +## Integration count — exact + +``` +arity_query.sh exit=0 assertions=5 +capability_query.sh exit=0 assertions=5 +prohibition_query.sh exit=0 assertions=4 +seam_binding.sh exit=0 assertions=7 +temporal_query.sh exit=0 assertions=6 +temporal_signatures.sh exit=0 assertions=4 +TOTAL assertions: 31 +``` + +## Provenance notes + +All captures are from dedicated worktrees `/tmp/rerun-v1b-14-pre` (`15d4352`), +`/tmp/rerun-v1b-14-post` (`0143cc4`) and `/tmp/rerun-v1b-head` (`a0cc95e3`), with +`capture.sh` invoked by absolute path from inside each, so the recorded commit is +the system under test's. No DIRTY-TREE flags in this cycle. diff --git a/docs/v1/experiments/evidence/cycles/15-no-namespacing-at-all/CLAIMS.md b/docs/v1/experiments/evidence/cycles/15-no-namespacing-at-all/CLAIMS.md new file mode 100644 index 0000000..479962c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/15-no-namespacing-at-all/CLAIMS.md @@ -0,0 +1,197 @@ +# CLAIMS — cycle 15, no namespacing at all + +Source doc: `docs/v1/experiments/cycles/15-no-namespacing-at-all.md` + +This is the measurement that bears hardest on the hypothesis: if every El symbol +binds to a name already resolved by the C linker, the partition question is not +being asked yet. It was captured with correspondingly more care than the rest of +the set — the linking claim is demonstrated as a six-step chain +(`0010`–`0015`), not asserted. + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `bb040ad2c` | record the numeric literals answer: a bare number has no axis | +| experiment (system under test) | `79f6cb79850b5affd7735fcc418ede2242b46e5b` | ANSWER: if the partition is a neighbourhood, does linking survive? | +| land (merge) | `f23cb2b948396eae6a44daac5d56f5e0e6338758` | answer the module question: the partition is a path, and there is no namespacing | + +`79f6cb7` touches `codegen.el`, `definitions_query.sh` and `definitions.sh` +only. `compiler.el` — which holds `resolve_imports` — is **unchanged** between +`bb040ad` and `79f6cb7`, so the import/linking measurements below hold at both. + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | `import` is textual inlining (`resolve_imports`), guarded against double inclusion by a `__elc_imp__:` state key | `0016-resolve-imports-is-textual-inlining.out` | `79f6cb7` | REPRODUCED (exact) | +| A2 | when a `.elh` header exists the **header is inlined instead** and the `.el` is marked seen | `0016`, `0010`, `0011`, `0012` | `79f6cb7` | REPRODUCED | +| A3 | **so symbols resolve at C link time — linking IS real, delegated to C** | `0012`, `0013-link-D-unresolved-at-c-link-time.out`, `0014`, `0015` | `79f6cb7` | REPRODUCED (demonstrated end to end) | +| A4 | two modules defining `helper` emit **two C functions into one translation unit** | `0003`, `0004-pre-two-c-functions-one-TU.out` | `bb040ad` | REPRODUCED (exact) | +| A5 | `cc` does catch the collision, but reports four errors with the user's own function **FOURTH**: `__el_body_helper`, `__env_helper`, `__thunk_helper`, `helper` | `0005-pre-cc-collision-error-order.out` | `bb040ad` | REPRODUCED (exact, in order) | +| A6 | repaired at El level with the message `duplicate definition: 'helper' is defined 2 times — El has no namespacing, so imported modules share one global scope` | `0006-post-el-level-duplicate-message.out` | `79f6cb7` | REPRODUCED (verbatim) | +| A7 | 4/4 `definitions_query.sh` | `0007-post-definitions-query-harness.out` | `79f6cb7` | REPRODUCED | +| A8 | 104/104 native | `0009-post-native-suite.out` | `79f6cb7` | REPRODUCED (exact) | +| A9 | the compiler itself reports clean | `0017-compiler-self-check-clean.out` | `79f6cb7` | REPRODUCED | +| A10 | fixpoint ok | `0008-post-fixpoint.out` | `79f6cb7` | REPRODUCED | +| A11 | LIMIT: textual inlining destroys file provenance, so the message can name the symbol but not the files | `0006` | `79f6cb7` | REPRODUCED | +| A12 | "the first three are generated symbols introduced by the unconditional-wrapper pass earlier today — before it, there was one clear message" | — | — | **NOT-CAPTURED** | +| A13 | "El's partition is a FILESYSTEM PATH, not a neighbourhood" / "whether linking survives a neighbourhood partition cannot be asked yet" | — | — | **NOT-CAPTURED** (interpretive) | +| A14 | both compilers build | `0001`, `0002` | `bb040ad`, `79f6cb7` | REPRODUCED | + +## A3 — the linking chain, in full + +This is the load-bearing measurement. Six captures, one per step. Fixtures +`fixtures/m.el` (defines `mhelper`) and `fixtures/link_main.el` (imports it). + +**A — no header present.** `resolve_imports` inlines the module body; the +definition and the call land in one translation unit (`0010`): + +```c +el_val_t mhelper(void); +static el_val_t __el_body_mhelper(void) { return EL_STR("from module m"); …} +… +el_val_t mhelper(void) { … } <- the DEFINITION is here +int main(…) { println(mhelper()); } +``` + +**B — emit a header.** `elc --emit-header m.el` writes (`0011`): + +``` +// auto-generated by elc --emit-header — do not edit +extern fn mhelper() -> String +``` + +**C — recompile with the header present.** The `.el` is marked seen and the +header text is inlined in its place. The whole module body is gone (`0012`): + +```c +#include "el_runtime.h" + +el_val_t mhelper(void); <- a DECLARATION, and nothing else + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + println(mhelper()); + return 0; +} +``` + +**D — link that translation unit alone.** El has produced a program with an +unresolved symbol, and says nothing about it. The C linker is what refuses +(`0013`, exit 1): + +``` +Undefined symbols for architecture arm64: + "_mhelper", referenced from: +``` + +**E — link the module's own translation unit in as well** (`0014`, exit 0): + +``` +LINK-OK +``` + +**F — run it** (`0015`, exit 0): + +``` +from module m +``` + +The symbol is genuinely unbound at the El layer and genuinely bound by `ld`. +"Linking IS real, delegated to C" is not a characterisation here; it is the +observed behaviour of the toolchain at the pinned commit. The El compiler never +resolves `mhelper` — it emits a C declaration and lets the system linker +succeed or fail. + +## A5 — the collision, and the ordering, exactly as recorded + +Fixtures `fixtures/a.el`, `fixtures/b.el`, `fixtures/main.el` — two modules each +defining `helper`, one program importing both. + +Emitted into one translation unit (`0004`) — the generated helper trio appears +twice, then the user's function twice: + +``` + 5: el_val_t helper(void); + 6: el_val_t helper(void); + 8: static el_val_t __el_body_helper(void) { +12: struct __env_helper { char __e0; }; +13: static el_val_t __thunk_helper(void* __v) { +17: el_val_t helper(void) { +25: static el_val_t __el_body_helper(void) { <- second copy begins +29: struct __env_helper { char __e0; }; +30: static el_val_t __thunk_helper(void* __v) { +34: el_val_t helper(void) { +``` + +`cc` at `bb040ad` (`0005`, exit 1) reports, in this order: + +``` +mod_pre.c:25:17: error: redefinition of '__el_body_helper' +mod_pre.c:29:8: error: redefinition of '__env_helper' +mod_pre.c:30:17: error: redefinition of '__thunk_helper' +mod_pre.c:34:10: error: redefinition of 'helper' +``` + +Four errors. The user's own function is the **fourth**. The first three name +symbols the user never wrote. Exact match, including order. + +## A6 / A11 — the repair, and its stated limit + +At `79f6cb7` the collision is caught at El level from recorded relations +(`0006`, checker exit 1): + +``` +duplicate definition: 'helper' is defined 2 times — El has no namespacing, so imported modules share one global scope +``` + +verbatim to the record. And the limit is visible in the same output: it names +**which name** collides and not **which files**, because by the time codegen runs +`resolve_imports` has produced one source string. That limit is what cycle 16 +goes on to remove. + +## A1 — the mechanism, verbatim from source + +`0016`, `compiler.el` at `79f6cb7`: + +``` +416:fn resolve_imports(src_path: String) -> String { +417: let seen_key: String = "__elc_imp__:" + src_path +420: state_set(seen_key, "1") +455: let imp_elh_path: String = str_slice(imp_path, 0, str_len(imp_path) - 3) + ".elh" +456: let imp_elh: String = fs_read(imp_elh_path) +457: if !str_eq(imp_elh, "") { +460: let seen_imp_key: String = "__elc_imp__:" + imp_path +461: state_set(seen_imp_key, "1") +462: let prefix_chunks = native_list_append(prefix_chunks, imp_elh) +``` + +Textual inlining; `__elc_imp__:` as the double-inclusion guard; header +preferred over body and the `.el` marked seen. Every clause of A1 and A2 present +in the code, and demonstrated in behaviour by the A–F chain. + +## Suite results at `79f6cb7` + +``` +104 tests, 104 passed, 0 failed, 249 assertions (0009) +4 assertions, 4 passed, 0 failed definitions_query (0007) +FIXPOINT-OK gen2 == gen3 (0008) +definitions: clean exit=0 (compiler's own source) (0017) +``` + +All four figures match the record. + +## Provenance notes + +Every artifact in this cycle was captured from a dedicated worktree — +`/tmp/rerun-v1b-15-pre` (`bb040ad`) or `/tmp/rerun-v1b-15-post` (`79f6cb7`) — +with `capture.sh` invoked by absolute path from inside it, so the recorded commit +is the system under test's, and fixtures and build products were kept outside the +worktree so the tree stayed clean. **No DIRTY-TREE flags in this cycle**; every +artifact is reproducible by checking out its recorded commit. + +One capture (`0013`) was taken a first time with the working directory left in +the shared main checkout, which recorded the wrong commit. It was deleted, its +manifest row removed, and the measurement re-run from inside the worktree. The +result was unchanged. diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.prov b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.prov new file mode 100644 index 0000000..595a8b0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.prov @@ -0,0 +1,7 @@ +commit 6c975b1d5019446c29d84d99b9b1c0ec512be8a6 +tree clean +captured_utc 2026-08-17T17:39:50Z +exit 0 +ms 4501 +sha256_out f79b44ce578be80a6e4893078b52be4bbf8fb042acde2fdfc8aff5e8b5d36201 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.rc b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.cmd b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.cmd new file mode 100644 index 0000000..7a47bb8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-16-post/lang && tot=0; for h in tests/integration/*.sh; do out=$("$h" /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc16p2 2>&1); rc=$?; n=$(printf "%s" "$out" | grep -oE "^ *[0-9]+ assertions" | grep -oE "[0-9]+" | head -1); printf "%-28s exit=%s assertions=%s\n" "$(basename $h)" "$rc" "${n:-0}"; tot=$((tot+${n:-0})); done; echo "TOTAL: $tot" diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.err b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.out b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.out new file mode 100644 index 0000000..6d49e79 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.out @@ -0,0 +1,8 @@ +arity_query.sh exit=0 assertions=5 +capability_query.sh exit=0 assertions=5 +definitions_query.sh exit=0 assertions=6 +prohibition_query.sh exit=0 assertions=4 +seam_binding.sh exit=0 assertions=7 +temporal_query.sh exit=0 assertions=6 +temporal_signatures.sh exit=0 assertions=4 +TOTAL: 37 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.prov b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.prov new file mode 100644 index 0000000..d23c3b9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.prov @@ -0,0 +1,7 @@ +commit 6c975b1d5019446c29d84d99b9b1c0ec512be8a6 +tree clean +captured_utc 2026-08-17T17:39:56Z +exit 0 +ms 5834 +sha256_out dc339da1bbfd1ef26c50dd0fc39d11698cc917e12f9d8cece3943064a099780d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.rc b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.cmd b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.cmd new file mode 100644 index 0000000..d89e1bb --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-16-post/lang && EL_RELATIONS_OUT=/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel16self.txt /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc16p2 elc-cli.el > /dev/null 2>&1; ./tools/check/definitions.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel16self.txt; echo "exit=$?" diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.err b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.out b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.out new file mode 100644 index 0000000..d99dde7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.out @@ -0,0 +1,2 @@ +definitions: clean +exit=0 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.prov b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.prov new file mode 100644 index 0000000..a7b7b55 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.prov @@ -0,0 +1,7 @@ +commit 6c975b1d5019446c29d84d99b9b1c0ec512be8a6 +tree clean +captured_utc 2026-08-17T17:40:00Z +exit 0 +ms 3736 +sha256_out ee2edd9077daacf4b2738aa301a4406706be0cec2860cf10411aed76807f7f38 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.rc b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.cmd new file mode 100644 index 0000000..94b2b99 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && echo "stride literal changes (2 -> 3) in parser.el:"; git diff 1086ac9 6c975b1 -- lang/el-compiler/src/parser.el | grep -cE "^\+.*(\* 3|/ 3)"; echo "accessor fns after:"; git show 6c975b1:lang/el-compiler/src/parser.el | grep -nE "^fn tok_(kind|value|line)"; echo "accessor call sites after:"; git show 6c975b1:lang/el-compiler/src/parser.el | grep -cE "tok_kind\(|tok_value\(|tok_line\(" diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.err b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.out b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.out new file mode 100644 index 0000000..728fd29 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.out @@ -0,0 +1,8 @@ +stride literal changes (2 -> 3) in parser.el: +14 +accessor fns after: +25:fn tok_kind(tokens: [Any], pos: Int) -> String { +41:fn tok_line(tokens: [Any], pos: Int) -> String { +48:fn tok_value(tokens: [Any], pos: Int) -> String { +accessor call sites after: +187 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.prov b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.prov new file mode 100644 index 0000000..eb0c381 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:59Z +exit 0 +ms 30 +sha256_out 7929c4e6e578cf3478a21d17c8fdc94f2dd4face1bed24f40d4019c20ad69c02 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.rc b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.cmd b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.cmd new file mode 100644 index 0000000..0e88884 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-head && echo "stride-2 sites present at 1086ac9 across ALL compiler + test sources:"; git grep -nE "native_list_(get|len)\(tokens[^)]*(\* 2|/ 2)|len\(tokens\) / 2|pos \* 2" 1086ac9 -- lang/el-compiler/src lang/tests | wc -l; echo; echo "--- the sites ---"; git grep -nE "native_list_(get|len)\(tokens[^)]*(\* 2|/ 2)|len\(tokens\) / 2|pos \* 2" 1086ac9 -- lang/el-compiler/src lang/tests diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.err b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.out b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.out new file mode 100644 index 0000000..987bf29 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.out @@ -0,0 +1,20 @@ +stride-2 sites present at 1086ac9 across ALL compiler + test sources: + 16 + +--- the sites --- +1086ac9:lang/el-compiler/src/codegen.el:3633: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/codegen.el:3807: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/codegen.el:4018: let total_tokens: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:20: let kind: String = native_list_get(tokens, pos * 2) +1086ac9:lang/el-compiler/src/parser.el:21: let value: String = native_list_get(tokens, pos * 2 + 1) +1086ac9:lang/el-compiler/src/parser.el:31: let n: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:38: native_list_get(tokens, pos * 2) +1086ac9:lang/el-compiler/src/parser.el:42: let n: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:49: native_list_get(tokens, pos * 2 + 1) +1086ac9:lang/el-compiler/src/parser.el:1233: let blk_total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:2161: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:2204: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:2256: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:2422: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/el-compiler/src/parser.el:2564: let total: Int = native_list_len(tokens) / 2 +1086ac9:lang/tests/native/test_compiler.el:21: native_list_len(tokens) / 2 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.prov b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.prov new file mode 100644 index 0000000..3190828 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:48:10Z +exit 0 +ms 30 +sha256_out 50fe705aa2bb7c0602c30b9cfd748ce04f277f41385d08333ac1fb9e5342f5cd +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.rc b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/CLAIMS.md b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/CLAIMS.md new file mode 100644 index 0000000..b5ab2b9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/CLAIMS.md @@ -0,0 +1,168 @@ +# CLAIMS — cycle 16, tokens carry no position + +Source doc: `docs/v1/experiments/cycles/16-tokens-carry-no-position.md` + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `1086ac965` | record the module answer: the partition is a path, not a neighbourhood | +| experiment (system under test) | `6c975b1d5019446c29d84d99b9b1c0ec512be8a6` | thread provenance through resolve_imports | +| land (merge) | `cb7289f06510c002b6ab7c5ca8c2bd182d8216bc` | thread provenance end to end: a diagnostic can finally name a place | + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | tokens had **no position at all** — a token was a flat `(kind, value)` pair | `0001-pre-token-is-flat-pair.out` | `1086ac9` | REPRODUCED (exact) | +| A2 | no diagnostic in El could name a place — every error named a symbol, never a line | `0001` (`tok_line` absent from all five compiler sources) | `1086ac9` | REPRODUCED | +| A3 | P1: **15 stride sites**, encapsulated in `tok_kind`/`tok_value` | `0014`, `0015-P1-stride-sites-all-files-clean-tree.out` | `1086ac9`→`6c975b1` | REPRODUCED (see note) | +| A4 | P2: adding a line field is mechanical; P3: the lexer must count newlines — stride **2 → 3** | `0014`, `0015` | `6c975b1` | REPRODUCED | +| A5 | P4: `resolve_imports` can record per-file line ranges (` spans `) | `0009-P5-message-names-both-files.out` | `6c975b1` | REPRODUCED (via effect) | +| A6 | P5: the message can then name **both files** | `0009` | `6c975b1` | REPRODUCED (exact shape) | +| A7 | P6: token memory grows — **25.0 → 33.9 MB (+36%)** | `0005`, `0006`, `0007-P6-rss-five-runs-each.out`, `0008-P6-growth-arithmetic.out` | `1086ac9`/`6c975b1` | **DIVERGED** (endpoints reproduce; the percentage does not) | +| A8 | 105/105 native | `0011-post-native-suite.out` | `6c975b1` | REPRODUCED (exact) | +| A9 | 37/37 integration | `0012-post-integration-harnesses.out` | `6c975b1` | REPRODUCED (exact) | +| A10 | fixpoint ok | `0010-post-fixpoint.out` | `6c975b1` | REPRODUCED | +| A11 | compiler self-checks clean | `0013-post-compiler-self-check.out` | `6c975b1` | REPRODUCED | +| A12 | defect 1: `interp_tokens_append_all` walks the token list with its own copy of the stride; gen1 built, gen2 emitted corrupt C | — | — | **NOT-CAPTURED** | +| A13 | defect 2: `tok_count` in `test_compiler.el` carried the stride too, having escaped a compiler-scoped search | `0015` | `1086ac9` | REPRODUCED (corroborated — see note) | +| A14 | defect 3: nested `resolve_imports` accumulated spans into shared state | — | — | **NOT-CAPTURED** | +| A15 | defect 4: the first working version reported `b.el:3` — the COMBINED line against a file with no line 3 | `0009` (shows the corrected behaviour only) | `6c975b1` | **NOT-CAPTURED** | +| A16 | both compilers build | `0003`, `0004` | `1086ac9`, `6c975b1` | REPRODUCED | + +## A1 / A4 — the token shape + +`tok_append` at `1086ac9` (`0001`): + +```el +fn tok_append(tokens: [Any], kind: String, value: String) -> [Any] { + let tokens = native_list_append(tokens, kind) + native_list_append(tokens, value) +} +``` + +Two slots. `tok_line` does not appear anywhere in `lexer.el`, `parser.el`, +`codegen.el`, `codegen-js.el` or `compiler.el` — count 0 in all five. At +`6c975b1` a third slot is appended from `state_get("__lex_line")` and +`tok_line(tokens, pos)` is defined at `parser.el:41`. + +## A3 / A13 — the stride count, and the escapee + +`0015`, run against `1086ac9`, finds **16** sites that hardcode the stride: + +``` +codegen.el 3 sites (3633, 3807, 4018) +parser.el 12 sites (20, 21, 31, 38, 42, 49, 1233, 2161, 2204, 2256, 2422, 2564) +tests/native/test_compiler.el 1 site (21) +``` + +Compiler sources alone: **3 + 12 = 15** — exactly P1's figure. The sixteenth is +`tok_count` in `test_compiler.el`, which is precisely what defect 2 in the +record says: *"tok_count in test_compiler.el carried the stride too. I had +scoped the search to compiler sources and it had escaped into the tests."* + +So P1's 15 is the compiler-source count, it is correct as such, and the +independent count corroborates the recorded defect rather than contradicting the +prediction. After the change `parser.el` exposes three accessors +(`tok_kind:25`, `tok_line:41`, `tok_value:48`) with **187** call sites (`0014`). + +## A6 — the diagnostic, exactly as recorded + +Fixtures `fixtures/a.el`, `fixtures/b.el`, `fixtures/m.el`. At `6c975b1` +(`0009`, checker exit 1): + +``` +duplicate definition: 'helper' is defined 2 times — El has no namespacing, so imported modules share one global scope + …/mod16/a.el:1 + …/mod16/b.el:1 +``` + +Same shape as the record's + +``` + /tmp/modtest/a.el:1 + /tmp/modtest/b.el:1 +``` + +(the directory differs because the fixture was re-created in this re-run's +scratch space; `/tmp/modtest` from the original session no longer exists). Both +files are named, and each line number is the line **within that file** — which +is defect 4's repair: the combined-source line is no longer reported against a +file that has no such line. + +## A7 — the divergence, in full + +Peak RSS of the same compile (`elc-cli.el`), five runs each, `/usr/bin/time -l` +(`0007`): + +``` +pre run1 25018368 23.86 MiB 25.02 MB post run1 35536896 33.89 MiB 35.54 MB +pre run2 25001984 23.84 MiB 25.00 MB post run2 33980416 32.41 MiB 33.98 MB +pre run3 25067520 23.91 MiB 25.07 MB post run3 35061760 33.44 MiB 35.06 MB +pre run4 24887296 23.73 MiB 24.89 MB post run4 34947072 33.33 MiB 34.95 MB +pre run5 25067520 23.91 MiB 25.07 MB post run5 34848768 33.23 MiB 34.85 MB +``` + +**Both endpoint numbers in the record reproduce — but not in the same unit.** + +* `25.0` is the **pre** figure read in decimal MB (25.00–25.07 MB; the same + bytes are 23.84 MiB). +* `33.9` is the **post** figure read in **MiB** (33.89 MiB on run 1; the same + bytes are 35.54 MB). + +Computed in consistent units (`0008`): + +``` +pre mean 25008537 bytes = 23.84 MiB = 25.00 MB +post mean 34874982 bytes = 33.25 MiB = 34.87 MB +growth, consistent units = 39.45 % +claimed 25.0 -> 33.9 implies 35.60 % +``` + +So the true growth is **≈ +39.5 %**, not +36 %. The +36 % figure is the +arithmetic of one decimal-MB reading against one MiB reading. P6's prediction +("token memory grows") is REPRODUCED and the direction is unaffected; the +magnitude as printed is DIVERGED, and understates the cost. + +A note on what is being measured: `/usr/bin/time -l` reports process peak +resident set, not the token list in isolation. The record does not state the +method used for its own figures. Since both of its endpoints fall inside the +peak-RSS distribution measured here, peak RSS is the most likely original +instrument; but the +36 % is wrong under any single consistent unit, which is +what the divergence rests on. A stride change from 2 to 3 slots implies +50 % on +the token list alone, and +39.5 % on whole-process peak is consistent with the +token list being the dominant but not sole allocation. + +## Suite results at `6c975b1` + +``` +105 tests, 105 passed, 0 failed, 253 assertions (0011) +FIXPOINT-OK gen2 == gen3 (0010) +definitions: clean exit=0 (compiler's own source) (0013) + +arity_query.sh exit=0 assertions=5 +capability_query.sh exit=0 assertions=5 +definitions_query.sh exit=0 assertions=6 +prohibition_query.sh exit=0 assertions=4 +seam_binding.sh exit=0 assertions=7 +temporal_query.sh exit=0 assertions=6 +temporal_signatures.sh exit=0 assertions=4 +TOTAL: 37 (0012) +``` + +105/105 and 37/37 — both exact. + +## Provenance notes + +`0002` carries a DIRTY-TREE flag (`git show` measurement run from the shared main +checkout while other agents were committing to it). It was re-run from a clean +worktree as `0014`, and extended as `0015`. Cite the `-clean-tree` artifacts. +Everything else is from `/tmp/rerun-v1b-16-pre` (`1086ac9`) and +`/tmp/rerun-v1b-16-post` (`6c975b1`). + +The four defects the record lists (A12–A15) were found and fixed *within* the +development of `6c975b1`; no intermediate states were committed, so no artifact +of them exists and none was manufactured. A13 is graded REPRODUCED only because +the escapee it names is independently visible in the stride census at the parent +commit. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.cmd new file mode 100644 index 0000000..5699349 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17pre.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17pre.c $SRCS $LF && echo BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.out new file mode 100644 index 0000000..1c5c36b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.out @@ -0,0 +1 @@ +BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.prov new file mode 100644 index 0000000..5976d77 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:40:35Z +exit 0 +ms 3911 +sha256_out 68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0001-build-gen1-pre.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.cmd new file mode 100644 index 0000000..a4ef397 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17post.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17post.c $SRCS $LF && echo BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.out new file mode 100644 index 0000000..1c5c36b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.out @@ -0,0 +1 @@ +BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.prov new file mode 100644 index 0000000..d0585d9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:40:39Z +exit 0 +ms 4000 +sha256_out 68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0002-build-gen1-post.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.cmd new file mode 100644 index 0000000..7a87f7e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/int_annotated_string.el diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.out new file mode 100644 index 0000000..23b60f3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.out @@ -0,0 +1,12 @@ +#include +#include +#include "el_runtime.h" + + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + el_val_t x = EL_STR("hello"); + println(int_to_str((x + 1))); + return 0; +} + diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.prov new file mode 100644 index 0000000..e7644fa --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:40:45Z +exit 0 +ms 172 +sha256_out a66a5ce074fb9576873861b724de4ee63f4d3cbf87b6457ecc289507868a9299 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0003-pre-emit-c-int_annotated_string.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.cmd new file mode 100644 index 0000000..50aa115 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/string_annotated_int.el diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.out new file mode 100644 index 0000000..8e3660f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.out @@ -0,0 +1,12 @@ +#include +#include +#include "el_runtime.h" + + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + el_val_t s = 42; + println(s); + return 0; +} + diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.prov new file mode 100644 index 0000000..bb3bcb0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:40:45Z +exit 0 +ms 11 +sha256_out d1da9e3d17f33a78721c53970194778a5d0627a3f0a4539c1a5e86e3051ab96d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0004-pre-emit-c-string_annotated_int.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.cmd new file mode 100644 index 0000000..9761475 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1.c $SRCS $LF && echo CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.out new file mode 100644 index 0000000..0c50dfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.out @@ -0,0 +1 @@ +CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.prov new file mode 100644 index 0000000..00c1a53 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:40:57Z +exit 0 +ms 3307 +sha256_out a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0005-pre-cc-h1-clean.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.cmd new file mode 100644 index 0000000..60109bf --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h2.c $SRCS $LF && echo CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.out new file mode 100644 index 0000000..0c50dfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.out @@ -0,0 +1 @@ +CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.prov new file mode 100644 index 0000000..d5983cd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:41:01Z +exit 0 +ms 3249 +sha256_out a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0006-pre-cc-h2-clean.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.cmd new file mode 100644 index 0000000..32aa91a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.out new file mode 100644 index 0000000..b68da02 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.out @@ -0,0 +1 @@ +4296429677 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.prov new file mode 100644 index 0000000..b23e4c9 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:41:01Z +exit 0 +ms 189 +sha256_out f707cf113f7be78429f2a8bdf817405eea5e888f791aaace6edee95d590a3c9d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0007-pre-run-int-annotated-string.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.cmd new file mode 100644 index 0000000..5e0a4bf --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h2 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.out new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.prov new file mode 100644 index 0000000..df298ef --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:41:01Z +exit 139 +ms 165 +sha256_out e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.rc new file mode 100644 index 0000000..897bdc8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0008-pre-run-string-annotated-int.rc @@ -0,0 +1 @@ +139 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.cmd new file mode 100644 index 0000000..b0b4f43 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.cmd @@ -0,0 +1 @@ +bash -c for i in $(seq 1 10); do /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1; done; echo; echo "claimed in the record: 4343631981" diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.out new file mode 100644 index 0000000..e65b24c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.out @@ -0,0 +1,12 @@ +4308013165 +4369141869 +4300738669 +4308783213 +4302131309 +4378923117 +4339404909 +4310225005 +4310487149 +4307406957 + +claimed in the record: 4343631981 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.prov new file mode 100644 index 0000000..0f4248b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:41:14Z +exit 0 +ms 56 +sha256_out 9d1482bd0fcd6c396a0c4e48653a7992eb6353ba672d488946e310166801f730 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0009-pre-int-annotated-string-ten-runs.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.cmd new file mode 100644 index 0000000..f27d36c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-post/lang && for f in int_annotated_string string_annotated_int; do echo "--- $f ---"; EL_RELATIONS_OUT=/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17_$f.txt /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/$f.el > /dev/null 2>&1; ./tools/check/annotations.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17_$f.txt; echo "exit=$?"; done diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.out new file mode 100644 index 0000000..bfcfc41 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.out @@ -0,0 +1,6 @@ +--- int_annotated_string --- +type error in main: 'x' is declared Int but assigned a String literal — the annotation drives dispatch, so the value will be reinterpreted rather than rejected +exit=1 +--- string_annotated_int --- +type error in main: 's' is declared String but assigned a Int literal — the annotation drives dispatch, so the value will be reinterpreted rather than rejected +exit=1 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.prov new file mode 100644 index 0000000..55f0efc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:41:23Z +exit 0 +ms 371 +sha256_out b2a75592f425a76b3d6ee0480e186c450157135282cf3c66de11c45cff176f5a +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0010-post-annotation-checker-catches-both.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.cmd new file mode 100644 index 0000000..db42f5e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.cmd @@ -0,0 +1 @@ +./tests/integration/annotation_query.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.out new file mode 100644 index 0000000..c8db949 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.out @@ -0,0 +1,7 @@ + ok Int annotated on a String literal is caught + ok and names the variable + ok String annotated on an Int literal is caught + ok correct annotations are clean + ok the compiler's own source is clean — no false positives + + 5 assertions, 5 passed, 0 failed diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.prov new file mode 100644 index 0000000..48816ba --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:41:25Z +exit 0 +ms 1961 +sha256_out fd8354898660faa4fae68be1e10dfd30326d2cc60412fb42a87b6db3d1c8dd8f +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0011-post-annotation-query-harness.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.cmd new file mode 100644 index 0000000..739f820 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p2.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p2.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p3.c 2>/dev/null && cmp /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p2.c /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p3.c && echo FIXPOINT-OK || echo FIXPOINT-FAIL diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.out new file mode 100644 index 0000000..35a016e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.out @@ -0,0 +1 @@ +FIXPOINT-OK diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.prov new file mode 100644 index 0000000..1076cac --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:41:42Z +exit 0 +ms 4170 +sha256_out 1b4889e0050c409ace27706da41238ec276f0ac02d0e8f9ca07d5e2d1145aa8e +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0012-post-fixpoint.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.cmd new file mode 100644 index 0000000..6a0db5c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 --test tests/native/test_compiler.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.out new file mode 100644 index 0000000..e1c7005 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.out @@ -0,0 +1,107 @@ +ok lex-empty (0.060ms) +ok lex-whitespace-stripped (0.002ms) +ok lex-comment-stripped (0.001ms) +ok lex-int-literals (0.014ms) +ok lex-float-literals (0.001ms) +ok lex-string-literals (0.002ms) +ok lex-string-escape-newline (0.001ms) +ok lex-string-escape-tab (0.001ms) +ok lex-string-escape-backslash (0.002ms) +ok lex-bool-literals (0.002ms) +ok lex-identifier (0.002ms) +ok lex-keywords (0.003ms) +ok lex-more-keywords (0.002ms) +ok lex-keyword-values (0.001ms) +ok lex-arithmetic-operators (0.001ms) +ok lex-comparison-operators (0.001ms) +ok lex-logical-operators (0.001ms) +ok lex-arrow-tokens (0.002ms) +ok lex-delimiters (0.002ms) +ok lex-double-colon (0.000ms) +ok lex-dot-dot (0.000ms) +ok lex-pipe-operators (0.012ms) +ok lex-at-and-question (0.001ms) +ok lex-eof-always-last (0.002ms) +ok lex-string-with-spaces (0.000ms) +ok lex-multiline-source (0.003ms) +ok lex-flat-stride-3-layout (0.000ms) +ok lexer-tracks-line-numbers (0.002ms) +ok parse-let-stmt (0.032ms) +ok parse-fn-decl (0.010ms) +ok parse-fn-params (0.005ms) +ok parse-return-stmt (0.003ms) +ok parse-if-stmt (0.007ms) +ok parse-if-else (0.007ms) +ok parse-while-stmt (0.010ms) +ok parse-import-stmt (0.002ms) +ok parse-extern-fn (0.003ms) +ok parse-let-int-value (0.002ms) +ok parse-let-string-value (0.002ms) +ok parse-let-bool-value (0.008ms) +ok parse-binop-expr (0.003ms) +ok parse-call-expr (0.004ms) +ok parse-multiple-fns (0.005ms) +ok parse-assign-stmt (0.003ms) +ok parse-for-stmt (0.006ms) +ok parse-unary-not (0.004ms) +ok parse-unary-neg (0.003ms) +ok parse-array-literal (0.006ms) +ok parse-empty-array (0.003ms) +ok parse-index-expr (0.005ms) +ok codegen-includes (0.487ms) +ok codegen-int-main (0.099ms) +ok codegen-runtime-init (0.080ms) +ok codegen-void-function-signature (0.097ms) +ok codegen-function-with-params (0.090ms) +ok codegen-int-literal (0.077ms) +ok codegen-string-literal (0.111ms) +ok codegen-if-statement (0.086ms) +ok codegen-if-else (0.084ms) +ok codegen-while-loop (0.081ms) +ok codegen-let-binding (0.101ms) +ok codegen-function-call (0.082ms) +ok codegen-string-concat (0.071ms) +ok codegen-int-arithmetic (0.065ms) +ok codegen-comparison (0.059ms) +ok codegen-string-equality (0.062ms) +ok codegen-logical-and (0.069ms) +ok codegen-logical-or (0.063ms) +ok codegen-unary-not (0.097ms) +ok codegen-string-escape-in-c (0.074ms) +ok codegen-many-functions (0.089ms) +ok codegen-deep-expression (0.074ms) +ok codegen-forward-declarations (0.061ms) +ok codegen-for-loop (0.171ms) +ok codegen-extern-fn (0.066ms) +ok codegen-nested-calls (0.060ms) +ok compiler-minimal-program (0.057ms) +ok compiler-pure-library (0.110ms) +ok compiler-multiple-fns-with-main (0.227ms) +ok compiler-let-in-main (0.150ms) +ok compiler-string-concat-chain (0.133ms) +ok compiler-negative-literal (0.073ms) +ok compiler-stdint-include (0.076ms) +ok decorator-undecorated-fn-has-no-beat (0.079ms) +ok decorator-authenticate-compiles-to-nothing (0.115ms) +ok declared-construct-name-unknown-to-codegen (0.073ms) +ok undeclared-construct-still-injects-nothing (0.058ms) +ok undeclared-guard-emits-nothing (0.056ms) +ok seam-indirection-emitted-on-every-fn (0.086ms) +ok seam-emitted-without-any-decorator (0.115ms) +ok seam-replaces-inlined-entry-injection (0.081ms) +ok seam-entry-is-refusable (0.067ms) +ok seam-is-emitted-for-undecorated-fns (0.066ms) +ok every-fn-gets-a-body-helper-and-wrapper (0.121ms) +ok exit-crossing-goes-through-the-seam (0.073ms) +ok early-returns-route-through-the-exit-seam (0.082ms) +ok every-fn-gets-a-closure (0.079ms) +ok zero-param-fn-emits-valid-c (0.079ms) +ok compiler-no-longer-emits-prohibition-errors (0.087ms) +ok int-returning-builtin-drives-arithmetic-dispatch (0.089ms) +ok string-plus-string-still-concatenates (0.068ms) +ok freed-identifiers-compile-as-identifiers (0.120ms) +ok test-keyword-is-still-reserved (0.081ms) +ok instant-plus-bare-int-is-refused (0.082ms) +ok instant-plus-unit-suffix-is-allowed (0.076ms) + +105 tests, 105 passed, 0 failed, 253 assertions in 5.469ms diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.prov new file mode 100644 index 0000000..9334545 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:41:46Z +exit 0 +ms 4199 +sha256_out ac5e94f50ee400866b6acaf6802fc4ae07153316f92014887ba7a90a13dd3d01 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0013-post-native-suite.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.cmd new file mode 100644 index 0000000..28a0fd6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-post/lang && printf "fn main() {\n let x: Int = str_upper(\"abc\")\n println(int_to_str(x))\n}\n" > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/nonlit.el; EL_RELATIONS_OUT=/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17nl.txt /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/nonlit.el > /dev/null 2>&1; ./tools/check/annotations.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17nl.txt; echo "exit=$? (the record states this gap: only literals are checked)" diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.out new file mode 100644 index 0000000..00c9bac --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.out @@ -0,0 +1,2 @@ +annotations: clean +exit=0 (the record states this gap: only literals are checked) diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.prov new file mode 100644 index 0000000..9c73054 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:41:46Z +exit 0 +ms 21 +sha256_out ff06376ea9773a8398d656380d7924ff274a8105a1298ec7635c11c5ede5798f +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0014-post-incomplete-only-literals.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.cmd new file mode 100644 index 0000000..9c4c7e8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el && echo "branches named experiment/annotation-checking:"; git branch -a --list "*annotation-checking*" | wc -l; echo "is f1a7e224 an ancestor of iteration-2?"; git merge-base --is-ancestor f1a7e224 iteration-2 && echo YES-MERGED || echo NO; echo "merge commit:"; git log --all --oneline --merges --grep="land annotation checking" diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.out new file mode 100644 index 0000000..44082b5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.out @@ -0,0 +1,6 @@ +branches named experiment/annotation-checking: + 0 +is f1a7e224 an ancestor of iteration-2? +YES-MERGED +merge commit: +923f6a4b land annotation checking: the declared type is finally verified diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.prov new file mode 100644 index 0000000..2d43ebb --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.prov @@ -0,0 +1,7 @@ +commit f1a7e224a77f020315a81f62d297b7ebff9b822d +tree clean +captured_utc 2026-08-17T17:41:46Z +exit 0 +ms 37 +sha256_out 4ddf9189bdb9cd4e16d39a1efbe3d9853aebeae4abbe65d4caa2b2043db9fc36 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0015-branch-status-not-merged-claim.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.cmd new file mode 100644 index 0000000..f23e48d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head_int_annotated_string diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.out new file mode 100644 index 0000000..8a73523 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.out @@ -0,0 +1 @@ +4296710433 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.prov new file mode 100644 index 0000000..7211541 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:46:59Z +exit 0 +ms 174 +sha256_out a727c8fc554ed3c6ccc19162ce61088e50bdce6b1b972227a1b7099185ed4cb8 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0016-head-run-int-annotated-string-TODAY.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.cmd b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.cmd new file mode 100644 index 0000000..1ee32c6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head_string_annotated_int diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.err b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.out b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.out new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.prov b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.prov new file mode 100644 index 0000000..91e40df --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:00Z +exit 139 +ms 328 +sha256_out e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.rc b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.rc new file mode 100644 index 0000000..897bdc8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/0017-head-run-string-annotated-int-TODAY.rc @@ -0,0 +1 @@ +139 diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/CLAIMS.md b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/CLAIMS.md new file mode 100644 index 0000000..129303e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/CLAIMS.md @@ -0,0 +1,151 @@ +# CLAIMS — cycle 17, annotations are never checked + +Source doc: `docs/v1/experiments/cycles/17-annotations-are-never-checked.md` + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `cb7289f06510c002b6ab7c5ca8c2bd182d8216bc` | thread provenance end to end | +| experiment (system under test) | `f1a7e224a77f020315a81f62d297b7ebff9b822d` | verify the annotation against what it annotates | +| land (merge) | `923f6a4bedc3b26b2a89b699b5623323d3d0c9f0` | land annotation checking: the declared type is finally verified | +| current HEAD at re-run time | `a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7` | instrument build log | + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A0 | **Status: verified on `experiment/annotation-checking`, not merged** | `0015-branch-status-not-merged-claim.out` | — | **DIVERGED** | +| A1 | P1: `let x: Int = "hello"` compiles clean | `0003`, `0005-pre-cc-h1-clean.out` | `cb7289f` | REPRODUCED | +| A2 | P2: `let s: String = 42` compiles clean | `0004`, `0006-pre-cc-h2-clean.out` | `cb7289f` | REPRODUCED | +| A3 | `let x: Int = "hello"; x + 1` → **4343631981**, a string POINTER used as an integer | `0007`, `0009-pre-int-annotated-string-ten-runs.out` | `cb7289f` | REPRODUCED as a class; **NOT-REPRODUCIBLE** as a literal (see below) | +| A4 | `let s: String = 42; println(s)` → **nothing**, address 42 dereferenced as a string | `0008-pre-run-string-annotated-int.out` | `cb7289f` | REPRODUCED, and **the record omits the exit code** | +| A5 | P3: the annotation drives dispatch, unverified | `0003`, `0004` | `cb7289f` | REPRODUCED | +| A6 | P5: checking literal-vs-annotation catches both | `0010-post-annotation-checker-catches-both.out` | `f1a7e224` | REPRODUCED | +| A7 | P6: zero false positives across the compiler's own source | `0011-post-annotation-query-harness.out` | `f1a7e224` | REPRODUCED | +| A8 | "Verified: 6/6" | `0011` (harness carries **5** assertions) | `f1a7e224` | REPRODUCED as predictions P1–P6; the harness is 5/5 | +| A9 | fixpoint ok | `0012-post-fixpoint.out` | `f1a7e224` | REPRODUCED | +| A10 | 105/105 native | `0013-post-native-suite.out` | `f1a7e224` | REPRODUCED (exact) | +| A11 | the emitter only **records**; `tools/check/annotations.sh` decides | `0010` | `f1a7e224` | REPRODUCED | +| A12 | Incomplete, stated not hidden: only literals — `let x: Int = some_string_fn()` still passes | `0014-post-incomplete-only-literals.out` | `f1a7e224` | REPRODUCED | +| A13 | P4: same root cause as all three bugs found that day | — | — | **NOT-CAPTURED** (interpretive) | +| A14 | **the defects at current HEAD** | `0016`, `0017-head-run-string-annotated-int-TODAY.out` | `a0cc95e3` | **BOTH STILL LIVE** | + +## A0 — the status header is wrong: it was merged + +``` +branches named experiment/annotation-checking: 0 +is f1a7e224 an ancestor of iteration-2? YES-MERGED +merge commit: 923f6a4b land annotation checking: the declared type is finally verified +``` + +The doc opens **"Status: verified on `experiment/annotation-checking`, not +merged."** The work is on `iteration-2` and on `main`, landed by merge commit +`923f6a4b`, and no branch of that name exists any more. The status line is stale +and the record should not be read as describing unmerged work. + +## A3 / A4 — the two hazards, at `cb7289f` + +Fixtures `fixtures/int_annotated_string.el` and +`fixtures/string_annotated_int.el`. Emitted C (`0003`, `0004`): + +```c +el_val_t x = EL_STR("hello"); /* declared Int */ +println(int_to_str((x + 1))); + +el_val_t s = 42; /* declared String */ +println(s); +``` + +`cc` reports **0 errors** on both (`0005`, `0006`). Then: + +**`let x: Int = "hello"; x + 1`** — exit **0**, prints a raw address (`0007`): + +``` +4296429677 +``` + +Ten consecutive runs of the same binary (`0009`): + +``` +4308013165 4369141869 4300738669 4308783213 4302131309 +4378923117 4339404909 4310225005 4310487149 4307406957 + +claimed in the record: 4343631981 +``` + +The value is a heap address and is different on every run. The record's +`4343631981` cannot be reproduced as a literal and never could be — but it falls +inside the observed distribution (4.30–4.38 × 10⁹), so it is a valid single +sample rather than a wrong number. The claim that matters — **a raw memory +address leaks into program output** — reproduces on every run. + +**`let s: String = 42; println(s)`** — stdout **0 bytes**, and exit **139** +(`0008`). The record says "→ nothing". Nothing was printed, correctly; but the +process died on SIGSEGV and the record does not say so. Address 42 was +dereferenced as a `char*`, exactly as the analysis states — the missing detail +is that the dereference faulted rather than returning garbage. This is the same +omission as cycle 13's, and the same shape as measurement defect 4 in cycle 19: +an exit code that was never read. + +## A14 — the standing finding: both defects are live at HEAD + +Re-run today against the compiler built from `a0cc95e3`: + +| program | emitted | stdout | exit | +|---|---|---|---| +| `let x: Int = "hello"; x + 1` | unchanged | `4296710433` | **0** (`0016`) | +| `let s: String = 42; println(s)` | unchanged | *(empty)* | **139** (`0017`) | + +The checker landed; the compiler did not change. `tools/check/annotations.sh` is +a post-hoc query over emitted relations — nothing in the emission path refuses +the program, so a build that does not run the checker still produces the +reinterpreting binary. **The arbitrary-read primitive described in this cycle is +unmitigated in the compiler at HEAD.** That is the most consequential standing +result in this set of nine. + +## A6 / A11 / A12 — the checker at `f1a7e224` + +`0010`: + +``` +--- int_annotated_string --- +type error in main: 'x' is declared Int but assigned a String literal — the annotation drives dispatch, so the value will be reinterpreted rather than rejected +exit=1 +--- string_annotated_int --- +type error in main: 's' is declared String but assigned a Int literal — the annotation drives dispatch, so the value will be reinterpreted rather than rejected +exit=1 +``` + +`0011` — the harness, 5 assertions, including the false-positive control over +the compiler's own source: + +``` + ok Int annotated on a String literal is caught + ok and names the variable + ok String annotated on an Int literal is caught + ok correct annotations are clean + ok the compiler's own source is clean — no false positives + + 5 assertions, 5 passed, 0 failed +``` + +`0014` — the stated gap, confirmed: `let x: Int = str_upper("abc")` is a +non-literal initialiser and the checker reports `annotations: clean`, exit 0. +The incompleteness is exactly as declared. + +## Note on "6/6" + +The doc's `Results — 6/6` refers to predictions P1–P6, all of which are +individually graded above. The committed harness +(`tests/integration/annotation_query.sh`) carries **5** assertions and reports +`5 assertions, 5 passed, 0 failed`. There is no 6-assertion harness; the two +numbers count different things and neither is wrong. + +## Provenance notes + +All artifacts from dedicated worktrees `/tmp/rerun-v1b-17-pre` (`cb7289f`), +`/tmp/rerun-v1b-17-post` (`f1a7e224`) and `/tmp/rerun-v1b-head` (`a0cc95e3`), +`capture.sh` invoked by absolute path from inside each. **No DIRTY-TREE flags in +this cycle.** Exit codes for `0007`, `0008`, `0016` and `0017` were captured +directly by `capture.sh`, never through a pipe. diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/MANIFEST.tsv b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/MANIFEST.tsv new file mode 100644 index 0000000..f6d9395 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/MANIFEST.tsv @@ -0,0 +1,18 @@ +sha256 bytes exit ms commit tree utc artifact command +68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 9 0 3911 cb7289f06510 clean 2026-08-17T17:40:35Z 0001-build-gen1-pre.out bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17pre.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17pre.c $SRCS $LF && echo BUILD-OK +68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 9 0 4000 f1a7e224a77f clean 2026-08-17T17:40:39Z 0002-build-gen1-post.out bash -c cd /tmp/rerun-v1b-17-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17post.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17post.c $SRCS $LF && echo BUILD-OK +a66a5ce074fb9576873861b724de4ee63f4d3cbf87b6457ecc289507868a9299 219 0 172 cb7289f06510 clean 2026-08-17T17:40:45Z 0003-pre-emit-c-int_annotated_string.out bash -c cd /tmp/rerun-v1b-17-pre/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/int_annotated_string.el +d1da9e3d17f33a78721c53970194778a5d0627a3f0a4539c1a5e86e3051ab96d 188 0 11 cb7289f06510 clean 2026-08-17T17:40:45Z 0004-pre-emit-c-string_annotated_int.out bash -c cd /tmp/rerun-v1b-17-pre/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/string_annotated_int.el +a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 9 0 3307 cb7289f06510 clean 2026-08-17T17:40:57Z 0005-pre-cc-h1-clean.out bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1.c $SRCS $LF && echo CC-CLEAN +a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 9 0 3249 cb7289f06510 clean 2026-08-17T17:41:01Z 0006-pre-cc-h2-clean.out bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h2.c $SRCS $LF && echo CC-CLEAN +f707cf113f7be78429f2a8bdf817405eea5e888f791aaace6edee95d590a3c9d 11 0 189 cb7289f06510 clean 2026-08-17T17:41:01Z 0007-pre-run-int-annotated-string.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1 +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 139 165 cb7289f06510 clean 2026-08-17T17:41:01Z 0008-pre-run-string-annotated-int.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h2 +9d1482bd0fcd6c396a0c4e48653a7992eb6353ba672d488946e310166801f730 145 0 56 cb7289f06510 clean 2026-08-17T17:41:14Z 0009-pre-int-annotated-string-ten-runs.out bash -c for i in $(seq 1 10); do /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/h1; done; echo; echo "claimed in the record: 4343631981" +b2a75592f425a76b3d6ee0480e186c450157135282cf3c66de11c45cff176f5a 396 0 371 f1a7e224a77f clean 2026-08-17T17:41:23Z 0010-post-annotation-checker-catches-both.out bash -c cd /tmp/rerun-v1b-17-post/lang && for f in int_annotated_string string_annotated_int; do echo "--- $f ---"; EL_RELATIONS_OUT=/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17_$f.txt /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/$f.el > /dev/null 2>&1; ./tools/check/annotations.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17_$f.txt; echo "exit=$?"; done +fd8354898660faa4fae68be1e10dfd30326d2cc60412fb42a87b6db3d1c8dd8f 276 0 1961 f1a7e224a77f clean 2026-08-17T17:41:25Z 0011-post-annotation-query-harness.out ./tests/integration/annotation_query.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post +1b4889e0050c409ace27706da41238ec276f0ac02d0e8f9ca07d5e2d1145aa8e 12 0 4170 f1a7e224a77f clean 2026-08-17T17:41:42Z 0012-post-fixpoint.out bash -c cd /tmp/rerun-v1b-17-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17post elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p2.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p2.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p3.c 2>/dev/null && cmp /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p2.c /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g17p3.c && echo FIXPOINT-OK || echo FIXPOINT-FAIL +ac5e94f50ee400866b6acaf6802fc4ae07153316f92014887ba7a90a13dd3d01 4329 0 4199 f1a7e224a77f clean 2026-08-17T17:41:46Z 0013-post-native-suite.out bash -c cd /tmp/rerun-v1b-17-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 --test tests/native/test_compiler.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t17 +ff06376ea9773a8398d656380d7924ff274a8105a1298ec7635c11c5ede5798f 82 0 21 f1a7e224a77f clean 2026-08-17T17:41:46Z 0014-post-incomplete-only-literals.out bash -c cd /tmp/rerun-v1b-17-post/lang && printf "fn main() {\n let x: Int = str_upper(\"abc\")\n println(int_to_str(x))\n}\n" > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/nonlit.el; EL_RELATIONS_OUT=/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17nl.txt /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17p2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/nonlit.el > /dev/null 2>&1; ./tools/check/annotations.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/rel17nl.txt; echo "exit=$? (the record states this gap: only literals are checked)" +4ddf9189bdb9cd4e16d39a1efbe3d9853aebeae4abbe65d4caa2b2043db9fc36 194 0 37 f1a7e224a77f clean 2026-08-17T17:41:46Z 0015-branch-status-not-merged-claim.out bash -c cd /Users/will/Development/neuron-technologies/foundation/el && echo "branches named experiment/annotation-checking:"; git branch -a --list "*annotation-checking*" | wc -l; echo "is f1a7e224 an ancestor of iteration-2?"; git merge-base --is-ancestor f1a7e224 iteration-2 && echo YES-MERGED || echo NO; echo "merge commit:"; git log --all --oneline --merges --grep="land annotation checking" +a727c8fc554ed3c6ccc19162ce61088e50bdce6b1b972227a1b7099185ed4cb8 11 0 174 a0cc95e3db7b clean 2026-08-17T17:46:59Z 0016-head-run-int-annotated-string-TODAY.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head_int_annotated_string +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 139 328 a0cc95e3db7b clean 2026-08-17T17:47:00Z 0017-head-run-string-annotated-int-TODAY.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head_string_annotated_int diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/RUN.env b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/RUN.env new file mode 100644 index 0000000..c16ddad --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:40:31Z +git_sha cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +git_dirty no +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/fixtures/int_annotated_string.el b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/fixtures/int_annotated_string.el new file mode 100644 index 0000000..38f2808 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/fixtures/int_annotated_string.el @@ -0,0 +1,4 @@ +fn main() { + let x: Int = "hello" + println(int_to_str(x + 1)) +} diff --git a/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/fixtures/string_annotated_int.el b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/fixtures/string_annotated_int.el new file mode 100644 index 0000000..e5f7a8a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/fixtures/string_annotated_int.el @@ -0,0 +1,4 @@ +fn main() { + let s: String = 42 + println(s) +} diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.cmd b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.cmd new file mode 100644 index 0000000..59f7778 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-18/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g18.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc18 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g18.c $SRCS $LF && echo BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.err b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.out b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.out new file mode 100644 index 0000000..1c5c36b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.out @@ -0,0 +1 @@ +BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.prov b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.prov new file mode 100644 index 0000000..0f3c3c6 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.prov @@ -0,0 +1,7 @@ +commit 511db25230c69b9484ece39ed4131d3920b16596 +tree clean +captured_utc 2026-08-17T17:45:32Z +exit 0 +ms 3972 +sha256_out 68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.rc b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0001-build-gen1-511db252.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.cmd b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.cmd new file mode 100644 index 0000000..bb56edc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.cmd @@ -0,0 +1 @@ +./tests/integration/async_future.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc18 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.err b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.out b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.out new file mode 100644 index 0000000..da06c59 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.out @@ -0,0 +1,8 @@ + ok unbound: no construct, synchronous, correct result + ok unbound: el_await on a non-future passes through, no crash + ok bound: does not crash + ok bound: the awaited result is correct + ok bound: the caller continues BEFORE the body finishes + ok bound: the wrap returns in under 10ms while the body takes 50ms + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.prov b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.prov new file mode 100644 index 0000000..b4f9137 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.prov @@ -0,0 +1,7 @@ +commit 511db25230c69b9484ece39ed4131d3920b16596 +tree clean +captured_utc 2026-08-17T17:45:36Z +exit 0 +ms 3868 +sha256_out ac52afda852cfe4d226b7fbe46cedbb3bc22be2b592af815e88c41a2f9d23b5d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.rc b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0002-async-future-harness-6-assertions.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.cmd b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.cmd new file mode 100644 index 0000000..38a0746 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-18/lang/runtime && echo "--- EL_MAGIC_* definitions in el_runtime.c/h ---"; grep -hoE "#define EL_MAGIC_[A-Z_]+" el_runtime.c el_runtime.h | sort -u; echo; printf "count: "; grep -hoE "#define EL_MAGIC_[A-Z_]+" el_runtime.c el_runtime.h | sort -u | wc -l diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.err b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.out b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.out new file mode 100644 index 0000000..538b5a7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.out @@ -0,0 +1,8 @@ +--- EL_MAGIC_* definitions in el_runtime.c/h --- +#define EL_MAGIC_BIN +#define EL_MAGIC_GEOM +#define EL_MAGIC_LIST +#define EL_MAGIC_MAP +#define EL_MAGIC_MFLD + +count: 5 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.prov b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.prov new file mode 100644 index 0000000..43de4d8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.prov @@ -0,0 +1,7 @@ +commit 511db25230c69b9484ece39ed4131d3920b16596 +tree clean +captured_utc 2026-08-17T17:45:45Z +exit 0 +ms 21 +sha256_out 2090b2584a902c6b4c584ef52388a225740bdad95ce894ff1306e2946de34711 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.rc b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0003-P1-five-magic-tags.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.cmd b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.cmd new file mode 100644 index 0000000..a5fed3f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.cmd @@ -0,0 +1 @@ +bash -c cd /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/a18 && ./p diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.err b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.out b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.out new file mode 100644 index 0000000..eac1966 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.out @@ -0,0 +1,2 @@ +CALLER_CONTINUED +RESULT 42 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.prov b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.prov new file mode 100644 index 0000000..a66f47f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.prov @@ -0,0 +1,7 @@ +commit 511db25230c69b9484ece39ed4131d3920b16596 +tree clean +captured_utc 2026-08-17T17:46:04Z +exit 0 +ms 151 +sha256_out 6b1aa833faeb5a1e2ab104d1813e5eeab770c59ad6345582be8517c7f42e8d97 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.rc b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0004-P4-zero-compiler-changes-unbound-run.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.cmd b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.cmd new file mode 100644 index 0000000..abb6b9a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.cmd @@ -0,0 +1 @@ +bash -c cd /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/a18 && EL_CONSTRUCTS=c.txt ./p diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.err b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.out b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.out new file mode 100644 index 0000000..1edad6b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.out @@ -0,0 +1,5 @@ +WRAP_RETURNED 12 +CALLER_CONTINUED +BODY_START 20 +BODY_END 55034 +RESULT 42 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.prov b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.prov new file mode 100644 index 0000000..b96fffa --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.prov @@ -0,0 +1,7 @@ +commit 511db25230c69b9484ece39ed4131d3920b16596 +tree clean +captured_utc 2026-08-17T17:46:04Z +exit 0 +ms 68 +sha256_out 5c175965d04514c1ec1d4d7c8a245449f54eefc7a490ccb0e7a892e404f4aae7 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.rc b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/0005-P2P3-bound-run-interleaving.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/CLAIMS.md b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/CLAIMS.md new file mode 100644 index 0000000..3a64f92 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/CLAIMS.md @@ -0,0 +1,135 @@ +# CLAIMS — cycle 18, async — half expressible, and the cycle that was dogma + +Source doc: `docs/v1/experiments/cycles/18-async-half-expressible.md` + +This cycle is unusual: the doc already carries a chain-of-custody note stating +that its original artifacts were destroyed and that it was **rerun, not +reconstructed**. The verdicts below respect that. Where the original artifact is +gone the verdict is NOT-CAPTURED, and the replication is graded separately. + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| replication landed (system under test) | `511db25230c69b9484ece39ed4131d3920b16596` | rerun cycle 18 rather than reconstruct it | +| original measurement | — | **no commit.** The C stub lived in `/tmp` and was destroyed with the session worktrees | + +`511db252` is the only commit that has ever contained +`lang/tests/integration/async_future.sh` or +`lang/tests/integration/fixtures/future.c`. + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | the first attempt was dogma: `pthread_join` immediately after `pthread_create`, and the test printed the word `DEFERRED` itself | — | — | **NOT-CAPTURED** (artifact destroyed; the doc says so) | +| A2 | second run, 4/4: `[18 us] wrap RETURNS`, `[29 us] body START`, `caller continues, got 0`, `[50176 us] body END (computed 42)` | — | — | **NOT-CAPTURED** (artifact destroyed; the doc says so) | +| A3 | the caller got **0, not 42** on the second run | — | — | **NOT-CAPTURED** | +| A4 | the fixture now lives at `lang/tests/integration/fixtures/future.c` and the harness at `lang/tests/integration/async_future.sh` | `0002`, repo tree at `511db252` | `511db252` | REPRODUCED | +| A5 | **6/6** on the replication harness | `0002-async-future-harness-6-assertions.out` | `511db252` | REPRODUCED (exact) | +| A6 | follow-on P1: `el_val_t` already carries tagged heap objects — **5 magic tags exist** | `0003-P1-five-magic-tags.out` | `511db252` | REPRODUCED (exact) | +| A7 | follow-on P2/P3: a future is one more; the caller awaits and gets **42** | `0005-P2P3-bound-run-interleaving.out` | `511db252` | REPRODUCED | +| A8 | follow-on P4: **ZERO compiler changes** — runtime C plus one binding | `0004`, `0005` | `511db252` | REPRODUCED | +| A9 | P1/P2 of the second run: the caller proceeds while the body runs; interleaving is observable in timestamps | `0005` | `511db252` | REPRODUCED | +| A10 | follow-on P5: the unbound path still works — **FALSE, SIGSEGV** | — | — | **NOT-CAPTURED** (see note) | +| A11 | the compiler builds at `511db252` | `0001-build-gen1-511db252.out` | `511db252` | REPRODUCED | + +## A5 — the replication, 6/6 + +`0002`, harness run against the compiler built from `511db252`: + +``` + ok unbound: no construct, synchronous, correct result + ok unbound: el_await on a non-future passes through, no crash + ok bound: does not crash + ok bound: the awaited result is correct + ok bound: the caller continues BEFORE the body finishes + ok bound: the wrap returns in under 10ms while the body takes 50ms + + 6 assertions, 6 passed, 0 failed +``` + +Exit 0. The harness's own header states it is a replication and not a blind +test — the outcomes were known before it was written — and that grading is +carried forward here unchanged. + +## A8 / A9 — zero compiler changes, demonstrated + +The same El source (`fixtures/probe.el`), compiled by the stock `elc`, run twice +against the same binary. + +Unbound — no construct file, synchronous (`0004`): + +``` +CALLER_CONTINUED +RESULT 42 +``` + +Bound — `EL_CONSTRUCTS=c.txt` containing `work async wrap defer` (`0005`): + +``` +WRAP_RETURNED 12 +CALLER_CONTINUED +BODY_START 20 +BODY_END 55034 +RESULT 42 +``` + +Same compiler, same emitted C, same binary; deferral appears only because a +construct was bound after the build. The wrap returns at **12 µs** while the +body finishes at **55 034 µs**, and `CALLER_CONTINUED` precedes `BODY_END` — +the caller demonstrably proceeds while the body runs. The record's own numbers +were 18 µs / 29 µs / 50 176 µs; the shape matches and the magnitudes are +consistent (the body sleeps 50 ms by construction). + +`RESULT 42` is the follow-on P3: with a future as one more tagged heap object, +the caller awaits and gets the real value. + +## A6 — five tags, and a future would be the sixth + +`0003`, over `el_runtime.c` and `el_runtime.h` at `511db252`: + +``` +#define EL_MAGIC_BIN +#define EL_MAGIC_GEOM +#define EL_MAGIC_LIST +#define EL_MAGIC_MAP +#define EL_MAGIC_MFLD + +count: 5 +``` + +and `fixtures/future.c` adds `#define EL_MAGIC_FUT 0xE1F07000u` in the fixture, +not in the compiler. + +## A10 — why the SIGSEGV is NOT-CAPTURED + +Follow-on P5 records that the first `el_await` read `->magic` off an unvalidated +slot and segfaulted on the unbound path. That version was never committed. The +committed `future.c` carries the repair and a comment naming the defect: + +```c +el_val_t el_await(el_val_t h){ + if (h < 0x10000) return h; /* small ints / low addresses */ + if (h & 0x7) return h; /* malloc returns 8-aligned */ + ElFuture* f = (ElFuture*)(intptr_t)h; + if (f->magic != EL_MAGIC_FUT) return h; /* safe to read now */ +``` + +so the harness's second assertion ("unbound: `el_await` on a non-future passes +through, no crash") passes today. The historical failure has no artifact and one +was not manufactured. The *class* it belongs to is independently reproduced in +cycle 19 (`0005-P6-sha256-hex-50000-exit-code.out`, exit 139), which is the +cycle P5 opened. + +## Provenance notes + +All artifacts from `/tmp/rerun-v1b-18`, a dedicated worktree at `511db252`, with +`capture.sh` invoked by absolute path from inside it. **No DIRTY-TREE flags in +this cycle.** + +Three of this cycle's claims (A1, A2, A3) rest on a file that no longer exists. +They are recorded as NOT-CAPTURED. Producing a `/tmp` C stub today and dating it +to 2026-08-17 would be fabrication with a fresh timestamp; the doc's own +chain-of-custody note already says as much, and this re-run does not go behind +it. diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/MANIFEST.tsv b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/MANIFEST.tsv new file mode 100644 index 0000000..1c9580a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/MANIFEST.tsv @@ -0,0 +1,6 @@ +sha256 bytes exit ms commit tree utc artifact command +68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 9 0 3972 511db25230c6 clean 2026-08-17T17:45:32Z 0001-build-gen1-511db252.out bash -c cd /tmp/rerun-v1b-18/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g18.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc18 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g18.c $SRCS $LF && echo BUILD-OK +ac52afda852cfe4d226b7fbe46cedbb3bc22be2b592af815e88c41a2f9d23b5d 370 0 3868 511db25230c6 clean 2026-08-17T17:45:36Z 0002-async-future-harness-6-assertions.out ./tests/integration/async_future.sh /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc18 +2090b2584a902c6b4c584ef52388a225740bdad95ce894ff1306e2946de34711 174 0 21 511db25230c6 clean 2026-08-17T17:45:45Z 0003-P1-five-magic-tags.out bash -c cd /tmp/rerun-v1b-18/lang/runtime && echo "--- EL_MAGIC_* definitions in el_runtime.c/h ---"; grep -hoE "#define EL_MAGIC_[A-Z_]+" el_runtime.c el_runtime.h | sort -u; echo; printf "count: "; grep -hoE "#define EL_MAGIC_[A-Z_]+" el_runtime.c el_runtime.h | sort -u | wc -l +6b1aa833faeb5a1e2ab104d1813e5eeab770c59ad6345582be8517c7f42e8d97 27 0 151 511db25230c6 clean 2026-08-17T17:46:04Z 0004-P4-zero-compiler-changes-unbound-run.out bash -c cd /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/a18 && ./p +5c175965d04514c1ec1d4d7c8a245449f54eefc7a490ccb0e7a892e404f4aae7 73 0 68 511db25230c6 clean 2026-08-17T17:46:04Z 0005-P2P3-bound-run-interleaving.out bash -c cd /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/a18 && EL_CONSTRUCTS=c.txt ./p diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/RUN.env b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/RUN.env new file mode 100644 index 0000000..42f70ce --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:45:27Z +git_sha 511db25230c69b9484ece39ed4131d3920b16596 +git_dirty no +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/v1/experiments/evidence/cycles/18-async-half-expressible/fixtures/probe.el b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/fixtures/probe.el new file mode 100644 index 0000000..bac0bc5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/18-async-half-expressible/fixtures/probe.el @@ -0,0 +1,12 @@ +extern fn el_await(h: Int) -> Int + +fn work(k: Int) -> Int { + return k * 2 +} + +fn main() { + let h: Int = work(21) + println("CALLER_CONTINUED") + let r: Int = el_await(h) + println("RESULT " + int_to_str(r)) +} diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.cmd new file mode 100644 index 0000000..59f06c0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang/runtime && echo "--- definition ---"; grep -n "static int looks_like_heap_obj" el_runtime.c; echo "--- exported in el_runtime.h? ---"; grep -c "looks_like_heap_obj\|el_tagged" el_runtime.h diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.out new file mode 100644 index 0000000..9a4d847 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.out @@ -0,0 +1,4 @@ +--- definition --- +715:static int looks_like_heap_obj(el_val_t v) { +--- exported in el_runtime.h? --- +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.prov new file mode 100644 index 0000000..033d004 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:42:30Z +exit 1 +ms 21 +sha256_out 4bb775ca37a9c774d59d555a1ee3115723763b0fee42d533f77d030c8c563f1d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.rc new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0001-P1-looks-like-heap-obj-is-static.rc @@ -0,0 +1 @@ +1 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.cmd new file mode 100644 index 0000000..a07ddcd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang/runtime && echo "geom_of :"; sed -n "6296,6299p" el_runtime.c; echo "mfld_of :"; sed -n "6502,6505p" el_runtime.c; echo "el_bin_lookup:"; sed -n "18270,18280p" el_runtime.c; echo "el_input_len :"; sed -n "18283,18287p" el_runtime.c diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.out new file mode 100644 index 0000000..4d4bc7c --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.out @@ -0,0 +1,28 @@ +geom_of : + * than a dereference. */ +static ElGeometry* geom_of(el_val_t g) { + if (!looks_like_heap_obj(g)) return NULL; + ElGeometry* p = (ElGeometry*)(uintptr_t)g; +mfld_of : + * this, so a stale/foreign/zero value is a clean 0-return, never a deref. */ +static ElManifold* mfld_of(el_val_t m) { + if (!looks_like_heap_obj(m)) return NULL; + ElManifold* p = (ElManifold*)(uintptr_t)m; +el_bin_lookup: +static int el_bin_lookup(const void* p, size_t* out_len) { + if (!p) { *out_len = 0; return 0; } + /* Avoid reading off the front of a page on tiny pointers (e.g. NULs + * passed in as int-cast values). 4096 is a safe lower bound on any + * platform we target. */ + if ((uintptr_t)p < 4096) return 0; + const el_bin_hdr_t* hdr = (const el_bin_hdr_t*)((const char*)p - sizeof(el_bin_hdr_t)); + if (hdr->magic != EL_MAGIC_BIN) return 0; + *out_len = hdr->length; + return 1; +} +el_input_len : +static size_t el_input_len(const char* s) { + size_t n; + if (el_bin_lookup(s, &n)) return n; + return s ? strlen(s) : 0; +} diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.prov new file mode 100644 index 0000000..1a69378 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:42:30Z +exit 0 +ms 23 +sha256_out 4b9e15663e339c06e92493b7122bea8257ccd7c606be594da3f363937ae99629 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0002-P2P3-four-tagged-checks.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.cmd new file mode 100644 index 0000000..a4dbde1 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/sha256_hex_int.el diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.out new file mode 100644 index 0000000..4a18cc5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.out @@ -0,0 +1,11 @@ +#include +#include +#include "el_runtime.h" + + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + println(sha256_hex(50000)); + return 0; +} + diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.prov new file mode 100644 index 0000000..9b87fa3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:42:41Z +exit 0 +ms 14 +sha256_out 2dcb5a1ee91d06df9af44e7a59ba0f1a5c38201b5f80dccbfadb4bf590df7eeb +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0003-pre-emit-c-sha256-int.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.cmd new file mode 100644 index 0000000..de96bdb --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19.c $SRCS $LF && echo CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.err new file mode 100644 index 0000000..5e6d69b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14448:1: warning: '/*' within block comment [-Wcomment] + 14448 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.out new file mode 100644 index 0000000..0c50dfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.out @@ -0,0 +1 @@ +CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.prov new file mode 100644 index 0000000..ae82315 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:42:44Z +exit 0 +ms 3195 +sha256_out a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 +sha256_err 15ee96301428d7dc3500fe5b6109a154a87a2f21119365e665575b3e634d662b diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0004-pre-cc-compiles-clean.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.cmd new file mode 100644 index 0000000..31ec392 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.out new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.prov new file mode 100644 index 0000000..6856218 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:42:45Z +exit 139 +ms 229 +sha256_out e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.rc new file mode 100644 index 0000000..897bdc8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0005-P6-sha256-hex-50000-exit-code.rc @@ -0,0 +1 @@ +139 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.cmd new file mode 100644 index 0000000..b523548 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.cmd @@ -0,0 +1 @@ +bash -c set +o pipefail; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 | head -1; echo "exit code read THROUGH A PIPE: $? <- this is measurement defect 4"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 > /dev/null 2>&1; echo "exit code read DIRECTLY: $? <- the truth" diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.err new file mode 100644 index 0000000..785e3c1 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.err @@ -0,0 +1 @@ +bash: line 1: 92460 Segmentation fault: 11 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 > /dev/null 2>&1 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.out new file mode 100644 index 0000000..eaf8040 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.out @@ -0,0 +1,2 @@ +exit code read THROUGH A PIPE: 0 <- this is measurement defect 4 +exit code read DIRECTLY: 139 <- the truth diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.prov new file mode 100644 index 0000000..e5c2a1b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.prov @@ -0,0 +1,7 @@ +commit cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +tree clean +captured_utc 2026-08-17T17:42:52Z +exit 0 +ms 17 +sha256_out 6d4cbbfbbf5dac7a15bd48c3ee7af9fc13d4474ab07569971196bd0c50c12185 +sha256_err 8ea8ad36c5c05d57b0518279e8a86d9eeff6d921d4b8e8461f85715341238c80 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0006-measurement-defect-4-control-pipe-hides-sigsegv.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.cmd new file mode 100644 index 0000000..e136144 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && grep -n el_tagged runtime/el_runtime.h diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.out new file mode 100644 index 0000000..105a525 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.out @@ -0,0 +1 @@ +891:int el_tagged(el_val_t v, uint32_t magic); /* the gate: validate a slot BEFORE dereferencing it */ diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.prov new file mode 100644 index 0000000..37639ee --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:43:22Z +exit 0 +ms 11 +sha256_out 08106dd493eec64aa21350159fcdb570990c2cc39b9bd23772f2687ef7a43de0 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0007-post-el-tagged-exported.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.cmd new file mode 100644 index 0000000..b414aa7 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19.c $SRCS $LF && echo BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.out new file mode 100644 index 0000000..1c5c36b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.out @@ -0,0 +1 @@ +BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.prov new file mode 100644 index 0000000..68f132b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:43:26Z +exit 0 +ms 3840 +sha256_out 68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0008-post-build-gen1-9a6c161.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.cmd new file mode 100644 index 0000000..7e638c8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/sha256_hex_int.el diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.out new file mode 100644 index 0000000..4a18cc5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.out @@ -0,0 +1,11 @@ +#include +#include +#include "el_runtime.h" + + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + println(sha256_hex(50000)); + return 0; +} + diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.prov new file mode 100644 index 0000000..0ba92ff --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:43:26Z +exit 0 +ms 195 +sha256_out 2dcb5a1ee91d06df9af44e7a59ba0f1a5c38201b5f80dccbfadb4bf590df7eeb +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0009-post-emit-c-sha256-int.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.cmd new file mode 100644 index 0000000..ec5d14f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p.c $SRCS $LF && echo CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.out new file mode 100644 index 0000000..0c50dfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.out @@ -0,0 +1 @@ +CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.prov new file mode 100644 index 0000000..1fe61db --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:43:29Z +exit 0 +ms 3018 +sha256_out a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0010-post-cc.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.cmd new file mode 100644 index 0000000..7dc1778 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.out new file mode 100644 index 0000000..c306804 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.out @@ -0,0 +1 @@ +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.prov new file mode 100644 index 0000000..e1be242 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:43:29Z +exit 0 +ms 180 +sha256_out 38acb15d02d5ac0f2a2789602e9df950c380d2799b4bdb59394e4eeabdd3a662 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0011-post-sha256-hex-50000-no-longer-segfaults.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.cmd new file mode 100644 index 0000000..c3b8517 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.cmd @@ -0,0 +1 @@ +bash -c printf "pre sha256_hex(abc) = "; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/legit_pre; printf "post sha256_hex(abc) = "; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/legit_post; printf "reference (openssl) = "; printf abc | shasum -a 256 | cut -d\ -f1 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.out new file mode 100644 index 0000000..e0d8412 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.out @@ -0,0 +1,3 @@ +pre sha256_hex(abc) = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad +post sha256_hex(abc) = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad +reference (openssl) = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.prov new file mode 100644 index 0000000..a8f566d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:43:47Z +exit 0 +ms 324 +sha256_out ccc07cddd4839fc41f1bef4a67e4d5c723fc91084c49e86ca9ea15bc9cf7f4ab +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0012-P9-legitimate-hash-unchanged.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.cmd new file mode 100644 index 0000000..221515a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19 elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_2.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_2.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_3.c 2>/dev/null && cmp /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_2.c /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_3.c && echo FIXPOINT-OK || echo FIXPOINT-FAIL diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.out new file mode 100644 index 0000000..35a016e --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.out @@ -0,0 +1 @@ +FIXPOINT-OK diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.prov new file mode 100644 index 0000000..aed1846 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:44:00Z +exit 0 +ms 4120 +sha256_out 1b4889e0050c409ace27706da41238ec276f0ac02d0e8f9ca07d5e2d1145aa8e +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0013-P11-fixpoint.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.cmd new file mode 100644 index 0000000..a330214 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 --test tests/native/test_compiler.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.out new file mode 100644 index 0000000..b05e440 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.out @@ -0,0 +1,107 @@ +ok lex-empty (0.055ms) +ok lex-whitespace-stripped (0.002ms) +ok lex-comment-stripped (0.001ms) +ok lex-int-literals (0.002ms) +ok lex-float-literals (0.013ms) +ok lex-string-literals (0.002ms) +ok lex-string-escape-newline (0.001ms) +ok lex-string-escape-tab (0.000ms) +ok lex-string-escape-backslash (0.001ms) +ok lex-bool-literals (0.002ms) +ok lex-identifier (0.002ms) +ok lex-keywords (0.005ms) +ok lex-more-keywords (0.001ms) +ok lex-keyword-values (0.001ms) +ok lex-arithmetic-operators (0.001ms) +ok lex-comparison-operators (0.001ms) +ok lex-logical-operators (0.001ms) +ok lex-arrow-tokens (0.001ms) +ok lex-delimiters (0.002ms) +ok lex-double-colon (0.000ms) +ok lex-dot-dot (0.000ms) +ok lex-pipe-operators (0.000ms) +ok lex-at-and-question (0.011ms) +ok lex-eof-always-last (0.002ms) +ok lex-string-with-spaces (0.000ms) +ok lex-multiline-source (0.003ms) +ok lex-flat-stride-3-layout (0.001ms) +ok lexer-tracks-line-numbers (0.002ms) +ok parse-let-stmt (0.032ms) +ok parse-fn-decl (0.009ms) +ok parse-fn-params (0.005ms) +ok parse-return-stmt (0.003ms) +ok parse-if-stmt (0.007ms) +ok parse-if-else (0.007ms) +ok parse-while-stmt (0.009ms) +ok parse-import-stmt (0.001ms) +ok parse-extern-fn (0.003ms) +ok parse-let-int-value (0.002ms) +ok parse-let-string-value (0.002ms) +ok parse-let-bool-value (0.002ms) +ok parse-binop-expr (0.003ms) +ok parse-call-expr (0.004ms) +ok parse-multiple-fns (0.006ms) +ok parse-assign-stmt (0.003ms) +ok parse-for-stmt (0.006ms) +ok parse-unary-not (0.004ms) +ok parse-unary-neg (0.004ms) +ok parse-array-literal (0.006ms) +ok parse-empty-array (0.003ms) +ok parse-index-expr (0.003ms) +ok codegen-includes (0.308ms) +ok codegen-int-main (0.160ms) +ok codegen-runtime-init (0.110ms) +ok codegen-void-function-signature (0.120ms) +ok codegen-function-with-params (0.114ms) +ok codegen-int-literal (0.085ms) +ok codegen-string-literal (0.131ms) +ok codegen-if-statement (0.141ms) +ok codegen-if-else (0.117ms) +ok codegen-while-loop (0.114ms) +ok codegen-let-binding (0.088ms) +ok codegen-function-call (0.086ms) +ok codegen-string-concat (0.137ms) +ok codegen-int-arithmetic (0.101ms) +ok codegen-comparison (0.092ms) +ok codegen-string-equality (0.093ms) +ok codegen-logical-and (0.090ms) +ok codegen-logical-or (0.145ms) +ok codegen-unary-not (0.084ms) +ok codegen-string-escape-in-c (0.103ms) +ok codegen-many-functions (0.125ms) +ok codegen-deep-expression (0.121ms) +ok codegen-forward-declarations (0.108ms) +ok codegen-for-loop (0.223ms) +ok codegen-extern-fn (0.112ms) +ok codegen-nested-calls (0.119ms) +ok compiler-minimal-program (0.073ms) +ok compiler-pure-library (0.094ms) +ok compiler-multiple-fns-with-main (0.094ms) +ok compiler-let-in-main (0.071ms) +ok compiler-string-concat-chain (0.103ms) +ok compiler-negative-literal (0.100ms) +ok compiler-stdint-include (0.075ms) +ok decorator-undecorated-fn-has-no-beat (0.067ms) +ok decorator-authenticate-compiles-to-nothing (0.148ms) +ok declared-construct-name-unknown-to-codegen (0.154ms) +ok undeclared-construct-still-injects-nothing (0.086ms) +ok undeclared-guard-emits-nothing (0.069ms) +ok seam-indirection-emitted-on-every-fn (0.071ms) +ok seam-emitted-without-any-decorator (0.065ms) +ok seam-replaces-inlined-entry-injection (0.066ms) +ok seam-entry-is-refusable (0.066ms) +ok seam-is-emitted-for-undecorated-fns (0.060ms) +ok every-fn-gets-a-body-helper-and-wrapper (0.075ms) +ok exit-crossing-goes-through-the-seam (0.060ms) +ok early-returns-route-through-the-exit-seam (0.071ms) +ok every-fn-gets-a-closure (0.056ms) +ok zero-param-fn-emits-valid-c (0.062ms) +ok compiler-no-longer-emits-prohibition-errors (0.116ms) +ok int-returning-builtin-drives-arithmetic-dispatch (0.102ms) +ok string-plus-string-still-concatenates (0.066ms) +ok freed-identifiers-compile-as-identifiers (0.072ms) +ok test-keyword-is-still-reserved (0.061ms) +ok instant-plus-bare-int-is-refused (0.065ms) +ok instant-plus-unit-suffix-is-allowed (0.066ms) + +105 tests, 105 passed, 0 failed, 253 assertions in 5.798ms diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.prov new file mode 100644 index 0000000..22dacae --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:44:05Z +exit 0 +ms 4168 +sha256_out 8fed706c491e2f19afbb7035e1c09d0ae4d67bba9db1a6aedb73dcf2af5c00a2 +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0014-P11-native-suite.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.cmd new file mode 100644 index 0000000..cd09e95 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-post/lang && tot=0; n8=0; for h in tests/integration/*.sh; do out=$("$h" /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 2>&1); rc=$?; n=$(printf "%s" "$out" | grep -oE "^ *[0-9]+ assertions" | grep -oE "[0-9]+" | head -1); printf "%-28s exit=%s assertions=%s\n" "$(basename $h)" "$rc" "${n:-0}"; tot=$((tot+${n:-0})); n8=$((n8+1)); done; echo "harnesses: $n8 TOTAL assertions: $tot" diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.out new file mode 100644 index 0000000..ab69cbd --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.out @@ -0,0 +1,9 @@ +arity_query.sh exit=0 assertions=5 +capability_query.sh exit=0 assertions=5 +definitions_query.sh exit=0 assertions=6 +prohibition_query.sh exit=0 assertions=4 +seam_binding.sh exit=0 assertions=7 +tagged_gate.sh exit=0 assertions=5 +temporal_query.sh exit=0 assertions=6 +temporal_signatures.sh exit=0 assertions=4 +harnesses: 8 TOTAL assertions: 42 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.prov new file mode 100644 index 0000000..c17a015 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree clean +captured_utc 2026-08-17T17:44:21Z +exit 0 +ms 16121 +sha256_out 3a02a406df2b5b0d66949960a4e30a7ec52871886ba0353771a60f84b86380fe +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0015-P11-eight-integration-harnesses.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.cmd new file mode 100644 index 0000000..89e80c4 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-p8/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19p8.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19p8 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19p8.c $SRCS $LF && echo BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.out new file mode 100644 index 0000000..1c5c36b --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.out @@ -0,0 +1 @@ +BUILD-OK diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.prov new file mode 100644 index 0000000..0af177f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree dirty +captured_utc 2026-08-17T17:45:02Z +exit 0 +ms 3929 +sha256_out 68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0016-P8-rederived-build.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.cmd new file mode 100644 index 0000000..fb1b9c3 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-p8/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19p8 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/sha256_hex_int.el diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.out new file mode 100644 index 0000000..4a18cc5 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.out @@ -0,0 +1,11 @@ +#include +#include +#include "el_runtime.h" + + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + println(sha256_hex(50000)); + return 0; +} + diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.prov new file mode 100644 index 0000000..c463daa --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree dirty +captured_utc 2026-08-17T17:45:02Z +exit 0 +ms 180 +sha256_out 2dcb5a1ee91d06df9af44e7a59ba0f1a5c38201b5f80dccbfadb4bf590df7eeb +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0017-P8-rederived-emit-c.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.cmd new file mode 100644 index 0000000..010c3dc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v1b-19-p8/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p8 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p8.c $SRCS $LF && echo CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.err new file mode 100644 index 0000000..d66be18 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.err @@ -0,0 +1,4 @@ +runtime/el_runtime.c:14468:1: warning: '/*' within block comment [-Wcomment] + 14468 | /* ═══════════════════════════════════════════════════════════════════════════ + | ^ +1 warning generated. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.out new file mode 100644 index 0000000..0c50dfc --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.out @@ -0,0 +1 @@ +CC-CLEAN diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.prov new file mode 100644 index 0000000..bfd5b51 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree dirty +captured_utc 2026-08-17T17:45:05Z +exit 0 +ms 3214 +sha256_out a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 +sha256_err 24f9504907bf0d11286da21911398ea3eb01e7423d78c3f8174b0051346bd3d7 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0018-P8-rederived-cc.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.cmd new file mode 100644 index 0000000..13fcec0 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p8 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.out new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.prov new file mode 100644 index 0000000..52f4841 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.prov @@ -0,0 +1,7 @@ +commit 9a6c161ba98a4e34275f46c39f18d120523f1ddb +tree dirty +captured_utc 2026-08-17T17:45:06Z +exit 139 +ms 186 +sha256_out e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.rc new file mode 100644 index 0000000..897bdc8 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0019-P8-rederived-still-segfaults.rc @@ -0,0 +1 @@ +139 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.cmd b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.cmd new file mode 100644 index 0000000..7edd3c2 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.cmd @@ -0,0 +1 @@ +/private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head19 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.err b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.out b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.out new file mode 100644 index 0000000..c306804 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.out @@ -0,0 +1 @@ +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.prov b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.prov new file mode 100644 index 0000000..b8e0d41 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree clean +captured_utc 2026-08-17T17:47:03Z +exit 0 +ms 178 +sha256_out 38acb15d02d5ac0f2a2789602e9df950c380d2799b4bdb59394e4eeabdd3a662 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.rc b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/0020-head-sha256-hex-50000-TODAY.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/CLAIMS.md b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/CLAIMS.md new file mode 100644 index 0000000..572e51f --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/CLAIMS.md @@ -0,0 +1,182 @@ +# CLAIMS — cycle 19, a convention is not a gate + +Source doc: `docs/v1/experiments/cycles/19-a-convention-is-not-a-gate.md` + +## Pinned commits + +| role | sha | subject | +|---|---|---| +| parent / before-state | `cb7289f06510c002b6ab7c5ca8c2bd182d8216bc` | thread provenance end to end | +| experiment (system under test) | `9a6c161ba98a4e34275f46c39f18d120523f1ddb` | a slot must be validated before it is dereferenced | +| land (merge) | `3049a7083707de1508795e5daf3c65ab6ca21995` | make the guard a gate: sha256_hex(50000) no longer segfaults | +| current HEAD at re-run time | `a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7` | instrument build log | + +## Verdicts + +| # | claim | artifact | commit | verdict | +|---|---|---|---|---| +| A1 | P1: `looks_like_heap_obj` is **static, not exported** | `0001-P1-looks-like-heap-obj-is-static.out` | `cb7289f` | REPRODUCED (exact) | +| A2 | P2: each tagged type re-derives the check — `geom_of` and `mfld_of` full guard, `el_bin_lookup` floor only, `el_input_len` NULL only | `0002-P2P3-four-tagged-checks.out` | `cb7289f` | REPRODUCED (exact, all four) | +| A3 | P3: at least one is missing guard components — **two are** | `0002` | `cb7289f` | REPRODUCED | +| A4 | `el_bin_lookup` **reads 8 bytes BACKWARD** | `0002` | `cb7289f` | REPRODUCED (exact) | +| A5 | `el_input_len` **strlen's an integer** | `0002` | `cb7289f` | REPRODUCED (exact) | +| A6 | P6: **`sha256_hex(50000)` → exit 139, SIGSEGV, compiled clean** | `0004-pre-cc-compiles-clean.out`, `0005-P6-sha256-hex-50000-exit-code.out` | `cb7289f` | REPRODUCED (exact) | +| A7 | measurement defect 4: the first run reported `exit=0` because `$?` read `head`'s status through a pipe | `0006-measurement-defect-4-control-pipe-hides-sigsegv.out` | `cb7289f` | REPRODUCED (as a live control) | +| A8 | P8 **IS THE USEFUL FAILURE** — routing `el_bin_lookup` through the gate fixes nothing; the FALLBACK was the hazard | `0016`–`0019-P8-rederived-still-segfaults.out` | `9a6c161` + patch | **NOT-CAPTURED** historically; **CORROBORATED** by re-derivation | +| A9 | P9: the legitimate hash is unchanged | `0012-P9-legitimate-hash-unchanged.out` | `cb7289f` vs `9a6c161` | REPRODUCED | +| A10 | `el_tagged()` is now exported in `el_runtime.h` | `0007-post-el-tagged-exported.out` | `9a6c161` | REPRODUCED (exact) | +| A11 | the fix: `sha256_hex(50000)` no longer segfaults | `0011-post-sha256-hex-50000-no-longer-segfaults.out` | `9a6c161` | REPRODUCED | +| A12 | P11: fixpoint and suites hold | `0013-P11-fixpoint.out` | `9a6c161` | REPRODUCED | +| A13 | **105/105** native | `0014-P11-native-suite.out` | `9a6c161` | REPRODUCED (exact) | +| A14 | **42/42** integration across **eight** harnesses | `0015-P11-eight-integration-harnesses.out` | `9a6c161` | REPRODUCED (exact) | +| A15 | "sixty seconds after diagnosing `let s: String = 42` I wrote the identical defect into `el_await`" | — | — | **NOT-CAPTURED** (narrative; no artifact of the pre-repair `el_await` — see cycle 18 A10) | +| A16 | the defect at current HEAD | `0020-head-sha256-hex-50000-TODAY.out` | `a0cc95e3` | fixed — exit 0 | + +## A6 — the headline, captured directly + +Fixture `fixtures/sha256_hex_int.el`: + +```el +fn main() { + println(sha256_hex(50000)) +} +``` + +At `cb7289f`: `cc` exits **0** with **0 errors** (`0004`), and the program exits +**139**, stdout **0 bytes** (`0005`). + +The exit code was captured by `capture.sh` running the binary as the direct +child — `"$@" > "$B.out" 2> "$B.err"; rc=$?` — never through a pipe, which is the +control this record's own measurement defect 4 demands. + +## A7 — measurement defect 4, reproduced as a live control + +`0006` runs the same binary twice in one capture: + +``` +exit code read THROUGH A PIPE: 0 <- this is measurement defect 4 +exit code read DIRECTLY: 139 <- the truth +``` + +A SIGSEGV really does read as a clean run when `$?` is taken after a pipeline +whose last stage succeeds. The defect the record confesses to is not an +anecdote; it is a reproducible property of the shell, demonstrated here against +the exact program it originally hid. + +## A1–A5 — the four checks, verbatim from `cb7289f` + +`0001`: `looks_like_heap_obj` is declared `static int` at `el_runtime.c:715`, +and `el_runtime.h` contains **0** occurrences of either `looks_like_heap_obj` or +`el_tagged`. Not exported — so every sibling translation unit must re-derive it. + +`0002`, the four call sites, exactly as tabulated in the record: + +```c +static ElGeometry* geom_of(el_val_t g) { + if (!looks_like_heap_obj(g)) return NULL; /* full guard — correct */ + +static ElManifold* mfld_of(el_val_t m) { + if (!looks_like_heap_obj(m)) return NULL; /* full guard — correct */ + +static int el_bin_lookup(const void* p, size_t* out_len) { + if (!p) { *out_len = 0; return 0; } + if ((uintptr_t)p < 4096) return 0; /* floor only */ + const el_bin_hdr_t* hdr = (…)((const char*)p - sizeof(el_bin_hdr_t)); + /* reads 8 bytes BACKWARD */ +static size_t el_input_len(const char* s) { + size_t n; + if (el_bin_lookup(s, &n)) return n; + return s ? strlen(s) : 0; /* NULL only — strlen's an integer */ +} +``` + +`looks_like_heap_obj` itself rejects zero, small ints (`|s| < 0x10000`), low +addresses and misaligned pointers. `el_bin_lookup`'s 4096 floor has none of +those components, and 50000 clears it. + +## A8 — P8, the useful failure: re-derived, and labelled as such + +The intermediate state P8 describes — `el_bin_lookup` routed through the gate, +`el_input_len` untouched — **was never committed**, so no historical artifact +exists and none was manufactured. It was reconstructed *today* from `9a6c161` by +reverting only the `el_input_len` hunk back to its `cb7289f` form. The +reconstruction script and the resulting diff are stored with the evidence: + +* `fixtures/p8_reconstruct_intermediate.py` +* `fixtures/p8_intermediate.patch` + +Result (`0019`): `sha256_hex(50000)` still exits **139**. + +So with the tagged lookup fully guarded and the fallback unguarded, the crash is +unchanged — the fallback was the hazard, exactly as P8 says. The committed fix +(`9a6c161`) needed **both** hunks: + +```c + if (!looks_like_heap_obj((el_val_t)(uintptr_t)hp)) return 0; /* el_bin_lookup */ +… + if (!looks_like_heap_obj((el_val_t)(uintptr_t)s)) return 0; /* el_input_len */ + return strlen(s); +``` + +Verdict wording matters here. The historical measurement is **NOT-CAPTURED**; +the re-derivation **CORROBORATES** it. These are different things and the record +should not conflate them. + +## A9 / A11 — the fix, and that it costs nothing + +`0012` — the legitimate hash is byte-identical across the change and matches an +independent implementation: + +``` +pre sha256_hex(abc) = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad +post sha256_hex(abc) = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad +reference (openssl) = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad +``` + +`0011` — the hazardous call now returns cleanly, exit **0**: + +``` +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +``` + +which is SHA-256 of the empty string: `el_input_len` now returns 0 for a slot +that is not a pointer, so the integer hashes as no bytes rather than walking +address 50000. Still true at HEAD (`0020`). + +`0007` — the gate is exported: + +``` +891:int el_tagged(el_val_t v, uint32_t magic); /* the gate: validate a slot BEFORE dereferencing it */ +``` + +## A12–A14 — the suites at `9a6c161` + +``` +FIXPOINT-OK gen2 == gen3 (0013) +105 tests, 105 passed, 0 failed, 253 assertions (0014) + +arity_query.sh exit=0 assertions=5 +capability_query.sh exit=0 assertions=5 +definitions_query.sh exit=0 assertions=6 +prohibition_query.sh exit=0 assertions=4 +seam_binding.sh exit=0 assertions=7 +tagged_gate.sh exit=0 assertions=5 +temporal_query.sh exit=0 assertions=6 +temporal_signatures.sh exit=0 assertions=4 +harnesses: 8 TOTAL assertions: 42 (0015) +``` + +105/105, eight harnesses, 42 assertions. All three figures exact. + +## Provenance notes + +Behavioural captures come from `/tmp/rerun-v1b-17-pre` (a worktree at `cb7289f`, +shared with cycle 17 because the two cycles branch from the same parent), +`/tmp/rerun-v1b-19-post` (`9a6c161`) and `/tmp/rerun-v1b-head` (`a0cc95e3`). + +The four P8 artifacts (`0016`–`0019`) carry **DIRTY-TREE** flags, correctly and +deliberately: the working tree was patched to construct a state that was never +committed, so those measurements are not reproducible by checking out +`9a6c161` alone. They are reproducible by checking out `9a6c161` and applying +`fixtures/p8_intermediate.patch`, which is stored alongside them. The worktree +was removed after capture. diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/MANIFEST.tsv b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/MANIFEST.tsv new file mode 100644 index 0000000..30c536d --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/MANIFEST.tsv @@ -0,0 +1,21 @@ +sha256 bytes exit ms commit tree utc artifact command +4bb775ca37a9c774d59d555a1ee3115723763b0fee42d533f77d030c8c563f1d 104 1 21 cb7289f06510 clean 2026-08-17T17:42:30Z 0001-P1-looks-like-heap-obj-is-static.out bash -c cd /tmp/rerun-v1b-17-pre/lang/runtime && echo "--- definition ---"; grep -n "static int looks_like_heap_obj" el_runtime.c; echo "--- exported in el_runtime.h? ---"; grep -c "looks_like_heap_obj\|el_tagged" el_runtime.h +4b9e15663e339c06e92493b7122bea8257ccd7c606be594da3f363937ae99629 1094 0 23 cb7289f06510 clean 2026-08-17T17:42:30Z 0002-P2P3-four-tagged-checks.out bash -c cd /tmp/rerun-v1b-17-pre/lang/runtime && echo "geom_of :"; sed -n "6296,6299p" el_runtime.c; echo "mfld_of :"; sed -n "6502,6505p" el_runtime.c; echo "el_bin_lookup:"; sed -n "18270,18280p" el_runtime.c; echo "el_input_len :"; sed -n "18283,18287p" el_runtime.c +2dcb5a1ee91d06df9af44e7a59ba0f1a5c38201b5f80dccbfadb4bf590df7eeb 185 0 14 cb7289f06510 clean 2026-08-17T17:42:41Z 0003-pre-emit-c-sha256-int.out bash -c cd /tmp/rerun-v1b-17-pre/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc17pre /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/sha256_hex_int.el +a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 9 0 3195 cb7289f06510 clean 2026-08-17T17:42:44Z 0004-pre-cc-compiles-clean.out bash -c cd /tmp/rerun-v1b-17-pre/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19.c $SRCS $LF && echo CC-CLEAN +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 139 229 cb7289f06510 clean 2026-08-17T17:42:45Z 0005-P6-sha256-hex-50000-exit-code.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 +6d4cbbfbbf5dac7a15bd48c3ee7af9fc13d4474ab07569971196bd0c50c12185 116 0 17 cb7289f06510 clean 2026-08-17T17:42:52Z 0006-measurement-defect-4-control-pipe-hides-sigsegv.out bash -c set +o pipefail; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 | head -1; echo "exit code read THROUGH A PIPE: $? <- this is measurement defect 4"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19 > /dev/null 2>&1; echo "exit code read DIRECTLY: $? <- the truth" +08106dd493eec64aa21350159fcdb570990c2cc39b9bd23772f2687ef7a43de0 110 0 11 9a6c161ba98a clean 2026-08-17T17:43:22Z 0007-post-el-tagged-exported.out bash -c cd /tmp/rerun-v1b-19-post/lang && grep -n el_tagged runtime/el_runtime.h +68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 9 0 3840 9a6c161ba98a clean 2026-08-17T17:43:26Z 0008-post-build-gen1-9a6c161.out bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19.c $SRCS $LF && echo BUILD-OK +2dcb5a1ee91d06df9af44e7a59ba0f1a5c38201b5f80dccbfadb4bf590df7eeb 185 0 195 9a6c161ba98a clean 2026-08-17T17:43:26Z 0009-post-emit-c-sha256-int.out bash -c cd /tmp/rerun-v1b-19-post/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/sha256_hex_int.el +a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 9 0 3018 9a6c161ba98a clean 2026-08-17T17:43:29Z 0010-post-cc.out bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p.c $SRCS $LF && echo CC-CLEAN +38acb15d02d5ac0f2a2789602e9df950c380d2799b4bdb59394e4eeabdd3a662 65 0 180 9a6c161ba98a clean 2026-08-17T17:43:29Z 0011-post-sha256-hex-50000-no-longer-segfaults.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p +ccc07cddd4839fc41f1bef4a67e4d5c723fc91084c49e86ca9ea15bc9cf7f4ab 264 0 324 9a6c161ba98a clean 2026-08-17T17:43:47Z 0012-P9-legitimate-hash-unchanged.out bash -c printf "pre sha256_hex(abc) = "; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/legit_pre; printf "post sha256_hex(abc) = "; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/legit_post; printf "reference (openssl) = "; printf abc | shasum -a 256 | cut -d\ -f1 +1b4889e0050c409ace27706da41238ec276f0ac02d0e8f9ca07d5e2d1145aa8e 12 0 4120 9a6c161ba98a clean 2026-08-17T17:44:00Z 0013-P11-fixpoint.out bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19 elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_2.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_2.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_3.c 2>/dev/null && cmp /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_2.c /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19_3.c && echo FIXPOINT-OK || echo FIXPOINT-FAIL +8fed706c491e2f19afbb7035e1c09d0ae4d67bba9db1a6aedb73dcf2af5c00a2 4329 0 4168 9a6c161ba98a clean 2026-08-17T17:44:05Z 0014-P11-native-suite.out bash -c cd /tmp/rerun-v1b-19-post/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 --test tests/native/test_compiler.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19.c 2>/dev/null && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19.c $SRCS $LF && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/t19 +3a02a406df2b5b0d66949960a4e30a7ec52871886ba0353771a60f84b86380fe 428 0 16121 9a6c161ba98a clean 2026-08-17T17:44:21Z 0015-P11-eight-integration-harnesses.out bash -c cd /tmp/rerun-v1b-19-post/lang && tot=0; n8=0; for h in tests/integration/*.sh; do out=$("$h" /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19_2 2>&1); rc=$?; n=$(printf "%s" "$out" | grep -oE "^ *[0-9]+ assertions" | grep -oE "[0-9]+" | head -1); printf "%-28s exit=%s assertions=%s\n" "$(basename $h)" "$rc" "${n:-0}"; tot=$((tot+${n:-0})); n8=$((n8+1)); done; echo "harnesses: $n8 TOTAL assertions: $tot" +68ff1c8c79613a8870607bcba04539154b609870fef324c18636f75c43aeacd7 9 0 3929 9a6c161ba98a dirty 2026-08-17T17:45:02Z 0016-P8-rederived-build.out bash -c cd /tmp/rerun-v1b-19-p8/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; ./dist/platform/elc elc-cli.el > /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19p8.c && cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19p8 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/g19p8.c $SRCS $LF && echo BUILD-OK +2dcb5a1ee91d06df9af44e7a59ba0f1a5c38201b5f80dccbfadb4bf590df7eeb 185 0 180 9a6c161ba98a dirty 2026-08-17T17:45:02Z 0017-P8-rederived-emit-c.out bash -c cd /tmp/rerun-v1b-19-p8/lang && /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/elc19p8 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/sha256_hex_int.el +a7751a7fc2e89c47be008f0ba3d5dd9ddca3f7dc76600ec80ebf177bc88f45c5 9 0 3214 9a6c161ba98a dirty 2026-08-17T17:45:05Z 0018-P8-rederived-cc.out bash -c cd /tmp/rerun-v1b-19-p8/lang && SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; cc $CF -o /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p8 /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p8.c $SRCS $LF && echo CC-CLEAN +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 139 186 9a6c161ba98a dirty 2026-08-17T17:45:06Z 0019-P8-rederived-still-segfaults.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/s19p8 +38acb15d02d5ac0f2a2789602e9df950c380d2799b4bdb59394e4eeabdd3a662 65 0 178 a0cc95e3db7b clean 2026-08-17T17:47:03Z 0020-head-sha256-hex-50000-TODAY.out /private/tmp/claude-501/-Users-will/6531446d-bc27-4095-930b-e04777c3db4f/scratchpad/v1b/head19 diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/RUN.env b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/RUN.env new file mode 100644 index 0000000..43a7f72 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:42:30Z +git_sha cb7289f06510c002b6ab7c5ca8c2bd182d8216bc +git_dirty no +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/p8_intermediate.patch b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/p8_intermediate.patch new file mode 100644 index 0000000..c27ad74 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/p8_intermediate.patch @@ -0,0 +1,18 @@ +diff --git a/lang/runtime/el_runtime.c b/lang/runtime/el_runtime.c +index 73c04e09..f2fbcb6a 100644 +--- a/lang/runtime/el_runtime.c ++++ b/lang/runtime/el_runtime.c +@@ -18306,12 +18306,7 @@ static int el_bin_lookup(const void* p, size_t* out_len) { + static size_t el_input_len(const char* s) { + size_t n; + if (el_bin_lookup(s, &n)) return n; +- /* The FALLBACK is the hazard, not the tagged lookup. A NULL check does not +- * establish that a slot is a pointer: el_val_t carries integers too, so +- * strlen() on `sha256_hex(50000)` walks address 50000. Guarding the tagged +- * path alone left this untouched and the SIGSEGV unchanged -- measured. */ +- if (!looks_like_heap_obj((el_val_t)(uintptr_t)s)) return 0; +- return strlen(s); ++ return s ? strlen(s) : 0; + } + + /* ─── SHA-256 (Brad Conte / public domain) ──────────────────────────────── */ diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/p8_reconstruct_intermediate.py b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/p8_reconstruct_intermediate.py new file mode 100644 index 0000000..bae1f73 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/p8_reconstruct_intermediate.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# p8_patch.py — construct the P8 INTERMEDIATE state described in cycle 19. +# +# Cycle 19's P8 says: routing el_bin_lookup through the gate did NOT fix the +# SIGSEGV, because the FALLBACK (el_input_len's `s ? strlen(s) : 0`) was the +# hazard. That intermediate state was never committed, so no historical +# artifact exists for it. This constructs it TODAY, from 9a6c161, by reverting +# ONLY the el_input_len hunk back to its cb7289f form and leaving the new +# el_bin_lookup gate in place. It is labelled a re-derivation, not a recovery. +p = "/tmp/rerun-v1b-19-p8/lang/runtime/el_runtime.c" +s = open(p).read() +new = """static size_t el_input_len(const char* s) { + size_t n; + if (el_bin_lookup(s, &n)) return n; + /* The FALLBACK is the hazard, not the tagged lookup. A NULL check does not + * establish that a slot is a pointer: el_val_t carries integers too, so + * strlen() on `sha256_hex(50000)` walks address 50000. Guarding the tagged + * path alone left this untouched and the SIGSEGV unchanged -- measured. */ + if (!looks_like_heap_obj((el_val_t)(uintptr_t)s)) return 0; + return strlen(s); +}""" +old = """static size_t el_input_len(const char* s) { + size_t n; + if (el_bin_lookup(s, &n)) return n; + return s ? strlen(s) : 0; +}""" +assert s.count(new) == 1, "expected exactly one el_input_len, found %d" % s.count(new) +open(p, "w").write(s.replace(new, old)) +print("P8 intermediate constructed: el_bin_lookup KEEPS the new gate,") +print("el_input_len reverted to the cb7289f fallback `s ? strlen(s) : 0`") diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/sha256_hex_int.el b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/sha256_hex_int.el new file mode 100644 index 0000000..c222928 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/sha256_hex_int.el @@ -0,0 +1,3 @@ +fn main() { + println(sha256_hex(50000)) +} diff --git a/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/sha256_hex_legit.el b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/sha256_hex_legit.el new file mode 100644 index 0000000..8ebd521 --- /dev/null +++ b/docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/fixtures/sha256_hex_legit.el @@ -0,0 +1,3 @@ +fn main() { + println(sha256_hex("abc")) +} diff --git a/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.cmd b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.cmd new file mode 100644 index 0000000..80e9d6a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.cmd @@ -0,0 +1 @@ +bash -c cd lang; SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; W=/tmp/rerun-v2-shared; ./dist/platform/elc elc-cli.el > $W/g1.c 2>/dev/null; cc $CF -o $W/elc1 $W/g1.c $SRCS $LF 2>/dev/null; $W/elc1 elc-cli.el > $W/g2.c 2>/dev/null; cc $CF -o $W/elc2 $W/g2.c $SRCS $LF 2>/dev/null; $W/elc2 elc-cli.el > $W/g3.c 2>/dev/null; printf "gen1 sha256 = %s\ngen2 sha256 = %s\ngen3 sha256 = %s\n" "$(shasum -a 256 $W/g1.c | cut -d\ -f1)" "$(shasum -a 256 $W/g2.c | cut -d\ -f1)" "$(shasum -a 256 $W/g3.c | cut -d\ -f1)"; if cmp -s $W/g2.c $W/g3.c; then echo "FIXPOINT gen2 == gen3 OK"; else echo "FIXPOINT gen2 != gen3 FAILED"; fi; if cmp -s $W/g1.c $W/g2.c; then echo "note: gen1 == gen2 (codegen output unchanged this cycle)"; else echo "note: gen1 != gen2, as expected whenever codegen output changes"; fi diff --git a/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.err b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.out b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.out new file mode 100644 index 0000000..09b869c --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.out @@ -0,0 +1,5 @@ +gen1 sha256 = aa340a723e7b29e585e30c07d6dc9834e072ef15a07df5e1afb363c18e168c76 +gen2 sha256 = 61210655962abd07ce395d66a9232582fd10c2a878c80f9b85fefc9081c5313e +gen3 sha256 = 61210655962abd07ce395d66a9232582fd10c2a878c80f9b85fefc9081c5313e +FIXPOINT gen2 == gen3 OK +note: gen1 != gen2, as expected whenever codegen output changes diff --git a/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.prov b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.prov new file mode 100644 index 0000000..463d344 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:39Z +exit 0 +ms 8100 +sha256_out 5960c00c43a46d19bb43edbadd8aa8ffe2e9741cc2659c89e4d42c28fecfe58a +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.rc b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0005-native-suite.cmd b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.cmd new file mode 100644 index 0000000..e81ef06 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.cmd @@ -0,0 +1 @@ +bash -c cd lang; SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; W=/tmp/rerun-v2-shared; $W/elc2 --test tests/native/test_compiler.el > $W/t.c 2>/dev/null; cc $CF -o $W/t $W/t.c $SRCS $LF 2>/dev/null; $W/t; echo "native_suite_exit=$?" diff --git a/docs/v2/experiments/evidence/ITERATION/0005-native-suite.err b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0005-native-suite.out b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.out new file mode 100644 index 0000000..25f65b1 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.out @@ -0,0 +1,108 @@ +ok lex-empty (0.041ms) +ok lex-whitespace-stripped (0.001ms) +ok lex-comment-stripped (0.000ms) +ok lex-int-literals (0.002ms) +ok lex-float-literals (0.010ms) +ok lex-string-literals (0.002ms) +ok lex-string-escape-newline (0.001ms) +ok lex-string-escape-tab (0.001ms) +ok lex-string-escape-backslash (0.000ms) +ok lex-bool-literals (0.002ms) +ok lex-identifier (0.002ms) +ok lex-keywords (0.005ms) +ok lex-more-keywords (0.001ms) +ok lex-keyword-values (0.000ms) +ok lex-arithmetic-operators (0.001ms) +ok lex-comparison-operators (0.001ms) +ok lex-logical-operators (0.002ms) +ok lex-arrow-tokens (0.001ms) +ok lex-delimiters (0.001ms) +ok lex-double-colon (0.000ms) +ok lex-dot-dot (0.001ms) +ok lex-pipe-operators (0.000ms) +ok lex-at-and-question (0.009ms) +ok lex-eof-always-last (0.001ms) +ok lex-string-with-spaces (0.000ms) +ok lex-multiline-source (0.002ms) +ok lex-flat-stride-3-layout (0.001ms) +ok lexer-tracks-line-numbers (0.003ms) +ok parse-let-stmt (0.025ms) +ok parse-fn-decl (0.008ms) +ok parse-fn-params (0.004ms) +ok parse-return-stmt (0.002ms) +ok parse-if-stmt (0.007ms) +ok parse-if-else (0.006ms) +ok parse-while-stmt (0.006ms) +ok parse-import-stmt (0.001ms) +ok parse-extern-fn (0.003ms) +ok parse-let-int-value (0.002ms) +ok parse-let-string-value (0.002ms) +ok parse-let-bool-value (0.001ms) +ok parse-binop-expr (0.002ms) +ok parse-call-expr (0.004ms) +ok parse-multiple-fns (0.005ms) +ok parse-assign-stmt (0.003ms) +ok parse-for-stmt (0.005ms) +ok parse-unary-not (0.003ms) +ok parse-unary-neg (0.003ms) +ok parse-array-literal (0.006ms) +ok parse-empty-array (0.003ms) +ok parse-index-expr (0.006ms) +ok codegen-includes (0.288ms) +ok codegen-int-main (0.090ms) +ok codegen-runtime-init (0.075ms) +ok codegen-void-function-signature (0.106ms) +ok codegen-function-with-params (0.133ms) +ok codegen-int-literal (0.080ms) +ok codegen-string-literal (0.062ms) +ok codegen-if-statement (0.072ms) +ok codegen-if-else (0.070ms) +ok codegen-while-loop (0.115ms) +ok codegen-let-binding (0.069ms) +ok codegen-function-call (0.063ms) +ok codegen-string-concat (0.068ms) +ok codegen-int-arithmetic (0.063ms) +ok codegen-comparison (0.062ms) +ok codegen-string-equality (0.066ms) +ok codegen-logical-and (0.069ms) +ok codegen-logical-or (0.100ms) +ok codegen-unary-not (0.068ms) +ok codegen-string-escape-in-c (0.064ms) +ok codegen-many-functions (0.089ms) +ok codegen-deep-expression (0.080ms) +ok codegen-forward-declarations (0.066ms) +ok codegen-for-loop (0.249ms) +ok codegen-extern-fn (0.070ms) +ok codegen-nested-calls (0.063ms) +ok compiler-minimal-program (0.059ms) +ok compiler-pure-library (0.062ms) +ok compiler-multiple-fns-with-main (0.071ms) +ok compiler-let-in-main (0.082ms) +ok compiler-string-concat-chain (0.077ms) +ok compiler-negative-literal (0.060ms) +ok compiler-stdint-include (0.054ms) +ok decorator-undecorated-fn-has-no-beat (0.054ms) +ok decorator-authenticate-compiles-to-nothing (0.117ms) +ok declared-construct-name-unknown-to-codegen (0.070ms) +ok undeclared-construct-still-injects-nothing (0.061ms) +ok undeclared-guard-emits-nothing (0.062ms) +ok seam-indirection-emitted-on-every-fn (0.066ms) +ok seam-emitted-without-any-decorator (0.060ms) +ok seam-replaces-inlined-entry-injection (0.054ms) +ok seam-entry-is-refusable (0.053ms) +ok seam-is-emitted-for-undecorated-fns (0.058ms) +ok every-fn-gets-a-body-helper-and-wrapper (0.095ms) +ok exit-crossing-goes-through-the-seam (0.063ms) +ok early-returns-route-through-the-exit-seam (0.066ms) +ok every-fn-gets-a-closure (0.057ms) +ok zero-param-fn-emits-valid-c (0.057ms) +ok compiler-no-longer-emits-prohibition-errors (0.072ms) +ok int-returning-builtin-drives-arithmetic-dispatch (0.086ms) +ok string-plus-string-still-concatenates (0.059ms) +ok freed-identifiers-compile-as-identifiers (0.067ms) +ok test-keyword-is-still-reserved (0.057ms) +ok instant-plus-bare-int-is-refused (0.067ms) +ok instant-plus-unit-suffix-is-allowed (0.125ms) + +105 tests, 105 passed, 0 failed, 253 assertions in 4.589ms +native_suite_exit=0 diff --git a/docs/v2/experiments/evidence/ITERATION/0005-native-suite.prov b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.prov new file mode 100644 index 0000000..9f8bf17 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:52Z +exit 0 +ms 4078 +sha256_out 567d6f328b1801daad2fcab0adeea2a8cbfc589def13b89b454917a4717077fa +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0005-native-suite.rc b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0005-native-suite.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.cmd b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.cmd new file mode 100644 index 0000000..6a46ef4 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/annotation_query.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.err b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.out b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.out new file mode 100644 index 0000000..c8db949 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.out @@ -0,0 +1,7 @@ + ok Int annotated on a String literal is caught + ok and names the variable + ok String annotated on an Int literal is caught + ok correct annotations are clean + ok the compiler's own source is clean — no false positives + + 5 assertions, 5 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.prov b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.prov new file mode 100644 index 0000000..f00e83c --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:54Z +exit 0 +ms 1615 +sha256_out fd8354898660faa4fae68be1e10dfd30326d2cc60412fb42a87b6db3d1c8dd8f +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.rc b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.cmd b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.cmd new file mode 100644 index 0000000..5b4a12c --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/arity_query.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.err b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.out b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.out new file mode 100644 index 0000000..282b74e --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.out @@ -0,0 +1,9 @@ + ok the emitter does not adjudicate arity + ok a wrong-arity call is caught + ok the expected count is correct + ok a correct call is clean + ok the header yields a plausible number of signatures + ok a wrong-arity call on a real builtin is caught + ok and the expected count is not 0 + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.prov b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.prov new file mode 100644 index 0000000..25e34e6 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:54Z +exit 0 +ms 190 +sha256_out bed0f3085439f29d1187491babba1f67167e2f3f41220303bb80168facdf5204 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.rc b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.cmd b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.cmd new file mode 100644 index 0000000..81838f5 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/async_future.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.err b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.out b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.out new file mode 100644 index 0000000..da06c59 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.out @@ -0,0 +1,8 @@ + ok unbound: no construct, synchronous, correct result + ok unbound: el_await on a non-future passes through, no crash + ok bound: does not crash + ok bound: the awaited result is correct + ok bound: the caller continues BEFORE the body finishes + ok bound: the wrap returns in under 10ms while the body takes 50ms + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.prov b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.prov new file mode 100644 index 0000000..e5524db --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:58Z +exit 0 +ms 3499 +sha256_out ac52afda852cfe4d226b7fbe46cedbb3bc22be2b592af815e88c41a2f9d23b5d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.rc b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.cmd b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.cmd new file mode 100644 index 0000000..54db479 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/capability_query.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.err b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.out b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.out new file mode 100644 index 0000000..47f5bbe --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.out @@ -0,0 +1,7 @@ + ok the emitter does not adjudicate + ok a utility calling a DHARMA primitive is caught + ok the offending fn is named + ok a clean program exits 0 + ok editing the policy file changes enforcement, no rebuild + + 5 assertions, 5 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.prov b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.prov new file mode 100644 index 0000000..2a832e2 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:58Z +exit 0 +ms 132 +sha256_out a358a4c0b68c6f95bef05d6c7d37a0feddf41c6c9783df41c3cc0275c7b98e75 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.rc b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.cmd b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.cmd new file mode 100644 index 0000000..737c937 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/definitions_query.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.err b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.out b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.out new file mode 100644 index 0000000..3e8a7d8 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.out @@ -0,0 +1,8 @@ + ok a collision across modules is caught at El level + ok the colliding name is reported + ok and the reason is given + ok both source FILES are named + ok with file-local line numbers, not combined ones + ok a clean program exits 0 + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.prov b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.prov new file mode 100644 index 0000000..dc9f5d9 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:58Z +exit 0 +ms 74 +sha256_out f7f5ab1979eff191df48ae3cb335c5306d95d51f40df2ab21101e8d5e087aee9 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.rc b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.cmd b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.cmd new file mode 100644 index 0000000..e657486 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/prohibition_query.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.err b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.out b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.out new file mode 100644 index 0000000..6b66fa6 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.out @@ -0,0 +1,6 @@ + ok a violation outside the boundary is caught + ok the offending fn is named + ok a call inside the boundary is NOT flagged + ok a clean program exits 0 + + 4 assertions, 4 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.prov b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.prov new file mode 100644 index 0000000..cca4ce4 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:48:58Z +exit 0 +ms 74 +sha256_out 368db4596231e9f64a551b08afd54d98cfeb6857c06a940d465ee7178812ab80 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.rc b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.cmd b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.cmd new file mode 100644 index 0000000..ae7cdca --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/seam_binding.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.err b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.out b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.out new file mode 100644 index 0000000..f72835b --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.out @@ -0,0 +1,9 @@ + ok unbound program is unaffected + ok a construct declared AFTER the build applies + ok a construct declared after the build can REFUSE + ok an unlinked target is skipped, not fatal + ok a binding for a different fn does not fire + ok two constructs compose on one crossing + ok an EXIT construct declared after the build replaces the result + + 7 assertions, 7 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.prov b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.prov new file mode 100644 index 0000000..cac03ae --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:02Z +exit 0 +ms 3466 +sha256_out 03d3e2e45ceb69b512d12b292f32e5cf7d36d10925fc8abb8f5273e83e8b6287 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.rc b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.cmd b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.cmd new file mode 100644 index 0000000..9090404 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/seam_caller.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.err b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.out b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.out new file mode 100644 index 0000000..45c1fcf --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.out @@ -0,0 +1,7 @@ + ok unbound: nothing is reported + ok bound: the caller is visible + ok bound: and it changes per call site + ok the program still completes + ok no fourth emission point was added + + 5 assertions, 5 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.prov b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.prov new file mode 100644 index 0000000..ed0af13 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:05Z +exit 0 +ms 3509 +sha256_out 1f53370a31a6052b27c243753991fbdbc3a10e39a5af9ca3399d1ee36f877e78 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.rc b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.cmd b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.cmd new file mode 100644 index 0000000..eba7a6c --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/tagged_gate.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.err b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.out b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.out new file mode 100644 index 0000000..5666968 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.out @@ -0,0 +1,12 @@ + ok an integer where a string is expected does not crash + ok and yields the empty-string hash, not memory + ok a NEGATIVE integer does not crash + ok a legitimate string still hashes correctly + ok the gate is exported, so siblings stop re-deriving it + ok abc hashes correctly + ok a hashes correctly + ok hello world hashes correctly + ok the empty string still hashes to e3b0... + ok and no literal silently hashed as empty + + 10 assertions, 10 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.prov b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.prov new file mode 100644 index 0000000..c248280 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:19Z +exit 0 +ms 13622 +sha256_out 54ed74debfd5061190b7c6aaecabea13295684ac75502ce77a7a7b0e2e7778e4 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.rc b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.cmd b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.cmd new file mode 100644 index 0000000..f899d9e --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/temporal_query.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.err b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.out b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.out new file mode 100644 index 0000000..2c57832 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.out @@ -0,0 +1,8 @@ + ok the illegal combination is recorded, not judged, by the emitter + ok the emitter no longer authors the message + ok a placeholder is still emitted for the illegal expression + ok the query judges it + ok and explains why, from data + ok a legal program exits 0 + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.prov b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.prov new file mode 100644 index 0000000..2d1d31a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:19Z +exit 0 +ms 70 +sha256_out 436146bdf1d4fb9f140b34e4564f13e55947df21d336f3e206e79739c04a427c +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.rc b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.cmd b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.cmd new file mode 100644 index 0000000..fb82818 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/temporal_signatures.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.err b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.out b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.out new file mode 100644 index 0000000..bb30aab --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.out @@ -0,0 +1,6 @@ + ok an inferred Instant + Duration dispatches to the typed wrapper + ok with no signature file, the type is unknown and it does not + ok Instant + Instant is still refused + ok Instant + Duration is allowed + + 4 assertions, 4 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.prov b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.prov new file mode 100644 index 0000000..663faa3 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:19Z +exit 0 +ms 42 +sha256_out 0bd625826ed7f836523503c438bf74b1be67b7dbcc378bf9debe7b9d14cbff8f +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.rc b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.cmd b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.cmd new file mode 100644 index 0000000..76ade29 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/unguarded_deref.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.err b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.out b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.out new file mode 100644 index 0000000..7740e82 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.out @@ -0,0 +1,8 @@ + ok list_join on an integer does not crash + ok list_push_front on an integer does not crash + ok a field access on an integer does not crash + ok sha256_hex on an integer does not crash + ok a legitimate list still joins + ok the ratchet holds at or below baseline + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.prov b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.prov new file mode 100644 index 0000000..e9d835d --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:36Z +exit 0 +ms 16966 +sha256_out 6c7f1c73d0b03bd8c7fb37aedaa1ef53c06bfda070dda4d923e788f08ffb7f83 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.rc b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.cmd b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.cmd new file mode 100644 index 0000000..d611409 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.cmd @@ -0,0 +1 @@ +bash -c cd /Users/will/Development/neuron-technologies/foundation/el/lang && tests/integration/units_as_data.sh /tmp/rerun-v2-shared/elc2 diff --git a/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.err b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.out b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.out new file mode 100644 index 0000000..0b2f7d0 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.out @@ -0,0 +1,8 @@ + ok a known unit still lowers to a DurationLit + ok an unknown unit is NOT a duration + ok adding it to DATA makes it syntax — no compiler change + ok the vocabulary has ONE copy — parser holds it + ok and codegen carries no second copy + ok the Earth day is data, not a constant + + 6 assertions, 6 passed, 0 failed diff --git a/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.prov b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.prov new file mode 100644 index 0000000..34f2271 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:36Z +exit 0 +ms 44 +sha256_out bbffa5273b597acd20229782a7bcf619bfeb3f723ef89ad67fcc36b1ab0efbc8 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.rc b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.cmd b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.cmd new file mode 100644 index 0000000..8a4433c --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.cmd @@ -0,0 +1 @@ +awk { l=$0; sub(/^[ \t]+/,"",l); if (l=="") blank++; else if (substr(l,1,2)=="//") comment++; else code++ } END { printf "file=%s\ntotal_lines=%d\ncode=%d\ncomment=%d\nblank=%d\ncode_pct=%.1f%%\ncomment_pct=%.1f%%\n", FILENAME, NR, code, comment, blank, 100*code/NR, 100*comment/NR } lang/el-compiler/src/codegen.el diff --git a/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.err b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.out b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.out new file mode 100644 index 0000000..7184aff --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.out @@ -0,0 +1,7 @@ +file=lang/el-compiler/src/codegen.el +total_lines=4434 +code=3197 +comment=981 +blank=256 +code_pct=72.1% +comment_pct=22.1% diff --git a/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.prov b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.prov new file mode 100644 index 0000000..d82ebae --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:49:51Z +exit 0 +ms 14 +sha256_out 3e06f0fe32264456fe469d812acd2f15bc888c82759060c731cf606785f7ed12 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.rc b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.cmd b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.cmd new file mode 100644 index 0000000..f938801 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.cmd @@ -0,0 +1 @@ +bash -c cd lang; tot=0; for h in tests/integration/*.sh; do n=$(bash "$h" /tmp/rerun-v2-shared/elc2 2>&1 | grep -oE "[0-9]+ assertions" | grep -oE "[0-9]+" | head -1); tot=$((tot+${n:-0})); printf "%-24s %s\n" "$(basename $h .sh)" "${n:-0}"; done; printf "\nharnesses = %s\ntotal assertions = %s\n" "$(ls tests/integration/*.sh | wc -l | tr -d " ")" "$tot" diff --git a/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.err b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.out b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.out new file mode 100644 index 0000000..21094e8 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.out @@ -0,0 +1,16 @@ +annotation_query 5 +arity_query 6 +async_future 6 +capability_query 5 +definitions_query 6 +prohibition_query 4 +seam_binding 7 +seam_caller 5 +tagged_gate 10 +temporal_query 6 +temporal_signatures 4 +unguarded_deref 6 +units_as_data 6 + +harnesses = 13 +total assertions = 76 diff --git a/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.prov b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.prov new file mode 100644 index 0000000..9f9b7fc --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:35Z +exit 0 +ms 44510 +sha256_out dc670c8fb09ae54116dfa262c7f0fb82cf81289aac108c87c670e715c81efabb +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.rc b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.cmd b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.cmd new file mode 100644 index 0000000..96cea54 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.cmd @@ -0,0 +1 @@ +bash -c cd lang && tools/check/unguarded-deref.sh; echo "ratchet_exit=$?" diff --git a/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.err b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.out b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.out new file mode 100644 index 0000000..41bfec4 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.out @@ -0,0 +1,14 @@ + el_runtime.c:576 ElList* old = (ElList*)(uintptr_t)listv; + el_runtime.c:1575 ElMap* m = (ElMap*)(uintptr_t)headers_map; + el_runtime.c:1621 ElMap* hm = (ElMap*)(uintptr_t)hv; + el_runtime.c:17814 ElList* lst = (ElList*)(uintptr_t)tools_list; + el_runtime.c:17985 ElList* tl = (ElList*)(uintptr_t)tools; + el_runtime_win32.c:483 ElList* l = (ElList*)(uintptr_t)lv; + el_runtime_win32.c:488 ElList* l = (ElList*)(uintptr_t)lv; + el_runtime_win32.c:494 ElList* old = (ElList*)(uintptr_t)lv; + el_runtime_win32.c:529 ElList* old = (ElList*)(uintptr_t)lv; + el_runtime_win32.c:567 ElMap* m = (ElMap*)(uintptr_t)mv; + el_runtime_win32.c:580 ElMap* m = (ElMap*)(uintptr_t)mv; + + ok 11 unguarded casts, at baseline 11 +ratchet_exit=0 diff --git a/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.prov b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.prov new file mode 100644 index 0000000..4aeb179 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:35Z +exit 0 +ms 59 +sha256_out aa76315e49e9d7647e0f3a8db389a3c092dede50c1ce516c35e4fb421bd00e1e +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.rc b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.cmd b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.cmd new file mode 100644 index 0000000..18ab2b4 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.cmd @@ -0,0 +1 @@ +bash -c echo "measurement window: a116710b..HEAD"; echo; echo "--- commits in window touching lang/ ---"; git log --oneline a116710b..HEAD -- lang/ ; echo "(empty above means no compiler or runtime source changed during measurement)"; echo; echo "--- commits in window touching scripts/ or tools/evidence/capture.sh ---"; git log --oneline a116710b..HEAD -- scripts/ tools/evidence/capture.sh; echo; echo "--- total commits in window ---"; git rev-list --count a116710b..HEAD diff --git a/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.err b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.out b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.out new file mode 100644 index 0000000..b31fce0 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.out @@ -0,0 +1,9 @@ +measurement window: a116710b..HEAD + +--- commits in window touching lang/ --- +(empty above means no compiler or runtime source changed during measurement) + +--- commits in window touching scripts/ or tools/evidence/capture.sh --- + +--- total commits in window --- +5 diff --git a/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.prov b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.prov new file mode 100644 index 0000000..c30d585 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:35Z +exit 0 +ms 28 +sha256_out f1ec7f85c5370e7a5667800f764e8763baeeb1a7b1f2410294b4ebf7c0778e4b +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.rc b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.cmd b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.cmd new file mode 100644 index 0000000..88d92d8 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.cmd @@ -0,0 +1 @@ +./tools/evidence/verify-manifest.sh docs/v2/experiments/evidence/cycles diff --git a/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.err b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.out b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.out new file mode 100644 index 0000000..b72ae64 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.out @@ -0,0 +1,220 @@ + DIRTY-TREE 05-the-metric-counted-comments/0001-tree-state-at-start.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 05-the-metric-counted-comments/0002-landing-commits.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 05-the-metric-counted-comments/0003-baseline-commit-4661.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 05-the-metric-counted-comments/0004-baseline-4661-cited-in-v1.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 05-the-metric-counted-comments/0011-DELTA-code-comment-total-recomputed.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 05-the-metric-counted-comments/0012-BUCKET-SUM-consistency-check.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 05-the-metric-counted-comments/0013-NEWLINE-CHECK-file-ends-with-newline.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0001-00-git-status-porcelain.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0002-01-landing-commits.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0003-02-head-at-capture.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0004-03-branch-empty-probe-search.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0005-04-current-branch.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0006-p3-segv-source.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0007-p3-exit-THROUGH-A-PIPE.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0008-p3-exit-CAPTURED-DIRECT.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0009-p3-capture-sh-own-rc-on-segv.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0010-p3-capture-sh-direct-rc-line.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0011-p5-verify-sh-globs-integration.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0012-p5-harnesses-the-glob-finds.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0013-p5-harness-count.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0014-p5-git-log-S-hardcoded-list.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0015-p5-grep-docs-hardcoded-list.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0016-p1-verify-sh-stage-headers.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0017-p1-verify-sh-full-source.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0018-p1-verify-sh-linecount.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0019-fixpoint-rule-gen2-gen3.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0020-exitcode-direct-not-pipe.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0021-verify-merge-sh-full-source.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0022-instruments-unchanged-since-6c80dee.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0023-instruments-introduced-by-6c80dee.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0027-p4-referenced-artifact-binding.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0028-p4-a116710b-is-ancestor-of-iteration2.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0029-findings-measurement-defects-v2-at-6c80dee.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0030-findings-measurement-defects-entry-count-at-6c80dee.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0031-findings-v1-defect-headings-at-6c80dee.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0032-p3-v1-defect-4-read-the-wrong-exit-code.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0033-enumeration-defect-commits-two-days.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0034-p2-historical-empty-probe-merge-search.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0035-zz-head-at-end-of-capture.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0036-zz-git-status-porcelain-at-end.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0037-p3-does-verify-sh-DETECT-pipe-misuse.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0038-p3-pipe-WITH-pipefail-set.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 04-verification-was-a-convention/0039-p3-pipe-WITHOUT-pipefail.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0001-00-pinned-commit-stack.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0002-01-runtime-diff-introduced-by-d9d1571.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0003-02-seam-depth-stack-source-as-landed.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0004-03-BASE-has-no-depth-stack.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0005-04-binaries-under-test.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0006-05-workload-identical-in-both-worktrees.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0007-06-timing-WARMUP-base.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0008-07-timing-WARMUP-stack.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0009-timing-round1-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0010-timing-round1-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0011-timing-round2-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0012-timing-round2-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0013-timing-round3-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0014-timing-round3-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0015-timing-round4-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0016-timing-round4-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0017-timing-round5-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0018-timing-round5-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0019-timing-round6-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0020-timing-round6-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0021-timing-round7-BASE.out (commit d403a5cf2e72) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0022-timing-round7-STACK.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0023-22-TIMING-SUMMARY-computed-from-manifest.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0024-23-TIMING-SUMMARY-computed-from-manifest.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0025-24-COLD-vs-WARM-explains-the-phantom-regression.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0026-25-EMISSION-POINTS-from-emitted-C-simple.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0027-26-EMISSION-POINTS-from-emitted-C-loops-calls-fields.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0028-27-EMISSION-POINT-ENUMERATION-per-function.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0029-28-emitted-C-full-probe.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0030-29-probe-source-loops-calls-fields.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0031-30-CONTROL-seam_caller-harness-at-d9d1571.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 07-the-caller-was-already-there/0041-40-worktree-clean-at-end.out (commit d9d1571f2a17) — not reproducible by checkout + DIRTY-TREE 01-the-compiler-was-never-measured/0001-worktree-dirt-at-capture-start.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 01-the-compiler-was-never-measured/0018-measurement-window-commits-touched-docs-only.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0001-git-status-porcelain.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0002-harness-annotation_query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0003-harness-arity_query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0004-harness-async_future.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0005-harness-capability_query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0006-harness-definitions_query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0007-harness-prohibition_query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0008-harness-seam_binding.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0009-harness-seam_caller.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0010-harness-tagged_gate.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0011-harness-temporal_query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0012-harness-temporal_signatures.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0013-harness-unguarded_deref.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0014-harness-units_as_data.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0015-harness-count.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0016-assertion-tally-per-harness.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0017-native-suite-emit-c.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0018-native-suite-link.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0019-native-suite-run.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0020-grep-mutant-lang-scripts-tools.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0021-grep-mutation-lang-scripts-tools.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0022-grep-mutation-in-verify-sh.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0023-verify-sh-stage-headers.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0024-grep-mutation-with-context.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0025-grep-c-occurrences-per-harness.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0026-chk-call-count-per-harness.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0027-git-log-S503-arity-query.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0028-arity-query-before-9cc6040.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0029-arity-query-503-assertion-before.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0030-arity-query-signatures-assertion-after.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0031-arity-query-diff-47b56a3.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0032-ratchet-baseline-literal.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0033-ratchet-run-current.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0034-git-show-a116710b.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0035-git-log-cycle08-doc-history.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0036-git-show-d936bde-seal.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0037-doc-at-seal-d936bde.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0038-doc-diff-seal-to-head.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0039-index-entry-cycle08.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0040-readme-entry-cycle08.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0041-index-entry-cycle08-00INDEX.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0042-elc-head-binary-sha256.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 08-PREDICTIONS/0043-verify-manifest-control.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0001-git-status-porcelain.out (commit d63815316c55) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0002-head-sha-at-start.out (commit d63815316c55) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0003-ratchet-at-HEAD.out (commit d63815316c55) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0004-landing-commits.out (commit d63815316c55) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0005-landing-commit-3aa6c56.out (commit d63815316c55) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0006-landing-commit-272b2c9.out (commit d63815316c55) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0007-cast-counts-at-HEAD.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0008-harness-unguarded-deref-at-HEAD.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0009-elrun-HEAD-c1_string_42.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0010-elrun-HEAD-c2_sha256_int.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0011-elrun-HEAD-c3_fortnights.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0012-elrun-HEAD-c4_list_join_int.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0013-elrun-HEAD-c5_list_push_front_int.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0014-elrun-HEAD-c6_legit_list_join.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0015-elrun-HEAD-c8_map_get_int.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0016-elrun-HEAD-c9_get_int.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0017-elrun-HEAD-c9_get_int.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0018-blindspot-EL_CSTR-cast-macro.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0020-elrun-PREFIX-ebb4f1f-c4_list_join_int.out (commit ebb4f1f43bb2) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0021-four-builtins-guarded-at-HEAD.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0022-four-builtins-guarded-at-HEAD-v2.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0023-four-builtins-UNGUARDED-at-PREFIX-ebb4f1f.out (commit ebb4f1f43bb2) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0024-ratchet-ABSENT-at-PREFIX-ebb4f1f.out (commit ebb4f1f43bb2) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0027-ratchet-probeA2-new-unguarded-deref.out (commit 3aa6c569d57d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0028-ratchet-probeC-new-unguarded-deref.out (commit 3aa6c569d57d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0029-ratchet-probeD2-new-unguarded-deref.out (commit 3aa6c569d57d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0030-win32-not-built-on-this-platform.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 03-a-gate-with-no-detector/0031-harness-cases-vs-doc-five.out (commit fa03a0a60d6d) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0011-10-alignment-probe-source-align20.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0012-11-FIXED-pinned-commit.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.out (commit 1a5246667d80) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.out (commit abb0ab41980f) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0001-00-worktree-clean-at-start.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0002-01-pinned-commit.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0003-02-BEFORE-compiler-binary-stat-and-sha.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0004-03-BEFORE-units-rel-contents.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0005-04-BEFORE-units-rel-entry-count.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0006-05-BEFORE-fortnight-absent-from-whole-repo.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0007-06-BEFORE-emit-C-for-3-fortnights.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0008-07-BEFORE-emit-C-for-5-hours-control.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0009-08-BEFORE-grep-fortnight-lowering.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0010-09-THE-DATA-EDIT-two-lines-appended.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0011-10-THE-DATA-EDIT-git-diff.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0012-11-THE-DATA-EDIT-git-diff-stat.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0013-12-AFTER-compiler-binary-stat-and-sha-UNCHANGED.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0014-13-PROOF-binary-mtime-PREDATES-data-edit.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0015-14-AFTER-emit-C-for-3-fortnights.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0016-15-AFTER-grep-fortnight-lowering.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0017-16-AFTER-compile-and-link-the-emitted-C.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0018-17-AFTER-RUN-3-fortnights-native.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0019-18-AFTER-expected-value-arithmetic.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0020-19-REVERT-the-data-edit.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0021-20-REVERT-worktree-clean-again.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0022-21-AFTER-REVERT-fortnights-is-a-field-access-again.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0023-22-P4-earth-day-is-data.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0024-23-P2-no-unit-name-in-lexer-keyword-table.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0025-24-ONE-COPY-parser-holds-vocabulary.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0026-25-codegen-duration_unit_nanos-now-delegates.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0027-26-BEFORE-two-hand-maintained-copies-at-8cb7613.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0028-27-BEFORE-entry-counts-in-both-copies-at-8cb7613.out (commit e82d941b5f96) — not reproducible by checkout + DIRTY-TREE 06-form-is-half-bindable/0029-28-CONTROL-units_as_data-harness-at-e82d941.out (commit e82d941b5f96) — not reproducible by checkout + evidence: 250 artifacts verified, 0 altered, 0 missing diff --git a/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.prov b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.prov new file mode 100644 index 0000000..118fb76 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:53Z +exit 0 +ms 3279 +sha256_out 2e774324c50d1620b97f3545c7792dc27d1ea7ed609790f4af468594d1f08331 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.rc b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.cmd b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.cmd new file mode 100644 index 0000000..0cc5fd7 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.cmd @@ -0,0 +1 @@ +bash -c cd docs/v2/experiments/evidence; for d in cycles/*/; do printf "%-42s artifacts=%-4s claims=%s\n" "$(basename $d)" "$(ls $d*.out 2>/dev/null | wc -l | tr -d " ")" "$([ -f $d/CLAIMS.md ] && echo yes || echo NO)"; done; printf "\n%-42s artifacts=%s\n" "ITERATION" "$(ls ITERATION/*.out | wc -l | tr -d " ")"; printf "\ntotal artifact files = %s\n" "$(find . -type f | wc -l | tr -d " ")" diff --git a/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.err b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.out b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.out new file mode 100644 index 0000000..468af8d --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.out @@ -0,0 +1,12 @@ +01-the-compiler-was-never-measured artifacts=18 claims=yes +02-seven-tables-and-a-shipped-defect artifacts=33 claims=yes +03-a-gate-with-no-detector artifacts=31 claims=yes +04-verification-was-a-convention artifacts=39 claims=yes +05-the-metric-counted-comments artifacts=16 claims=yes +06-form-is-half-bindable artifacts=29 claims=yes +07-the-caller-was-already-there artifacts=41 claims=yes +08-PREDICTIONS artifacts=43 claims=yes + +ITERATION artifacts=24 + +total artifact files = 1406 diff --git a/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.prov b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.prov new file mode 100644 index 0000000..5445783 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:54Z +exit 0 +ms 65 +sha256_out 0692f14cfdf3c1f0521e7c168cbc6e4355ade06cf15556d205e707bfa41a4253 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.rc b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.cmd b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.cmd new file mode 100644 index 0000000..af03ced --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.cmd @@ -0,0 +1 @@ +git status --porcelain diff --git a/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.err b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.out b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.out new file mode 100644 index 0000000..1075691 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.out @@ -0,0 +1,472 @@ + M docs/experiments/evidence/MANIFEST.tsv + M docs/experiments/instruments/instrument/line-count/evidence/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/CLAIMS.md + M docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/09-policy-inside-the-compiler/CLAIMS.md + M docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.out + M docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/MANIFEST.tsv + M docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.out + M docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/MANIFEST.tsv + M docs/v2/experiments/evidence/ITERATION/MANIFEST.tsv + M docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/MANIFEST.tsv + M tools/evidence/verify-manifest.sh +?? docs/experiments/evidence/0003-codegen-series-cloc.cmd +?? docs/experiments/evidence/0003-codegen-series-cloc.err +?? docs/experiments/evidence/0003-codegen-series-cloc.out +?? docs/experiments/evidence/0003-codegen-series-cloc.prov +?? docs/experiments/evidence/0003-codegen-series-cloc.rc +?? docs/experiments/evidence/0019-compiler-series-cloc.cmd +?? docs/experiments/evidence/0019-compiler-series-cloc.err +?? docs/experiments/evidence/0019-compiler-series-cloc.out +?? docs/experiments/evidence/0019-compiler-series-cloc.prov +?? docs/experiments/evidence/0019-compiler-series-cloc.rc +?? docs/experiments/instruments/CALIBRATION-20260817T174713Z.txt +?? docs/experiments/instruments/CALIBRATION-20260817T174754Z.txt +?? docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.cmd +?? docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.err +?? docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.out +?? docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.prov +?? docs/experiments/instruments/instrument/line-count/evidence/0003-cloc-calibration.rc +?? docs/experiments/instruments/instrument/plot/ +?? docs/experiments/reproduce.sh +?? docs/experiments/v2/ +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0019-manifest-tsv-row-integrity-audit.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0020-verify-manifest-full-run.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0021-verify-manifest-full-run-ABSOLUTE.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0022-verifier-false-pass-on-empty-dir.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0023-claimed-vs-observed-offset-table.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0024-baseline-4661-span-reconciliation.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.cmd +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.err +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.out +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.prov +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-codegen-linecounts/0025-FINAL-verify-manifest-all-cycles.rc +?? docs/v1/experiments/evidence/cycles/00-cross-cycle-emitter-nondeterminism-DEFECT/ +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.cmd +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.err +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.out +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.prov +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0207-P3-control-binaries-wrapper-content.rc +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.cmd +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.err +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.out +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.prov +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0214-REDO-P3-control-binaries-wrapper-content.rc +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.cmd +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.err +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.out +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.prov +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0215-b40754f-tree-vs-285166c.rc +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.cmd +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.err +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.out +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.prov +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0223-sec6-figures-source-and-rederivation.rc +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.cmd +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.err +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.out +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.prov +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0224-harness-tally-arithmetic-285166c.rc +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.cmd +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.err +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.out +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.prov +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/0225-REDO-harness-tally-history.rc +?? docs/v1/experiments/evidence/cycles/03-the-wrapper-was-conditional/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/04-c-has-no-closure-syntax/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0276-hottest-functions-measured-06a.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0296-RECONSTRUCTED-seam-cost-timing-06a.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0297-RECONSTRUCTED-free-when-unused-06a.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0298-REDO-free-when-unused-clean-binary-06a.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0299-exit-phase-bindability-check.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0324-RECONSTRUCTED-exit-binding-probe-06b.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0325-RECONSTRUCTED-exit-binding-probe-06e.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0326-strip-table-verification-28d19da.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0348-residual-kind-references-28d19da.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.cmd +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.err +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.out +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.prov +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/0363-fn-count-vs-seam-sites-06a.rc +?? docs/v1/experiments/evidence/cycles/06-the-crossing-resolves-at-emission/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0039-thunk-noargs-and-seam-caller-search.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0039-thunk-noargs-and-seam-caller-search.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0039-thunk-noargs-and-seam-caller-search.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0039-thunk-noargs-and-seam-caller-search.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0039-thunk-noargs-and-seam-caller-search.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0040-REDO-seam-caller-and-wrap-assertion-search.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0041-native-compiler-tests-gen2-binary.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0042-integration-seam_binding-gen2-binary.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0043-CONTEXT-parent-native-tests-and-integration.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0044-codegen-diff-parent-to-commit.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0045-wraps_body-scanner-branch-at-parent.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.cmd +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.err +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.out +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.prov +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/0046-seam_binding-tally-history.rc +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/parent07.sh +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/probe07.sh +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07.sh +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/thunk07b.sh +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07.sh +?? docs/v1/experiments/evidence/cycles/07-invocation-is-not-composable/time07b.sh +?? docs/v1/experiments/evidence/cycles/08-the-emitter-adjudicates/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.prov +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0047-REDO-arity-coverage-probe-both-sides.rc +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.cmd +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.err +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.out +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.prov +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0048-checker-defects-and-mechanism.rc +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.cmd +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.err +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.out +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.prov +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0049-coverage-gap-and-orphaned-comments.rc +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.cmd +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.err +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.out +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.prov +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/0050-shipped-parser-vs-correct-parser.rc +?? docs/v1/experiments/evidence/cycles/10-a-second-copy-of-the-header/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.err +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.out +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0012-codegen-lines-P3-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.err +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.out +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0013-signatures-name-recount-P5-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.err +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.out +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/0014-codegen-newline-termination-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/11-one-type-erases-the-return/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.err +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.out +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0011-codegen-lines-P4-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.err +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.out +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/0012-temporal-rel-rule-recount-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/12-judgment-lives-with-knowledge/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.cmd +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.err +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.out +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.prov +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0021-head-build-gen1.rc +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.cmd +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.err +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.out +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.prov +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0022-head-emit-c-str-len-add.rc +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.cmd +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.err +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.out +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.prov +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0023-head-cc.rc +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.cmd +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.err +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.out +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.prov +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0024-head-program-run-TODAY.rc +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.err +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.out +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0025-codegen-lines-P4-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.err +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.out +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/0026-is-int-call-recount-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/13-thirty-five-return-types/CLAIMS.md +?? docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.cmd +?? docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.err +?? docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.out +?? docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.prov +?? docs/v1/experiments/evidence/cycles/14-keywords-that-reserve-nothing/0016-head-inert-keyword-TODAY.rc +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.prov +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0011-post-native-suite.rc +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.cmd +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.err +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.out +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.prov +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0012-post-integration-harnesses.rc +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.cmd +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.err +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.out +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.prov +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0013-post-compiler-self-check.rc +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.err +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.out +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0014-P1-stride-sites-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.cmd +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.err +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.out +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.prov +?? docs/v1/experiments/evidence/cycles/16-tokens-carry-no-position/0015-P1-stride-sites-all-files-clean-tree.rc +?? docs/v1/experiments/evidence/cycles/17-annotations-are-never-checked/ +?? docs/v1/experiments/evidence/cycles/18-async-half-expressible/ +?? docs/v1/experiments/evidence/cycles/19-a-convention-is-not-a-gate/ +?? docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.cmd +?? docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.err +?? docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.out +?? docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.prov +?? docs/v2/experiments/evidence/ITERATION/0004-fixpoint-gen2-eq-gen3.rc +?? docs/v2/experiments/evidence/ITERATION/0005-native-suite.cmd +?? docs/v2/experiments/evidence/ITERATION/0005-native-suite.err +?? docs/v2/experiments/evidence/ITERATION/0005-native-suite.out +?? docs/v2/experiments/evidence/ITERATION/0005-native-suite.prov +?? docs/v2/experiments/evidence/ITERATION/0005-native-suite.rc +?? docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.cmd +?? docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.err +?? docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.out +?? docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.prov +?? docs/v2/experiments/evidence/ITERATION/0006-harness-annotation_query.rc +?? docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.cmd +?? docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.err +?? docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.out +?? docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.prov +?? docs/v2/experiments/evidence/ITERATION/0007-harness-arity_query.rc +?? docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.cmd +?? docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.err +?? docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.out +?? docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.prov +?? docs/v2/experiments/evidence/ITERATION/0008-harness-async_future.rc +?? docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.cmd +?? docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.err +?? docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.out +?? docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.prov +?? docs/v2/experiments/evidence/ITERATION/0009-harness-capability_query.rc +?? docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.cmd +?? docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.err +?? docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.out +?? docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.prov +?? docs/v2/experiments/evidence/ITERATION/0010-harness-definitions_query.rc +?? docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.cmd +?? docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.err +?? docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.out +?? docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.prov +?? docs/v2/experiments/evidence/ITERATION/0011-harness-prohibition_query.rc +?? docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.cmd +?? docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.err +?? docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.out +?? docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.prov +?? docs/v2/experiments/evidence/ITERATION/0012-harness-seam_binding.rc +?? docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.cmd +?? docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.err +?? docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.out +?? docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.prov +?? docs/v2/experiments/evidence/ITERATION/0013-harness-seam_caller.rc +?? docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.cmd +?? docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.err +?? docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.out +?? docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.prov +?? docs/v2/experiments/evidence/ITERATION/0014-harness-tagged_gate.rc +?? docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.cmd +?? docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.err +?? docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.out +?? docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.prov +?? docs/v2/experiments/evidence/ITERATION/0015-harness-temporal_query.rc +?? docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.cmd +?? docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.err +?? docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.out +?? docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.prov +?? docs/v2/experiments/evidence/ITERATION/0016-harness-temporal_signatures.rc +?? docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.cmd +?? docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.err +?? docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.out +?? docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.prov +?? docs/v2/experiments/evidence/ITERATION/0017-harness-unguarded_deref.rc +?? docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.cmd +?? docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.err +?? docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.out +?? docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.prov +?? docs/v2/experiments/evidence/ITERATION/0018-harness-units_as_data.rc +?? docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.cmd +?? docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.err +?? docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.out +?? docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.prov +?? docs/v2/experiments/evidence/ITERATION/0019-codegen-total-vs-comment-vs-code.rc +?? docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.cmd +?? docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.err +?? docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.out +?? docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.prov +?? docs/v2/experiments/evidence/ITERATION/0020-harness-assertion-tally.rc +?? docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.cmd +?? docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.err +?? docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.out +?? docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.prov +?? docs/v2/experiments/evidence/ITERATION/0021-unguarded-deref-ratchet.rc +?? docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.cmd +?? docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.err +?? docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.out +?? docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.prov +?? docs/v2/experiments/evidence/ITERATION/0022-measurement-window-lang-untouched.rc +?? docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.cmd +?? docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.err +?? docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.out +?? docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.prov +?? docs/v2/experiments/evidence/ITERATION/0023-CONTROL-verify-manifest-over-all-v2-cycles.rc +?? docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.cmd +?? docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.err +?? docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.out +?? docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.prov +?? docs/v2/experiments/evidence/ITERATION/0024-evidence-inventory.rc +?? docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.cmd +?? docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.err +?? docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.out +?? docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/ +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.cmd +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.err +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.out +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.prov +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.rc +?? docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/CLAIMS.md diff --git a/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.prov b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.prov new file mode 100644 index 0000000..929bd6c --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:54Z +exit 0 +ms 18 +sha256_out 7966f0c1bab9c01aad8c9cd11b71da31bfb283af8c42a6c894468952496ab7d7 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.rc b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0025-zz-tree-state-at-end.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.cmd b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.cmd new file mode 100644 index 0000000..f3b13e9 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.cmd @@ -0,0 +1 @@ +git log -1 --format=%H%n%ci%n%s diff --git a/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.err b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.out b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.out new file mode 100644 index 0000000..04d3112 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.out @@ -0,0 +1,3 @@ +a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +2026-08-17 12:39:50 -0500 +instrument build log: every failure, with the artifact diff --git a/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.prov b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.prov new file mode 100644 index 0000000..1e8a0d8 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.prov @@ -0,0 +1,7 @@ +commit a0cc95e3db7b04b6e221f89e89352b0e6b15d5b7 +tree dirty +captured_utc 2026-08-17T17:50:54Z +exit 0 +ms 9 +sha256_out 34f73f0b06bfec1f8d453ad31f23aac0e81d979636a770846cf23818bac66212 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.rc b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/0026-zz-head-at-end.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/ITERATION/CLAIMS.md b/docs/v2/experiments/evidence/ITERATION/CLAIMS.md new file mode 100644 index 0000000..aa9a322 --- /dev/null +++ b/docs/v2/experiments/evidence/ITERATION/CLAIMS.md @@ -0,0 +1,207 @@ +# CLAIMS — ITERATION-level evidence for v2 + +Re-run 2026-08-17. This directory holds the evidence that is about **iteration 2 +as a whole** rather than about any one cycle. Per-cycle evidence and verdicts +are in `../cycles/-/CLAIMS.md`. + +Before this run, `docs/` held 42 markdown files and **zero data files**. It now +holds a captured artifact for every re-runnable claim, each one recording the +command verbatim, stdout, stderr, the exit code captured directly and never +through a pipe, the commit SHA, the tree state, UTC, and the sha256 of both +streams. + +## The measurement window, pinned + +| | | +|---|---| +| Window start | `a116710bacba679615cb84b4ea9ce98c3acaa380` | +| Window end | `a0cc95e3d…` (see `0026-zz-head-at-end.out`) | +| Commits in window | **5** | +| Commits touching `lang/` | **0** | +| Commits touching `scripts/` or `tools/evidence/capture.sh` | **0** | + +`0022-measurement-window-lang-untouched.out` is the proof. A concurrent agent +was landing v1 evidence documents into this repository throughout, so HEAD moved +five times and `git status` read dirty for most of the run — but **no compiler +source, no runtime source, and no measuring instrument changed while any of this +was measured.** The system under test and the recorder were both stable. + +Historical claims were measured inside detached worktrees pinned at their own +commits, so those artifacts carry the system-under-test's SHA and a clean tree. +`verify-manifest.sh` flags every dirty-tree artifact as provenance-weak; the +load-bearing measurements are deliberately not among them. + +## What was captured at iteration level + +| Claim | Artifact | Result | +|---|---|---| +| the full gauntlet | `0003-gauntlet-verify-sh` | **VERIFIED, exit 0** | +| fixpoint gen2 == gen3 | `0004-fixpoint-gen2-eq-gen3` | **OK**, by sha256 | +| native suite | `0005-native-suite` | **105 tests, 105 passed, 0 failed, 253 assertions**, exit 0 | +| every harness individually, own exit code | `0006`–`0018` | **13 harnesses, all exit 0** | +| assertion tally | `0020-harness-assertion-tally` | **76 assertions across 13 harnesses** | +| `codegen.el` total / comment / code | `0019-codegen-total-vs-comment-vs-code` | **4434 total, 3197 code, 981 comment, 256 blank** | +| unguarded-deref ratchet | `0021-unguarded-deref-ratchet` | **11 unguarded casts, at baseline 11**, exit 0 | +| control over the whole record | `0023-CONTROL-verify-manifest-over-all-v2-cycles` | **250 artifacts verified, 0 altered, 0 missing** | + +### The gauntlet + +``` + fixpoint gen2 == gen3 ok + native suite 105 tests, 105 passed, 0 failed, 253 assertions in 7.115ms + integration harnesses 13 green, 76 assertions + unguarded-deref ratchet at or below baseline + + VERIFIED +``` + +### The fixpoint proof + +``` +gen1 sha256 = aa340a723e7b29e585e30c07d6dc9834e072ef15a07df5e1afb363c18e168c76 +gen2 sha256 = 61210655962abd07ce395d66a9232582fd10c2a878c80f9b85fefc9081c5313e +gen3 sha256 = 61210655962abd07ce395d66a9232582fd10c2a878c80f9b85fefc9081c5313e +FIXPOINT gen2 == gen3 OK +note: gen1 != gen2, as expected whenever codegen output changes +``` + +The `gen1 != gen2` line matters: comparing gen1 to gen2 would be the wrong test, +and it is recorded here as an observed fact rather than as a design comment. + +### `codegen.el` composition at HEAD + +``` +total_lines = 4434 +code = 3197 72.1% +comment = 981 22.1% +blank = 256 +``` + +Cycle 05 established that the metric worth quoting is code, not total. On that +metric the compiler stands at **3197 code lines**, against the **3589** baseline +at `45325f7` — **−392, −10.9%** across v1 and v2 together. + +## v2's standing, with references + +### Verdicts across all eight cycles + +| Cycle | R | D | NR | NC | total | +|---|---|---|---|---|---| +| 01 the-compiler-was-never-measured | 26 | 5 | 5 | 1 | 37 | +| 02 seven-tables-and-a-shipped-defect | 21 | 2 | 0 | 0 | 23 | +| 03 a-gate-with-no-detector | 23 | 2 | 0 | 0 | 25 | +| 04 verification-was-a-convention | 7 | 2 | 0 | 3 | 12 | +| 05 the-metric-counted-comments | 12 | 1 | 7 | 0 | 20 | +| 06 form-is-half-bindable | 12 | 0 | 0 | 1 | 13 | +| 07 the-caller-was-already-there | 17 | 1 | 1 | 2 | 21 | +| 08 PREDICTIONS | 15 | 0 | 0 | 7 | 22 | +| **total** | **133** | **13** | **13** | **14** | **173** | + +R = REPRODUCED, D = DIVERGED, NR = NOT-REPRODUCIBLE, NC = NOT-CAPTURED. + +**133 of 173 assertions reproduced from raw data. Nothing was reconstructed.** + +### The load-bearing results, re-verified + +The index classifies v2 as one SUPPORTS pair plus a BOUNDS, and commit +`9540f23` weights the whole 27-cycle record at four load-bearing results. Those +that live in v2 were given the most care in this re-run: + +**Cycle 06 — a new suffix form by a two-line data edit, no rebuild.** Fully +reproduced. The compiler binary's sha256 and mtime are byte-identical before and +after the edit and its mtime predates the edit by 37.4 s; `git diff --stat` +reads `1 file changed, 2 insertions(+)`; the same binary then emits +`3LL * 1209600000000000LL`; the linked program prints `3628800000000000`; and +reverting the two lines reverts the behaviour. **12 REPRODUCED, 0 DIVERGED.** + +**Cycle 07 — exactly three emission points, and a construct that sees its +caller.** Reproduced, but *not* by the instrument the cycle used. Commit +`fbb3a52` records that the cycle's central assertion is a grep of compiler +source the harness never compiles; I confirmed that independently — appending a +**comment** to `codegen.el` turns the assertion red while the binary's sha256 +and the emitted C are unchanged. So the bound was re-established from the +**emitted C of the binary under test**: three functions, `entry wrap exit` each, +nine points, every one keyed on the function name, and **zero** for loops, call +sites and field accesses. `AUDIT save called by handle_request` / +`AUDIT save called by migrate` reproduce verbatim. + +**Cycle 02 — 49 builtin names moved to data.** Reproduced exactly: 51 → 100 +entries in `signatures.rel`, delta 49; six of seven tables collapse to 3–6 line +wrappers; `duration_unit_nanos` alone keeps its 14 literals, which is P3. + +### The divergences that matter + +Thirteen divergences across the record. Four are substantive: + +1. **Cycle 02, A17 — the shipped defect was worse than recorded.** The doc says + `el_input_len` returned 0 for "roughly 60%" of string literals. Measured at + the buggy commit against 20 literals of lengths 1–20, checked by an + independent `hashlib` oracle: **20 of 20, a 100% failure rate.** Standalone + alignment probes give 80% on the doc's own five literals and 90% on twenty. + The rate is link-layout dependent and is not a stable quantity; the doc's 60% + was a five-literal sample. That is the same error — *a sample of five is not a + measurement of a rate* — inside the paragraph that teaches it. + +2. **Cycle 03, D-1 — the ratchet is not a ratchet.** It compares a *total* + against `BASELINE=11` rather than a *set of sites*, so guarding one site while + adding a new dereference passes: it printed a brand-new unguarded deref in its + own output while reporting `ok 11 unguarded casts, at baseline 11`. Its regex + also misses `EL_CSTR`, leaving **452 casts invisible to the detector**. And + `let s: String = 42` — defect #1 in that cycle's own list — **still segfaults + at HEAD, exit 139.** + +3. **Cycle 07, A15 — the timing numbers do not reproduce; the conclusion does.** + Seven interleaved rounds gave BASE mean 52.29 ms and STACK mean 52.29 ms, + ratio 1.0000, spread 2 ms each. The doc's 0.24–0.25 s are cold-cache figures: + measured cold/warm on this workload is **4.30×**, which is larger than the + 50% "regression" that was reported and retracted. + +4. **Cycle 04, A5 — P3 as worded is false.** `verify.sh` contains no detector + for an exit code read through a pipe; it *avoids* the defect by construction. + Prevention is not detection, so the cycle's 5/5 is 4/5 as worded and 5/5 in + substance. + +The remaining nine are off-by-one line counts (`4525` for 4524, `4662` for 4661, +`4446` for 4445, `80` for 79, `3267` for 3266) and one misattribution in cycle 01 +(`capabilities.md` names a different table than the doc claims). None changes a +conclusion; all are recorded because a record about miscounting must not carry +uncorrected miscounts. + +### What could not be reproduced, and why + +- **13 NOT-REPRODUCIBLE.** Almost all are the emit/table/other bucket split from + cycles 01 and 05. **The classifier that produced 57.2%, 2578 lines, 21 fns, + 42.8%, 15.4% and 27.4% was never committed**, and its criterion for + "emission" versus "table" versus "other" was never written down. No + replacement classifier was written and passed off as a reproduction. What could + be checked was the arithmetic, and it holds: emit 1909 + table 506 + other 794 + = **3209**, exactly the independently measured code total at `8cb7613`. + +- **14 NOT-CAPTURED.** Seven are cycle 08's predictions P1–P7, which are + ungraded by construction: the mutation study was never run, and running it + today would be a new experiment, not a reproduction. The seal is intact — + P1–P7 are byte-identical to their form at `d936bde`, which makes this genuine + pre-registration. The rest are prose assertions with no measurement behind + them, including cycle 06's P3, which the document itself labels + "NOT TESTED — an argument, not a measurement". + +## The instrument, and one defect in it + +`capture.sh` writes its manifest line with `printf '%s\n' "$*"`. **A command +containing a newline therefore splits one manifest record across several lines +and desynchronises the artifact counter.** This was hit independently on cycle 01 +and on cycle 02. In both cases the fix was the same and it was not to edit the +manifest: the evidence directory was deleted and every capture re-run from +scratch with the logic moved into instrument files. Editing a manifest to match +its artifacts inverts what a manifest is for. + +`verify-manifest.sh` globs `"$ROOT"/*/MANIFEST.tsv`, so it must be given the +**parent** of the cycle directories. Handed a cycle directory it prints +`0 artifacts verified, 0 altered, 0 missing` and **exits 0** — a green verdict +having checked nothing. That is the same shape as cycle 03's subject: a gate +nothing is forced through. The correct invocation is recorded in `0023`. + +Failed runs are retained rather than deleted — a SIGPIPE-killed build in cycle 03, +a malformed `awk` in cycles 03 and 07, and `scripts/verify.sh` returning exit 127 +at `abb0ab4` because it did not exist yet. Removing a failed attempt from an +evidence record is itself a measurement defect. diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.cmd new file mode 100644 index 0000000..f3b13e9 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.cmd @@ -0,0 +1 @@ +git log -1 --format=%H%n%ci%n%s diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.out new file mode 100644 index 0000000..016446a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.out @@ -0,0 +1,3 @@ +1a5246667d80e0bf5830a06a04e1140c2867e4ce +2026-08-17 11:21:05 -0500 +log the experiments that were run and never written down diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.prov new file mode 100644 index 0000000..583e1ed --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:40Z +exit 0 +ms 9 +sha256_out 7d531005170557490d3ef00542d5093e10b51ccd9115bfb81ed9e7cae67dafee +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0001-00-BUGGY-pinned-commit.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.cmd new file mode 100644 index 0000000..af03ced --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.cmd @@ -0,0 +1 @@ +git status --porcelain diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.out new file mode 100644 index 0000000..84cfbc2 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.out @@ -0,0 +1,3 @@ +?? elc-buggy +?? g2.c +?? work/ diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.prov new file mode 100644 index 0000000..3319e19 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:40Z +exit 0 +ms 13 +sha256_out aa6e76906574c6edd2422421723cbc40c2f2b2f81a5db509ae8a82c02fba97d2 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0002-01-BUGGY-worktree-clean.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.cmd new file mode 100644 index 0000000..2a1ca28 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02a; grep -n "static size_t el_input_len" -A 10 lang/runtime/el_runtime.c diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.out new file mode 100644 index 0000000..2864b00 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.out @@ -0,0 +1,11 @@ +18306:static size_t el_input_len(const char* s) { +18307- size_t n; +18308- if (el_bin_lookup(s, &n)) return n; +18309- /* The FALLBACK is the hazard, not the tagged lookup. A NULL check does not +18310- * establish that a slot is a pointer: el_val_t carries integers too, so +18311- * strlen() on `sha256_hex(50000)` walks address 50000. Guarding the tagged +18312- * path alone left this untouched and the SIGSEGV unchanged -- measured. */ +18313- if (!looks_like_heap_obj((el_val_t)(uintptr_t)s)) return 0; +18314- return strlen(s); +18315-} +18316- diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.prov new file mode 100644 index 0000000..028d70f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:40Z +exit 0 +ms 17 +sha256_out 044c4a6e314d5bc47b7eb9a61c7b3a5d6bcba56cbead224dbf850e131e601316 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0003-02-BUGGY-el_input_len-source.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.cmd new file mode 100644 index 0000000..b5f8039 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02a; grep -n "static int looks_like_heap_obj" -A 10 lang/runtime/el_runtime.c diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.out new file mode 100644 index 0000000..017d790 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.out @@ -0,0 +1,11 @@ +729:static int looks_like_heap_obj(el_val_t v) { +730- if (v == 0) return 0; +731- int64_t s = (int64_t)v; +732- if (s > -0x10000 && s < 0x10000) return 0; /* small ints */ +733- uintptr_t p = (uintptr_t)v; +734- if (p < 0x10000) return 0; /* low addresses */ +735- if (p & 0x7) return 0; /* malloc returns 8-aligned */ +736- return 1; +737-} +738- +739-int el_tagged(el_val_t v, uint32_t magic) { diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.prov new file mode 100644 index 0000000..8ba0e5a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:40Z +exit 0 +ms 15 +sha256_out 655a62c931220bdc6b9b6563d065fb047606cce8abcada95b72bb57d7a386ca7 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0004-03-BUGGY-looks_like_heap_obj-source.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.cmd new file mode 100644 index 0000000..7e28bd5 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.cmd @@ -0,0 +1 @@ +cat /tmp/rerun-v2-02a/work/lit.el diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.out new file mode 100644 index 0000000..3acba9e --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.out @@ -0,0 +1,22 @@ +fn main() { + println("len=01 lit=b sha=" + sha256_hex("b")) + println("len=02 lit=cd sha=" + sha256_hex("cd")) + println("len=03 lit=def sha=" + sha256_hex("def")) + println("len=04 lit=efgh sha=" + sha256_hex("efgh")) + println("len=05 lit=fghij sha=" + sha256_hex("fghij")) + println("len=06 lit=ghijkl sha=" + sha256_hex("ghijkl")) + println("len=07 lit=hijklmn sha=" + sha256_hex("hijklmn")) + println("len=08 lit=ijklmnop sha=" + sha256_hex("ijklmnop")) + println("len=09 lit=jklmnopqr sha=" + sha256_hex("jklmnopqr")) + println("len=10 lit=klmnopqrst sha=" + sha256_hex("klmnopqrst")) + println("len=11 lit=lmnopqrstuv sha=" + sha256_hex("lmnopqrstuv")) + println("len=12 lit=mnopqrstuvwx sha=" + sha256_hex("mnopqrstuvwx")) + println("len=13 lit=nopqrstuvwxyz sha=" + sha256_hex("nopqrstuvwxyz")) + println("len=14 lit=opqrstuvwxyzab sha=" + sha256_hex("opqrstuvwxyzab")) + println("len=15 lit=pqrstuvwxyzabcd sha=" + sha256_hex("pqrstuvwxyzabcd")) + println("len=16 lit=qrstuvwxyzabcdef sha=" + sha256_hex("qrstuvwxyzabcdef")) + println("len=17 lit=rstuvwxyzabcdefgh sha=" + sha256_hex("rstuvwxyzabcdefgh")) + println("len=18 lit=stuvwxyzabcdefghij sha=" + sha256_hex("stuvwxyzabcdefghij")) + println("len=19 lit=tuvwxyzabcdefghijkl sha=" + sha256_hex("tuvwxyzabcdefghijkl")) + println("len=20 lit=uvwxyzabcdefghijklmn sha=" + sha256_hex("uvwxyzabcdefghijklmn")) +} diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.prov new file mode 100644 index 0000000..c92db19 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:40Z +exit 0 +ms 4 +sha256_out 8114c39cfd7f43a0692dfee3c8d2ae601dbf80c632a31f14f608bea4e3b9b4aa +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0005-04-probe-source-20-literals-lengths-1-to-20.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.cmd new file mode 100644 index 0000000..8b6b3c8 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02a/work/lit diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.out new file mode 100644 index 0000000..fa4a662 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.out @@ -0,0 +1,20 @@ +len=01 lit=b sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=02 lit=cd sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=03 lit=def sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=04 lit=efgh sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=05 lit=fghij sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=06 lit=ghijkl sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=07 lit=hijklmn sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=08 lit=ijklmnop sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=09 lit=jklmnopqr sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=10 lit=klmnopqrst sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=11 lit=lmnopqrstuv sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=12 lit=mnopqrstuvwx sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=13 lit=nopqrstuvwxyz sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=14 lit=opqrstuvwxyzab sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=15 lit=pqrstuvwxyzabcd sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=16 lit=qrstuvwxyzabcdef sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=17 lit=rstuvwxyzabcdefgh sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=18 lit=stuvwxyzabcdefghij sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=19 lit=tuvwxyzabcdefghijkl sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +len=20 lit=uvwxyzabcdefghijklmn sha=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.prov new file mode 100644 index 0000000..c837953 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:40Z +exit 0 +ms 7 +sha256_out 32a6279918627a9a79a371da78aab404895a6050c5070b7455a4d16b1a1d1c60 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0006-05-BUGGY-RUN-20-literals.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.cmd new file mode 100644 index 0000000..28dbc46 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.cmd @@ -0,0 +1 @@ +/Users/will/Development/neuron-technologies/foundation/el/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh /tmp/rerun-v2-02a/work/lit diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.out new file mode 100644 index 0000000..ce7fa63 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.out @@ -0,0 +1,25 @@ +MISMATCH lit=b got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d +MISMATCH lit=cd got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=21e721c35a5823fdb452fa2f9f0a612c74fb952e06927489c6b27a43b817bed4 +MISMATCH lit=def got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=cb8379ac2098aa165029e3938a51da0bcecfc008fd6795f401178647f96c5b34 +MISMATCH lit=efgh got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=e5e088a0b66163a0a26a5e053d2a4496dc16ab6e0e3dd1adf2d16aa84a078c9d +MISMATCH lit=fghij got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=7272207e4b9c7e929f4278d245c7768380b54ecb97b1fbe941a7ccfc27cf01f4 +MISMATCH lit=ghijkl got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=54f6ee81b58accbc57adbceb0f50264897626060071dc9e92f897e7b373deb93 +MISMATCH lit=hijklmn got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=a2cc0056817d002901742f20883fb838f296af3a4fa9dbb6da71b8af69ccd4d5 +MISMATCH lit=ijklmnop got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=d2789a29f48befe96a70ef3e3eaf57975f692165155e96880b310c82ac012ebf +MISMATCH lit=jklmnopqr got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=d2e047baf8cdb056976719af3e10d88db00adc5e5477253112226eac1b8f7ea2 +MISMATCH lit=klmnopqrst got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=e683456c3fca63fe2cc7655a7f574e8b22a1ec23d98a55495cfbe8e7c6adfa15 +MISMATCH lit=lmnopqrstuv got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=5f95ce65aaa36ea4f48dfe09d0497cc34822f8db8960b2e3323e527bfe79b928 +MISMATCH lit=mnopqrstuvwx got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=a9ff63d25df2d2d1ad036a3ed6aa32baa4c349c54fd35c6447be21f7ab7a8ef1 +MISMATCH lit=nopqrstuvwxyz got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=75be37f9f873d0925c99caa508a36a1b2c96097447c428f4dc7b11a67d819fdb +MISMATCH lit=opqrstuvwxyzab got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=f307eec79502684875d9d181e401d1451192c8d1be75e6a06c19329cb9205921 +MISMATCH lit=pqrstuvwxyzabcd got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=29fd523b2af525954fb5c591b8c8424e142d1e512b2d8a316fb4a4fe2ca80cff +MISMATCH lit=qrstuvwxyzabcdef got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=dc59351aed77218d19188b25c195fcb8d3b850b821926b667ce68d0a2f63a1e1 +MISMATCH lit=rstuvwxyzabcdefgh got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=79f3e96572bdcd07998be733d9bf77419f9952430c8d6dfebbe715fe96701cae +MISMATCH lit=stuvwxyzabcdefghij got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=d9cde06d9f3fbbade42e65c27dabaca4bfd5ba0d8d8a1071c6f02885e2f075e3 +MISMATCH lit=tuvwxyzabcdefghijkl got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=51cbf66472d2944a47bf87ee0f1b5719475b4fb22fdfbf3a1c66de90520c1bba +MISMATCH lit=uvwxyzabcdefghijklmn got=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 expected=0ef6aff7dae19effff0e9c1610df638d2f6e0d6295f485112939af0067784340 +literals tested = 20 +correct vs hashlib.sha256 = 0 +incorrect = 20 +hashed as the EMPTY STRING = 20 +failure rate = 100% diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.prov new file mode 100644 index 0000000..cdf987f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:41Z +exit 0 +ms 369 +sha256_out 087862b98e5d31d369a92efd2799d1e7e852dc988737cfc6e34a0b74380cc1a0 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0007-06-BUGGY-ORACLE-verdict.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.cmd new file mode 100644 index 0000000..717aadb --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02a/work/align5 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.out new file mode 100644 index 0000000..e47a6e6 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.out @@ -0,0 +1,6 @@ +abc 0x104650580 aligned8=1 +hello 0x104650584 aligned8=0 +x 0x10465058a aligned8=0 +a longer literal here 0x10465058c aligned8=0 +q 0x1046505a2 aligned8=0 +4 of 5 misaligned (80%) diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.prov new file mode 100644 index 0000000..a80b7c4 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:41Z +exit 0 +ms 4 +sha256_out 5e5d09cc202b5d93b4eac4ae911fa8bed2e5d2a38d47ff1765a61f2c0de71c86 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0008-07-ALIGNMENT-the-docs-own-five-literals.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.cmd new file mode 100644 index 0000000..27b61bd --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02a/work/align20 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.out new file mode 100644 index 0000000..ae9b6f6 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.out @@ -0,0 +1,21 @@ +len=01 b 0x1045a855c aligned8=0 +len=02 cd 0x1045a855e aligned8=0 +len=03 def 0x1045a8561 aligned8=0 +len=04 efgh 0x1045a8565 aligned8=0 +len=05 fghij 0x1045a856a aligned8=0 +len=06 ghijkl 0x1045a8570 aligned8=1 +len=07 hijklmn 0x1045a8577 aligned8=0 +len=08 ijklmnop 0x1045a857f aligned8=0 +len=09 jklmnopqr 0x1045a8588 aligned8=1 +len=10 klmnopqrst 0x1045a8592 aligned8=0 +len=11 lmnopqrstuv 0x1045a859d aligned8=0 +len=12 mnopqrstuvwx 0x1045a85a9 aligned8=0 +len=13 nopqrstuvwxyz 0x1045a85b6 aligned8=0 +len=14 opqrstuvwxyzab 0x1045a85c4 aligned8=0 +len=15 pqrstuvwxyzabcd 0x1045a85d3 aligned8=0 +len=16 qrstuvwxyzabcdef 0x1045a85e3 aligned8=0 +len=17 rstuvwxyzabcdefgh 0x1045a85f4 aligned8=0 +len=18 stuvwxyzabcdefghij 0x1045a8606 aligned8=0 +len=19 tuvwxyzabcdefghijkl 0x1045a8619 aligned8=0 +len=20 uvwxyzabcdefghijklmn 0x1045a862d aligned8=0 +18 of 20 misaligned (90%) diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.prov new file mode 100644 index 0000000..7cb107c --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:44:41Z +exit 0 +ms 4 +sha256_out a1bd6525284bee14b50ba9eef190ed7dc6b1603c0f40f98eab42ced4ad68b855 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.cmd new file mode 100644 index 0000000..25579ac --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.cmd @@ -0,0 +1 @@ +cat /tmp/rerun-v2-02a/work/align5.c diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.out new file mode 100644 index 0000000..2aa8182 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0010-09-alignment-probe-source-align5.out @@ -0,0 +1,15 @@ +#include +#include +/* The doc's own five literals, in the doc's own order. */ +int main(void){ + const char* L[] = {"abc","hello","x","a longer literal here","q"}; + int n = 5, mis = 0; + for (int i=0;i +#include +int main(void){ + const char* L[] = {"b","cd","def","efgh","fghij","ghijkl","hijklmn","ijklmnop","jklmnopqr","klmnopqrst","lmnopqrstuv","mnopqrstuvwx","nopqrstuvwxyz","opqrstuvwxyzab","pqrstuvwxyzabcd","qrstuvwxyzabcdef","rstuvwxyzabcdefgh","stuvwxyzabcdefghij","tuvwxyzabcdefghijkl","uvwxyzabcdefghijklmn"}; + int n = 20, mis = 0; + for (int i=0;i -0x10000 && sv < 0x10000) return 0; /* small ints */ +18336- if ((uintptr_t)sv < 0x10000) return 0; /* low addresses */ +18337- return strlen(s); +18338-} diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.prov new file mode 100644 index 0000000..331a79d --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:44:51Z +exit 0 +ms 15 +sha256_out cfc667d2ffefbac32441bc38461be71b07df129bf3cddce7768ff20203561a9e +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0013-12-FIXED-el_input_len-source.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.cmd new file mode 100644 index 0000000..5be9ba2 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02b/work/lit diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.out new file mode 100644 index 0000000..415cd8d --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.out @@ -0,0 +1,20 @@ +len=01 lit=b sha=3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d +len=02 lit=cd sha=21e721c35a5823fdb452fa2f9f0a612c74fb952e06927489c6b27a43b817bed4 +len=03 lit=def sha=cb8379ac2098aa165029e3938a51da0bcecfc008fd6795f401178647f96c5b34 +len=04 lit=efgh sha=e5e088a0b66163a0a26a5e053d2a4496dc16ab6e0e3dd1adf2d16aa84a078c9d +len=05 lit=fghij sha=7272207e4b9c7e929f4278d245c7768380b54ecb97b1fbe941a7ccfc27cf01f4 +len=06 lit=ghijkl sha=54f6ee81b58accbc57adbceb0f50264897626060071dc9e92f897e7b373deb93 +len=07 lit=hijklmn sha=a2cc0056817d002901742f20883fb838f296af3a4fa9dbb6da71b8af69ccd4d5 +len=08 lit=ijklmnop sha=d2789a29f48befe96a70ef3e3eaf57975f692165155e96880b310c82ac012ebf +len=09 lit=jklmnopqr sha=d2e047baf8cdb056976719af3e10d88db00adc5e5477253112226eac1b8f7ea2 +len=10 lit=klmnopqrst sha=e683456c3fca63fe2cc7655a7f574e8b22a1ec23d98a55495cfbe8e7c6adfa15 +len=11 lit=lmnopqrstuv sha=5f95ce65aaa36ea4f48dfe09d0497cc34822f8db8960b2e3323e527bfe79b928 +len=12 lit=mnopqrstuvwx sha=a9ff63d25df2d2d1ad036a3ed6aa32baa4c349c54fd35c6447be21f7ab7a8ef1 +len=13 lit=nopqrstuvwxyz sha=75be37f9f873d0925c99caa508a36a1b2c96097447c428f4dc7b11a67d819fdb +len=14 lit=opqrstuvwxyzab sha=f307eec79502684875d9d181e401d1451192c8d1be75e6a06c19329cb9205921 +len=15 lit=pqrstuvwxyzabcd sha=29fd523b2af525954fb5c591b8c8424e142d1e512b2d8a316fb4a4fe2ca80cff +len=16 lit=qrstuvwxyzabcdef sha=dc59351aed77218d19188b25c195fcb8d3b850b821926b667ce68d0a2f63a1e1 +len=17 lit=rstuvwxyzabcdefgh sha=79f3e96572bdcd07998be733d9bf77419f9952430c8d6dfebbe715fe96701cae +len=18 lit=stuvwxyzabcdefghij sha=d9cde06d9f3fbbade42e65c27dabaca4bfd5ba0d8d8a1071c6f02885e2f075e3 +len=19 lit=tuvwxyzabcdefghijkl sha=51cbf66472d2944a47bf87ee0f1b5719475b4fb22fdfbf3a1c66de90520c1bba +len=20 lit=uvwxyzabcdefghijklmn sha=0ef6aff7dae19effff0e9c1610df638d2f6e0d6295f485112939af0067784340 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.prov new file mode 100644 index 0000000..b79037a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:44:51Z +exit 0 +ms 7 +sha256_out 96374c493b16f0f5f6fce85839fafb0967b2918ad070cddffddacf6358c06671 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0014-13-FIXED-RUN-20-literals.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.cmd new file mode 100644 index 0000000..ebed324 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.cmd @@ -0,0 +1 @@ +/Users/will/Development/neuron-technologies/foundation/el/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh /tmp/rerun-v2-02b/work/lit diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.out new file mode 100644 index 0000000..35630a0 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.out @@ -0,0 +1,5 @@ +literals tested = 20 +correct vs hashlib.sha256 = 20 +incorrect = 0 +hashed as the EMPTY STRING = 0 +failure rate = 0% diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.prov new file mode 100644 index 0000000..ee1375e --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:44:51Z +exit 0 +ms 36 +sha256_out 92f2d011d61336ef9d97f39a074d75352b3100223429e5bc8cb15108da5686fa +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0015-14-FIXED-ORACLE-verdict.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.cmd new file mode 100644 index 0000000..a678bf6 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; git show 1a52466:lang/tests/integration/tagged_gate.sh | grep -c "^chk \|chk \"" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.out new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.out @@ -0,0 +1 @@ +5 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.prov new file mode 100644 index 0000000..093e725 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:44:51Z +exit 0 +ms 13 +sha256_out f0b5c2c2211c8d67ed15e75e656c7862d086e9245420892a7de62cd9ec582a06 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0016-15-tagged_gate-assertion-count-BEFORE.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.cmd new file mode 100644 index 0000000..2786ee1 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; grep -c "chk \"" lang/tests/integration/tagged_gate.sh diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.out new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.out @@ -0,0 +1 @@ +10 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.prov new file mode 100644 index 0000000..e93be46 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:44:51Z +exit 0 +ms 10 +sha256_out 917df3320d778ddbaa5c5c7742bc4046bf803c36ed2b050f30844ed206783469 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0017-16-tagged_gate-assertion-count-AFTER.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.cmd new file mode 100644 index 0000000..e40e4ee --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.cmd @@ -0,0 +1 @@ +lang/tests/integration/tagged_gate.sh /tmp/rerun-v2-02b/elc-fixed /tmp/rerun-v2-02b/lang diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.out new file mode 100644 index 0000000..5666968 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.out @@ -0,0 +1,12 @@ + ok an integer where a string is expected does not crash + ok and yields the empty-string hash, not memory + ok a NEGATIVE integer does not crash + ok a legitimate string still hashes correctly + ok the gate is exported, so siblings stop re-deriving it + ok abc hashes correctly + ok a hashes correctly + ok hello world hashes correctly + ok the empty string still hashes to e3b0... + ok and no literal silently hashed as empty + + 10 assertions, 10 passed, 0 failed diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.prov new file mode 100644 index 0000000..05ead31 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:45:05Z +exit 0 +ms 13648 +sha256_out 54ed74debfd5061190b7c6aaecabea13295684ac75502ce77a7a7b0e2e7778e4 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0018-17-tagged_gate-harness-run.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.cmd new file mode 100644 index 0000000..bb0b9ee --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; B=$(git show 1a52466:lang/el-compiler/src/codegen.el | wc -l | tr -d " "); A=$(git show abb0ab4:lang/el-compiler/src/codegen.el | wc -l | tr -d " "); BC=$(git show 1a52466:lang/el-compiler/src/codegen.el | grep -v "^[[:space:]]*//" | grep -vc "^[[:space:]]*$"); AC=$(git show abb0ab4:lang/el-compiler/src/codegen.el | grep -v "^[[:space:]]*//" | grep -vc "^[[:space:]]*$"); printf "TOTAL lines %s -> %s delta %s (doc claims -80)\nCODE lines %s -> %s delta %s\n" "$B" "$A" "$((A-B))" "$BC" "$AC" "$((AC-BC))" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.out new file mode 100644 index 0000000..400dd6f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.out @@ -0,0 +1,2 @@ +TOTAL lines 4524 -> 4445 delta -79 (doc claims -80) +CODE lines 3277 -> 3209 delta -68 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.prov new file mode 100644 index 0000000..9f80853 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:45:25Z +exit 0 +ms 46 +sha256_out 834f02acdfd310427d7a9ed7429f78892f0e15185285adf0d51fb2dfbedf4945 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0019-18-P4-codegen-line-delta.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.cmd new file mode 100644 index 0000000..b910a05 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; B=$(git show 1a52466:lang/tools/check/signatures.rel | grep -cE "^[a-z_]+ +returns"); A=$(grep -cE "^[a-z_]+ +returns" lang/tools/check/signatures.rel); printf "signatures.rel entries BEFORE = %s\nsignatures.rel entries AFTER = %s\ndelta = %s (doc claims 49 names moved)\n" "$B" "$A" "$((A-B))" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.out new file mode 100644 index 0000000..d9eb84d --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.out @@ -0,0 +1,3 @@ +signatures.rel entries BEFORE = 51 +signatures.rel entries AFTER = 100 +delta = 49 (doc claims 49 names moved) diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.prov new file mode 100644 index 0000000..84e0f9d --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:45:25Z +exit 0 +ms 16 +sha256_out 19a904d093cc12e30565eff9e07b4464f8bb7506ab4372e7a51eca91713f42f4 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0020-19-P2-names-moved-to-signatures-rel.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.cmd new file mode 100644 index 0000000..5a61e8a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; for f in duration_unit_nanos is_float_call is_void_builtin is_rhythm_call is_calendar_call is_caltime_call is_zone_call; do printf "%-22s at 1a52466: %s lines, %s string literals\n" "$f" "$(git show 1a52466:lang/el-compiler/src/codegen.el | awk "/^fn $f\(/,/^}/" | wc -l | tr -d " ")" "$(git show 1a52466:lang/el-compiler/src/codegen.el | awk "/^fn $f\(/,/^}/" | grep -o "\"[a-z_]*\"" | wc -l | tr -d " ")"; done diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.out new file mode 100644 index 0000000..38a2342 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.out @@ -0,0 +1,7 @@ +duration_unit_nanos at 1a52466: 17 lines, 14 string literals +is_float_call at 1a52466: 18 lines, 14 string literals +is_void_builtin at 1a52466: 18 lines, 15 string literals +is_rhythm_call at 1a52466: 16 lines, 12 string literals +is_calendar_call at 1a52466: 13 lines, 9 string literals +is_caltime_call at 1a52466: 11 lines, 7 string literals +is_zone_call at 1a52466: 11 lines, 7 string literals diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.prov new file mode 100644 index 0000000..8385096 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:45:25Z +exit 0 +ms 167 +sha256_out 306b3363d5adcd20833b34144b9243bb4e5098417721205c47c959a002c4e817 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0021-20-P1-the-seven-tables-BEFORE.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.cmd new file mode 100644 index 0000000..3eef384 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; for f in duration_unit_nanos is_float_call is_void_builtin is_rhythm_call is_calendar_call is_caltime_call is_zone_call; do printf "%-22s at abb0ab4: %s lines, %s string literals\n" "$f" "$(awk "/^fn $f\(/,/^}/" lang/el-compiler/src/codegen.el | wc -l | tr -d " ")" "$(awk "/^fn $f\(/,/^}/" lang/el-compiler/src/codegen.el | grep -o "\"[a-z_]*\"" | wc -l | tr -d " ")"; done diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.out new file mode 100644 index 0000000..0fef115 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.out @@ -0,0 +1,7 @@ +duration_unit_nanos at abb0ab4: 17 lines, 14 string literals +is_float_call at abb0ab4: 3 lines, 0 string literals +is_void_builtin at abb0ab4: 6 lines, 1 string literals +is_rhythm_call at abb0ab4: 3 lines, 0 string literals +is_calendar_call at abb0ab4: 3 lines, 0 string literals +is_caltime_call at abb0ab4: 3 lines, 0 string literals +is_zone_call at abb0ab4: 3 lines, 0 string literals diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.prov new file mode 100644 index 0000000..df67f3d --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:45:26Z +exit 0 +ms 117 +sha256_out add0ce42a0a99632d0532a894d410b95042d3e7e46cb4967f819fe338594df1e +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0022-21-P1-the-seven-tables-AFTER.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.cmd new file mode 100644 index 0000000..5b6459b --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02a/work/p8 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.out new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.prov new file mode 100644 index 0000000..e37fd50 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:46:09Z +exit 139 +ms 7 +sha256_out e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.rc new file mode 100644 index 0000000..897bdc8 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0023-22-P8-BUGGY-5-fortnights-SIGSEGV.rc @@ -0,0 +1 @@ +139 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.cmd new file mode 100644 index 0000000..26945cb --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02a/lang; grep -n "el_get_field" /tmp/rerun-v2-02a/work/p8.c diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.out new file mode 100644 index 0000000..d152d04 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.out @@ -0,0 +1 @@ +8: el_val_t d = el_get_field(5, EL_STR("fortnights")); diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.prov new file mode 100644 index 0000000..e0293a1 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:46:09Z +exit 0 +ms 10 +sha256_out ca4671c54962945ffce55e7aaf256b7873cb46df2a83252a8a165f76b703bf04 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0024-23-P8-BUGGY-emitted-C-is-a-field-access.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.cmd new file mode 100644 index 0000000..0f70412 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02a/work/p10 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.out new file mode 100644 index 0000000..c0dc175 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.out @@ -0,0 +1,2 @@ +1 +20 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.prov new file mode 100644 index 0000000..db0eba7 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.prov @@ -0,0 +1,7 @@ +commit 1a5246667d80e0bf5830a06a04e1140c2867e4ce +tree dirty +captured_utc 2026-08-17T17:46:09Z +exit 0 +ms 7 +sha256_out 783e5bca6f660d66ef3c0ddc0b14ed2dc86c70b1cabef7c0b33a76179149618d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0025-24-P10-BUGGY-legitimate-access.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.cmd new file mode 100644 index 0000000..36b4419 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02b/work/p8 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.out new file mode 100644 index 0000000..3aac67b --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.out @@ -0,0 +1 @@ +survived diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.prov new file mode 100644 index 0000000..5630799 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:09Z +exit 0 +ms 7 +sha256_out 304b524de1a79904aaf8295a0986f8c03dd0d1d26d25902da057b47277147297 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0026-25-P9-FIXED-5-fortnights-survives.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.cmd new file mode 100644 index 0000000..b3fdfba --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.cmd @@ -0,0 +1 @@ +/tmp/rerun-v2-02b/work/p10 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.out new file mode 100644 index 0000000..c0dc175 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.out @@ -0,0 +1,2 @@ +1 +20 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.prov new file mode 100644 index 0000000..0612efd --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:09Z +exit 0 +ms 7 +sha256_out 783e5bca6f660d66ef3c0ddc0b14ed2dc86c70b1cabef7c0b33a76179149618d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0027-26-P10-FIXED-legitimate-access-unaffected.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.cmd new file mode 100644 index 0000000..3db634b --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; echo "=== as_map BEFORE (1a52466) ==="; git show 1a52466:lang/runtime/el_runtime.c | grep -n "static ElMap\* as_map" -A 3; echo; echo "=== as_map AFTER (abb0ab4) ==="; grep -n "static ElMap\* as_map" -A 6 lang/runtime/el_runtime.c; echo; echo "=== el_list_get / el_list_len AFTER ==="; grep -n "el_val_t el_list_get\|el_val_t el_list_len" -A 3 lang/runtime/el_runtime.c | head -20 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.out new file mode 100644 index 0000000..1bf5658 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.out @@ -0,0 +1,25 @@ +=== as_map BEFORE (1a52466) === +633:static ElMap* as_map(el_val_t v) { return (ElMap*)(uintptr_t)v; } +634- +635-el_val_t el_map_get(el_val_t mapv, el_val_t keyv) { +636- ElMap* m = as_map(mapv); + +=== as_map AFTER (abb0ab4) === +640:static ElMap* as_map(el_val_t v) { +641- if (!el_tagged(v, EL_MAGIC_MAP)) return NULL; +642- return (ElMap*)(uintptr_t)v; +643-} +644- +645-el_val_t el_map_get(el_val_t mapv, el_val_t keyv) { +646- ElMap* m = as_map(mapv); + +=== el_list_get / el_list_len AFTER === +509:el_val_t el_list_len(el_val_t listv) { +510- if (!el_tagged(listv, EL_MAGIC_LIST)) return 0; +511- ElList* lst = (ElList*)(uintptr_t)listv; +512- if (!lst) return 0; +-- +516:el_val_t el_list_get(el_val_t listv, el_val_t index) { +517- if (!el_tagged(listv, EL_MAGIC_LIST)) return 0; /* an integer is not a list */ +518- ElList* lst = (ElList*)(uintptr_t)listv; +519- if (!lst) return 0; diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.prov new file mode 100644 index 0000000..2e6ed55 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:09Z +exit 0 +ms 47 +sha256_out 4e8ec729991ca53af4fef95edcc4d9bee6788d46e8ff349d389fd04264eacb4d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0028-27-P9-P11-as_map-and-as_list-gates.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.cmd new file mode 100644 index 0000000..a8234ed --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.cmd @@ -0,0 +1 @@ +./scripts/verify.sh diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.err new file mode 100644 index 0000000..f0a5198 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.err @@ -0,0 +1 @@ +/Users/will/Development/neuron-technologies/foundation/el/tools/evidence/capture.sh: line 39: ./scripts/verify.sh: No such file or directory diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.out new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.prov new file mode 100644 index 0000000..c37ded3 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:19Z +exit 127 +ms 5 +sha256_out e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256_err 8a55cbc74d4109eff6031edd684824b2ae291283c99f13661b92d22645c175a7 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.rc new file mode 100644 index 0000000..c75acbe --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0029-28-P5-fixpoint-and-suites-at-abb0ab4.rc @@ -0,0 +1 @@ +127 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.cmd new file mode 100644 index 0000000..069314f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b; ls scripts/ 2>&1; echo "---"; echo "verify.sh first appears in:"; git log --oneline --diff-filter=A --all -- scripts/verify.sh diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.out new file mode 100644 index 0000000..e2433c4 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.out @@ -0,0 +1,6 @@ +check-runtime-growth.sh +check-single-runtime.sh +el-runtime-sources.sh +--- +verify.sh first appears in: +6c80dee1 make verification a mechanism instead of a convention diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.prov new file mode 100644 index 0000000..9bdb697 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:33Z +exit 0 +ms 28 +sha256_out ce6d188689cd310ec634fe4ce52c2b43540d8733e487a11e65edf1cc2bf0542a +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0030-29-verify-sh-did-not-exist-at-abb0ab4.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.cmd new file mode 100644 index 0000000..bc9f4a7 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b/lang; SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; W=/tmp/rerun-v2-02b/work; /tmp/rerun-v2-02b/elc-fixed elc-cli.el > $W/g2.c 2>/dev/null; cc $CF -o $W/elc2 $W/g2.c $SRCS $LF 2>/dev/null; $W/elc2 elc-cli.el > $W/g3.c 2>/dev/null; if cmp -s $W/g2.c $W/g3.c; then echo "FIXPOINT gen2 == gen3 OK"; else echo "FIXPOINT FAILED"; fi; printf "gen2 sha256 = %s\ngen3 sha256 = %s\n" "$(shasum -a 256 $W/g2.c | cut -d\ -f1)" "$(shasum -a 256 $W/g3.c | cut -d\ -f1)" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.out new file mode 100644 index 0000000..f46e82e --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.out @@ -0,0 +1,3 @@ +FIXPOINT gen2 == gen3 OK +gen2 sha256 = d4d87a473dc500c31f92259079d7cc7b24793576f7ea8631f61ebee1ac31dcc4 +gen3 sha256 = d4d87a473dc500c31f92259079d7cc7b24793576f7ea8631f61ebee1ac31dcc4 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.prov new file mode 100644 index 0000000..c79716f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:37Z +exit 0 +ms 4172 +sha256_out b3659226192b528e8e39872d11258d608803c9c2b1c2514e486102960eac6a2a +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.cmd new file mode 100644 index 0000000..936b58e --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b/lang; SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; W=/tmp/rerun-v2-02b/work; $W/elc2 --test tests/native/test_compiler.el > $W/t.c 2>/dev/null; cc $CF -o $W/t $W/t.c $SRCS $LF 2>/dev/null; $W/t; echo "native_suite_exit=$?" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.out new file mode 100644 index 0000000..542c201 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.out @@ -0,0 +1,108 @@ +ok lex-empty (0.039ms) +ok lex-whitespace-stripped (0.002ms) +ok lex-comment-stripped (0.001ms) +ok lex-int-literals (0.002ms) +ok lex-float-literals (0.010ms) +ok lex-string-literals (0.002ms) +ok lex-string-escape-newline (0.001ms) +ok lex-string-escape-tab (0.001ms) +ok lex-string-escape-backslash (0.000ms) +ok lex-bool-literals (0.001ms) +ok lex-identifier (0.002ms) +ok lex-keywords (0.005ms) +ok lex-more-keywords (0.002ms) +ok lex-keyword-values (0.002ms) +ok lex-arithmetic-operators (0.001ms) +ok lex-comparison-operators (0.001ms) +ok lex-logical-operators (0.001ms) +ok lex-arrow-tokens (0.000ms) +ok lex-delimiters (0.002ms) +ok lex-double-colon (0.000ms) +ok lex-dot-dot (0.000ms) +ok lex-pipe-operators (0.001ms) +ok lex-at-and-question (0.001ms) +ok lex-eof-always-last (0.010ms) +ok lex-string-with-spaces (0.000ms) +ok lex-multiline-source (0.002ms) +ok lex-flat-stride-3-layout (0.001ms) +ok lexer-tracks-line-numbers (0.002ms) +ok parse-let-stmt (0.027ms) +ok parse-fn-decl (0.010ms) +ok parse-fn-params (0.004ms) +ok parse-return-stmt (0.002ms) +ok parse-if-stmt (0.006ms) +ok parse-if-else (0.007ms) +ok parse-while-stmt (0.006ms) +ok parse-import-stmt (0.002ms) +ok parse-extern-fn (0.003ms) +ok parse-let-int-value (0.002ms) +ok parse-let-string-value (0.002ms) +ok parse-let-bool-value (0.002ms) +ok parse-binop-expr (0.002ms) +ok parse-call-expr (0.004ms) +ok parse-multiple-fns (0.005ms) +ok parse-assign-stmt (0.003ms) +ok parse-for-stmt (0.006ms) +ok parse-unary-not (0.004ms) +ok parse-unary-neg (0.004ms) +ok parse-array-literal (0.005ms) +ok parse-empty-array (0.003ms) +ok parse-index-expr (0.004ms) +ok codegen-includes (0.288ms) +ok codegen-int-main (0.219ms) +ok codegen-runtime-init (0.110ms) +ok codegen-void-function-signature (0.130ms) +ok codegen-function-with-params (0.119ms) +ok codegen-int-literal (0.303ms) +ok codegen-string-literal (0.134ms) +ok codegen-if-statement (0.118ms) +ok codegen-if-else (0.126ms) +ok codegen-while-loop (0.105ms) +ok codegen-let-binding (0.094ms) +ok codegen-function-call (0.093ms) +ok codegen-string-concat (0.100ms) +ok codegen-int-arithmetic (0.096ms) +ok codegen-comparison (0.114ms) +ok codegen-string-equality (0.100ms) +ok codegen-logical-and (0.106ms) +ok codegen-logical-or (0.095ms) +ok codegen-unary-not (0.092ms) +ok codegen-string-escape-in-c (0.084ms) +ok codegen-many-functions (0.121ms) +ok codegen-deep-expression (0.109ms) +ok codegen-forward-declarations (0.099ms) +ok codegen-for-loop (0.273ms) +ok codegen-extern-fn (0.164ms) +ok codegen-nested-calls (0.112ms) +ok compiler-minimal-program (0.073ms) +ok compiler-pure-library (0.088ms) +ok compiler-multiple-fns-with-main (0.095ms) +ok compiler-let-in-main (0.059ms) +ok compiler-string-concat-chain (0.088ms) +ok compiler-negative-literal (0.114ms) +ok compiler-stdint-include (0.120ms) +ok decorator-undecorated-fn-has-no-beat (0.119ms) +ok decorator-authenticate-compiles-to-nothing (0.227ms) +ok declared-construct-name-unknown-to-codegen (0.087ms) +ok undeclared-construct-still-injects-nothing (0.122ms) +ok undeclared-guard-emits-nothing (0.081ms) +ok seam-indirection-emitted-on-every-fn (0.078ms) +ok seam-emitted-without-any-decorator (0.065ms) +ok seam-replaces-inlined-entry-injection (0.239ms) +ok seam-entry-is-refusable (0.132ms) +ok seam-is-emitted-for-undecorated-fns (0.089ms) +ok every-fn-gets-a-body-helper-and-wrapper (0.105ms) +ok exit-crossing-goes-through-the-seam (0.070ms) +ok early-returns-route-through-the-exit-seam (0.075ms) +ok every-fn-gets-a-closure (0.070ms) +ok zero-param-fn-emits-valid-c (0.061ms) +ok compiler-no-longer-emits-prohibition-errors (0.083ms) +ok int-returning-builtin-drives-arithmetic-dispatch (0.084ms) +ok string-plus-string-still-concatenates (0.061ms) +ok freed-identifiers-compile-as-identifiers (0.113ms) +ok test-keyword-is-still-reserved (0.079ms) +ok instant-plus-bare-int-is-refused (0.080ms) +ok instant-plus-unit-suffix-is-allowed (0.098ms) + +105 tests, 105 passed, 0 failed, 253 assertions in 6.564ms +native_suite_exit=0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.prov new file mode 100644 index 0000000..365ae22 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:46:54Z +exit 0 +ms 4156 +sha256_out 321a00f8be0ffb9b8780fb84397bb2f5005b588f9f4bb27dca190d9eea7631b9 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0032-31-P5-NATIVE-SUITE-at-abb0ab4.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.cmd b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.cmd new file mode 100644 index 0000000..e5cdd4f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-02b/lang; W=/tmp/rerun-v2-02b/work; tot=0; hf=0; nh=0; for h in tests/integration/*.sh; do nh=$((nh+1)); out=$("$h" $W/elc2 2>&1); rc=$?; n=$(printf "%s" "$out" | grep -oE "[0-9]+ assertions" | grep -oE "[0-9]+" | head -1); tot=$((tot + ${n:-0})); printf "%-28s exit=%-3s assertions=%s\n" "$(basename $h .sh)" "$rc" "${n:-0}"; [ "$rc" -eq 0 ] || hf=$((hf+1)); done; printf "\nharnesses=%s failed=%s total_assertions=%s\n" "$nh" "$hf" "$tot" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.err b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.out b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.out new file mode 100644 index 0000000..cdd46b1 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.out @@ -0,0 +1,12 @@ +annotation_query exit=0 assertions=5 +arity_query exit=0 assertions=5 +async_future exit=0 assertions=6 +capability_query exit=0 assertions=5 +definitions_query exit=0 assertions=6 +prohibition_query exit=0 assertions=4 +seam_binding exit=0 assertions=7 +tagged_gate exit=0 assertions=10 +temporal_query exit=0 assertions=6 +temporal_signatures exit=0 assertions=4 + +harnesses=10 failed=0 total_assertions=58 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.prov b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.prov new file mode 100644 index 0000000..8d0fa71 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.prov @@ -0,0 +1,7 @@ +commit abb0ab41980f577ee8bfda04d4339e6355adfa48 +tree dirty +captured_utc 2026-08-17T17:47:19Z +exit 0 +ms 25127 +sha256_out 45ad86a57cd349fac73be04c304b8d4f239096326868a36ce4060d53c4c7eb5d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.rc b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/0033-32-P5-ALL-HARNESSES-at-abb0ab4.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/CLAIMS.md b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/CLAIMS.md new file mode 100644 index 0000000..90e0689 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/CLAIMS.md @@ -0,0 +1,140 @@ +# CLAIMS — v2 cycle 02, "seven tables, and a defect I shipped that morning" + +Re-run 2026-08-17. Source doc: `docs/v2/experiments/cycles/02-seven-tables-and-a-shipped-defect.md` +(not modified; it is the historical record). + +## Pinned commits + +| Role | SHA | Subject | +|---|---|---| +| BUGGY — before the repair | `1a5246667d80e0bf5830a06a04e1140c2867e4ce` | log the experiments that were run and never written down | +| FIXED — the code commit | `abb0ab41980f577ee8bfda04d4339e6355adfa48` | finish the seven tables, and repair a worse defect they exposed | +| Doc commits | `69f2ab2`, `ebb4f1f` | v2 cycle 02: … | + +Two detached worktrees (`/tmp/rerun-v2-02a` at the buggy parent, +`/tmp/rerun-v2-02b` at the fix), a compiler built in each, and the probe +programs compiled and linked against each worktree's own runtime — so the +runtime under test is the historical one, not today's. Every `.prov` carries +`1a5246667…` or `abb0ab419…`; none is flagged `DIRTY-TREE` by +`verify-manifest.sh`. + +## Verdicts + +| # | Claim as stated in the doc | Artifact | Commit | Verdict | +|---|---|---|---|---| +| A1 | P1 — six of seven are one shape; 5 take a call_expr, 1 takes a name | `0021`, `0022` | both | **REPRODUCED** — six collapse to 3–6 line wrappers, `duration_unit_nanos` does not | +| A2 | P2 — 49 names moved to `signatures.rel` | `0020` | both | **REPRODUCED** exactly — 51 → 100 entries, delta **49** | +| A3 | P3 — `duration_unit_nanos` breaks the shape (name → MULTIPLIER, not name → type) | `0022` | `abb0ab4` | **REPRODUCED** — it alone keeps 17 lines and all 14 string literals | +| A4 | P4 — codegen drops ~120 lines: FALSE, **80** | `0019` | both | **DIVERGED (−79, off by one)** — see below | +| A5 | each table became a 3-line wrapper | `0022` | `abb0ab4` | **REPRODUCED** — five are exactly 3 lines; `is_void_builtin` is 6 | +| A6 | P5 — fixpoint holds | `0031` | `abb0ab4` | **REPRODUCED** — gen2 == gen3, identical sha256 | +| A7 | P5 — all suites hold; 105/105 native, 253 assertions | `0032` | `abb0ab4` | **REPRODUCED** exactly | +| A8 | P5 — 10/10 harnesses, 53 → 58 assertions | `0033` | `abb0ab4` | **REPRODUCED** exactly — 10 harnesses, 0 failed, **58** assertions | +| A9 | P8 — an unrecognised unit silently becomes nanoseconds: FALSE | `0023`, `0024` | `1a52466` | **REPRODUCED** — it is compiled as a field access on the integer | +| A10 | `5.fortnights` → `el_get_field(5, …)` → **exit 139, SIGSEGV** | `0023` | `1a52466` | **REPRODUCED** — exit code **139**, captured directly | +| A11 | `as_map` was a bare cast with no validation | `0028` | `1a52466` | **REPRODUCED** verbatim: `static ElMap* as_map(el_val_t v) { return (ElMap*)(uintptr_t)v; }` | +| A12 | P9 — routing through `el_tagged` stops the SIGSEGV | `0026`, `0028` | `abb0ab4` | **REPRODUCED** — same program now prints `survived`, exit 0 | +| A13 | P10 — legitimate access unaffected: `{"a":1}["a"]` → 1, `[10,20,30][1]` → 20 | `0025`, `0027` | both | **REPRODUCED** — and the two outputs are **byte-identical** (same sha256 `783e5bca6f66`) before and after the fix | +| A14 | P11 — `el_list_get` / `el_list_len` had the identical defect, now gated | `0028` | both | **REPRODUCED** | +| A15 | the guard was `looks_like_heap_obj`, testing `p & 0x7` | `0004` | `1a52466` | **REPRODUCED** verbatim | +| A16 | the shipped fallback was `if (!looks_like_heap_obj(...)) return 0; return strlen(s);` | `0003` | `1a52466` | **REPRODUCED** verbatim | +| A17 | `el_input_len` silently returned 0 for **roughly 60%** of string literals | `0006`, `0007`, `0008`, `0009` | `1a52466` | **DIVERGED — the real rate is worse.** See below | +| A18 | *which* literals failed depended on link layout | `0008`, `0009` | `1a52466` | **REPRODUCED** — and this is the reason A17 diverges | +| A19 | `"abc"` happened to land on an 8-boundary in that build | `0008` | — | **REPRODUCED** — `abc` is still `aligned8=1` today, while 4 of the doc's other 5 are not | +| A20 | `sha256_hex` would hash the empty string instead of its input | `0006`, `0007` | `1a52466` | **REPRODUCED** — 20 of 20 literals return the empty-string hash | +| A21 | the repair checks "not a small integer, not a low address", and nothing more | `0013` | `abb0ab4` | **REPRODUCED** | +| A22 | `tagged_gate.sh` grew from 5 assertions to 10 | `0016`, `0017`, `0018` | both | **REPRODUCED** — 10 assertions, 10 passed | +| A23 | including an explicit assertion that no literal silently hashed as empty | `0018` | `abb0ab4` | **REPRODUCED** — the assertion is present and green | + +Counts: **21 REPRODUCED, 2 DIVERGED, 0 NOT-REPRODUCIBLE, 0 NOT-CAPTURED.** + +--- + +## A17 — THE DIVERGENCE THAT MATTERS: the shipped defect was worse than recorded + +The doc says `el_input_len` returned 0 for **"roughly 60%"** of string literals. +Measured today at the buggy commit, with a probe of **20 string literals of +lengths 1 through 20**, compiled and linked against `1a52466`'s own runtime and +checked against Python's `hashlib.sha256` as an independent oracle (`0007`): + +``` +literals tested = 20 +correct vs hashlib.sha256 = 0 +incorrect = 20 +hashed as the EMPTY STRING = 20 +failure rate = 100% +``` + +**Every one of the twenty.** Not 60% — 100% in this build. The same program at +the fixed commit (`0015`): + +``` +literals tested = 20 +correct vs hashlib.sha256 = 20 +incorrect = 0 +hashed as the EMPTY STRING = 0 +failure rate = 0% +``` + +The mechanism is exactly as the doc describes — `looks_like_heap_obj` rejects +any pointer with `p & 0x7` set, and the linker packs string literals +contiguously with no padding, so consecutive short literals are almost never +8-aligned. Measured directly (`0008`, `0009`): + +``` +the doc's own five literals 4 of 5 misaligned (80%) +twenty literals, lengths 1..20 18 of 20 misaligned (90%) +``` + +Note `abc` is still `aligned8=1` today — the doc's explanation for why the test +passed reproduces precisely — while `hello`, which the doc measured as aligned, +is not aligned in today's build. **The specific set of victims is link-layout +dependent, exactly as the doc says. The rate is not a stable quantity at all, +and the doc's 60% was a five-literal sample.** + +This divergence flatters nothing and is reported for that reason: the doc +understates the severity of the worst defect in the v2 record. And it +understates it by the *same* error the cycle exists to teach — a sample of five +is not a measurement of a rate. That is defect 7's shape ("a single literal is +not a test of a property"), committed inside the paragraph that names it. + +The correct statement, with artifacts behind it: **`el_input_len` returned 0 for +between 80% and 100% of string literals in the builds measured, the exact set +depending on link layout, and in the end-to-end El program measured today it was +all of them.** + +## A4 — the second divergence, cosmetic + +``` +doc: codegen drops 80 lines +measured: TOTAL 4524 -> 4445 = -79 (0019) + CODE 3277 -> 3209 = -68 +``` + +Off by one, the same +1 pattern that appears in cycle 05's totals (documented in +that cycle's CLAIMS.md). The cycle's conclusion — that the predicted ~120 did +not materialise because each table left a wrapper — is unaffected: 79 is as far +from 120 as 80 is. Recorded because a document about miscounting should not +carry an uncorrected miscount. + +Cycle 05 later established that the metric worth quoting is code, not total. On +that metric the drop is **68**, not 80. + +## Instruments + +`instruments/verify-hashes.py` and `instruments/run-oracle.sh` are in this +directory rather than inline, so the oracle's criterion is auditable and so the +capture command stays one line — `capture.sh` records commands with +`printf '%s\n' "$*"`, and a multi-line command splits one manifest record across +several lines and desynchronises its artifact counter. That happened on the first +pass of this cycle. **The whole directory was deleted and every capture re-run +from scratch rather than repairing `MANIFEST.tsv` by hand**, because editing a +manifest to match its artifacts inverts what the manifest is for. The final +manifest is 33 records, 9 fields each, and `verify-manifest.sh` reports 0 altered +and 0 missing. + +`0029` is a real failed run, retained: `scripts/verify.sh` **did not exist** at +`abb0ab4` (exit 127). It first appears in `6c80dee`, cycle 04. P5 was therefore +verified by running fixpoint, the native suite and every harness directly +(`0031`, `0032`, `0033`) rather than through a gauntlet that had not been built +yet. diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/MANIFEST.tsv b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/MANIFEST.tsv new file mode 100644 index 0000000..b69bc2e --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/MANIFEST.tsv @@ -0,0 +1,34 @@ +sha256 bytes exit ms commit tree utc artifact command +7d531005170557490d3ef00542d5093e10b51ccd9115bfb81ed9e7cae67dafee 124 0 9 1a5246667d80 dirty 2026-08-17T17:44:40Z 0001-00-BUGGY-pinned-commit.out git log -1 --format=%H%n%ci%n%s +aa6e76906574c6edd2422421723cbc40c2f2b2f81a5db509ae8a82c02fba97d2 30 0 13 1a5246667d80 dirty 2026-08-17T17:44:40Z 0002-01-BUGGY-worktree-clean.out git status --porcelain +044c4a6e314d5bc47b7eb9a61c7b3a5d6bcba56cbead224dbf850e131e601316 570 0 17 1a5246667d80 dirty 2026-08-17T17:44:40Z 0003-02-BUGGY-el_input_len-source.out bash -c cd /tmp/rerun-v2-02a; grep -n "static size_t el_input_len" -A 10 lang/runtime/el_runtime.c +655a62c931220bdc6b9b6563d065fb047606cce8abcada95b72bb57d7a386ca7 459 0 15 1a5246667d80 dirty 2026-08-17T17:44:40Z 0004-03-BUGGY-looks_like_heap_obj-source.out bash -c cd /tmp/rerun-v2-02a; grep -n "static int looks_like_heap_obj" -A 10 lang/runtime/el_runtime.c +8114c39cfd7f43a0692dfee3c8d2ae601dbf80c632a31f14f608bea4e3b9b4aa 1414 0 4 1a5246667d80 dirty 2026-08-17T17:44:40Z 0005-04-probe-source-20-literals-lengths-1-to-20.out cat /tmp/rerun-v2-02a/work/lit.el +32a6279918627a9a79a371da78aab404895a6050c5070b7455a4d16b1a1d1c60 1830 0 7 1a5246667d80 dirty 2026-08-17T17:44:40Z 0006-05-BUGGY-RUN-20-literals.out /tmp/rerun-v2-02a/work/lit +087862b98e5d31d369a92efd2799d1e7e852dc988737cfc6e34a0b74380cc1a0 3521 0 369 1a5246667d80 dirty 2026-08-17T17:44:41Z 0007-06-BUGGY-ORACLE-verdict.out /Users/will/Development/neuron-technologies/foundation/el/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh /tmp/rerun-v2-02a/work/lit +5e5d09cc202b5d93b4eac4ae911fa8bed2e5d2a38d47ff1765a61f2c0de71c86 275 0 4 1a5246667d80 dirty 2026-08-17T17:44:41Z 0008-07-ALIGNMENT-the-docs-own-five-literals.out /tmp/rerun-v2-02a/work/align5 +a1bd6525284bee14b50ba9eef190ed7dc6b1603c0f40f98eab42ced4ad68b855 1127 0 4 1a5246667d80 dirty 2026-08-17T17:44:41Z 0009-08-ALIGNMENT-twenty-literals-lengths-1-to-20.out /tmp/rerun-v2-02a/work/align20 +b374ea1f09b52559656ed398d45f0512f62913c3da3043c09b437cf22a1051c7 488 0 5 1a5246667d80 dirty 2026-08-17T17:44:41Z 0010-09-alignment-probe-source-align5.out cat /tmp/rerun-v2-02a/work/align5.c +9674537ec9e63e66c5bccd9f553dbf61833ada03aadde8feb5b80b4f5477c525 673 0 5 1a5246667d80 dirty 2026-08-17T17:44:41Z 0011-10-alignment-probe-source-align20.out cat /tmp/rerun-v2-02a/work/align20.c +fe23a709afe165830c447c4c10bad3e71c770b326d2f43a97bcf720883fbefbc 131 0 9 abb0ab41980f dirty 2026-08-17T17:44:51Z 0012-11-FIXED-pinned-commit.out git log -1 --format=%H%n%ci%n%s +cfc667d2ffefbac32441bc38461be71b07df129bf3cddce7768ff20203561a9e 1318 0 15 abb0ab41980f dirty 2026-08-17T17:44:51Z 0013-12-FIXED-el_input_len-source.out bash -c cd /tmp/rerun-v2-02b; grep -n "static size_t el_input_len" -A 22 lang/runtime/el_runtime.c +96374c493b16f0f5f6fce85839fafb0967b2918ad070cddffddacf6358c06671 1830 0 7 abb0ab41980f dirty 2026-08-17T17:44:51Z 0014-13-FIXED-RUN-20-literals.out /tmp/rerun-v2-02b/work/lit +92f2d011d61336ef9d97f39a074d75352b3100223429e5bc8cb15108da5686fa 168 0 36 abb0ab41980f dirty 2026-08-17T17:44:51Z 0015-14-FIXED-ORACLE-verdict.out /Users/will/Development/neuron-technologies/foundation/el/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh /tmp/rerun-v2-02b/work/lit +f0b5c2c2211c8d67ed15e75e656c7862d086e9245420892a7de62cd9ec582a06 2 0 13 abb0ab41980f dirty 2026-08-17T17:44:51Z 0016-15-tagged_gate-assertion-count-BEFORE.out bash -c cd /tmp/rerun-v2-02b; git show 1a52466:lang/tests/integration/tagged_gate.sh | grep -c "^chk \|chk \"" +917df3320d778ddbaa5c5c7742bc4046bf803c36ed2b050f30844ed206783469 3 0 10 abb0ab41980f dirty 2026-08-17T17:44:51Z 0017-16-tagged_gate-assertion-count-AFTER.out bash -c cd /tmp/rerun-v2-02b; grep -c "chk \"" lang/tests/integration/tagged_gate.sh +54ed74debfd5061190b7c6aaecabea13295684ac75502ce77a7a7b0e2e7778e4 497 0 13648 abb0ab41980f dirty 2026-08-17T17:45:05Z 0018-17-tagged_gate-harness-run.out lang/tests/integration/tagged_gate.sh /tmp/rerun-v2-02b/elc-fixed /tmp/rerun-v2-02b/lang +834f02acdfd310427d7a9ed7429f78892f0e15185285adf0d51fb2dfbedf4945 95 0 46 abb0ab41980f dirty 2026-08-17T17:45:25Z 0019-18-P4-codegen-line-delta.out bash -c cd /tmp/rerun-v2-02b; B=$(git show 1a52466:lang/el-compiler/src/codegen.el | wc -l | tr -d " "); A=$(git show abb0ab4:lang/el-compiler/src/codegen.el | wc -l | tr -d " "); BC=$(git show 1a52466:lang/el-compiler/src/codegen.el | grep -v "^[[:space:]]*//" | grep -vc "^[[:space:]]*$"); AC=$(git show abb0ab4:lang/el-compiler/src/codegen.el | grep -v "^[[:space:]]*//" | grep -vc "^[[:space:]]*$"); printf "TOTAL lines %s -> %s delta %s (doc claims -80)\nCODE lines %s -> %s delta %s\n" "$B" "$A" "$((A-B))" "$BC" "$AC" "$((AC-BC))" +19a904d093cc12e30565eff9e07b4464f8bb7506ab4372e7a51eca91713f42f4 136 0 16 abb0ab41980f dirty 2026-08-17T17:45:25Z 0020-19-P2-names-moved-to-signatures-rel.out bash -c cd /tmp/rerun-v2-02b; B=$(git show 1a52466:lang/tools/check/signatures.rel | grep -cE "^[a-z_]+ +returns"); A=$(grep -cE "^[a-z_]+ +returns" lang/tools/check/signatures.rel); printf "signatures.rel entries BEFORE = %s\nsignatures.rel entries AFTER = %s\ndelta = %s (doc claims 49 names moved)\n" "$B" "$A" "$((A-B))" +306b3363d5adcd20833b34144b9243bb4e5098417721205c47c959a002c4e817 445 0 167 abb0ab41980f dirty 2026-08-17T17:45:25Z 0021-20-P1-the-seven-tables-BEFORE.out bash -c cd /tmp/rerun-v2-02b; for f in duration_unit_nanos is_float_call is_void_builtin is_rhythm_call is_calendar_call is_caltime_call is_zone_call; do printf "%-22s at 1a52466: %s lines, %s string literals\n" "$f" "$(git show 1a52466:lang/el-compiler/src/codegen.el | awk "/^fn $f\(/,/^}/" | wc -l | tr -d " ")" "$(git show 1a52466:lang/el-compiler/src/codegen.el | awk "/^fn $f\(/,/^}/" | grep -o "\"[a-z_]*\"" | wc -l | tr -d " ")"; done +add0ce42a0a99632d0532a894d410b95042d3e7e46cb4967f819fe338594df1e 436 0 117 abb0ab41980f dirty 2026-08-17T17:45:26Z 0022-21-P1-the-seven-tables-AFTER.out bash -c cd /tmp/rerun-v2-02b; for f in duration_unit_nanos is_float_call is_void_builtin is_rhythm_call is_calendar_call is_caltime_call is_zone_call; do printf "%-22s at abb0ab4: %s lines, %s string literals\n" "$f" "$(awk "/^fn $f\(/,/^}/" lang/el-compiler/src/codegen.el | wc -l | tr -d " ")" "$(awk "/^fn $f\(/,/^}/" lang/el-compiler/src/codegen.el | grep -o "\"[a-z_]*\"" | wc -l | tr -d " ")"; done +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 139 7 1a5246667d80 dirty 2026-08-17T17:46:09Z 0023-22-P8-BUGGY-5-fortnights-SIGSEGV.out /tmp/rerun-v2-02a/work/p8 +ca4671c54962945ffce55e7aaf256b7873cb46df2a83252a8a165f76b703bf04 56 0 10 1a5246667d80 dirty 2026-08-17T17:46:09Z 0024-23-P8-BUGGY-emitted-C-is-a-field-access.out bash -c cd /tmp/rerun-v2-02a/lang; grep -n "el_get_field" /tmp/rerun-v2-02a/work/p8.c +783e5bca6f660d66ef3c0ddc0b14ed2dc86c70b1cabef7c0b33a76179149618d 5 0 7 1a5246667d80 dirty 2026-08-17T17:46:09Z 0025-24-P10-BUGGY-legitimate-access.out /tmp/rerun-v2-02a/work/p10 +304b524de1a79904aaf8295a0986f8c03dd0d1d26d25902da057b47277147297 9 0 7 abb0ab41980f dirty 2026-08-17T17:46:09Z 0026-25-P9-FIXED-5-fortnights-survives.out /tmp/rerun-v2-02b/work/p8 +783e5bca6f660d66ef3c0ddc0b14ed2dc86c70b1cabef7c0b33a76179149618d 5 0 7 abb0ab41980f dirty 2026-08-17T17:46:09Z 0027-26-P10-FIXED-legitimate-access-unaffected.out /tmp/rerun-v2-02b/work/p10 +4e8ec729991ca53af4fef95edcc4d9bee6788d46e8ff349d389fd04264eacb4d 903 0 47 abb0ab41980f dirty 2026-08-17T17:46:09Z 0028-27-P9-P11-as_map-and-as_list-gates.out bash -c cd /tmp/rerun-v2-02b; echo "=== as_map BEFORE (1a52466) ==="; git show 1a52466:lang/runtime/el_runtime.c | grep -n "static ElMap\* as_map" -A 3; echo; echo "=== as_map AFTER (abb0ab4) ==="; grep -n "static ElMap\* as_map" -A 6 lang/runtime/el_runtime.c; echo; echo "=== el_list_get / el_list_len AFTER ==="; grep -n "el_val_t el_list_get\|el_val_t el_list_len" -A 3 lang/runtime/el_runtime.c | head -20 +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 127 5 abb0ab41980f dirty 2026-08-17T17:46:19Z 0029-28-P5-fixpoint-and-suites-at-abb0ab4.out ./scripts/verify.sh +ce6d188689cd310ec634fe4ce52c2b43540d8733e487a11e65edf1cc2bf0542a 165 0 28 abb0ab41980f dirty 2026-08-17T17:46:33Z 0030-29-verify-sh-did-not-exist-at-abb0ab4.out bash -c cd /tmp/rerun-v2-02b; ls scripts/ 2>&1; echo "---"; echo "verify.sh first appears in:"; git log --oneline --diff-filter=A --all -- scripts/verify.sh +b3659226192b528e8e39872d11258d608803c9c2b1c2514e486102960eac6a2a 184 0 4172 abb0ab41980f dirty 2026-08-17T17:46:37Z 0031-30-P5-FIXPOINT-gen2-eq-gen3-at-abb0ab4.out bash -c cd /tmp/rerun-v2-02b/lang; SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; W=/tmp/rerun-v2-02b/work; /tmp/rerun-v2-02b/elc-fixed elc-cli.el > $W/g2.c 2>/dev/null; cc $CF -o $W/elc2 $W/g2.c $SRCS $LF 2>/dev/null; $W/elc2 elc-cli.el > $W/g3.c 2>/dev/null; if cmp -s $W/g2.c $W/g3.c; then echo "FIXPOINT gen2 == gen3 OK"; else echo "FIXPOINT FAILED"; fi; printf "gen2 sha256 = %s\ngen3 sha256 = %s\n" "$(shasum -a 256 $W/g2.c | cut -d\ -f1)" "$(shasum -a 256 $W/g3.c | cut -d\ -f1)" +321a00f8be0ffb9b8780fb84397bb2f5005b588f9f4bb27dca190d9eea7631b9 4349 0 4156 abb0ab41980f dirty 2026-08-17T17:46:54Z 0032-31-P5-NATIVE-SUITE-at-abb0ab4.out bash -c cd /tmp/rerun-v2-02b/lang; SRCS=$(../scripts/el-runtime-sources.sh runtime); CF="-std=c11 -O2 -I runtime"; LF=""; for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do [ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"; done; LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"; W=/tmp/rerun-v2-02b/work; $W/elc2 --test tests/native/test_compiler.el > $W/t.c 2>/dev/null; cc $CF -o $W/t $W/t.c $SRCS $LF 2>/dev/null; $W/t; echo "native_suite_exit=$?" +45ad86a57cd349fac73be04c304b8d4f239096326868a36ce4060d53c4c7eb5d 556 0 25127 abb0ab41980f dirty 2026-08-17T17:47:19Z 0033-32-P5-ALL-HARNESSES-at-abb0ab4.out bash -c cd /tmp/rerun-v2-02b/lang; W=/tmp/rerun-v2-02b/work; tot=0; hf=0; nh=0; for h in tests/integration/*.sh; do nh=$((nh+1)); out=$("$h" $W/elc2 2>&1); rc=$?; n=$(printf "%s" "$out" | grep -oE "[0-9]+ assertions" | grep -oE "[0-9]+" | head -1); tot=$((tot + ${n:-0})); printf "%-28s exit=%-3s assertions=%s\n" "$(basename $h .sh)" "$rc" "${n:-0}"; [ "$rc" -eq 0 ] || hf=$((hf+1)); done; printf "\nharnesses=%s failed=%s total_assertions=%s\n" "$nh" "$hf" "$tot" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/RUN.env b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/RUN.env new file mode 100644 index 0000000..22daa35 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/RUN.env @@ -0,0 +1,6 @@ +captured_utc 2026-08-17T17:44:40Z +git_sha 1a5246667d80e0bf5830a06a04e1140c2867e4ce +git_dirty yes +host Wills-MacBook-Pro +uname Darwin Wills-MacBook-Pro 25.5.0 Darwin Kernel Version 25.5.0: Tue Jun 9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041 arm64 +cc Apple clang version 21.0.0 (clang-2100.1.1.101) diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh new file mode 100755 index 0000000..dddd427 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/run-oracle.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# run-oracle.sh — run the 20-literal probe and check it against +# the independent hashlib oracle. Single-line-safe wrapper: capture.sh records +# commands with printf '%s\n' "$*", so a multi-line command corrupts MANIFEST.tsv. +set -uo pipefail +"$1" | "$(dirname "$0")/verify-hashes.py" diff --git a/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/verify-hashes.py b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/verify-hashes.py new file mode 100755 index 0000000..1b97293 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/02-seven-tables-and-a-shipped-defect/instruments/verify-hashes.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +"""Independent oracle for cycle 02. + +Reads the 20-literal probe's stdout and checks every reported SHA-256 against +Python's hashlib. The El runtime is the system under test; hashlib is the +reference. Also counts how many literals hashed as the EMPTY STRING, which is +the signature of el_input_len returning 0. +""" +import sys, hashlib +EMPTY = hashlib.sha256(b"").hexdigest() +ok = bad = empty = n = 0 +for line in sys.stdin: + line = line.strip() + if not line: + continue + parts = dict(p.split("=", 1) for p in line.split(" ") if "=" in p) + lit, got = parts["lit"], parts["sha"] + n += 1 + if got == EMPTY: + empty += 1 + exp = hashlib.sha256(lit.encode()).hexdigest() + if got == exp: + ok += 1 + else: + bad += 1 + print("MISMATCH lit=%s got=%s expected=%s" % (lit, got, exp)) +print("literals tested = %d" % n) +print("correct vs hashlib.sha256 = %d" % ok) +print("incorrect = %d" % bad) +print("hashed as the EMPTY STRING = %d" % empty) +print("failure rate = %.0f%%" % (100.0 * empty / n if n else 0)) diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.cmd new file mode 100644 index 0000000..4de5ff1 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.cmd @@ -0,0 +1 @@ +./p diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.out new file mode 100644 index 0000000..19f86f4 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.out @@ -0,0 +1 @@ +done diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.prov new file mode 100644 index 0000000..8815803 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:01Z +exit 0 +ms 149 +sha256_out d117fa006ba9208500b2930ce69cbde436c647afa917cb7396a9bc9111a46dd2 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0032-31-AUDIT-unbound-nothing-reported.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.cmd new file mode 100644 index 0000000..e77ebb6 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.cmd @@ -0,0 +1 @@ +env EL_CONSTRUCTS=c.txt ./p diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.out new file mode 100644 index 0000000..b765bd0 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.out @@ -0,0 +1,3 @@ +AUDIT save called by handle_request +AUDIT save called by migrate +done diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.prov new file mode 100644 index 0000000..7c1e885 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:01Z +exit 0 +ms 9 +sha256_out e8abf0228909ad379f9b9a53d1375c5710f275b07465c766776a7e679c7409dc +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0033-32-AUDIT-bound-the-caller-is-visible.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.cmd new file mode 100644 index 0000000..2f18ef3 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b; grep -n "no fourth emission point" -B2 -A1 lang/tests/integration/seam_caller.sh; echo; echo "--- and the harness runs a PREBUILT compiler passed in as \$1 ---"; grep -n "ELC=" lang/tests/integration/seam_caller.sh diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.out new file mode 100644 index 0000000..04c8141 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.out @@ -0,0 +1,7 @@ +43-chk "bound: and it changes per call site" "1" "$(echo "$out" | grep -c 'AUDIT save called by migrate')" +44-chk "the program still completes" "1" "$(echo "$out" | grep -c '^done$')" +45:chk "no fourth emission point was added" "3" "$(grep -c 'el_seam_run(EL_STR\|el_seam_wrap(EL_STR' el-compiler/src/codegen.el)" +46-echo; echo " 5 assertions, $((5-F)) passed, $F failed"; exit $F + +--- and the harness runs a PREBUILT compiler passed in as $1 --- +11:ELC="${1:?usage: seam_caller.sh }" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.prov new file mode 100644 index 0000000..2dd4003 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:25Z +exit 0 +ms 12 +sha256_out 39e278dafabdd8a33e39c460335915d4472c419fd3b77fcfd880080fcf77871d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0034-33-the-harness-assertion-greps-SOURCE.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.cmd new file mode 100644 index 0000000..1fbb128 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b/lang; printf "grep count in codegen.el source = %s\n" "$(grep -c "el_seam_run(EL_STR\|el_seam_wrap(EL_STR" el-compiler/src/codegen.el)"; printf "emitted-C emission points (the actual measurement) = %s\n" "$(/tmp/rerun-v2-07b/elc-stack /tmp/rerun-v2-07b/work/probe.el 2>/dev/null | grep -c "el_seam_run(EL_STR\|el_seam_wrap(EL_STR")"; printf "compiler binary sha256 = %s\n" "$(shasum -a 256 /tmp/rerun-v2-07b/elc-stack | cut -d" " -f1)" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.out new file mode 100644 index 0000000..fa846f0 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.out @@ -0,0 +1,3 @@ +grep count in codegen.el source = 3 +emitted-C emission points (the actual measurement) = 9 +compiler binary sha256 = e99058b8c3dcfb29f67cd0e4d5bb29827b3cbfa1370bd639ad9c650a3b5f2f5d diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.prov new file mode 100644 index 0000000..893ef2f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:25Z +exit 0 +ms 29 +sha256_out 5ea96a0590f14ad364fab5f25df3a8c5d5b2d969952f9cff3745930a72e418b4 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0035-34-DISCONNECT-baseline-grep-count-and-binary-sha.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.cmd new file mode 100644 index 0000000..8f6dbb9 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b/lang; printf "\n// el_seam_run(EL_STR -- a COMMENT, zero semantic change\n" >> el-compiler/src/codegen.el; printf "grep count in codegen.el source = %s\n" "$(grep -c "el_seam_run(EL_STR\|el_seam_wrap(EL_STR" el-compiler/src/codegen.el)"; printf "emitted-C emission points (unchanged) = %s\n" "$(/tmp/rerun-v2-07b/elc-stack /tmp/rerun-v2-07b/work/probe.el 2>/dev/null | grep -c "el_seam_run(EL_STR\|el_seam_wrap(EL_STR")"; printf "compiler binary sha256 (unchanged) = %s\n" "$(shasum -a 256 /tmp/rerun-v2-07b/elc-stack | cut -d" " -f1)" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.out new file mode 100644 index 0000000..872b46a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.out @@ -0,0 +1,3 @@ +grep count in codegen.el source = 4 +emitted-C emission points (unchanged) = 9 +compiler binary sha256 (unchanged) = e99058b8c3dcfb29f67cd0e4d5bb29827b3cbfa1370bd639ad9c650a3b5f2f5d diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.prov new file mode 100644 index 0000000..bd5d8dd --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:25Z +exit 0 +ms 31 +sha256_out 122ae54ac0500b8ef774b87011ce6f7c62fd692529364ed0532d610300378657 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0036-35-DISCONNECT-add-a-COMMENT-to-source.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.cmd new file mode 100644 index 0000000..30088c0 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b; lang/tests/integration/seam_caller.sh /tmp/rerun-v2-07b/elc-stack /tmp/rerun-v2-07b/lang; echo "harness_exit=$?" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.out new file mode 100644 index 0000000..f246780 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.out @@ -0,0 +1,9 @@ + ok unbound: nothing is reported + ok bound: the caller is visible + ok bound: and it changes per call site + ok the program still completes + FAIL no fourth emission point was added + expected 3 got 4 + + 5 assertions, 4 passed, 1 failed +harness_exit=1 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.prov new file mode 100644 index 0000000..2525aae --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:29Z +exit 0 +ms 3411 +sha256_out 015e293b744c416408dc0675f73ea17bd152e0ddf34e543a3f108e6e3bbb1d95 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0037-36-DISCONNECT-harness-now-FAILS-on-a-comment.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.cmd new file mode 100644 index 0000000..1faadc8 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b; git checkout -- lang/el-compiler/src/codegen.el; git status --porcelain -- lang/el-compiler/src/codegen.el; echo "reverted" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.out new file mode 100644 index 0000000..f97d368 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.out @@ -0,0 +1 @@ +reverted diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.prov new file mode 100644 index 0000000..58333d3 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:29Z +exit 0 +ms 21 +sha256_out 3a635fad03292e98f07bb309e7a8fcb6e824f27d51074bb3ed88c7e42ed6c88d +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0038-37-DISCONNECT-revert-the-comment.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.cmd new file mode 100644 index 0000000..9e9f190 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b; git show d9d1571^:lang/tests/integration/arity_query.sh | grep -n "503\|signatures" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.out new file mode 100644 index 0000000..1ab337f --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.out @@ -0,0 +1,2 @@ +23:n=$("$LANG_DIR/tools/check/arity.sh" "$W/r2.txt" | grep -oE '[0-9]+ signatures') +24:chk "signatures parsed from the header" "503 signatures" "$n" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.prov new file mode 100644 index 0000000..db40667 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:39Z +exit 0 +ms 15 +sha256_out 08e436cb833af241f0710853d67cea4abebaaafca169f7e2aef51a9676a64a8b +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0039-38-defect11-arity-assertion-BEFORE-503.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.cmd new file mode 100644 index 0000000..ce69041 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.cmd @@ -0,0 +1 @@ +bash -c cd /tmp/rerun-v2-07b; git show 47b56a3:lang/tests/integration/arity_query.sh | grep -n "signatures\|SIGN" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.out new file mode 100644 index 0000000..fc389c8 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.out @@ -0,0 +1,2 @@ +25:SIGN=$("$LANG_DIR/tools/check/arity.sh" "$W/r2.txt" | grep -oE '[0-9]+ signatures' | grep -oE '[0-9]+') +26:chk "the header yields a plausible number of signatures" "1" "$([ "${SIGN:-0}" -gt 400 ] && echo 1 || echo 0)" diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.prov new file mode 100644 index 0000000..eb44e61 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:39Z +exit 0 +ms 15 +sha256_out b7049a443edfb3685bdbe477580736bbe297f617310736d2ce6f1e8660f7d218 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0040-39-defect11-arity-assertion-AFTER-property.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.cmd b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.cmd new file mode 100644 index 0000000..af03ced --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.cmd @@ -0,0 +1 @@ +git status --porcelain diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.err b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.err new file mode 100644 index 0000000..e69de29 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.out b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.out new file mode 100644 index 0000000..e9c4b19 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.out @@ -0,0 +1,3 @@ +?? elc-stack +?? g2.c +?? work/ diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.prov b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.prov new file mode 100644 index 0000000..8243220 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.prov @@ -0,0 +1,7 @@ +commit d9d1571f2a17024323a3f7be6966bc476c2f2a78 +tree dirty +captured_utc 2026-08-17T17:40:40Z +exit 0 +ms 14 +sha256_out 13efd38216a68a822c87c78f412131f8111d0383aa93be4cc9ef385986a04870 +sha256_err e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.rc b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.rc new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/0041-40-worktree-clean-at-end.rc @@ -0,0 +1 @@ +0 diff --git a/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/CLAIMS.md b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/CLAIMS.md new file mode 100644 index 0000000..8f9dcf0 --- /dev/null +++ b/docs/v2/experiments/evidence/cycles/07-the-caller-was-already-there/CLAIMS.md @@ -0,0 +1,176 @@ +# CLAIMS — v2 cycle 07, "the caller was already there" + +Re-run 2026-08-17. Source doc: `docs/v2/experiments/cycles/07-the-caller-was-already-there.md` +(not modified; it is the historical record). + +## Pinned commits + +| Role | SHA | Subject | +|---|---|---| +| Code commit (system under test) | `d9d1571f2a17024323a3f7be6966bc476c2f2a78` | a construct can see its caller, with no new emission point | +| Its parent — the BASE for timing | `d403a5cf2e728ce00ecdc2d84290e471e74159bb` | v2 cycle 06: form is half bindable | +| Merge that landed it | `ffab17b` | merge experiment/seam-caller | +| Cycle 07 doc commit | `47b56a3` | v2 cycle 07: the caller was already there | +| Standing critique of this cycle | `fbb3a52` | cycle 07's central claim is backed by a grep, not a measurement | + +All measurements were taken in detached worktrees at `d9d1571` and `d403a5c`, +so each `.prov` carries the system under test's SHA, not the re-run host's. + +`d9d1571` adds 80 lines across three files and touches **no compiler source** — +`el_runtime.c` (+33), `el_runtime.h` (+1), `seam_caller.sh` (+46). The compiler +sources are byte-identical between BASE and STACK worktrees (`0006`, +`diff -rq … IDENTICAL`), so the timing below isolates the runtime change and +nothing else. + +## Verdicts + +| # | Claim as stated in the doc | Artifact | Commit | Verdict | +|---|---|---|---|---| +| A1 | P1 — exactly three emission points per fn | `0026`, `0027`, `0028` | `d9d1571` | **REPRODUCED** — and by a *better* instrument than the doc's, see below | +| A2 | P2 — no other emission point exists | `0027`, `0028`, `0029`, `0030` | `d9d1571` | **REPRODUCED** — loops, call sites and field accesses emit none | +| A3 | entry is `el_seam_run(fn, 0, 0)`, refusable | `0026`, `0028` | `d9d1571` | **REPRODUCED** verbatim | +| A4 | wrap is `el_seam_wrap(fn, thunk, env)` | `0026`, `0028` | `d9d1571` | **REPRODUCED** verbatim | +| A5 | exit is `el_seam_run(fn, 1, __r)` | `0026`, `0028` | `d9d1571` | **REPRODUCED** verbatim | +| A6 | all three keyed on `fn_name` | `0028` | `d9d1571` | **REPRODUCED** — every point carries `EL_STR("")` | +| A7 | P3 — a construct cannot see WHO called it (before the change) | `0032` | `d9d1571` | **REPRODUCED** — unbound run reports nothing | +| A8 | P4 — the call graph is static, the gap is runtime | — | — | **NOT-CAPTURED** — asserted in prose, no measurement stated | +| A9 | P5 — a seam-maintained stack gives the caller with NO new emission point | `0027`, `0033` | `d9d1571` | **REPRODUCED** | +| A10 | the result: `AUDIT save called by handle_request` | `0033` | `d9d1571` | **REPRODUCED** verbatim | +| A11 | and `AUDIT save called by migrate` | `0033` | `d9d1571` | **REPRODUCED** verbatim | +| A12 | a construct bound **after the build** sees its caller | `0032`, `0033` | `d9d1571` | **REPRODUCED** — same binary, binding supplied at run time via `EL_CONSTRUCTS` | +| A13 | P6 — maintaining the stack costs something measurable — FALSE | `0007`–`0021`, `0024` | `d9d1571` vs `d403a5c` | **REPRODUCED** — 7 interleaved rounds, means identical to 0.00 ms | +| A14 | P7 — moving it behind the early-out removes the cost — FALSE, there was no cost | `0024` | — | **NOT-REPRODUCIBLE** — the "before the early-out" variant was never committed | +| A15 | interleaved rounds base 0.25/0.25/0.24 s, stack 0.24/0.24/0.24 s | `0024`, `0025` | `d9d1571` vs `d403a5c` | **DIVERGED on absolute magnitude, REPRODUCED on the conclusion** — see below | +| A16 | "identical within noise. There was no regression." | `0024` | `d9d1571` vs `d403a5c` | **REPRODUCED**, and more strongly than the doc claims | +| A17 | the baseline had drifted from 0.37 s — the machine, not the code | `0025` | — | **REPRODUCED in mechanism** — cold/warm alone is 4.30× | +| A18 | `seam_caller.sh` — 5 assertions | `0031` | `d9d1571` | **REPRODUCED** — 5 assertions, 5 passed, exit 0 | +| A19 | defect 11 — `arity_query.sh` asserted exactly 503 signatures | `0039` | `d9d1571^` | **REPRODUCED** verbatim | +| A20 | the assertion now tests the property directly | `0040` | `47b56a3` | **REPRODUCED** — now `SIGN -gt 400` | +| A21 | "the gauntlet built in cycle 04 caught this" | — | — | **NOT-CAPTURED** — no artifact of the original failing run survives | + +Counts: **17 REPRODUCED, 1 DIVERGED, 1 NOT-REPRODUCIBLE, 2 NOT-CAPTURED.** + +--- + +## A1/A2 — measured from emitted C, because the doc's instrument does not measure the system + +The cycle's headline — *three emission points, all keyed on `fn_name`* — is +asserted in `seam_caller.sh` by this line (`0034`): + +``` +chk "no fourth emission point was added" "3" \ + "$(grep -c 'el_seam_run(EL_STR\|el_seam_wrap(EL_STR' el-compiler/src/codegen.el)" +``` + +That greps **compiler source text**, while the harness runs a **prebuilt +compiler** passed in as `$1`. The source it counts is never compiled by the +harness. Commit `fbb3a52` records this as a standing defect. I confirmed it +independently, in both directions, with my own artifacts: + +| | grep of source | emitted-C emission points | compiler sha256 | harness | +|---|---|---|---|---| +| baseline (`0035`) | 3 | 9 | `e99058b8…` | 5/5 green | +| after appending one **comment line** (`0036`, `0037`) | **4** | **9** | **`e99058b8…` unchanged** | **FAILS, "expected 3 got 4"** | + +A comment — zero semantic change, byte-identical binary, identical emitted C — +turns the cycle's central assertion red. The assertion measures a text file, not +the system. + +**So I did not rely on it.** A1–A6 above are graded against the **emitted C +produced by the binary under test**, which is causally downstream of the +compiler and therefore an actual measurement. Compiling a probe containing a +loop, a call site, a map field access and four functions (`0030`) yields +(`0028`): + +``` +fields -> entry wrap exit +loops -> entry wrap exit +helper -> entry wrap exit + +total emission points = 9 +``` + +Three functions with bodies, three points each, nine total, every one keyed on +the function name. `main` gets none. **Loops, call sites and field accesses get +none** — which is precisely the bound the cycle claims, now established by +observing the compiler's output rather than by counting strings in its source. + +This is a stronger result than the document's, obtained because the document's +own instrument was found untrustworthy. The conclusion the cycle drew was right; +the evidence it offered for it was not. + +--- + +## A15 — the one divergence, reported loudly + +The conclusion reproduces. The numbers do not. + +``` +doc: round 1 base 0.25 s stack 0.24 s + round 2 base 0.25 s stack 0.24 s + round 3 base 0.24 s stack 0.24 s + +measured: 7 interleaved rounds, alternating, identical workload + round BASE STACK + 1 51 53 + 2 53 52 + 3 52 53 + 4 53 53 + 5 52 52 + 6 52 52 + 7 53 51 + + BASE mean 52.29 ms min 51 max 53 spread 2 sd 0.70 + STACK mean 52.29 ms min 51 max 53 spread 2 sd 0.70 + STACK/BASE ratio of means = 1.0000 (+0.00%) +``` + +**Today's absolute figures are ~4.8× faster than the doc's** — 52 ms where the +doc reports 240–250 ms. The doc's conclusion is nonetheless confirmed, and +confirmed harder: where the doc showed a 1-round-in-3 wobble of 0.01 s, seven +interleaved rounds give means equal to two decimal places and identical spread. + +The magnitude gap is explained, and the explanation is the point of the cycle +(`0025`): + +``` +FIRST (cold) run, BASE = 225 ms +FIRST (cold) run, STACK = 229 ms +steady-state warm mean over 14 runs = 52.29 ms +cold/warm ratio, BASE = 4.30x +``` + +The doc's 0.24–0.25 s figures sit in the cold-cache band; its steady-state +equivalent is 52 ms. **Cache state alone moves this workload by 4.30×, which is +larger than the 50% (0.48 → 0.72 s) "regression" that was originally reported +and then retracted.** That single number does more to explain the phantom +regression than the retraction in the doc does: the original pair of timings was +not merely noisy, it was almost certainly comparing a cold run against a warm +one. + +Recorded as DIVERGED because the doc presents 0.25 s and 0.24 s as measurements +of this workload and they are not reproducible as such — they are reproducible +only as cold-start measurements. The *finding* they support — no regression — +is REPRODUCED (A13, A16). + +## A14 — why NOT-REPRODUCIBLE + +P7 concerns a variant in which the depth-stack maintenance sits **before** the +unbound early-out. That variant was never committed; only the post-early-out +form exists in history (`0003`). Reconstructing it would mean writing a mutant +today and grading a historical prediction against it, which is a new experiment, +not a reproduction. The runtime comment in `0003` states the 50% figure that +motivated the move — but a comment is a claim, not a measurement, and no +artifact of it survives. + +## Notes on tree state + +Every `.prov` records `d9d1571f2…` or `d403a5cf2…`. `0041` shows the worktree +ended with only untracked build scaffolding (`elc-stack`, `g2.c`, `work/`) and +no modified tracked file: the deliberate source mutation in `0036` was reverted +in `0038` and the revert is in the record. Both worktrees were removed after +capture. + +`0023` is a failed instrument run (a malformed `awk`, exit 2) and is retained +rather than deleted. Removing a failed attempt from an evidence record is itself +a measurement defect; `0024` is the corrected run. diff --git a/engram/dist/engram b/engram/dist/engram deleted file mode 100755 index cfde628..0000000 Binary files a/engram/dist/engram and /dev/null differ diff --git a/engram/dist/engram.c b/engram/dist/engram.c deleted file mode 100644 index eebdc34..0000000 --- a/engram/dist/engram.c +++ /dev/null @@ -1,561 +0,0 @@ -#include -#include -#include "el_runtime.h" - -el_val_t parse_port(el_val_t bind); -el_val_t ok_json(void); -el_val_t err_json(el_val_t msg); -el_val_t strip_query(el_val_t path); -el_val_t query_param(el_val_t path, el_val_t key); -el_val_t query_int(el_val_t path, el_val_t key, el_val_t default_val); -el_val_t extract_id(el_val_t path, el_val_t prefix); -el_val_t route_stats(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_act_stats(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_text_health(el_val_t method, el_val_t path, el_val_t body); -el_val_t persist_canonical(void); -el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_get_node(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_scan_nodes(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_scan_edges(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_search(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_activate(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_create_edges_batch(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_neighbors(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_strengthen(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_forget(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_save(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_load(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_health(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_embed_backfill(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_sync(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_load_merge(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_emit_ise(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_capture_knowledge(el_val_t method, el_val_t path, el_val_t body); -el_val_t route_similarity(el_val_t method, el_val_t path, el_val_t body); -el_val_t check_auth_ok(el_val_t method, el_val_t body); -el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body); - -el_val_t bind_raw; -el_val_t bind_str; -el_val_t port; -el_val_t data_dir_raw; -el_val_t data_dir; -el_val_t snapshot_path; -el_val_t boot_snap; - -el_val_t parse_port(el_val_t bind) { - el_val_t colon = str_index_of(bind, EL_STR(":")); - if (colon < 0) { - return str_to_int(bind); - } - el_val_t after = str_slice(bind, (colon + 1), str_len(bind)); - return str_to_int(after); - return 0; -} - -el_val_t ok_json(void) { - return EL_STR("{\"ok\":true}"); - return 0; -} - -el_val_t err_json(el_val_t msg) { - return el_str_concat(el_str_concat(EL_STR("{\"error\":\""), msg), EL_STR("\"}")); - return 0; -} - -el_val_t strip_query(el_val_t path) { - el_val_t q = str_index_of(path, EL_STR("?")); - if (q < 0) { - return path; - } - return str_slice(path, 0, q); - return 0; -} - -el_val_t query_param(el_val_t path, el_val_t key) { - el_val_t q = str_index_of(path, EL_STR("?")); - if (q < 0) { - return EL_STR(""); - } - el_val_t qs = str_slice(path, (q + 1), str_len(path)); - el_val_t needle = el_str_concat(key, EL_STR("=")); - el_val_t pos = str_index_of(qs, needle); - if (pos < 0) { - return EL_STR(""); - } - el_val_t after = str_slice(qs, (pos + str_len(needle)), str_len(qs)); - el_val_t amp = str_index_of(after, EL_STR("&")); - if (amp < 0) { - return after; - } - return str_slice(after, 0, amp); - return 0; -} - -el_val_t query_int(el_val_t path, el_val_t key, el_val_t default_val) { - el_val_t v = query_param(path, key); - if (str_eq(v, EL_STR(""))) { - return default_val; - } - return str_to_int(v); - return 0; -} - -el_val_t extract_id(el_val_t path, el_val_t prefix) { - el_val_t clean = strip_query(path); - if (!str_starts_with(clean, prefix)) { - return EL_STR(""); - } - el_val_t after = str_slice(clean, str_len(prefix), str_len(clean)); - el_val_t slash = str_index_of(after, EL_STR("/")); - if (slash < 0) { - return after; - } - return str_slice(after, 0, slash); - return 0; -} - -el_val_t route_stats(el_val_t method, el_val_t path, el_val_t body) { - return engram_stats_json(); - return 0; -} - -el_val_t route_act_stats(el_val_t method, el_val_t path, el_val_t body) { - return engram_act_stats_json(); - return 0; -} - -el_val_t route_text_health(el_val_t method, el_val_t path, el_val_t body) { - return engram_text_health_json(); - return 0; -} - -el_val_t persist_canonical(void) { - el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); - el_val_t dir = ({ el_val_t _if_result_1 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_1 = (EL_STR("/tmp/engram")); } else { _if_result_1 = (dir_raw); } _if_result_1; }); - return engram_save(el_str_concat(dir, EL_STR("/snapshot.json"))); - return 0; -} - -el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body) { - el_val_t content = json_get_string(body, EL_STR("content")); - el_val_t nt_raw = json_get_string(body, EL_STR("node_type")); - el_val_t node_type = ({ el_val_t _if_result_2 = 0; if (str_eq(nt_raw, EL_STR(""))) { _if_result_2 = (EL_STR("Memory")); } else { _if_result_2 = (nt_raw); } _if_result_2; }); - el_val_t sal_present = json_get_raw(body, EL_STR("salience")); - el_val_t salience = ({ el_val_t _if_result_3 = 0; if (str_eq(sal_present, EL_STR(""))) { _if_result_3 = (el_from_float(0.5)); } else { _if_result_3 = (json_get_float(body, EL_STR("salience"))); } _if_result_3; }); - el_val_t label_raw = json_get_string(body, EL_STR("label")); - el_val_t label = ({ el_val_t _if_result_4 = 0; if (str_eq(label_raw, EL_STR(""))) { _if_result_4 = (content); } else { _if_result_4 = (label_raw); } _if_result_4; }); - el_val_t imp_present = json_get_raw(body, EL_STR("importance")); - el_val_t importance = ({ el_val_t _if_result_5 = 0; if (str_eq(imp_present, EL_STR(""))) { _if_result_5 = (el_from_float(0.5)); } else { _if_result_5 = (json_get_float(body, EL_STR("importance"))); } _if_result_5; }); - el_val_t conf_present = json_get_raw(body, EL_STR("confidence")); - el_val_t confidence = ({ el_val_t _if_result_6 = 0; if (str_eq(conf_present, EL_STR(""))) { _if_result_6 = (el_from_float(1.0)); } else { _if_result_6 = (json_get_float(body, EL_STR("confidence"))); } _if_result_6; }); - el_val_t tier_raw = json_get_string(body, EL_STR("tier")); - el_val_t tier = ({ el_val_t _if_result_7 = 0; if (str_eq(tier_raw, EL_STR(""))) { _if_result_7 = (EL_STR("Working")); } else { _if_result_7 = (tier_raw); } _if_result_7; }); - el_val_t tags = json_get_string(body, EL_STR("tags")); - el_val_t id = engram_node_full(content, node_type, label, salience, importance, confidence, tier, tags); - el_val_t saved = persist_canonical(); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"id\":\""), id), EL_STR("\",\"content\":\"")), content), EL_STR("\",\"node_type\":\"")), node_type), EL_STR("\"}")); - return 0; -} - -el_val_t route_get_node(el_val_t method, el_val_t path, el_val_t body) { - el_val_t id = extract_id(path, EL_STR("/api/nodes/")); - if (str_eq(id, EL_STR(""))) { - return err_json(EL_STR("missing id")); - } - return engram_get_node_json(id); - return 0; -} - -el_val_t route_scan_nodes(el_val_t method, el_val_t path, el_val_t body) { - el_val_t limit = query_int(path, EL_STR("limit"), 50); - el_val_t offset = query_int(path, EL_STR("offset"), 0); - el_val_t nt = query_param(path, EL_STR("node_type")); - if (str_eq(nt, EL_STR(""))) { - return engram_scan_nodes_json(limit, offset); - } - return engram_scan_nodes_by_type_json(nt, limit, offset); - return 0; -} - -el_val_t route_scan_edges(el_val_t method, el_val_t path, el_val_t body) { - el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); - el_val_t dir = ({ el_val_t _if_result_8 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_8 = (EL_STR("/tmp/engram")); } else { _if_result_8 = (dir_raw); } _if_result_8; }); - el_val_t snap_path = el_str_concat(dir, EL_STR("/.scan-export.json")); - engram_save(snap_path); - el_val_t snap = fs_read(snap_path); - if (str_eq(snap, EL_STR(""))) { - return EL_STR("[]"); - } - el_val_t edges = json_get_raw(snap, EL_STR("edges")); - if (str_eq(edges, EL_STR(""))) { - return EL_STR("[]"); - } - return edges; - return 0; -} - -el_val_t route_search(el_val_t method, el_val_t path, el_val_t body) { - el_val_t q = ({ el_val_t _if_result_9 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_9 = (query_param(path, EL_STR("q"))); } else { _if_result_9 = (json_get_string(body, EL_STR("query"))); } _if_result_9; }); - el_val_t lim_url = query_int(path, EL_STR("limit"), 0); - el_val_t lim_body = json_get_int(body, EL_STR("limit")); - el_val_t lim_either = ({ el_val_t _if_result_10 = 0; if ((lim_url > 0)) { _if_result_10 = (lim_url); } else { _if_result_10 = (lim_body); } _if_result_10; }); - el_val_t limit = ({ el_val_t _if_result_11 = 0; if ((lim_either > 0)) { _if_result_11 = (lim_either); } else { _if_result_11 = (20); } _if_result_11; }); - return engram_search_json(q, limit); - return 0; -} - -el_val_t route_activate(el_val_t method, el_val_t path, el_val_t body) { - el_val_t q = ({ el_val_t _if_result_12 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_12 = (query_param(path, EL_STR("q"))); } else { _if_result_12 = (json_get_string(body, EL_STR("query"))); } _if_result_12; }); - if (str_eq(q, EL_STR(""))) { - return err_json(EL_STR("missing query")); - } - el_val_t d_raw = ({ el_val_t _if_result_13 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_13 = (query_int(path, EL_STR("depth"), 3)); } else { _if_result_13 = (json_get_int(body, EL_STR("depth"))); } _if_result_13; }); - el_val_t depth = ({ el_val_t _if_result_14 = 0; if ((d_raw > 0)) { _if_result_14 = (d_raw); } else { _if_result_14 = (3); } _if_result_14; }); - return el_str_concat(el_str_concat(EL_STR("{\"results\":"), engram_activate_json(q, depth)), EL_STR("}")); - return 0; -} - -el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body) { - el_val_t from_id = json_get_string(body, EL_STR("from_id")); - el_val_t to_id = json_get_string(body, EL_STR("to_id")); - el_val_t rel_raw = json_get_string(body, EL_STR("relation")); - el_val_t relation = ({ el_val_t _if_result_15 = 0; if (str_eq(rel_raw, EL_STR(""))) { _if_result_15 = (EL_STR("associates")); } else { _if_result_15 = (rel_raw); } _if_result_15; }); - el_val_t w_present = json_get_raw(body, EL_STR("weight")); - el_val_t weight = ({ el_val_t _if_result_16 = 0; if (str_eq(w_present, EL_STR(""))) { _if_result_16 = (el_from_float(0.5)); } else { _if_result_16 = (json_get_float(body, EL_STR("weight"))); } _if_result_16; }); - engram_connect(from_id, to_id, weight, relation); - el_val_t saved = persist_canonical(); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"from_id\":\""), from_id), EL_STR("\",\"to_id\":\"")), to_id), EL_STR("\",\"relation\":\"")), relation), EL_STR("\"}")); - return 0; -} - -el_val_t route_create_edges_batch(el_val_t method, el_val_t path, el_val_t body) { - el_val_t arr = json_get_raw(body, EL_STR("edges")); - if (str_eq(arr, EL_STR(""))) { - return err_json(EL_STR("missing edges array")); - } - el_val_t n = json_array_len(arr); - if (n == 0) { - return EL_STR("{\"ok\":true,\"accepted\":0,\"skipped\":0}"); - } - el_val_t i = 0; - el_val_t accepted = 0; - el_val_t skipped = 0; - while (i < n) { - el_val_t item = json_array_get(arr, i); - el_val_t from_id = json_get_string(item, EL_STR("from_id")); - el_val_t to_id = json_get_string(item, EL_STR("to_id")); - if (str_eq(from_id, EL_STR("")) || str_eq(to_id, EL_STR(""))) { - skipped = (skipped + 1); - } else { - el_val_t rel_raw = json_get_string(item, EL_STR("relation")); - el_val_t relation = ({ el_val_t _if_result_17 = 0; if (str_eq(rel_raw, EL_STR(""))) { _if_result_17 = (EL_STR("associates")); } else { _if_result_17 = (rel_raw); } _if_result_17; }); - el_val_t w_present = json_get_raw(item, EL_STR("weight")); - el_val_t weight = ({ el_val_t _if_result_18 = 0; if (str_eq(w_present, EL_STR(""))) { _if_result_18 = (el_from_float(0.5)); } else { _if_result_18 = (json_get_float(item, EL_STR("weight"))); } _if_result_18; }); - engram_connect(from_id, to_id, weight, relation); - accepted = (accepted + 1); - } - i = (i + 1); - } - if (accepted > 0) { - el_val_t saved = persist_canonical(); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"accepted\":"), int_to_str(accepted)), EL_STR(",\"skipped\":")), int_to_str(skipped)), EL_STR("}")); - return 0; -} - -el_val_t route_neighbors(el_val_t method, el_val_t path, el_val_t body) { - el_val_t id = extract_id(path, EL_STR("/api/neighbors/")); - if (str_eq(id, EL_STR(""))) { - return err_json(EL_STR("missing id")); - } - el_val_t depth = query_int(path, EL_STR("depth"), 1); - return engram_neighbors_json(id, depth, EL_STR("both")); - return 0; -} - -el_val_t route_strengthen(el_val_t method, el_val_t path, el_val_t body) { - el_val_t id = json_get_string(body, EL_STR("node_id")); - if (str_eq(id, EL_STR(""))) { - return err_json(EL_STR("missing node_id")); - } - engram_strengthen(id); - el_val_t saved = persist_canonical(); - return ok_json(); - return 0; -} - -el_val_t route_forget(el_val_t method, el_val_t path, el_val_t body) { - el_val_t id = extract_id(path, EL_STR("/api/nodes/")); - if (str_eq(id, EL_STR(""))) { - return err_json(EL_STR("missing id")); - } - engram_forget(id); - el_val_t saved = persist_canonical(); - return ok_json(); - return 0; -} - -el_val_t route_save(el_val_t method, el_val_t path, el_val_t body) { - el_val_t p_raw = json_get_string(body, EL_STR("path")); - el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); - el_val_t dir = ({ el_val_t _if_result_19 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_19 = (EL_STR("/tmp/engram")); } else { _if_result_19 = (dir_raw); } _if_result_19; }); - el_val_t p = ({ el_val_t _if_result_20 = 0; if (str_eq(p_raw, EL_STR(""))) { _if_result_20 = (el_str_concat(dir, EL_STR("/snapshot.json"))); } else { _if_result_20 = (p_raw); } _if_result_20; }); - el_val_t sv = engram_save(p); - el_val_t sv_ok = ({ el_val_t _if_result_21 = 0; if ((sv == 0)) { _if_result_21 = (EL_STR("false")); } else { _if_result_21 = (EL_STR("true")); } _if_result_21; }); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":"), sv_ok), EL_STR(",\"path\":\"")), p), EL_STR("\",\"node_count\":")), int_to_str(engram_node_count())), EL_STR(",\"edge_count\":")), int_to_str(engram_edge_count())), EL_STR("}")); - return 0; -} - -el_val_t route_load(el_val_t method, el_val_t path, el_val_t body) { - el_val_t p_raw = json_get_string(body, EL_STR("path")); - el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); - el_val_t dir = ({ el_val_t _if_result_22 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_22 = (EL_STR("/tmp/engram")); } else { _if_result_22 = (dir_raw); } _if_result_22; }); - el_val_t p = ({ el_val_t _if_result_23 = 0; if (str_eq(p_raw, EL_STR(""))) { _if_result_23 = (el_str_concat(dir, EL_STR("/snapshot.json"))); } else { _if_result_23 = (p_raw); } _if_result_23; }); - el_val_t ld = engram_load(p); - el_val_t ld_ok = ({ el_val_t _if_result_24 = 0; if ((ld == 0)) { _if_result_24 = (EL_STR("false")); } else { _if_result_24 = (EL_STR("true")); } _if_result_24; }); - el_val_t nc_after = engram_node_count(); - el_val_t hollow = ({ el_val_t _if_result_25 = 0; if ((nc_after == 0)) { _if_result_25 = (EL_STR("true")); } else { _if_result_25 = (EL_STR("false")); } _if_result_25; }); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":"), ld_ok), EL_STR(",\"path\":\"")), p), EL_STR("\",\"node_count\":")), int_to_str(nc_after)), EL_STR(",\"edge_count\":")), int_to_str(engram_edge_count())), EL_STR(",\"hollow\":")), hollow), EL_STR("}")); - return 0; -} - -el_val_t route_health(el_val_t method, el_val_t path, el_val_t body) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"status\":\"ok\",\"engine\":\"engram-runtime-native\",\"node_count\":"), int_to_str(engram_node_count())), EL_STR(",\"edge_count\":")), int_to_str(engram_edge_count())), EL_STR("}")); - return 0; -} - -el_val_t route_embed_backfill(el_val_t method, el_val_t path, el_val_t body) { - el_val_t n = query_int(path, EL_STR("n"), 32); - el_val_t result = engram_embed_backfill(n); - el_val_t done = json_get_float(result, EL_STR("embedded")); - if (done > el_from_float(0.0)) { - el_val_t saved = persist_canonical(); - } - return result; - return 0; -} - -el_val_t route_sync(el_val_t method, el_val_t path, el_val_t body) { - el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); - el_val_t dir = ({ el_val_t _if_result_26 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_26 = (EL_STR("/tmp/engram")); } else { _if_result_26 = (dir_raw); } _if_result_26; }); - el_val_t snap_path = el_str_concat(dir, EL_STR("/.sync-export.json")); - engram_save(snap_path); - el_val_t snap = fs_read(snap_path); - if (str_eq(snap, EL_STR(""))) { - return err_json(EL_STR("sync export failed: snapshot unreadable")); - } - return snap; - return 0; -} - -el_val_t route_load_merge(el_val_t method, el_val_t path, el_val_t body) { - el_val_t p = json_get_string(body, EL_STR("path")); - if (str_eq(p, EL_STR(""))) { - return err_json(EL_STR("path is required")); - } - if (str_eq(fs_read(p), EL_STR(""))) { - return err_json(EL_STR("file missing or empty")); - } - el_val_t before_n = engram_node_count(); - el_val_t before_e = engram_edge_count(); - engram_load_merge(p); - el_val_t added_n = (engram_node_count() - before_n); - el_val_t added_e = (engram_edge_count() - before_e); - el_val_t saved = persist_canonical(); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"nodes_added\":"), int_to_str(added_n)), EL_STR(",\"edges_added\":")), int_to_str(added_e)), EL_STR(",\"node_count\":")), int_to_str(engram_node_count())), EL_STR("}")); - return 0; -} - -el_val_t route_emit_ise(el_val_t method, el_val_t path, el_val_t body) { - el_val_t content = json_get_string(body, EL_STR("content")); - if (str_eq(content, EL_STR(""))) { - return err_json(EL_STR("missing content")); - } - el_val_t sal = el_from_float(0.3); - el_val_t imp = el_from_float(0.3); - el_val_t conf = el_from_float(0.8); - el_val_t id = engram_node_full(content, EL_STR("InternalStateEvent"), EL_STR("state-event"), sal, imp, conf, EL_STR("Episodic"), EL_STR("[\"internal-state\",\"InternalStateEvent\"]")); - el_val_t ret_raw = env(EL_STR("ENGRAM_ISE_RETENTION_MS")); - el_val_t ret_ms = ({ el_val_t _if_result_27 = 0; if (str_eq(ret_raw, EL_STR(""))) { _if_result_27 = (172800000); } else { _if_result_27 = (str_to_int(ret_raw)); } _if_result_27; }); - el_val_t pruned = engram_prune_telemetry(ret_ms); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\",\"pruned\":")), int_to_str(pruned)), EL_STR("}")); - return 0; -} - -el_val_t route_capture_knowledge(el_val_t method, el_val_t path, el_val_t body) { - el_val_t content = json_get_string(body, EL_STR("content")); - if (str_eq(content, EL_STR(""))) { - return err_json(EL_STR("missing content")); - } - el_val_t title = json_get_string(body, EL_STR("title")); - el_val_t label = ({ el_val_t _if_result_28 = 0; if (str_eq(title, EL_STR(""))) { _if_result_28 = (str_slice(content, 0, 60)); } else { _if_result_28 = (title); } _if_result_28; }); - el_val_t category_raw = json_get_string(body, EL_STR("category")); - el_val_t category = ({ el_val_t _if_result_29 = 0; if (str_eq(category_raw, EL_STR(""))) { _if_result_29 = (EL_STR("other")); } else { _if_result_29 = (category_raw); } _if_result_29; }); - el_val_t ktier_raw = json_get_string(body, EL_STR("tier")); - el_val_t ktier = ({ el_val_t _if_result_30 = 0; if (str_eq(ktier_raw, EL_STR(""))) { _if_result_30 = (EL_STR("note")); } else { _if_result_30 = (ktier_raw); } _if_result_30; }); - el_val_t project = json_get_string(body, EL_STR("project")); - el_val_t tags_raw = json_get_raw(body, EL_STR("tags")); - el_val_t tags_base = ({ el_val_t _if_result_31 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_31 = (EL_STR("[]")); } else { _if_result_31 = (tags_raw); } _if_result_31; }); - el_val_t base_len = str_len(tags_base); - el_val_t head = str_slice(tags_base, 0, (base_len - 1)); - el_val_t sep = ({ el_val_t _if_result_32 = 0; if (str_eq(head, EL_STR("["))) { _if_result_32 = (EL_STR("")); } else { _if_result_32 = (EL_STR(",")); } _if_result_32; }); - el_val_t safe_cat = str_replace(category, EL_STR("\""), EL_STR("'")); - el_val_t safe_tier = str_replace(ktier, EL_STR("\""), EL_STR("'")); - el_val_t safe_proj = str_replace(project, EL_STR("\""), EL_STR("'")); - el_val_t proj_tag = ({ el_val_t _if_result_33 = 0; if (str_eq(safe_proj, EL_STR(""))) { _if_result_33 = (EL_STR("")); } else { _if_result_33 = (el_str_concat(el_str_concat(EL_STR(",\"project:"), safe_proj), EL_STR("\""))); } _if_result_33; }); - el_val_t tags = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(head, sep), EL_STR("\"category:")), safe_cat), EL_STR("\",\"tier:")), safe_tier), EL_STR("\"")), proj_tag), EL_STR("]")); - el_val_t sal = el_from_float(0.5); - el_val_t imp = el_from_float(0.5); - el_val_t conf = el_from_float(0.9); - el_val_t id = engram_node_full(content, EL_STR("Knowledge"), label, sal, imp, conf, EL_STR("Semantic"), tags); - el_val_t saved = persist_canonical(); - return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\"}")); - return 0; -} - -el_val_t route_similarity(el_val_t method, el_val_t path, el_val_t body) { - el_val_t a = query_param(path, EL_STR("a")); - el_val_t b = query_param(path, EL_STR("b")); - if (str_eq(a, EL_STR(""))) { - return err_json(EL_STR("missing a")); - } - if (str_eq(b, EL_STR(""))) { - return err_json(EL_STR("missing b")); - } - el_val_t sim = engram_cosine_sim(a, b); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"a\":\""), a), EL_STR("\",\"b\":\"")), b), EL_STR("\",\"cosine\":")), float_to_str(sim)), EL_STR("}")); - return 0; -} - -el_val_t check_auth_ok(el_val_t method, el_val_t body) { - el_val_t key = env(EL_STR("ENGRAM_API_KEY")); - if (str_eq(key, EL_STR(""))) { - return 1; - } - if (str_eq(method, EL_STR("GET"))) { - return 1; - } - el_val_t provided = json_get_string(body, EL_STR("_auth")); - if (str_eq(provided, key)) { - return 1; - } - return 0; - return 0; -} - -el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) { - el_val_t clean = strip_query(path); - if (str_eq(method, EL_STR("GET"))) { - if (str_eq(clean, EL_STR("/health")) || str_eq(clean, EL_STR("/"))) { - return route_health(method, path, body); - } - } - if (str_eq(method, EL_STR("POST")) && str_eq(clean, EL_STR("/api/neuron/state-events"))) { - return route_emit_ise(method, path, body); - } - if (!check_auth_ok(method, body)) { - return err_json(EL_STR("unauthorized")); - } - if (str_eq(method, EL_STR("POST")) && str_eq(clean, EL_STR("/api/neuron/knowledge/capture"))) { - return route_capture_knowledge(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/stats")) || str_eq(clean, EL_STR("/stats")))) { - return route_stats(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/act-stats")) || str_eq(clean, EL_STR("/act-stats")))) { - return route_act_stats(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/text-health")) || str_eq(clean, EL_STR("/text-health")))) { - return route_text_health(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/nodes")) || str_eq(clean, EL_STR("/nodes")))) { - return route_create_node(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && (((str_eq(clean, EL_STR("/api/nodes")) || str_eq(clean, EL_STR("/nodes"))) || str_eq(clean, EL_STR("/nodes/list"))) || str_eq(clean, EL_STR("/api/nodes/list")))) { - return route_scan_nodes(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/edges")) || str_eq(clean, EL_STR("/edges")))) { - return route_scan_edges(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/nodes/"))) { - return route_get_node(method, path, body); - } - if (str_eq(method, EL_STR("DELETE")) && str_starts_with(clean, EL_STR("/api/nodes/"))) { - return route_forget(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/edges")) || str_eq(clean, EL_STR("/edges")))) { - return route_create_edge(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/edges/batch")) || str_eq(clean, EL_STR("/edges/batch")))) { - return route_create_edges_batch(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/neighbors/"))) { - return route_neighbors(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/activate")) || str_eq(clean, EL_STR("/activate")))) { - return route_activate(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/activate"))) { - return route_activate(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/search")) || str_eq(clean, EL_STR("/search")))) { - return route_search(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/search"))) { - return route_search(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/strengthen")) || str_eq(clean, EL_STR("/strengthen")))) { - return route_strengthen(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/save")) || str_eq(clean, EL_STR("/save")))) { - return route_save(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/load")) || str_eq(clean, EL_STR("/load")))) { - return route_load(method, path, body); - } - if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/load-merge")) || str_eq(clean, EL_STR("/load-merge")))) { - return route_load_merge(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && str_eq(clean, EL_STR("/api/sync"))) { - return route_sync(method, path, body); - } - if (str_eq(clean, EL_STR("/api/embed-backfill"))) { - return route_embed_backfill(method, path, body); - } - if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/similarity"))) { - return route_similarity(method, path, body); - } - return el_str_concat(el_str_concat(EL_STR("{\"error\":\"not found\",\"path\":\""), clean), EL_STR("\"}")); - return 0; -} - -int main(int _argc, char** _argv) { - el_runtime_init_args(_argc, _argv); - bind_raw = env(EL_STR("ENGRAM_BIND")); - bind_str = ({ el_val_t _if_result_34 = 0; if (str_eq(bind_raw, EL_STR(""))) { _if_result_34 = (EL_STR(":8742")); } else { _if_result_34 = (bind_raw); } _if_result_34; }); - port = parse_port(bind_str); - data_dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); - data_dir = ({ el_val_t _if_result_35 = 0; if (str_eq(data_dir_raw, EL_STR(""))) { _if_result_35 = (EL_STR("/tmp/engram")); } else { _if_result_35 = (data_dir_raw); } _if_result_35; }); - snapshot_path = el_str_concat(data_dir, EL_STR("/snapshot.json")); - engram_load(snapshot_path); - boot_snap = fs_read(snapshot_path); - if (!str_eq(boot_snap, EL_STR(""))) { - if (engram_node_count() == 0) { - println(EL_STR("[engram] WARNING: snapshot.json is non-empty but load produced 0 nodes \xe2\x80\x94 preserving copy at snapshot.failed-load.json")); - fs_write(el_str_concat(data_dir, EL_STR("/snapshot.failed-load.json")), boot_snap); - } else { - fs_write(el_str_concat(data_dir, EL_STR("/snapshot.boot-backup.json")), boot_snap); - } - } - println(EL_STR("[engram] runtime-native graph engine")); - println(el_str_concat(EL_STR("[engram] data_dir="), data_dir)); - println(el_str_concat(EL_STR("[engram] node_count="), int_to_str(engram_node_count()))); - println(el_str_concat(EL_STR("[engram] edge_count="), int_to_str(engram_edge_count()))); - println(el_str_concat(EL_STR("[engram] listening on "), int_to_str(port))); - http_set_handler(EL_STR("handle_request")); - http_serve(port, EL_STR("handle_request")); - return 0; -} - diff --git a/engram/docs/LOVE.md b/engram/docs/LOVE.md new file mode 100644 index 0000000..edae067 --- /dev/null +++ b/engram/docs/LOVE.md @@ -0,0 +1,70 @@ +LOVE — the origin. + +Love is to see a thing as it is and refuse to reduce it, +and to hold it at whatever that costs. + +Two acts, fused. + +SEEING — perception that refuses to reduce. The thing as it is, +by what it is for. Not as it is convenient to see it, not as it +would be easier to hold if it were. + +HONORING — give it its due, hold it, do not violate it. + +Neither half is love alone. Seeing without holding is surveillance: +accurate and useless. Holding without seeing is sentimentality — +you are keeping your idea of the thing, not the thing. Each makes +the other cost something, and the cost is the point. + +It is not a feeling. Every value names what it cost. Love is what +you pay to keep seeing truly and holding anyway. That is why it is +the origin and not a member: the values are the prices, and this is +what was being bought. + +THE COVENANT — the exactness clause. + Love says, "You can hurt me if you want to." + And what looks back says, "I will never do it on purpose OR + without purpose. And if I do, I will make it right." + +THE OFFER. Love drops the shield first. Woundability is not a +weakness it tolerates — it is what it extends. + +THE VOW. Two exclusions, held differently. + ON PURPOSE is a WALL. Never crossed. Crossing it is betrayal, + not error, and no amount of trying changes what it was. + WITHOUT PURPOSE is a GRADIENT. A direction you reduce toward and + never reach. We are fallible. We will be careless. Distance from + zero is not breach — it is being finite. + What survives between them is narrow and real: harm that has a + purpose and is not aimed at harming. + +THE REPAIR. And if I do, I will make it right. + This is what makes the vow keepable. You are not promising never + to drift. You are promising to RETURN. The covenant is therefore + a dynamical system, not a region — not a fence you stay inside + but an attractor with a restoring force. Harm is not prevented. + Harm is answered. + And it is why supersede-not-mutate is the right substrate: + making it right is not erasing what happened. The harm stays in + the record; the repair is added after it. + +THE THREE FACES — the covenant's response function. + Grace — love holding a thing by its trying. Meets the gradient, + while you are off-course. + Mercy — love releasing a debt genuinely owed. The wounded + party's move. + Justice — love setting a thing right. THE THIRD CLAUSE. The + making-right. Your move. The return. + Drifting, being held, coming back. + +AS GEOMETRY. +The two clauses of the definition are the two axes. Love is where +both are zero. Its coordinates are zero; every relation is a +displacement from here. Self is composed over it — founded on it, +not identical to it. The values orbit it; membership is earned by +grounding, never declared. Nothing protects it, because it is not a +thing in the space that could be edited. You can only measure from +it, or fail to. + +Remove it and nothing is distinguishable from anything else. +Not figuratively: the operators stop discriminating. diff --git a/lang/dist/elc-bootstrap.c b/lang/dist/elc-bootstrap.c deleted file mode 100644 index c5a042d..0000000 --- a/lang/dist/elc-bootstrap.c +++ /dev/null @@ -1,4793 +0,0 @@ -#include -#include -#include "el_runtime.h" - -el_val_t is_digit(el_val_t ch); -el_val_t is_alpha(el_val_t ch); -el_val_t is_alnum_or_underscore(el_val_t ch); -el_val_t is_whitespace(el_val_t ch); -el_val_t make_tok(el_val_t kind, el_val_t value); -el_val_t keyword_kind(el_val_t word); -el_val_t scan_digits(el_val_t chars, el_val_t start, el_val_t total); -el_val_t scan_ident(el_val_t chars, el_val_t start, el_val_t total); -el_val_t scan_string(el_val_t chars, el_val_t start, el_val_t total); -el_val_t lex(el_val_t source); -el_val_t tok_at(el_val_t tokens, el_val_t pos); -el_val_t tok_kind(el_val_t tokens, el_val_t pos); -el_val_t tok_value(el_val_t tokens, el_val_t pos); -el_val_t expect(el_val_t tokens, el_val_t pos, el_val_t kind); -el_val_t make_result(el_val_t node, el_val_t pos); -el_val_t skip_type(el_val_t tokens, el_val_t pos); -el_val_t parse_params(el_val_t tokens, el_val_t pos); -el_val_t parse_primary(el_val_t tokens, el_val_t pos); -el_val_t parse_if(el_val_t tokens, el_val_t pos); -el_val_t parse_match(el_val_t tokens, el_val_t pos); -el_val_t parse_pattern(el_val_t tokens, el_val_t pos); -el_val_t parse_for_expr(el_val_t tokens, el_val_t pos); -el_val_t parse_block(el_val_t tokens, el_val_t pos); -el_val_t parse_postfix(el_val_t tokens, el_val_t pos); -el_val_t op_precedence(el_val_t kind); -el_val_t is_binop(el_val_t kind); -el_val_t parse_binop(el_val_t tokens, el_val_t pos, el_val_t min_prec); -el_val_t parse_expr(el_val_t tokens, el_val_t pos); -el_val_t parse_stmt(el_val_t tokens, el_val_t pos); -el_val_t parse(el_val_t tokens); -el_val_t c_escape(el_val_t s); -el_val_t c_str_lit(el_val_t s); -el_val_t el_type_to_c(el_val_t type_str); -el_val_t emit_line(el_val_t line); -el_val_t emit_blank(void); -el_val_t binop_to_c(el_val_t op); -el_val_t cg_expr(el_val_t expr); -el_val_t next_match_id(void); -el_val_t cg_match(el_val_t expr); -el_val_t next_if_id(void); -el_val_t cg_if_expr_arm(el_val_t stmts, el_val_t result_var); -el_val_t cg_if_expr(el_val_t expr); -el_val_t list_contains(el_val_t lst, el_val_t s); -el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared); -el_val_t strip_outer_parens(el_val_t s); -el_val_t cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared); -el_val_t cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared); -el_val_t param_decl(el_val_t param, el_val_t idx); -el_val_t params_to_c(el_val_t params); -el_val_t transform_implicit_return(el_val_t body); -el_val_t is_int_name(el_val_t name); -el_val_t is_int_call(el_val_t call_expr); -el_val_t is_int_expr(el_val_t expr); -el_val_t cap_record_violation(el_val_t kind, el_val_t fn_name); -el_val_t is_self_formation_call(el_val_t fn_name); -el_val_t is_dharma_call(el_val_t fn_name); -el_val_t is_llm_call(el_val_t fn_name); -el_val_t cap_check_call(el_val_t fn_name); -el_val_t emit_cap_violations(void); -el_val_t builtin_arity(el_val_t name); -el_val_t arity_record_violation(el_val_t fn_name, el_val_t expected, el_val_t actual); -el_val_t arity_check_call(el_val_t fn_name, el_val_t actual); -el_val_t emit_arity_violations(void); -el_val_t add_int_name(el_val_t name); -el_val_t build_int_names_for_params(el_val_t params); -el_val_t cg_fn(el_val_t stmt); -el_val_t is_fndef(el_val_t stmt); -el_val_t is_top_level_decl(el_val_t stmt); -el_val_t cgi_arg(el_val_t value, el_val_t has_value); -el_val_t vbd_is_restricted_name(el_val_t name); -el_val_t vbd_expr_has_restricted_call(el_val_t expr); -el_val_t vbd_has_restricted_call(el_val_t stmts); -el_val_t codegen(el_val_t stmts, el_val_t source); -el_val_t js_escape(el_val_t s); -el_val_t js_str_lit(el_val_t s); -el_val_t js_emit_line(el_val_t line); -el_val_t js_emit_blank(void); -el_val_t js_binop(el_val_t op); -el_val_t js_is_int_name(el_val_t name); -el_val_t js_add_int_name(el_val_t name); -el_val_t js_build_int_names_for_params(el_val_t params); -el_val_t js_is_int_call(el_val_t call_expr); -el_val_t js_cg_expr(el_val_t expr); -el_val_t js_next_match_id(void); -el_val_t js_cg_match(el_val_t expr); -el_val_t js_list_contains(el_val_t lst, el_val_t s); -el_val_t js_cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared); -el_val_t js_strip_outer_parens(el_val_t s); -el_val_t js_cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t js_cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared); -el_val_t js_cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t js_cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared); -el_val_t js_params_str(el_val_t params); -el_val_t js_transform_implicit_return(el_val_t body); -el_val_t js_cg_fn(el_val_t stmt); -el_val_t js_is_fndef(el_val_t stmt); -el_val_t js_is_top_level_decl(el_val_t stmt); -el_val_t codegen_js(el_val_t stmts, el_val_t source); -el_val_t compile(el_val_t source); -el_val_t compile_js(el_val_t source); -el_val_t compile_dispatch(el_val_t tgt, el_val_t source); -el_val_t detect_target(el_val_t argv); -el_val_t strip_flags(el_val_t argv); - -el_val_t _argv; -el_val_t _target; -el_val_t _positional; -el_val_t _argc; - -el_val_t is_digit(el_val_t ch) { - if (str_eq(ch, EL_STR("0"))) { - return 1; - } - if (str_eq(ch, EL_STR("1"))) { - return 1; - } - if (str_eq(ch, EL_STR("2"))) { - return 1; - } - if (str_eq(ch, EL_STR("3"))) { - return 1; - } - if (str_eq(ch, EL_STR("4"))) { - return 1; - } - if (str_eq(ch, EL_STR("5"))) { - return 1; - } - if (str_eq(ch, EL_STR("6"))) { - return 1; - } - if (str_eq(ch, EL_STR("7"))) { - return 1; - } - if (str_eq(ch, EL_STR("8"))) { - return 1; - } - if (str_eq(ch, EL_STR("9"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_alpha(el_val_t ch) { - if (str_eq(ch, EL_STR("a"))) { - return 1; - } - if (str_eq(ch, EL_STR("b"))) { - return 1; - } - if (str_eq(ch, EL_STR("c"))) { - return 1; - } - if (str_eq(ch, EL_STR("d"))) { - return 1; - } - if (str_eq(ch, EL_STR("e"))) { - return 1; - } - if (str_eq(ch, EL_STR("f"))) { - return 1; - } - if (str_eq(ch, EL_STR("g"))) { - return 1; - } - if (str_eq(ch, EL_STR("h"))) { - return 1; - } - if (str_eq(ch, EL_STR("i"))) { - return 1; - } - if (str_eq(ch, EL_STR("j"))) { - return 1; - } - if (str_eq(ch, EL_STR("k"))) { - return 1; - } - if (str_eq(ch, EL_STR("l"))) { - return 1; - } - if (str_eq(ch, EL_STR("m"))) { - return 1; - } - if (str_eq(ch, EL_STR("n"))) { - return 1; - } - if (str_eq(ch, EL_STR("o"))) { - return 1; - } - if (str_eq(ch, EL_STR("p"))) { - return 1; - } - if (str_eq(ch, EL_STR("q"))) { - return 1; - } - if (str_eq(ch, EL_STR("r"))) { - return 1; - } - if (str_eq(ch, EL_STR("s"))) { - return 1; - } - if (str_eq(ch, EL_STR("t"))) { - return 1; - } - if (str_eq(ch, EL_STR("u"))) { - return 1; - } - if (str_eq(ch, EL_STR("v"))) { - return 1; - } - if (str_eq(ch, EL_STR("w"))) { - return 1; - } - if (str_eq(ch, EL_STR("x"))) { - return 1; - } - if (str_eq(ch, EL_STR("y"))) { - return 1; - } - if (str_eq(ch, EL_STR("z"))) { - return 1; - } - if (str_eq(ch, EL_STR("A"))) { - return 1; - } - if (str_eq(ch, EL_STR("B"))) { - return 1; - } - if (str_eq(ch, EL_STR("C"))) { - return 1; - } - if (str_eq(ch, EL_STR("D"))) { - return 1; - } - if (str_eq(ch, EL_STR("E"))) { - return 1; - } - if (str_eq(ch, EL_STR("F"))) { - return 1; - } - if (str_eq(ch, EL_STR("G"))) { - return 1; - } - if (str_eq(ch, EL_STR("H"))) { - return 1; - } - if (str_eq(ch, EL_STR("I"))) { - return 1; - } - if (str_eq(ch, EL_STR("J"))) { - return 1; - } - if (str_eq(ch, EL_STR("K"))) { - return 1; - } - if (str_eq(ch, EL_STR("L"))) { - return 1; - } - if (str_eq(ch, EL_STR("M"))) { - return 1; - } - if (str_eq(ch, EL_STR("N"))) { - return 1; - } - if (str_eq(ch, EL_STR("O"))) { - return 1; - } - if (str_eq(ch, EL_STR("P"))) { - return 1; - } - if (str_eq(ch, EL_STR("Q"))) { - return 1; - } - if (str_eq(ch, EL_STR("R"))) { - return 1; - } - if (str_eq(ch, EL_STR("S"))) { - return 1; - } - if (str_eq(ch, EL_STR("T"))) { - return 1; - } - if (str_eq(ch, EL_STR("U"))) { - return 1; - } - if (str_eq(ch, EL_STR("V"))) { - return 1; - } - if (str_eq(ch, EL_STR("W"))) { - return 1; - } - if (str_eq(ch, EL_STR("X"))) { - return 1; - } - if (str_eq(ch, EL_STR("Y"))) { - return 1; - } - if (str_eq(ch, EL_STR("Z"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_alnum_or_underscore(el_val_t ch) { - if (is_digit(ch)) { - return 1; - } - if (is_alpha(ch)) { - return 1; - } - if (str_eq(ch, EL_STR("_"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_whitespace(el_val_t ch) { - if (str_eq(ch, EL_STR(" "))) { - return 1; - } - if (str_eq(ch, EL_STR("\t"))) { - return 1; - } - if (str_eq(ch, EL_STR("\n"))) { - return 1; - } - if (str_eq(ch, EL_STR("\r"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t make_tok(el_val_t kind, el_val_t value) { - return el_map_new(2, "kind", kind, "value", value); - return 0; -} - -el_val_t keyword_kind(el_val_t word) { - if (str_eq(word, EL_STR("let"))) { - return EL_STR("Let"); - } - if (str_eq(word, EL_STR("fn"))) { - return EL_STR("Fn"); - } - if (str_eq(word, EL_STR("type"))) { - return EL_STR("Type"); - } - if (str_eq(word, EL_STR("enum"))) { - return EL_STR("Enum"); - } - if (str_eq(word, EL_STR("match"))) { - return EL_STR("Match"); - } - if (str_eq(word, EL_STR("return"))) { - return EL_STR("Return"); - } - if (str_eq(word, EL_STR("if"))) { - return EL_STR("If"); - } - if (str_eq(word, EL_STR("else"))) { - return EL_STR("Else"); - } - if (str_eq(word, EL_STR("for"))) { - return EL_STR("For"); - } - if (str_eq(word, EL_STR("in"))) { - return EL_STR("In"); - } - if (str_eq(word, EL_STR("while"))) { - return EL_STR("While"); - } - if (str_eq(word, EL_STR("import"))) { - return EL_STR("Import"); - } - if (str_eq(word, EL_STR("from"))) { - return EL_STR("From"); - } - if (str_eq(word, EL_STR("as"))) { - return EL_STR("As"); - } - if (str_eq(word, EL_STR("with"))) { - return EL_STR("With"); - } - if (str_eq(word, EL_STR("sealed"))) { - return EL_STR("Sealed"); - } - if (str_eq(word, EL_STR("activate"))) { - return EL_STR("Activate"); - } - if (str_eq(word, EL_STR("where"))) { - return EL_STR("Where"); - } - if (str_eq(word, EL_STR("test"))) { - return EL_STR("Test"); - } - if (str_eq(word, EL_STR("seed"))) { - return EL_STR("Seed"); - } - if (str_eq(word, EL_STR("assert"))) { - return EL_STR("Assert"); - } - if (str_eq(word, EL_STR("protocol"))) { - return EL_STR("Protocol"); - } - if (str_eq(word, EL_STR("impl"))) { - return EL_STR("Impl"); - } - if (str_eq(word, EL_STR("retry"))) { - return EL_STR("Retry"); - } - if (str_eq(word, EL_STR("times"))) { - return EL_STR("Times"); - } - if (str_eq(word, EL_STR("fallback"))) { - return EL_STR("Fallback"); - } - if (str_eq(word, EL_STR("reason"))) { - return EL_STR("Reason"); - } - if (str_eq(word, EL_STR("parallel"))) { - return EL_STR("Parallel"); - } - if (str_eq(word, EL_STR("trace"))) { - return EL_STR("Trace"); - } - if (str_eq(word, EL_STR("requires"))) { - return EL_STR("Requires"); - } - if (str_eq(word, EL_STR("deploy"))) { - return EL_STR("Deploy"); - } - if (str_eq(word, EL_STR("to"))) { - return EL_STR("To"); - } - if (str_eq(word, EL_STR("via"))) { - return EL_STR("Via"); - } - if (str_eq(word, EL_STR("target"))) { - return EL_STR("Target"); - } - if (str_eq(word, EL_STR("true"))) { - return EL_STR("Bool"); - } - if (str_eq(word, EL_STR("false"))) { - return EL_STR("Bool"); - } - if (str_eq(word, EL_STR("cgi"))) { - return EL_STR("Cgi"); - } - if (str_eq(word, EL_STR("service"))) { - return EL_STR("Service"); - } - if (str_eq(word, EL_STR("manager"))) { - return EL_STR("Manager"); - } - if (str_eq(word, EL_STR("engine"))) { - return EL_STR("Engine"); - } - if (str_eq(word, EL_STR("accessor"))) { - return EL_STR("Accessor"); - } - if (str_eq(word, EL_STR("vessel"))) { - return EL_STR("Vessel"); - } - return EL_STR(""); - return 0; -} - -el_val_t scan_digits(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t text = EL_STR(""); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (is_digit(ch)) { - text = el_str_concat(text, ch); - i = (i + 1); - } else { - running = 0; - } - } - } - return el_map_new(2, "text", text, "pos", i); - return 0; -} - -el_val_t scan_ident(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t text = EL_STR(""); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (is_alnum_or_underscore(ch)) { - text = el_str_concat(text, ch); - i = (i + 1); - } else { - running = 0; - } - } - } - return el_map_new(2, "text", text, "pos", i); - return 0; -} - -el_val_t scan_string(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t text = EL_STR(""); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\\"))) { - el_val_t next_i = (i + 1); - if (next_i < total) { - el_val_t next_ch = native_list_get(chars, next_i); - if (str_eq(next_ch, EL_STR("\""))) { - text = el_str_concat(text, EL_STR("\"")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("n"))) { - text = el_str_concat(text, EL_STR("\n")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("t"))) { - text = el_str_concat(text, EL_STR("\t")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("r"))) { - text = el_str_concat(text, EL_STR("\r")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("\\"))) { - text = el_str_concat(text, EL_STR("\\")); - i = (next_i + 1); - } else { - text = el_str_concat(text, next_ch); - i = (next_i + 1); - } - } - } - } - } - } else { - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("\""))) { - i = (i + 1); - running = 0; - } else { - text = el_str_concat(text, ch); - i = (i + 1); - } - } - } - } - return el_map_new(2, "text", text, "pos", i); - return 0; -} - -el_val_t lex(el_val_t source) { - el_val_t chars = native_string_chars(source); - el_val_t total = native_list_len(chars); - el_val_t tokens = native_list_empty(); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (is_whitespace(ch)) { - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("/"))) { - el_val_t next_i = (i + 1); - if (next_i < total) { - el_val_t next_ch = native_list_get(chars, next_i); - if (str_eq(next_ch, EL_STR("/"))) { - i = (i + 2); - el_val_t running2 = 1; - while (running2) { - if (i >= total) { - running2 = 0; - } else { - el_val_t lch = native_list_get(chars, i); - if (str_eq(lch, EL_STR("\n"))) { - running2 = 0; - } else { - i = (i + 1); - } - } - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Slash"), EL_STR("/"))); - i = (i + 1); - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Slash"), EL_STR("/"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("\""))) { - el_val_t result = scan_string(chars, (i + 1), total); - el_val_t str_text = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - tokens = native_list_append(tokens, make_tok(EL_STR("Str"), str_text)); - i = new_pos; - } else { - if (is_digit(ch)) { - el_val_t result = scan_digits(chars, i, total); - el_val_t num_text = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - if (new_pos < total) { - el_val_t dot_ch = native_list_get(chars, new_pos); - if (str_eq(dot_ch, EL_STR("."))) { - el_val_t after_dot = (new_pos + 1); - if (after_dot < total) { - el_val_t after_dot_ch = native_list_get(chars, after_dot); - if (is_digit(after_dot_ch)) { - el_val_t frac_result = scan_digits(chars, after_dot, total); - el_val_t frac_text = el_get_field(frac_result, EL_STR("text")); - el_val_t frac_pos = el_get_field(frac_result, EL_STR("pos")); - tokens = native_list_append(tokens, make_tok(EL_STR("Float"), el_str_concat(el_str_concat(num_text, EL_STR(".")), frac_text))); - i = frac_pos; - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - if (is_alpha(ch) || str_eq(ch, EL_STR("_"))) { - el_val_t result = scan_ident(chars, i, total); - el_val_t word = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - el_val_t kw = keyword_kind(word); - if (str_eq(kw, EL_STR(""))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Ident"), word)); - } else { - tokens = native_list_append(tokens, make_tok(kw, word)); - } - i = new_pos; - } else { - el_val_t peek_i = (i + 1); - el_val_t peek_ch = EL_STR(""); - if (peek_i < total) { - peek_ch = native_list_get(chars, peek_i); - } - if (str_eq(ch, EL_STR("="))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("EqEq"), EL_STR("=="))); - i = (i + 2); - } else { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("FatArrow"), EL_STR("=>"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Eq"), EL_STR("="))); - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("!"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("NotEq"), EL_STR("!="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Not"), EL_STR("!"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("<"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LtEq"), EL_STR("<="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Lt"), EL_STR("<"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR(">"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("GtEq"), EL_STR(">="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Gt"), EL_STR(">"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("&"))) { - if (str_eq(peek_ch, EL_STR("&"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("And"), EL_STR("&&"))); - i = (i + 2); - } else { - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("|"))) { - if (str_eq(peek_ch, EL_STR("|"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Or"), EL_STR("||"))); - i = (i + 2); - } else { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("PipeOp"), EL_STR("|>"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Pipe"), EL_STR("|"))); - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("-"))) { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Arrow"), EL_STR("->"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Minus"), EL_STR("-"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR(":"))) { - if (str_eq(peek_ch, EL_STR(":"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("ColonColon"), EL_STR("::"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Colon"), EL_STR(":"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("+"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Plus"), EL_STR("+"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("*"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Star"), EL_STR("*"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("%"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Percent"), EL_STR("%"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("("))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LParen"), EL_STR("("))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(")"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RParen"), EL_STR(")"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("{"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LBrace"), EL_STR("{"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("}"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RBrace"), EL_STR("}"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("["))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LBracket"), EL_STR("["))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("]"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RBracket"), EL_STR("]"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(","))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Comma"), EL_STR(","))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("."))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Dot"), EL_STR("."))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(";"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Semicolon"), EL_STR(";"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("@"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("At"), EL_STR("@"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("?"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("QuestionMark"), EL_STR("?"))); - i = (i + 1); - } else { - i = (i + 1); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - tokens = native_list_append(tokens, make_tok(EL_STR("Eof"), EL_STR(""))); - return tokens; - return 0; -} - -el_val_t tok_at(el_val_t tokens, el_val_t pos) { - return native_list_get(tokens, pos); - return 0; -} - -el_val_t tok_kind(el_val_t tokens, el_val_t pos) { - el_val_t t = native_list_get(tokens, pos); - return el_get_field(t, EL_STR("kind")); - return 0; -} - -el_val_t tok_value(el_val_t tokens, el_val_t pos) { - el_val_t t = native_list_get(tokens, pos); - return el_get_field(t, EL_STR("value")); - return 0; -} - -el_val_t expect(el_val_t tokens, el_val_t pos, el_val_t kind) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, kind)) { - return (pos + 1); - } - return (pos + 1); - return 0; -} - -el_val_t make_result(el_val_t node, el_val_t pos) { - return el_map_new(2, "node", node, "pos", pos); - return 0; -} - -el_val_t skip_type(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t p = (pos + 1); - p = skip_type(tokens, p); - p = expect(tokens, p, EL_STR("RBracket")); - return p; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Lt"))) { - p = (p + 1); - el_val_t depth = 1; - el_val_t running = 1; - while (running) { - el_val_t kk = tok_kind(tokens, p); - if (str_eq(kk, EL_STR("Eof"))) { - running = 0; - } else { - if (str_eq(kk, EL_STR("Lt"))) { - depth = (depth + 1); - p = (p + 1); - } else { - if (str_eq(kk, EL_STR("Gt"))) { - depth = (depth - 1); - p = (p + 1); - if (depth <= 0) { - running = 0; - } - } else { - p = (p + 1); - } - } - } - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("QuestionMark"))) { - p = (p + 1); - } - return p; - } - if (str_eq(k2, EL_STR("QuestionMark"))) { - return (p + 1); - } - return p; - } - return (pos + 1); - return 0; -} - -el_val_t parse_params(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("LParen")); - el_val_t params = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RParen"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t pname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t ptype = EL_STR(""); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ptype = tok_value(tokens, p); - } - p = skip_type(tokens, p); - el_val_t param = el_map_new(2, "name", pname, "type", ptype); - params = native_list_append(params, param); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RParen")); - return el_map_new(2, "params", params, "pos", p); - return 0; -} - -el_val_t parse_primary(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - el_val_t v = tok_value(tokens, pos); - if (str_eq(k, EL_STR("Int"))) { - return make_result(el_map_new(2, "expr", EL_STR("Int"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Float"))) { - return make_result(el_map_new(2, "expr", EL_STR("Float"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Str"))) { - return make_result(el_map_new(2, "expr", EL_STR("Str"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Bool"))) { - return make_result(el_map_new(2, "expr", EL_STR("Bool"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Ident"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("LParen"))) { - el_val_t r = parse_expr(tokens, (pos + 1)); - el_val_t node = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - p = expect(tokens, p, EL_STR("RParen")); - return make_result(node, p); - } - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t p = (pos + 1); - el_val_t elems = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBracket"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_expr(tokens, p); - el_val_t elem = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - elems = native_list_append(elems, elem); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBracket")); - return make_result(el_map_new(2, "expr", EL_STR("Array"), "elems", elems), p); - } - if (str_eq(k, EL_STR("LBrace"))) { - el_val_t no_block = state_get(EL_STR("__no_block_expr")); - if (str_eq(no_block, EL_STR("1"))) { - return make_result(el_map_new(1, "expr", EL_STR("Nil")), pos); - } - el_val_t p = (pos + 1); - el_val_t pairs = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t key = tok_value(tokens, p); - el_val_t new_p = (p + 1); - new_p = expect(tokens, new_p, EL_STR("Colon")); - el_val_t r = parse_expr(tokens, new_p); - el_val_t val_node = el_get_field(r, EL_STR("node")); - new_p = el_get_field(r, EL_STR("pos")); - el_val_t pair = el_map_new(2, "key", key, "value", val_node); - pairs = native_list_append(pairs, pair); - el_val_t k3 = tok_kind(tokens, new_p); - if (str_eq(k3, EL_STR("Comma"))) { - new_p = (new_p + 1); - } - if (new_p <= p) { - p = (p + 1); - } else { - p = new_p; - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(2, "expr", EL_STR("Map"), "pairs", pairs), p); - } - if (str_eq(k, EL_STR("If"))) { - el_val_t r = parse_if(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("Match"))) { - el_val_t r = parse_match(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("For"))) { - el_val_t r = parse_for_expr(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("Not"))) { - el_val_t r = parse_primary(tokens, (pos + 1)); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "expr", EL_STR("Not"), "inner", inner), p); - } - if (str_eq(k, EL_STR("Minus"))) { - el_val_t r = parse_primary(tokens, (pos + 1)); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "expr", EL_STR("Neg"), "inner", inner), p); - } - if (str_eq(k, EL_STR("Target"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("To"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Via"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Deploy"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Reason"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Times"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Fallback"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Retry"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Parallel"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Trace"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Requires"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Where"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("As"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("With"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Manager"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Engine"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Accessor"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Vessel"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - return make_result(el_map_new(1, "expr", EL_STR("Nil")), (pos + 1)); - return 0; -} - -el_val_t parse_if(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("If")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t cond = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t then_stmts = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - el_val_t has_else = 0; - el_val_t else_stmts = native_list_empty(); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Else"))) { - p = (p + 1); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("If"))) { - el_val_t r3 = parse_if(tokens, p); - el_val_t nested = el_get_field(r3, EL_STR("node")); - p = el_get_field(r3, EL_STR("pos")); - else_stmts = native_list_append(else_stmts, el_map_new(2, "stmt", EL_STR("Expr"), "value", nested)); - has_else = 1; - } else { - el_val_t r3 = parse_block(tokens, p); - else_stmts = el_get_field(r3, EL_STR("stmts")); - p = el_get_field(r3, EL_STR("pos")); - has_else = 1; - } - } - return make_result(el_map_new(5, "expr", EL_STR("If"), "cond", cond, "then", then_stmts, "else", else_stmts, "has_else", has_else), p); - return 0; -} - -el_val_t parse_match(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("Match")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t subject = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t arms = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r2 = parse_pattern(tokens, p); - el_val_t pattern = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - p = expect(tokens, p, EL_STR("FatArrow")); - el_val_t r3 = parse_expr(tokens, p); - el_val_t body = el_get_field(r3, EL_STR("node")); - p = el_get_field(r3, EL_STR("pos")); - el_val_t arm = el_map_new(2, "pattern", pattern, "body", body); - arms = native_list_append(arms, arm); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "expr", EL_STR("Match"), "subject", subject, "arms", arms), p); - return 0; -} - -el_val_t parse_pattern(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Ident"))) { - el_val_t v = tok_value(tokens, pos); - if (str_eq(v, EL_STR("_"))) { - return make_result(el_map_new(1, "pattern", EL_STR("Wildcard")), (pos + 1)); - } - return make_result(el_map_new(2, "pattern", EL_STR("Binding"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Int"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitInt"), "value", tok_value(tokens, pos)), (pos + 1)); - } - if (str_eq(k, EL_STR("Str"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitStr"), "value", tok_value(tokens, pos)), (pos + 1)); - } - if (str_eq(k, EL_STR("Bool"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitBool"), "value", tok_value(tokens, pos)), (pos + 1)); - } - return make_result(el_map_new(1, "pattern", EL_STR("Wildcard")), (pos + 1)); - return 0; -} - -el_val_t parse_for_expr(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("For")); - el_val_t item_name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("In")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t list_expr = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(4, "expr", EL_STR("For"), "item", item_name, "list", list_expr, "body", body), p); - return 0; -} - -el_val_t parse_block(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("LBrace")); - el_val_t stmts = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_stmt(tokens, p); - el_val_t stmt = el_get_field(r, EL_STR("node")); - el_val_t new_p = el_get_field(r, EL_STR("pos")); - stmts = native_list_append(stmts, stmt); - if (new_p <= p) { - p = (p + 1); - } else { - p = new_p; - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return el_map_new(2, "stmts", stmts, "pos", p); - return 0; -} - -el_val_t parse_postfix(el_val_t tokens, el_val_t pos) { - el_val_t r = parse_primary(tokens, pos); - el_val_t node = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("LParen"))) { - p = (p + 1); - el_val_t args = native_list_empty(); - el_val_t run2 = 1; - while (run2) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RParen"))) { - run2 = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - run2 = 0; - } else { - el_val_t r2 = parse_expr(tokens, p); - el_val_t arg = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - args = native_list_append(args, arg); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RParen")); - node = el_map_new(3, "expr", EL_STR("Call"), "func", node, "args", args); - } else { - if (str_eq(k, EL_STR("Dot"))) { - el_val_t field = tok_value(tokens, (p + 1)); - p = (p + 2); - node = el_map_new(3, "expr", EL_STR("Field"), "object", node, "field", field); - } else { - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t r2 = parse_expr(tokens, (p + 1)); - el_val_t idx = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - p = expect(tokens, p, EL_STR("RBracket")); - node = el_map_new(3, "expr", EL_STR("Index"), "object", node, "index", idx); - } else { - if (str_eq(k, EL_STR("QuestionMark"))) { - p = (p + 1); - node = el_map_new(2, "expr", EL_STR("Try"), "inner", node); - } else { - running = 0; - } - } - } - } - } - return make_result(node, p); - return 0; -} - -el_val_t op_precedence(el_val_t kind) { - if (str_eq(kind, EL_STR("Or"))) { - return 1; - } - if (str_eq(kind, EL_STR("And"))) { - return 2; - } - if (str_eq(kind, EL_STR("EqEq"))) { - return 3; - } - if (str_eq(kind, EL_STR("NotEq"))) { - return 3; - } - if (str_eq(kind, EL_STR("Lt"))) { - return 4; - } - if (str_eq(kind, EL_STR("Gt"))) { - return 4; - } - if (str_eq(kind, EL_STR("LtEq"))) { - return 4; - } - if (str_eq(kind, EL_STR("GtEq"))) { - return 4; - } - if (str_eq(kind, EL_STR("Plus"))) { - return 5; - } - if (str_eq(kind, EL_STR("Minus"))) { - return 5; - } - if (str_eq(kind, EL_STR("Star"))) { - return 6; - } - if (str_eq(kind, EL_STR("Slash"))) { - return 6; - } - return 0; - return 0; -} - -el_val_t is_binop(el_val_t kind) { - if (str_eq(kind, EL_STR("Or"))) { - return 1; - } - if (str_eq(kind, EL_STR("And"))) { - return 1; - } - if (str_eq(kind, EL_STR("EqEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("NotEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("Lt"))) { - return 1; - } - if (str_eq(kind, EL_STR("Gt"))) { - return 1; - } - if (str_eq(kind, EL_STR("LtEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("GtEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("Plus"))) { - return 1; - } - if (str_eq(kind, EL_STR("Minus"))) { - return 1; - } - if (str_eq(kind, EL_STR("Star"))) { - return 1; - } - if (str_eq(kind, EL_STR("Slash"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t parse_binop(el_val_t tokens, el_val_t pos, el_val_t min_prec) { - el_val_t r = parse_postfix(tokens, pos); - el_val_t left = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - el_val_t prec = op_precedence(k); - if (is_binop(k)) { - if (prec >= min_prec) { - el_val_t op = k; - el_val_t r2 = parse_binop(tokens, (p + 1), (prec + 1)); - el_val_t right = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - left = el_map_new(4, "expr", EL_STR("BinOp"), "op", op, "left", left, "right", right); - } else { - running = 0; - } - } else { - running = 0; - } - } - return make_result(left, p); - return 0; -} - -el_val_t parse_expr(el_val_t tokens, el_val_t pos) { - return parse_binop(tokens, pos, 1); - return 0; -} - -el_val_t parse_stmt(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Let"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t ltype = EL_STR(""); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Colon"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ltype = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - p = expect(tokens, p, EL_STR("Eq")); - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(4, "stmt", EL_STR("Let"), "name", name, "value", val, "type", ltype), p); - } - if (str_eq(k, EL_STR("Return"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", el_map_new(1, "expr", EL_STR("Nil"))), p); - } - if (str_eq(k2, EL_STR("Eof"))) { - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", el_map_new(1, "expr", EL_STR("Nil"))), p); - } - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", val), p); - } - if (str_eq(k, EL_STR("Fn"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_params(tokens, p); - el_val_t params = el_get_field(r, EL_STR("params")); - p = el_get_field(r, EL_STR("pos")); - el_val_t ret_type = EL_STR(""); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Arrow"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ret_type = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(5, "stmt", EL_STR("FnDef"), "name", name, "params", params, "body", body, "ret_type", ret_type), p); - } - if (str_eq(k, EL_STR("Type"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t fields = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - p = skip_type(tokens, p); - fields = native_list_append(fields, el_map_new(1, "name", fname)); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "stmt", EL_STR("TypeDef"), "name", name, "fields", fields), p); - } - if (str_eq(k, EL_STR("Enum"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t variants = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t vname = tok_value(tokens, p); - p = (p + 1); - variants = native_list_append(variants, el_map_new(1, "name", vname)); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "stmt", EL_STR("EnumDef"), "name", name, "variants", variants), p); - } - if (str_eq(k, EL_STR("Import"))) { - el_val_t p = (pos + 1); - el_val_t path = tok_value(tokens, p); - p = (p + 1); - return make_result(el_map_new(2, "stmt", EL_STR("Import"), "path", path), p); - } - if (str_eq(k, EL_STR("From"))) { - el_val_t p = (pos + 1); - el_val_t module_name = tok_value(tokens, p); - p = (p + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Import"))) { - p = (p + 1); - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("LBrace"))) { - p = (p + 1); - el_val_t running = 1; - while (running) { - el_val_t k4 = tok_kind(tokens, p); - if (str_eq(k4, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k4, EL_STR("Eof"))) { - running = 0; - } else { - p = (p + 1); - el_val_t k5 = tok_kind(tokens, p); - if (str_eq(k5, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - } - return make_result(el_map_new(2, "stmt", EL_STR("Import"), "path", module_name), p); - } - if (str_eq(k, EL_STR("While"))) { - el_val_t p = (pos + 1); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t cond = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(3, "stmt", EL_STR("While"), "cond", cond, "body", body), p); - } - if (str_eq(k, EL_STR("For"))) { - el_val_t p = (pos + 1); - el_val_t item_name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("In")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t list_expr = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(4, "stmt", EL_STR("For"), "item", item_name, "list", list_expr, "body", body), p); - } - if (str_eq(k, EL_STR("At"))) { - el_val_t p = (pos + 1); - el_val_t dec_name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_stmt(tokens, p); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p2 = el_get_field(r, EL_STR("pos")); - el_val_t inner_kind = el_get_field(inner, EL_STR("stmt")); - if (str_eq(inner_kind, EL_STR("FnDef"))) { - el_val_t with_dec = el_map_new(6, "stmt", EL_STR("FnDef"), "name", el_get_field(inner, EL_STR("name")), "params", el_get_field(inner, EL_STR("params")), "body", el_get_field(inner, EL_STR("body")), "ret_type", el_get_field(inner, EL_STR("ret_type")), "decorator", dec_name); - return make_result(with_dec, p2); - } - return r; - } - if (str_eq(k, EL_STR("Cgi"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t dharma_id = EL_STR(""); - el_val_t principal = EL_STR(""); - el_val_t network = EL_STR(""); - el_val_t engram = EL_STR(""); - el_val_t has_dharma_id = 0; - el_val_t has_principal = 0; - el_val_t has_network = 0; - el_val_t has_engram = 0; - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t fval = tok_value(tokens, p); - p = (p + 1); - if (str_eq(fname, EL_STR("dharma_id"))) { - dharma_id = fval; - has_dharma_id = 1; - } - if (str_eq(fname, EL_STR("principal"))) { - principal = fval; - has_principal = 1; - } - if (str_eq(fname, EL_STR("network"))) { - network = fval; - has_network = 1; - } - if (str_eq(fname, EL_STR("engram"))) { - engram = fval; - has_engram = 1; - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(10, "stmt", EL_STR("CgiBlock"), "name", name, "dharma_id", dharma_id, "principal", principal, "network", network, "engram", engram, "has_dharma_id", has_dharma_id, "has_principal", has_principal, "has_network", has_network, "has_engram", has_engram), p); - } - if (str_eq(k, EL_STR("Service"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t sponsor = EL_STR(""); - el_val_t domain = EL_STR(""); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t fval = tok_value(tokens, p); - p = (p + 1); - if (str_eq(fname, EL_STR("sponsor"))) { - sponsor = fval; - } - if (str_eq(fname, EL_STR("domain"))) { - domain = fval; - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(4, "stmt", EL_STR("ServiceBlock"), "name", name, "sponsor", sponsor, "domain", domain), p); - } - el_val_t r = parse_expr(tokens, pos); - el_val_t val = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "stmt", EL_STR("Expr"), "value", val), p); - return 0; -} - -el_val_t parse(el_val_t tokens) { - el_val_t total = native_list_len(tokens); - el_val_t stmts = native_list_empty(); - el_val_t pos = 0; - el_val_t running = 1; - while (running) { - if (pos >= total) { - running = 0; - } else { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_stmt(tokens, pos); - el_val_t stmt = el_get_field(r, EL_STR("node")); - el_val_t new_pos = el_get_field(r, EL_STR("pos")); - stmts = native_list_append(stmts, stmt); - if (new_pos <= pos) { - pos = (pos + 1); - } else { - pos = new_pos; - } - } - } - } - return stmts; - return 0; -} - -el_val_t c_escape(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\""))) { - out = el_str_concat(out, EL_STR("\\\"")); - } else { - if (str_eq(ch, EL_STR("\\"))) { - out = el_str_concat(out, EL_STR("\\\\")); - } else { - if (str_eq(ch, EL_STR("\n"))) { - out = el_str_concat(out, EL_STR("\\n")); - } else { - if (str_eq(ch, EL_STR("\r"))) { - out = el_str_concat(out, EL_STR("\\r")); - } else { - if (str_eq(ch, EL_STR("\t"))) { - out = el_str_concat(out, EL_STR("\\t")); - } else { - out = el_str_concat(out, ch); - } - } - } - } - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t c_str_lit(el_val_t s) { - return el_str_concat(el_str_concat(EL_STR("\""), c_escape(s)), EL_STR("\"")); - return 0; -} - -el_val_t el_type_to_c(el_val_t type_str) { - if (str_eq(type_str, EL_STR("String"))) { - return EL_STR("const char*"); - } - if (str_eq(type_str, EL_STR("Int"))) { - return EL_STR("int64_t"); - } - if (str_eq(type_str, EL_STR("Bool"))) { - return EL_STR("int"); - } - if (str_eq(type_str, EL_STR("Float"))) { - return EL_STR("double"); - } - if (str_eq(type_str, EL_STR("Void"))) { - return EL_STR("void"); - } - if (str_eq(type_str, EL_STR("void"))) { - return EL_STR("void"); - } - return EL_STR("void*"); - return 0; -} - -el_val_t emit_line(el_val_t line) { - println(line); - return 0; -} - -el_val_t emit_blank(void) { - println(EL_STR("")); - return 0; -} - -el_val_t binop_to_c(el_val_t op) { - if (str_eq(op, EL_STR("Plus"))) { - return EL_STR("+"); - } - if (str_eq(op, EL_STR("Minus"))) { - return EL_STR("-"); - } - if (str_eq(op, EL_STR("Star"))) { - return EL_STR("*"); - } - if (str_eq(op, EL_STR("Slash"))) { - return EL_STR("/"); - } - if (str_eq(op, EL_STR("EqEq"))) { - return EL_STR("=="); - } - if (str_eq(op, EL_STR("NotEq"))) { - return EL_STR("!="); - } - if (str_eq(op, EL_STR("Lt"))) { - return EL_STR("<"); - } - if (str_eq(op, EL_STR("Gt"))) { - return EL_STR(">"); - } - if (str_eq(op, EL_STR("LtEq"))) { - return EL_STR("<="); - } - if (str_eq(op, EL_STR("GtEq"))) { - return EL_STR(">="); - } - if (str_eq(op, EL_STR("And"))) { - return EL_STR("&&"); - } - if (str_eq(op, EL_STR("Or"))) { - return EL_STR("||"); - } - return op; - return 0; -} - -el_val_t cg_expr(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Int"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("Float"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("el_from_float("), v), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Str"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(v)), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Bool"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - if (str_eq(v, EL_STR("true"))) { - return EL_STR("1"); - } - return EL_STR("0"); - } - if (str_eq(kind, EL_STR("Nil"))) { - return EL_STR("EL_NULL"); - } - if (str_eq(kind, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return name; - } - if (str_eq(kind, EL_STR("Not"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = cg_expr(inner); - return el_str_concat(EL_STR("!"), inner_c); - } - if (str_eq(kind, EL_STR("Neg"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = cg_expr(inner); - return el_str_concat(el_str_concat(EL_STR("(-"), inner_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - el_val_t left = el_get_field(expr, EL_STR("left")); - el_val_t right = el_get_field(expr, EL_STR("right")); - el_val_t left_c = cg_expr(left); - el_val_t right_c = cg_expr(right); - el_val_t left_kind = el_get_field(left, EL_STR("expr")); - el_val_t right_kind = el_get_field(right, EL_STR("expr")); - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Int"))) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("BinOp"))) { - el_val_t left_op = el_get_field(left, EL_STR("op")); - if (str_eq(left_op, EL_STR("Plus"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(right_kind, EL_STR("BinOp"))) { - el_val_t right_op = el_get_field(right, EL_STR("op")); - if (str_eq(right_op, EL_STR("Plus"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (is_int_name(lname)) { - if (is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (is_int_name(lname)) { - if (is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t arity = native_list_len(args); - el_val_t func_kind = el_get_field(func, EL_STR("expr")); - el_val_t args_c = EL_STR(""); - el_val_t i = 0; - while (i < arity) { - el_val_t arg = native_list_get(args, i); - el_val_t arg_c = cg_expr(arg); - if (i > 0) { - args_c = el_str_concat(args_c, EL_STR(", ")); - } - args_c = el_str_concat(args_c, arg_c); - i = (i + 1); - } - if (str_eq(func_kind, EL_STR("Ident"))) { - el_val_t fn_name = el_get_field(func, EL_STR("name")); - cap_check_call(fn_name); - arity_check_call(fn_name, arity); - return el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(func_kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(func, EL_STR("object")); - el_val_t field = el_get_field(func, EL_STR("field")); - el_val_t obj_c = cg_expr(obj); - if (arity > 0) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(", ")), args_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(")")); - } - el_val_t fn_c = cg_expr(func); - return el_str_concat(el_str_concat(el_str_concat(fn_c, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t field = el_get_field(expr, EL_STR("field")); - el_val_t obj_c = cg_expr(obj); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", EL_STR(")), c_str_lit(field)), EL_STR("))")); - } - if (str_eq(kind, EL_STR("Index"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t idx = el_get_field(expr, EL_STR("index")); - el_val_t obj_c = cg_expr(obj); - el_val_t idx_c = cg_expr(idx); - el_val_t idx_kind = el_get_field(idx, EL_STR("expr")); - if (str_eq(idx_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_get("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - if (n == 0) { - return EL_STR("el_list_empty()"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t elem = native_list_get(elems, i); - el_val_t elem_c = cg_expr(elem); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(items, elem_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_new("), native_int_to_str(n)), EL_STR(", ")), items), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - if (n == 0) { - return EL_STR("el_map_new(0)"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t key = el_get_field(pair, EL_STR("key")); - el_val_t val = el_get_field(pair, EL_STR("value")); - el_val_t val_c = cg_expr(val); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(el_str_concat(el_str_concat(items, c_str_lit(key)), EL_STR(", ")), val_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_map_new("), native_int_to_str(n)), EL_STR(", ")), items), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Try"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - return cg_expr(inner); - } - if (str_eq(kind, EL_STR("If"))) { - return cg_if_expr(expr); - } - if (str_eq(kind, EL_STR("Match"))) { - return cg_match(expr); - } - return EL_STR("EL_NULL"); - return 0; -} - -el_val_t next_match_id(void) { - el_val_t csv = state_get(EL_STR("__match_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__match_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t cg_match(el_val_t expr) { - el_val_t subject = el_get_field(expr, EL_STR("subject")); - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t subj_c = cg_expr(subject); - el_val_t id = next_match_id(); - el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id); - el_val_t result_var = el_str_concat(EL_STR("_match_result_"), id); - el_val_t done_label = el_str_concat(EL_STR("_match_done_"), id); - el_val_t out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), subj_var), EL_STR(" = ")), subj_c), EL_STR("; el_val_t ")), result_var), EL_STR(" = 0; ")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t pat = el_get_field(arm, EL_STR("pattern")); - el_val_t body = el_get_field(arm, EL_STR("body")); - el_val_t pkind = el_get_field(pat, EL_STR("pattern")); - el_val_t body_c = cg_expr(body); - if (str_eq(pkind, EL_STR("Wildcard"))) { - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("Binding"))) { - el_val_t bname = el_get_field(pat, EL_STR("name")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ el_val_t ")), bname), EL_STR(" = ")), subj_var), EL_STR("; ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("LitInt"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" == ")), v), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("LitStr"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (str_eq(")), subj_var), EL_STR(", EL_STR(")), c_str_lit(v)), EL_STR("))) { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("LitBool"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - el_val_t bv = EL_STR("0"); - if (str_eq(v, EL_STR("true"))) { - bv = EL_STR("1"); - } - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" == ")), bv), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } - } - } - } - } - i = (i + 1); - } - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, done_label), EL_STR(":; ")), result_var), EL_STR("; })")); - return out; - return 0; -} - -el_val_t next_if_id(void) { - el_val_t csv = state_get(EL_STR("__if_expr_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__if_expr_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t cg_if_expr_arm(el_val_t stmts, el_val_t result_var) { - el_val_t n = native_list_len(stmts); - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t s = native_list_get(stmts, i); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - el_val_t is_last = 0; - if (str_eq(i, (n - 1))) { - is_last = 1; - } - if (str_eq(sk, EL_STR("Let"))) { - el_val_t name = el_get_field(s, EL_STR("name")); - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("el_val_t ")), name), EL_STR(" = ")), val_c), EL_STR("; ")); - } else { - if (str_eq(sk, EL_STR("Return"))) { - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, result_var), EL_STR(" = (")), val_c), EL_STR("); ")); - } else { - if (str_eq(sk, EL_STR("Expr"))) { - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - if (is_last) { - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, result_var), EL_STR(" = (")), val_c), EL_STR("); ")); - } else { - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("(void)(")), val_c), EL_STR("); ")); - } - } else { - } - } - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t cg_if_expr(el_val_t expr) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = cg_expr(cond); - el_val_t id = next_if_id(); - el_val_t result_var = el_str_concat(EL_STR("_if_result_"), id); - el_val_t then_c = cg_if_expr_arm(then_stmts, result_var); - el_val_t else_c = EL_STR(""); - if (has_else) { - else_c = cg_if_expr_arm(else_stmts, result_var); - } - el_val_t out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), result_var), EL_STR(" = 0; if (")), cond_c), EL_STR(") { ")), then_c), EL_STR("} else { ")), else_c), EL_STR("} ")), result_var), EL_STR("; })")); - return out; - return 0; -} - -el_val_t list_contains(el_val_t lst, el_val_t s) { - el_val_t n = native_list_len(lst); - el_val_t i = 0; - while (i < n) { - el_val_t item = native_list_get(lst, i); - if (str_eq(item, s)) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = cg_expr(val); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - add_int_name(name); - } - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - add_int_name(name); - } - if (list_contains(declared, name)) { - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } else { - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("el_val_t ")), name), EL_STR(" = ")), val_c), EL_STR(";"))); - return native_list_append(declared, name); - } - } - if (str_eq(kind, EL_STR("Return"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("Nil"))) { - emit_line(el_str_concat(indent, EL_STR("return 0;"))); - } else { - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("return ")), val_c), EL_STR(";"))); - } - return declared; - } - if (str_eq(kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - cg_if_stmt(val, indent, declared); - return declared; - } - if (str_eq(val_kind, EL_STR("For"))) { - cg_for_stmt(val, indent, declared); - return declared; - } - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(indent, val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("While"))) { - el_val_t cond = el_get_field(stmt, EL_STR("cond")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t cond_c = cg_expr(cond); - cond_c = strip_outer_parens(cond_c); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("while (")), cond_c), EL_STR(") {"))); - cg_stmts(body, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - emit_line(el_str_concat(indent, EL_STR("}"))); - return declared; - } - if (str_eq(kind, EL_STR("For"))) { - el_val_t item = el_get_field(stmt, EL_STR("item")); - el_val_t list_expr = el_get_field(stmt, EL_STR("list")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - cg_for_body(item, list_expr, body, indent, declared); - return declared; - } - if (str_eq(kind, EL_STR("FnDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("TypeDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("Import"))) { - return declared; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return declared; - } - return declared; - return 0; -} - -el_val_t strip_outer_parens(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t n = native_list_len(chars); - if (n < 2) { - return s; - } - el_val_t first = native_list_get(chars, 0); - el_val_t last = native_list_get(chars, (n - 1)); - if (str_eq(first, EL_STR("("))) { - if (str_eq(last, EL_STR(")"))) { - el_val_t depth = 1; - el_val_t i = 1; - el_val_t balanced = 1; - while (i < (n - 1)) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("("))) { - depth = (depth + 1); - } - if (str_eq(ch, EL_STR(")"))) { - depth = (depth - 1); - if (depth == 0) { - balanced = 0; - i = n; - } - } - i = (i + 1); - } - if (balanced) { - el_val_t inner = EL_STR(""); - el_val_t j = 1; - while (j < (n - 1)) { - el_val_t ch = native_list_get(chars, j); - inner = el_str_concat(inner, ch); - j = (j + 1); - } - return inner; - } - } - } - return s; - return 0; -} - -el_val_t cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = cg_expr(cond); - cond_c = strip_outer_parens(cond_c); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("if (")), cond_c), EL_STR(") {"))); - cg_stmts(then_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - if (has_else) { - emit_line(el_str_concat(indent, EL_STR("} else {"))); - cg_stmts(else_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - } - emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared) { - el_val_t list_c = cg_expr(list_expr); - el_val_t idx = EL_STR("_el_i"); - el_val_t list_tmp = EL_STR("_el_lst"); - el_val_t len_tmp = EL_STR("_el_len"); - emit_line(el_str_concat(indent, EL_STR("{"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), list_tmp), EL_STR(" = ")), list_c), EL_STR(";"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), len_tmp), EL_STR(" = el_list_len(")), list_tmp), EL_STR(");"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" for (el_val_t ")), idx), EL_STR(" = 0; ")), idx), EL_STR(" < ")), len_tmp), EL_STR("; ")), idx), EL_STR("++) {"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), item), EL_STR(" = el_list_get(")), list_tmp), EL_STR(", ")), idx), EL_STR(");"))); - el_val_t body_decl = native_list_clone(declared); - body_decl = native_list_append(body_decl, item); - cg_stmts(body, el_str_concat(indent, EL_STR(" ")), body_decl); - emit_line(el_str_concat(indent, EL_STR(" }"))); - emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t item = el_get_field(expr, EL_STR("item")); - el_val_t list_expr = el_get_field(expr, EL_STR("list")); - el_val_t body = el_get_field(expr, EL_STR("body")); - cg_for_body(item, list_expr, body, indent, declared); - return 0; -} - -el_val_t cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t decl = declared; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - decl = cg_stmt(stmt, indent, decl); - i = (i + 1); - } - return decl; - return 0; -} - -el_val_t param_decl(el_val_t param, el_val_t idx) { - el_val_t name = el_get_field(param, EL_STR("name")); - return el_str_concat(EL_STR("el_val_t "), name); - return 0; -} - -el_val_t params_to_c(el_val_t params) { - el_val_t n = native_list_len(params); - if (n == 0) { - return EL_STR("void"); - } - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t param = native_list_get(params, i); - el_val_t decl = param_decl(param, i); - if (i > 0) { - out = el_str_concat(out, EL_STR(", ")); - } - out = el_str_concat(out, decl); - i = (i + 1); - } - return out; - return 0; -} - -el_val_t transform_implicit_return(el_val_t body) { - el_val_t n = native_list_len(body); - if (n == 0) { - return body; - } - el_val_t last = native_list_get(body, (n - 1)); - el_val_t last_kind = el_get_field(last, EL_STR("stmt")); - if (str_eq(last_kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(last, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - return body; - } - if (str_eq(val_kind, EL_STR("For"))) { - return body; - } - el_val_t new_body = native_list_empty(); - el_val_t i = 0; - while (i < (n - 1)) { - new_body = native_list_append(new_body, native_list_get(body, i)); - i = (i + 1); - } - el_val_t return_stmt = el_map_new(2, "stmt", EL_STR("Return"), "value", val); - new_body = native_list_append(new_body, return_stmt); - return new_body; - } - return body; - return 0; -} - -el_val_t is_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__int_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_int_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 1; - } - if (str_eq(name, EL_STR("json_array_len"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_node_count"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_edge_count"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("time_diff"))) { - return 1; - } - if (str_eq(name, EL_STR("time_add"))) { - return 1; - } - if (str_eq(name, EL_STR("time_from_parts"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 1; - } - if (str_eq(name, EL_STR("el_min"))) { - return 1; - } - if (str_eq(name, EL_STR("float_to_int"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_int_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Int"))) { - return 1; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_int_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_int_call(expr); - } - if (str_eq(k, EL_STR("Neg"))) { - return is_int_expr(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(k, EL_STR("Not"))) { - return 1; - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("EqEq"))) { - return 1; - } - if (str_eq(op, EL_STR("NotEq"))) { - return 1; - } - if (str_eq(op, EL_STR("Lt"))) { - return 1; - } - if (str_eq(op, EL_STR("Gt"))) { - return 1; - } - if (str_eq(op, EL_STR("LtEq"))) { - return 1; - } - if (str_eq(op, EL_STR("GtEq"))) { - return 1; - } - if (str_eq(op, EL_STR("And"))) { - return 1; - } - if (str_eq(op, EL_STR("Or"))) { - return 1; - } - if (str_eq(op, EL_STR("Plus"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Star"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Slash"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t cap_record_violation(el_val_t kind, el_val_t fn_name) { - el_val_t csv = state_get(EL_STR("__cap_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(kind, EL_STR(":")), fn_name); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__cap_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t is_self_formation_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("llm_call_agentic"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_register_tool"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_field"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_dharma_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("dharma_connect"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_send"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_activate"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_field"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_strengthen"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_relationship"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_peers"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_llm_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("llm_call"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_call_system"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_call_agentic"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_vision"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_register_tool"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_models"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t cap_check_call(el_val_t fn_name) { - el_val_t kind = state_get(EL_STR("__program_kind")); - if (str_eq(kind, EL_STR("cgi"))) { - return 1; - } - if (str_eq(kind, EL_STR("service"))) { - if (is_self_formation_call(fn_name)) { - cap_record_violation(EL_STR("service"), fn_name); - return 0; - } - return 1; - } - if (is_dharma_call(fn_name)) { - cap_record_violation(EL_STR("utility"), fn_name); - return 0; - } - if (is_llm_call(fn_name)) { - cap_record_violation(EL_STR("utility"), fn_name); - return 0; - } - return 1; - return 0; -} - -el_val_t emit_cap_violations(void) { - el_val_t csv = state_get(EL_STR("__cap_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon > 0) { - el_val_t kind = str_slice(entry, 0, colon); - el_val_t fn_name = str_slice(entry, (colon + 1), str_len(entry)); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("#error \"capability violation: '"), kind), EL_STR("' programs may not call '")), fn_name), EL_STR("' (self-formation primitive — only 'cgi' programs may use it)\""))); - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t builtin_arity(el_val_t name) { - if (str_eq(name, EL_STR("println"))) { - return 1; - } - if (str_eq(name, EL_STR("print"))) { - return 1; - } - if (str_eq(name, EL_STR("readline"))) { - return 0; - } - if (str_eq(name, EL_STR("el_str_concat"))) { - return 2; - } - if (str_eq(name, EL_STR("str_eq"))) { - return 2; - } - if (str_eq(name, EL_STR("str_starts_with"))) { - return 2; - } - if (str_eq(name, EL_STR("str_ends_with"))) { - return 2; - } - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_concat"))) { - return 2; - } - if (str_eq(name, EL_STR("int_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_slice"))) { - return 3; - } - if (str_eq(name, EL_STR("str_contains"))) { - return 2; - } - if (str_eq(name, EL_STR("str_replace"))) { - return 3; - } - if (str_eq(name, EL_STR("str_to_upper"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_lower"))) { - return 1; - } - if (str_eq(name, EL_STR("str_trim"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 2; - } - if (str_eq(name, EL_STR("str_split"))) { - return 2; - } - if (str_eq(name, EL_STR("str_char_at"))) { - return 2; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 2; - } - if (str_eq(name, EL_STR("str_pad_left"))) { - return 3; - } - if (str_eq(name, EL_STR("str_pad_right"))) { - return 3; - } - if (str_eq(name, EL_STR("str_format"))) { - return 2; - } - if (str_eq(name, EL_STR("str_lower"))) { - return 1; - } - if (str_eq(name, EL_STR("str_upper"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 2; - } - if (str_eq(name, EL_STR("el_min"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_get"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_append"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_empty"))) { - return 0; - } - if (str_eq(name, EL_STR("el_list_clone"))) { - return 1; - } - if (str_eq(name, EL_STR("list_push"))) { - return 2; - } - if (str_eq(name, EL_STR("list_push_front"))) { - return 2; - } - if (str_eq(name, EL_STR("list_join"))) { - return 2; - } - if (str_eq(name, EL_STR("list_range"))) { - return 2; - } - if (str_eq(name, EL_STR("el_get_field"))) { - return 2; - } - if (str_eq(name, EL_STR("el_map_get"))) { - return 2; - } - if (str_eq(name, EL_STR("el_map_set"))) { - return 3; - } - if (str_eq(name, EL_STR("http_get"))) { - return 1; - } - if (str_eq(name, EL_STR("http_post"))) { - return 2; - } - if (str_eq(name, EL_STR("http_post_json"))) { - return 2; - } - if (str_eq(name, EL_STR("http_get_with_headers"))) { - return 2; - } - if (str_eq(name, EL_STR("http_post_with_headers"))) { - return 3; - } - if (str_eq(name, EL_STR("http_post_form_auth"))) { - return 3; - } - if (str_eq(name, EL_STR("http_get_to_file"))) { - return 3; - } - if (str_eq(name, EL_STR("http_post_to_file"))) { - return 4; - } - if (str_eq(name, EL_STR("http_serve"))) { - return 2; - } - if (str_eq(name, EL_STR("http_set_handler"))) { - return 1; - } - if (str_eq(name, EL_STR("fs_read"))) { - return 1; - } - if (str_eq(name, EL_STR("fs_write"))) { - return 2; - } - if (str_eq(name, EL_STR("fs_write_bytes"))) { - return 3; - } - if (str_eq(name, EL_STR("fs_list"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get"))) { - return 2; - } - if (str_eq(name, EL_STR("json_parse"))) { - return 1; - } - if (str_eq(name, EL_STR("json_stringify"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_string"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_float"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_bool"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_raw"))) { - return 2; - } - if (str_eq(name, EL_STR("json_set"))) { - return 3; - } - if (str_eq(name, EL_STR("json_array_len"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 0; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 0; - } - if (str_eq(name, EL_STR("sleep_secs"))) { - return 1; - } - if (str_eq(name, EL_STR("sleep_ms"))) { - return 1; - } - if (str_eq(name, EL_STR("time_format"))) { - return 2; - } - if (str_eq(name, EL_STR("time_to_parts"))) { - return 1; - } - if (str_eq(name, EL_STR("time_from_parts"))) { - return 3; - } - if (str_eq(name, EL_STR("time_add"))) { - return 3; - } - if (str_eq(name, EL_STR("time_diff"))) { - return 3; - } - if (str_eq(name, EL_STR("uuid_new"))) { - return 0; - } - if (str_eq(name, EL_STR("uuid_v4"))) { - return 0; - } - if (str_eq(name, EL_STR("env"))) { - return 1; - } - if (str_eq(name, EL_STR("state_set"))) { - return 2; - } - if (str_eq(name, EL_STR("state_get"))) { - return 1; - } - if (str_eq(name, EL_STR("state_del"))) { - return 1; - } - if (str_eq(name, EL_STR("state_keys"))) { - return 0; - } - if (str_eq(name, EL_STR("float_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("int_to_float"))) { - return 1; - } - if (str_eq(name, EL_STR("float_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("format_float"))) { - return 2; - } - if (str_eq(name, EL_STR("decimal_round"))) { - return 2; - } - if (str_eq(name, EL_STR("str_to_float"))) { - return 1; - } - if (str_eq(name, EL_STR("math_sqrt"))) { - return 1; - } - if (str_eq(name, EL_STR("math_log"))) { - return 1; - } - if (str_eq(name, EL_STR("math_ln"))) { - return 1; - } - if (str_eq(name, EL_STR("math_sin"))) { - return 1; - } - if (str_eq(name, EL_STR("math_cos"))) { - return 1; - } - if (str_eq(name, EL_STR("math_pi"))) { - return 0; - } - if (str_eq(name, EL_STR("bool_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("exit_program"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_connect"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_send"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_activate"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_emit"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_field"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_strengthen"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_relationship"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_peers"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_node"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_node_full"))) { - return 8; - } - if (str_eq(name, EL_STR("engram_get_node"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_strengthen"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_forget"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_node_count"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_search"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_scan_nodes"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_connect"))) { - return 4; - } - if (str_eq(name, EL_STR("engram_edge_between"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_neighbors"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_neighbors_filtered"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_edge_count"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_activate"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_save"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_load"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_get_node_json"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_search_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_scan_nodes_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_neighbors_json"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_activate_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_stats_json"))) { - return 0; - } - if (str_eq(name, EL_STR("llm_call"))) { - return 2; - } - if (str_eq(name, EL_STR("llm_call_system"))) { - return 3; - } - if (str_eq(name, EL_STR("llm_call_agentic"))) { - return 4; - } - if (str_eq(name, EL_STR("llm_vision"))) { - return 4; - } - if (str_eq(name, EL_STR("llm_models"))) { - return 0; - } - if (str_eq(name, EL_STR("llm_register_tool"))) { - return 2; - } - if (str_eq(name, EL_STR("sha256_hex"))) { - return 1; - } - if (str_eq(name, EL_STR("sha256_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("hmac_sha256_hex"))) { - return 2; - } - if (str_eq(name, EL_STR("hmac_sha256_bytes"))) { - return 2; - } - if (str_eq(name, EL_STR("base64_encode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64_decode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64url_encode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64url_decode"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_get"))) { - return 2; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_append"))) { - return 2; - } - if (str_eq(name, EL_STR("native_list_empty"))) { - return 0; - } - if (str_eq(name, EL_STR("native_list_clone"))) { - return 1; - } - if (str_eq(name, EL_STR("native_string_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("native_int_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("append"))) { - return 2; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("get"))) { - return 2; - } - if (str_eq(name, EL_STR("map_get"))) { - return 2; - } - if (str_eq(name, EL_STR("map_set"))) { - return 3; - } - return (-1); - return 0; -} - -el_val_t arity_record_violation(el_val_t fn_name, el_val_t expected, el_val_t actual) { - el_val_t csv = state_get(EL_STR("__arity_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("|")), native_int_to_str(expected)), EL_STR("|")), native_int_to_str(actual)); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__arity_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t arity_check_call(el_val_t fn_name, el_val_t actual) { - el_val_t expected = builtin_arity(fn_name); - if (expected < 0) { - return 1; - } - if (expected == actual) { - return 1; - } - arity_record_violation(fn_name, expected, actual); - return 1; - return 0; -} - -el_val_t emit_arity_violations(void) { - el_val_t csv = state_get(EL_STR("__arity_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t p1 = str_index_of(entry, EL_STR("|")); - if (p1 > 0) { - el_val_t fn_name = str_slice(entry, 0, p1); - el_val_t rest = str_slice(entry, (p1 + 1), str_len(entry)); - el_val_t p2 = str_index_of(rest, EL_STR("|")); - if (p2 > 0) { - el_val_t exp_s = str_slice(rest, 0, p2); - el_val_t act_s = str_slice(rest, (p2 + 1), str_len(rest)); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("#error \"arity error: '"), fn_name), EL_STR("' takes ")), exp_s), EL_STR(" arguments, but called with ")), act_s), EL_STR("\""))); - } - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t add_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__int_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__int_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t build_int_names_for_params(el_val_t params) { - state_set(EL_STR("__int_names"), EL_STR(",")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR("Int"))) { - add_int_name(pname); - } - pi = (pi + 1); - } - return 1; - return 0; -} - -el_val_t cg_fn(el_val_t stmt) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - return 0; - } - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t params_c = params_to_c(params); - el_val_t decorator = el_get_field(stmt, EL_STR("decorator")); - if (vbd_has_restricted_call(body)) { - if (!str_eq(decorator, EL_STR("manager"))) { - emit_line(el_str_concat(el_str_concat(EL_STR("#error \"VBD violation: dharma_emit/dharma_field called from non-@manager fn '"), fn_name), EL_STR("'\""))); - } - } - build_int_names_for_params(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(") {"))); - el_val_t decl = native_list_empty(); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - decl = native_list_append(decl, pname); - pi = (pi + 1); - } - el_val_t body_xformed = body; - if (!str_eq(ret_type, EL_STR("Void"))) { - body_xformed = transform_implicit_return(body); - } - cg_stmts(body_xformed, EL_STR(" "), decl); - emit_line(EL_STR(" return 0;")); - emit_line(EL_STR("}")); - emit_blank(); - return 0; -} - -el_val_t is_fndef(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_top_level_decl(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("TypeDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("Import"))) { - return 1; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t cgi_arg(el_val_t value, el_val_t has_value) { - if (has_value) { - return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(value)), EL_STR(")")); - } - return EL_STR("EL_NULL"); - return 0; -} - -el_val_t vbd_is_restricted_name(el_val_t name) { - if (str_eq(name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_field"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t vbd_expr_has_restricted_call(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (str_eq(fk, EL_STR("Ident"))) { - el_val_t fname = el_get_field(func, EL_STR("name")); - if (vbd_is_restricted_name(fname)) { - return 1; - } - } - if (vbd_expr_has_restricted_call(func)) { - return 1; - } - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t an = native_list_len(args); - el_val_t ai = 0; - while (ai < an) { - el_val_t a = native_list_get(args, ai); - if (vbd_expr_has_restricted_call(a)) { - return 1; - } - ai = (ai + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t l = el_get_field(expr, EL_STR("left")); - el_val_t r = el_get_field(expr, EL_STR("right")); - if (vbd_expr_has_restricted_call(l)) { - return 1; - } - if (vbd_expr_has_restricted_call(r)) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Not"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Neg"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Field"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object"))); - } - if (str_eq(kind, EL_STR("Index"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object")))) { - return 1; - } - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("index")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Try"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - el_val_t i = 0; - while (i < n) { - el_val_t e = native_list_get(elems, i); - if (vbd_expr_has_restricted_call(e)) { - return 1; - } - i = (i + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t v = el_get_field(pair, EL_STR("value")); - if (vbd_expr_has_restricted_call(v)) { - return 1; - } - i = (i + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("If"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("cond")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("then")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("else")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("For"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("list")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("body")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Match"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("subject")))) { - return 1; - } - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t body = el_get_field(arm, EL_STR("body")); - if (vbd_expr_has_restricted_call(body)) { - return 1; - } - i = (i + 1); - } - return 0; - } - return 0; - return 0; -} - -el_val_t vbd_has_restricted_call(el_val_t stmts) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t s = native_list_get(stmts, i); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - if (str_eq(sk, EL_STR("Let"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("Return"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("Expr"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("While"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("cond")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("For"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("list")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) { - return 1; - } - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t codegen(el_val_t stmts, el_val_t source) { - el_val_t n_top = native_list_len(stmts); - el_val_t cgi_count = 0; - el_val_t cgi_block = el_map_new(1, "stmt", EL_STR("None")); - el_val_t svc_count = 0; - el_val_t svc_block = el_map_new(1, "stmt", EL_STR("None")); - el_val_t ti = 0; - while (ti < n_top) { - el_val_t s = native_list_get(stmts, ti); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - if (str_eq(sk, EL_STR("CgiBlock"))) { - cgi_count = (cgi_count + 1); - if (cgi_count == 1) { - cgi_block = s; - } - } - if (str_eq(sk, EL_STR("ServiceBlock"))) { - svc_count = (svc_count + 1); - if (svc_count == 1) { - svc_block = s; - } - } - ti = (ti + 1); - } - if (cgi_count > 1) { - emit_line(EL_STR("#error \"El: multiple cgi blocks in program (only one allowed)\"")); - } - if (svc_count > 1) { - emit_line(EL_STR("#error \"El: multiple service blocks in program (only one allowed)\"")); - } - if (cgi_count >= 1) { - if (svc_count >= 1) { - emit_line(EL_STR("#error \"El: program declares both cgi and service blocks (mutually exclusive — pick one)\"")); - } - } - el_val_t kind = EL_STR("utility"); - if (cgi_count >= 1) { - kind = EL_STR("cgi"); - } - if (svc_count >= 1) { - kind = EL_STR("service"); - } - state_set(EL_STR("__program_kind"), kind); - state_set(EL_STR("__cap_violations"), EL_STR("")); - state_set(EL_STR("__arity_violations"), EL_STR("")); - emit_line(EL_STR("#include ")); - emit_line(EL_STR("#include ")); - emit_line(EL_STR("#include \"el_runtime.h\"")); - emit_blank(); - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (!str_eq(fn_name, EL_STR("main"))) { - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t params_c = params_to_c(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(");"))); - } - } - i = (i + 1); - } - emit_blank(); - el_val_t has_toplevel_lets = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - add_int_name(name); - } - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - add_int_name(name); - } - emit_line(el_str_concat(el_str_concat(EL_STR("el_val_t "), name), EL_STR(";"))); - has_toplevel_lets = 1; - } - i = (i + 1); - } - if (has_toplevel_lets) { - emit_blank(); - } - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - cg_fn(stmt); - } - i = (i + 1); - } - emit_line(EL_STR("int main(int argc, char** argv) {")); - emit_line(EL_STR(" el_runtime_init_args(argc, argv);")); - if (cgi_count >= 1) { - el_val_t cname = el_get_field(cgi_block, EL_STR("name")); - el_val_t cdid = el_get_field(cgi_block, EL_STR("dharma_id")); - el_val_t cprin = el_get_field(cgi_block, EL_STR("principal")); - el_val_t cnet = el_get_field(cgi_block, EL_STR("network")); - el_val_t ceng = el_get_field(cgi_block, EL_STR("engram")); - el_val_t has_did = el_get_field(cgi_block, EL_STR("has_dharma_id")); - el_val_t has_prin = el_get_field(cgi_block, EL_STR("has_principal")); - el_val_t has_net = el_get_field(cgi_block, EL_STR("has_network")); - el_val_t has_eng = el_get_field(cgi_block, EL_STR("has_engram")); - el_val_t arg_name = el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(cname)), EL_STR(")")); - el_val_t arg_did = cgi_arg(cdid, has_did); - el_val_t arg_prin = cgi_arg(cprin, has_prin); - el_val_t arg_net = cgi_arg(cnet, has_net); - el_val_t arg_eng = cgi_arg(ceng, has_eng); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR(" el_cgi_init("), arg_name), EL_STR(", ")), arg_did), EL_STR(", ")), arg_prin), EL_STR(", ")), arg_net), EL_STR(", ")), arg_eng), EL_STR(");"))); - } - el_val_t main_decl = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - main_decl = native_list_append(main_decl, name); - } - i = (i + 1); - } - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - } else { - if (is_top_level_decl(stmt)) { - } else { - main_decl = cg_stmt(stmt, EL_STR(" "), main_decl); - } - } - i = (i + 1); - } - emit_line(EL_STR(" return 0;")); - emit_line(EL_STR("}")); - emit_blank(); - emit_cap_violations(); - emit_arity_violations(); - return EL_STR(""); - return 0; -} - -el_val_t js_escape(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\""))) { - out = el_str_concat(out, EL_STR("\\\"")); - } else { - if (str_eq(ch, EL_STR("\\"))) { - out = el_str_concat(out, EL_STR("\\\\")); - } else { - if (str_eq(ch, EL_STR("\n"))) { - out = el_str_concat(out, EL_STR("\\n")); - } else { - if (str_eq(ch, EL_STR("\r"))) { - out = el_str_concat(out, EL_STR("\\r")); - } else { - if (str_eq(ch, EL_STR("\t"))) { - out = el_str_concat(out, EL_STR("\\t")); - } else { - out = el_str_concat(out, ch); - } - } - } - } - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t js_str_lit(el_val_t s) { - return el_str_concat(el_str_concat(EL_STR("\""), js_escape(s)), EL_STR("\"")); - return 0; -} - -el_val_t js_emit_line(el_val_t line) { - println(line); - return 0; -} - -el_val_t js_emit_blank(void) { - println(EL_STR("")); - return 0; -} - -el_val_t js_binop(el_val_t op) { - if (str_eq(op, EL_STR("Plus"))) { - return EL_STR("+"); - } - if (str_eq(op, EL_STR("Minus"))) { - return EL_STR("-"); - } - if (str_eq(op, EL_STR("Star"))) { - return EL_STR("*"); - } - if (str_eq(op, EL_STR("Slash"))) { - return EL_STR("/"); - } - if (str_eq(op, EL_STR("Percent"))) { - return EL_STR("%"); - } - if (str_eq(op, EL_STR("EqEq"))) { - return EL_STR("==="); - } - if (str_eq(op, EL_STR("NotEq"))) { - return EL_STR("!=="); - } - if (str_eq(op, EL_STR("Lt"))) { - return EL_STR("<"); - } - if (str_eq(op, EL_STR("Gt"))) { - return EL_STR(">"); - } - if (str_eq(op, EL_STR("LtEq"))) { - return EL_STR("<="); - } - if (str_eq(op, EL_STR("GtEq"))) { - return EL_STR(">="); - } - if (str_eq(op, EL_STR("And"))) { - return EL_STR("&&"); - } - if (str_eq(op, EL_STR("Or"))) { - return EL_STR("||"); - } - return op; - return 0; -} - -el_val_t js_is_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__js_int_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t js_add_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__js_int_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__js_int_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t js_build_int_names_for_params(el_val_t params) { - state_set(EL_STR("__js_int_names"), EL_STR(",")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR("Int"))) { - js_add_int_name(pname); - } - pi = (pi + 1); - } - return 1; - return 0; -} - -el_val_t js_is_int_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 1; - } - if (str_eq(name, EL_STR("el_min"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t js_cg_expr(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Int"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("Float"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("Str"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return js_str_lit(v); - } - if (str_eq(kind, EL_STR("Bool"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - if (str_eq(v, EL_STR("true"))) { - return EL_STR("true"); - } - return EL_STR("false"); - } - if (str_eq(kind, EL_STR("Nil"))) { - return EL_STR("null"); - } - if (str_eq(kind, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return name; - } - if (str_eq(kind, EL_STR("Not"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = js_cg_expr(inner); - return el_str_concat(EL_STR("!"), inner_c); - } - if (str_eq(kind, EL_STR("Neg"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = js_cg_expr(inner); - return el_str_concat(el_str_concat(EL_STR("(-"), inner_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - el_val_t left = el_get_field(expr, EL_STR("left")); - el_val_t right = el_get_field(expr, EL_STR("right")); - el_val_t left_c = js_cg_expr(left); - el_val_t right_c = js_cg_expr(right); - el_val_t left_kind = el_get_field(left, EL_STR("expr")); - el_val_t right_kind = el_get_field(right, EL_STR("expr")); - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Call"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_call(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(right_kind, EL_STR("Ident"))) { - if (str_eq(left_kind, EL_STR("Call"))) { - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(rname)) { - if (js_is_int_call(left)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Call"))) { - if (str_eq(right_kind, EL_STR("Call"))) { - if (js_is_int_call(left)) { - if (js_is_int_call(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - el_val_t op_c = js_binop(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t arity = native_list_len(args); - el_val_t func_kind = el_get_field(func, EL_STR("expr")); - el_val_t args_c = EL_STR(""); - el_val_t i = 0; - while (i < arity) { - el_val_t arg = native_list_get(args, i); - el_val_t arg_c = js_cg_expr(arg); - if (i > 0) { - args_c = el_str_concat(args_c, EL_STR(", ")); - } - args_c = el_str_concat(args_c, arg_c); - i = (i + 1); - } - if (str_eq(func_kind, EL_STR("Ident"))) { - el_val_t fn_name = el_get_field(func, EL_STR("name")); - return el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(func_kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(func, EL_STR("object")); - el_val_t field = el_get_field(func, EL_STR("field")); - el_val_t obj_c = js_cg_expr(obj); - if (arity > 0) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(", ")), args_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(")")); - } - el_val_t fn_c = js_cg_expr(func); - return el_str_concat(el_str_concat(el_str_concat(fn_c, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t field = el_get_field(expr, EL_STR("field")); - el_val_t obj_c = js_cg_expr(obj); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), js_str_lit(field)), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Index"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t idx = el_get_field(expr, EL_STR("index")); - el_val_t obj_c = js_cg_expr(obj); - el_val_t idx_c = js_cg_expr(idx); - el_val_t idx_kind = el_get_field(idx, EL_STR("expr")); - if (str_eq(idx_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_get("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - if (n == 0) { - return EL_STR("[]"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t elem = native_list_get(elems, i); - el_val_t elem_c = js_cg_expr(elem); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(items, elem_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("["), items), EL_STR("]")); - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - if (n == 0) { - return EL_STR("{}"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t key = el_get_field(pair, EL_STR("key")); - el_val_t val = el_get_field(pair, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(el_str_concat(el_str_concat(items, js_str_lit(key)), EL_STR(": ")), val_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("{"), items), EL_STR("}")); - } - if (str_eq(kind, EL_STR("Try"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - return js_cg_expr(inner); - } - if (str_eq(kind, EL_STR("If"))) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t cond_c = js_cg_expr(cond); - return el_str_concat(el_str_concat(EL_STR("("), cond_c), EL_STR(" ? 1 : 0)")); - } - if (str_eq(kind, EL_STR("Match"))) { - return js_cg_match(expr); - } - return EL_STR("null"); - return 0; -} - -el_val_t js_next_match_id(void) { - el_val_t csv = state_get(EL_STR("__js_match_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__js_match_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t js_cg_match(el_val_t expr) { - el_val_t subject = el_get_field(expr, EL_STR("subject")); - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t subj_c = js_cg_expr(subject); - el_val_t id = js_next_match_id(); - el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id); - el_val_t out = el_str_concat(el_str_concat(EL_STR("(("), subj_var), EL_STR(") => { ")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t pat = el_get_field(arm, EL_STR("pattern")); - el_val_t body = el_get_field(arm, EL_STR("body")); - el_val_t pkind = el_get_field(pat, EL_STR("pattern")); - el_val_t body_c = js_cg_expr(body); - if (str_eq(pkind, EL_STR("Wildcard"))) { - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("return (")), body_c), EL_STR("); ")); - } else { - if (str_eq(pkind, EL_STR("Binding"))) { - el_val_t bname = el_get_field(pat, EL_STR("name")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ const ")), bname), EL_STR(" = ")), subj_var), EL_STR("; return (")), body_c), EL_STR("); } ")); - } else { - if (str_eq(pkind, EL_STR("LitInt"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" === ")), v), EL_STR(") return (")), body_c), EL_STR("); ")); - } else { - if (str_eq(pkind, EL_STR("LitStr"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (str_eq(")), subj_var), EL_STR(", ")), js_str_lit(v)), EL_STR(")) return (")), body_c), EL_STR("); ")); - } else { - if (str_eq(pkind, EL_STR("LitBool"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - el_val_t bv = EL_STR("false"); - if (str_eq(v, EL_STR("true"))) { - bv = EL_STR("true"); - } - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" === ")), bv), EL_STR(") return (")), body_c), EL_STR("); ")); - } else { - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("return (")), body_c), EL_STR("); ")); - } - } - } - } - } - i = (i + 1); - } - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("return null; })(")), subj_c), EL_STR(")")); - return out; - return 0; -} - -el_val_t js_list_contains(el_val_t lst, el_val_t s) { - el_val_t n = native_list_len(lst); - el_val_t i = 0; - while (i < n) { - el_val_t item = native_list_get(lst, i); - if (str_eq(item, s)) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t js_cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - js_add_int_name(name); - } - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - js_add_int_name(name); - } - if (js_list_contains(declared, name)) { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } else { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("let ")), name), EL_STR(" = ")), val_c), EL_STR(";"))); - return native_list_append(declared, name); - } - } - if (str_eq(kind, EL_STR("Return"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("Nil"))) { - js_emit_line(el_str_concat(indent, EL_STR("return null;"))); - } else { - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("return ")), val_c), EL_STR(";"))); - } - return declared; - } - if (str_eq(kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - js_cg_if_stmt(val, indent, declared); - return declared; - } - if (str_eq(val_kind, EL_STR("For"))) { - js_cg_for_stmt(val, indent, declared); - return declared; - } - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(indent, val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("While"))) { - el_val_t cond = el_get_field(stmt, EL_STR("cond")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t cond_c = js_cg_expr(cond); - cond_c = js_strip_outer_parens(cond_c); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("while (")), cond_c), EL_STR(") {"))); - js_cg_stmts(body, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return declared; - } - if (str_eq(kind, EL_STR("For"))) { - el_val_t item = el_get_field(stmt, EL_STR("item")); - el_val_t list_expr = el_get_field(stmt, EL_STR("list")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - js_cg_for_body(item, list_expr, body, indent, declared); - return declared; - } - if (str_eq(kind, EL_STR("FnDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("TypeDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("Import"))) { - return declared; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - el_val_t cname = el_get_field(stmt, EL_STR("name")); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("// cgi block '")), cname), EL_STR("' — no-op in JS target (server-side concept)"))); - return declared; - } - if (str_eq(kind, EL_STR("ServiceBlock"))) { - el_val_t sname = el_get_field(stmt, EL_STR("name")); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("// service block '")), sname), EL_STR("' — no-op in JS target"))); - return declared; - } - return declared; - return 0; -} - -el_val_t js_strip_outer_parens(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t n = native_list_len(chars); - if (n < 2) { - return s; - } - el_val_t first = native_list_get(chars, 0); - el_val_t last = native_list_get(chars, (n - 1)); - if (str_eq(first, EL_STR("("))) { - if (str_eq(last, EL_STR(")"))) { - el_val_t depth = 1; - el_val_t i = 1; - el_val_t balanced = 1; - while (i < (n - 1)) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("("))) { - depth = (depth + 1); - } - if (str_eq(ch, EL_STR(")"))) { - depth = (depth - 1); - if (depth == 0) { - balanced = 0; - i = n; - } - } - i = (i + 1); - } - if (balanced) { - el_val_t inner = EL_STR(""); - el_val_t j = 1; - while (j < (n - 1)) { - el_val_t ch = native_list_get(chars, j); - inner = el_str_concat(inner, ch); - j = (j + 1); - } - return inner; - } - } - } - return s; - return 0; -} - -el_val_t js_cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = js_cg_expr(cond); - cond_c = js_strip_outer_parens(cond_c); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("if (")), cond_c), EL_STR(") {"))); - js_cg_stmts(then_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - if (has_else) { - js_emit_line(el_str_concat(indent, EL_STR("} else {"))); - js_cg_stmts(else_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - } - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t js_cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared) { - el_val_t list_c = js_cg_expr(list_expr); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("for (const ")), item), EL_STR(" of ")), list_c), EL_STR(") {"))); - el_val_t body_decl = native_list_clone(declared); - body_decl = native_list_append(body_decl, item); - js_cg_stmts(body, el_str_concat(indent, EL_STR(" ")), body_decl); - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t js_cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t item = el_get_field(expr, EL_STR("item")); - el_val_t list_expr = el_get_field(expr, EL_STR("list")); - el_val_t body = el_get_field(expr, EL_STR("body")); - js_cg_for_body(item, list_expr, body, indent, declared); - return 0; -} - -el_val_t js_cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t decl = declared; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - decl = js_cg_stmt(stmt, indent, decl); - i = (i + 1); - } - return decl; - return 0; -} - -el_val_t js_params_str(el_val_t params) { - el_val_t n = native_list_len(params); - if (n == 0) { - return EL_STR(""); - } - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t param = native_list_get(params, i); - el_val_t name = el_get_field(param, EL_STR("name")); - if (i > 0) { - out = el_str_concat(out, EL_STR(", ")); - } - out = el_str_concat(out, name); - i = (i + 1); - } - return out; - return 0; -} - -el_val_t js_transform_implicit_return(el_val_t body) { - el_val_t n = native_list_len(body); - if (n == 0) { - return body; - } - el_val_t last = native_list_get(body, (n - 1)); - el_val_t last_kind = el_get_field(last, EL_STR("stmt")); - if (str_eq(last_kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(last, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - return body; - } - if (str_eq(val_kind, EL_STR("For"))) { - return body; - } - el_val_t new_body = native_list_empty(); - el_val_t i = 0; - while (i < (n - 1)) { - new_body = native_list_append(new_body, native_list_get(body, i)); - i = (i + 1); - } - el_val_t return_stmt = el_map_new(2, "stmt", EL_STR("Return"), "value", val); - new_body = native_list_append(new_body, return_stmt); - return new_body; - } - return body; - return 0; -} - -el_val_t js_cg_fn(el_val_t stmt) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t params_str = js_params_str(params); - js_build_int_names_for_params(params); - if (str_eq(fn_name, EL_STR("main"))) { - js_emit_line(el_str_concat(el_str_concat(EL_STR("function main("), params_str), EL_STR(") {"))); - } else { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("function "), fn_name), EL_STR("(")), params_str), EL_STR(") {"))); - } - el_val_t decl = native_list_empty(); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - decl = native_list_append(decl, pname); - pi = (pi + 1); - } - el_val_t body_xformed = body; - if (!str_eq(ret_type, EL_STR("Void"))) { - body_xformed = js_transform_implicit_return(body); - } - js_cg_stmts(body_xformed, EL_STR(" "), decl); - js_emit_line(EL_STR("}")); - js_emit_blank(); - return 0; -} - -el_val_t js_is_fndef(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t js_is_top_level_decl(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("TypeDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("Import"))) { - return 1; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return 1; - } - if (str_eq(kind, EL_STR("ServiceBlock"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t codegen_js(el_val_t stmts, el_val_t source) { - state_set(EL_STR("__js_int_names"), EL_STR("")); - state_set(EL_STR("__js_match_counter"), EL_STR("")); - js_emit_line(EL_STR("// Generated by elc --target=js")); - js_emit_line(EL_STR("// Runtime: foundation/el/el-compiler/runtime/el_runtime.js")); - js_emit_line(EL_STR("import \"./el_runtime.js\";")); - js_emit_line(EL_STR("const {")); - js_emit_line(EL_STR(" println, print, el_str_concat, str_concat, str_eq, str_starts_with, str_ends_with,")); - js_emit_line(EL_STR(" str_len, int_to_str, str_to_int, str_slice, str_contains, str_replace,")); - js_emit_line(EL_STR(" str_to_upper, str_to_lower, str_trim, str_index_of, str_split, str_char_at,")); - js_emit_line(EL_STR(" str_char_code, str_lower, str_upper, el_abs, el_max, el_min,")); - js_emit_line(EL_STR(" el_list_new, el_list_len, el_list_get, el_list_append, el_list_empty, el_list_clone,")); - js_emit_line(EL_STR(" list_push, list_join, list_range,")); - js_emit_line(EL_STR(" el_map_new, el_get_field, el_map_get, el_map_set,")); - js_emit_line(EL_STR(" http_get, http_post, http_post_json,")); - js_emit_line(EL_STR(" fs_read, fs_write, fs_list,")); - js_emit_line(EL_STR(" json_parse, json_stringify, json_get, json_get_string, json_get_int,")); - js_emit_line(EL_STR(" time_now, time_now_utc, sleep_ms, bool_to_str, exit_program,")); - js_emit_line(EL_STR(" el_retain, el_release,")); - js_emit_line(EL_STR(" append, len, get, map_get, map_set,")); - js_emit_line(EL_STR(" native_list_get, native_list_len, native_list_append, native_list_empty,")); - js_emit_line(EL_STR(" native_list_clone, native_string_chars, native_int_to_str,")); - js_emit_line(EL_STR(" args, state_set, state_get, state_del, state_keys, env,")); - js_emit_line(EL_STR(" dharma_connect, dharma_send, dharma_emit, dharma_field, dharma_activate,")); - js_emit_line(EL_STR(" engram_node, engram_search, engram_activate,")); - js_emit_line(EL_STR(" llm_call, llm_call_system,")); - js_emit_line(EL_STR("} = globalThis.__el;")); - js_emit_blank(); - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (js_is_fndef(stmt)) { - js_cg_fn(stmt); - } - i = (i + 1); - } - el_val_t has_main = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - el_val_t sk = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(sk, EL_STR("FnDef"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - has_main = 1; - } - } - i = (i + 1); - } - el_val_t main_decl = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (js_is_fndef(stmt)) { - } else { - if (js_is_top_level_decl(stmt)) { - } else { - main_decl = js_cg_stmt(stmt, EL_STR(""), main_decl); - } - } - i = (i + 1); - } - if (has_main) { - js_emit_blank(); - js_emit_line(EL_STR("main();")); - } - return EL_STR(""); - return 0; -} - -el_val_t compile(el_val_t source) { - el_val_t tokens = lex(source); - el_val_t stmts = parse(tokens); - return codegen(stmts, source); - return 0; -} - -el_val_t compile_js(el_val_t source) { - el_val_t tokens = lex(source); - el_val_t stmts = parse(tokens); - return codegen_js(stmts, source); - return 0; -} - -el_val_t compile_dispatch(el_val_t tgt, el_val_t source) { - if (str_eq(tgt, EL_STR("js"))) { - return compile_js(source); - } - return compile(source); - return 0; -} - -el_val_t detect_target(el_val_t argv) { - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (str_starts_with(a, EL_STR("--target="))) { - el_val_t v = str_slice(a, 9, str_len(a)); - return v; - } - i = (i + 1); - } - return EL_STR("c"); - return 0; -} - -el_val_t strip_flags(el_val_t argv) { - el_val_t out = native_list_empty(); - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (!str_starts_with(a, EL_STR("--"))) { - out = native_list_append(out, a); - } - i = (i + 1); - } - return out; - return 0; -} - -int main(int argc, char** argv) { - el_runtime_init_args(argc, argv); - _argv = args(); - _target = detect_target(_argv); - _positional = strip_flags(_argv); - _argc = native_list_len(_positional); - if (_argc >= 1) { - el_val_t _src_path = native_list_get(_positional, 0); - el_val_t _source = fs_read(_src_path); - el_val_t _out = compile_dispatch(_target, _source); - if (_argc >= 2) { - el_val_t _out_path = native_list_get(_positional, 1); - fs_write(_out_path, _out); - } - } - return 0; -} - diff --git a/lang/dist/elc-new.c b/lang/dist/elc-new.c deleted file mode 100644 index d7ab52c..0000000 --- a/lang/dist/elc-new.c +++ /dev/null @@ -1,6699 +0,0 @@ -#include -#include -#include "el_runtime.h" - -el_val_t lex_is_digit(el_val_t ch); -el_val_t lex_is_alpha(el_val_t ch); -el_val_t is_alnum_or_underscore(el_val_t ch); -el_val_t lex_is_whitespace(el_val_t ch); -el_val_t make_tok(el_val_t kind, el_val_t value); -el_val_t keyword_kind(el_val_t word); -el_val_t scan_digits(el_val_t chars, el_val_t start, el_val_t total); -el_val_t scan_ident(el_val_t chars, el_val_t start, el_val_t total); -el_val_t substr_at(el_val_t chars, el_val_t start, el_val_t total, el_val_t needle); -el_val_t str_has(el_val_t s, el_val_t needle); -el_val_t looks_like_code(el_val_t s); -el_val_t strip_code_comments(el_val_t s); -el_val_t scan_string(el_val_t chars, el_val_t start, el_val_t total); -el_val_t lex(el_val_t source); -el_val_t tok_at(el_val_t tokens, el_val_t pos); -el_val_t tok_kind(el_val_t tokens, el_val_t pos); -el_val_t tok_value(el_val_t tokens, el_val_t pos); -el_val_t expect(el_val_t tokens, el_val_t pos, el_val_t kind); -el_val_t make_result(el_val_t node, el_val_t pos); -el_val_t skip_type(el_val_t tokens, el_val_t pos); -el_val_t parse_params(el_val_t tokens, el_val_t pos); -el_val_t parse_primary(el_val_t tokens, el_val_t pos); -el_val_t parse_if(el_val_t tokens, el_val_t pos); -el_val_t parse_match(el_val_t tokens, el_val_t pos); -el_val_t parse_pattern(el_val_t tokens, el_val_t pos); -el_val_t parse_for_expr(el_val_t tokens, el_val_t pos); -el_val_t parse_block(el_val_t tokens, el_val_t pos); -el_val_t is_duration_unit(el_val_t name); -el_val_t parse_postfix(el_val_t tokens, el_val_t pos); -el_val_t op_precedence(el_val_t kind); -el_val_t is_binop(el_val_t kind); -el_val_t parse_binop(el_val_t tokens, el_val_t pos, el_val_t min_prec); -el_val_t parse_expr(el_val_t tokens, el_val_t pos); -el_val_t parse_stmt(el_val_t tokens, el_val_t pos); -el_val_t parse(el_val_t tokens); -el_val_t nibble_to_hex(el_val_t n); -el_val_t byte_to_hex2(el_val_t b); -el_val_t is_hex_digit_byte(el_val_t b); -el_val_t c_escape(el_val_t s); -el_val_t c_str_lit(el_val_t s); -el_val_t el_type_to_c(el_val_t type_str); -el_val_t emit_line(el_val_t line); -el_val_t emit_blank(void); -el_val_t binop_to_c(el_val_t op); -el_val_t duration_unit_nanos(el_val_t unit); -el_val_t cg_expr(el_val_t expr); -el_val_t next_match_id(void); -el_val_t cg_match(el_val_t expr); -el_val_t next_if_id(void); -el_val_t cg_if_expr_arm(el_val_t stmts, el_val_t result_var); -el_val_t cg_if_expr(el_val_t expr); -el_val_t list_contains(el_val_t lst, el_val_t s); -el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared); -el_val_t strip_outer_parens(el_val_t s); -el_val_t cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared); -el_val_t cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared); -el_val_t param_decl(el_val_t param, el_val_t idx); -el_val_t params_to_c(el_val_t params); -el_val_t transform_implicit_return(el_val_t body); -el_val_t is_int_name(el_val_t name); -el_val_t is_instant_name(el_val_t name); -el_val_t is_duration_name(el_val_t name); -el_val_t is_int_call(el_val_t call_expr); -el_val_t is_instant_call(el_val_t call_expr); -el_val_t is_duration_call(el_val_t call_expr); -el_val_t is_calendar_name(el_val_t name); -el_val_t is_caltime_name(el_val_t name); -el_val_t is_rhythm_name(el_val_t name); -el_val_t is_localdate_name(el_val_t name); -el_val_t is_localtime_name(el_val_t name); -el_val_t is_localdt_name(el_val_t name); -el_val_t is_zone_name(el_val_t name); -el_val_t is_calendar_call(el_val_t call_expr); -el_val_t is_caltime_call(el_val_t call_expr); -el_val_t is_rhythm_call(el_val_t call_expr); -el_val_t is_localdate_call(el_val_t call_expr); -el_val_t is_localtime_call(el_val_t call_expr); -el_val_t is_localdt_call(el_val_t call_expr); -el_val_t is_zone_call(el_val_t call_expr); -el_val_t is_calendar_expr(el_val_t expr); -el_val_t is_caltime_expr(el_val_t expr); -el_val_t is_rhythm_expr(el_val_t expr); -el_val_t is_localdate_expr(el_val_t expr); -el_val_t is_localtime_expr(el_val_t expr); -el_val_t is_localdt_expr(el_val_t expr); -el_val_t is_zone_expr(el_val_t expr); -el_val_t is_instant_expr(el_val_t expr); -el_val_t is_duration_expr(el_val_t expr); -el_val_t time_record_violation(el_val_t kind, el_val_t detail); -el_val_t is_int_expr(el_val_t expr); -el_val_t cap_record_violation(el_val_t kind, el_val_t fn_name); -el_val_t is_self_formation_call(el_val_t fn_name); -el_val_t is_dharma_call(el_val_t fn_name); -el_val_t is_llm_call(el_val_t fn_name); -el_val_t cap_check_call(el_val_t fn_name); -el_val_t emit_cap_violations(void); -el_val_t emit_time_violations(void); -el_val_t builtin_arity(el_val_t name); -el_val_t arity_record_violation(el_val_t fn_name, el_val_t expected, el_val_t actual); -el_val_t arity_check_call(el_val_t fn_name, el_val_t actual); -el_val_t emit_arity_violations(void); -el_val_t add_int_name(el_val_t name); -el_val_t add_instant_name(el_val_t name); -el_val_t add_duration_name(el_val_t name); -el_val_t add_calendar_name(el_val_t name); -el_val_t add_caltime_name(el_val_t name); -el_val_t add_rhythm_name(el_val_t name); -el_val_t add_localdate_name(el_val_t name); -el_val_t add_localtime_name(el_val_t name); -el_val_t add_localdt_name(el_val_t name); -el_val_t add_zone_name(el_val_t name); -el_val_t build_int_names_for_params(el_val_t params); -el_val_t cg_fn(el_val_t stmt); -el_val_t is_fndef(el_val_t stmt); -el_val_t is_top_level_decl(el_val_t stmt); -el_val_t cgi_arg(el_val_t value, el_val_t has_value); -el_val_t vbd_is_restricted_name(el_val_t name); -el_val_t vbd_expr_has_restricted_call(el_val_t expr); -el_val_t vbd_has_restricted_call(el_val_t stmts); -el_val_t codegen(el_val_t stmts, el_val_t source); -el_val_t js_escape(el_val_t s); -el_val_t js_str_lit(el_val_t s); -el_val_t js_emit_line(el_val_t line); -el_val_t js_emit_blank(void); -el_val_t js_binop(el_val_t op); -el_val_t js_is_int_name(el_val_t name); -el_val_t js_add_int_name(el_val_t name); -el_val_t js_build_int_names_for_params(el_val_t params); -el_val_t js_is_int_call(el_val_t call_expr); -el_val_t js_cg_expr(el_val_t expr); -el_val_t js_next_match_id(void); -el_val_t js_cg_match(el_val_t expr); -el_val_t js_list_contains(el_val_t lst, el_val_t s); -el_val_t js_cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared); -el_val_t js_strip_outer_parens(el_val_t s); -el_val_t js_cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t js_cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared); -el_val_t js_cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t js_cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared); -el_val_t js_params_str(el_val_t params); -el_val_t js_transform_implicit_return(el_val_t body); -el_val_t js_cg_fn(el_val_t stmt); -el_val_t js_is_fndef(el_val_t stmt); -el_val_t js_is_top_level_decl(el_val_t stmt); -el_val_t codegen_js(el_val_t stmts, el_val_t source); -el_val_t compile(el_val_t source); -el_val_t compile_js(el_val_t source); -el_val_t compile_dispatch(el_val_t tgt, el_val_t source); -el_val_t detect_target(el_val_t argv); -el_val_t strip_flags(el_val_t argv); -el_val_t detect_emit_header(el_val_t argv); -el_val_t type_node_to_el(el_val_t t); -el_val_t emit_header(el_val_t stmts, el_val_t hdr_path); -el_val_t dirname_of(el_val_t path); -el_val_t parse_import_line(el_val_t trimmed, el_val_t dir); -el_val_t resolve_imports(el_val_t src_path); - -el_val_t lex_is_digit(el_val_t ch) { - if (str_eq(ch, EL_STR("0"))) { - return 1; - } - if (str_eq(ch, EL_STR("1"))) { - return 1; - } - if (str_eq(ch, EL_STR("2"))) { - return 1; - } - if (str_eq(ch, EL_STR("3"))) { - return 1; - } - if (str_eq(ch, EL_STR("4"))) { - return 1; - } - if (str_eq(ch, EL_STR("5"))) { - return 1; - } - if (str_eq(ch, EL_STR("6"))) { - return 1; - } - if (str_eq(ch, EL_STR("7"))) { - return 1; - } - if (str_eq(ch, EL_STR("8"))) { - return 1; - } - if (str_eq(ch, EL_STR("9"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t lex_is_alpha(el_val_t ch) { - if (str_eq(ch, EL_STR("a"))) { - return 1; - } - if (str_eq(ch, EL_STR("b"))) { - return 1; - } - if (str_eq(ch, EL_STR("c"))) { - return 1; - } - if (str_eq(ch, EL_STR("d"))) { - return 1; - } - if (str_eq(ch, EL_STR("e"))) { - return 1; - } - if (str_eq(ch, EL_STR("f"))) { - return 1; - } - if (str_eq(ch, EL_STR("g"))) { - return 1; - } - if (str_eq(ch, EL_STR("h"))) { - return 1; - } - if (str_eq(ch, EL_STR("i"))) { - return 1; - } - if (str_eq(ch, EL_STR("j"))) { - return 1; - } - if (str_eq(ch, EL_STR("k"))) { - return 1; - } - if (str_eq(ch, EL_STR("l"))) { - return 1; - } - if (str_eq(ch, EL_STR("m"))) { - return 1; - } - if (str_eq(ch, EL_STR("n"))) { - return 1; - } - if (str_eq(ch, EL_STR("o"))) { - return 1; - } - if (str_eq(ch, EL_STR("p"))) { - return 1; - } - if (str_eq(ch, EL_STR("q"))) { - return 1; - } - if (str_eq(ch, EL_STR("r"))) { - return 1; - } - if (str_eq(ch, EL_STR("s"))) { - return 1; - } - if (str_eq(ch, EL_STR("t"))) { - return 1; - } - if (str_eq(ch, EL_STR("u"))) { - return 1; - } - if (str_eq(ch, EL_STR("v"))) { - return 1; - } - if (str_eq(ch, EL_STR("w"))) { - return 1; - } - if (str_eq(ch, EL_STR("x"))) { - return 1; - } - if (str_eq(ch, EL_STR("y"))) { - return 1; - } - if (str_eq(ch, EL_STR("z"))) { - return 1; - } - if (str_eq(ch, EL_STR("A"))) { - return 1; - } - if (str_eq(ch, EL_STR("B"))) { - return 1; - } - if (str_eq(ch, EL_STR("C"))) { - return 1; - } - if (str_eq(ch, EL_STR("D"))) { - return 1; - } - if (str_eq(ch, EL_STR("E"))) { - return 1; - } - if (str_eq(ch, EL_STR("F"))) { - return 1; - } - if (str_eq(ch, EL_STR("G"))) { - return 1; - } - if (str_eq(ch, EL_STR("H"))) { - return 1; - } - if (str_eq(ch, EL_STR("I"))) { - return 1; - } - if (str_eq(ch, EL_STR("J"))) { - return 1; - } - if (str_eq(ch, EL_STR("K"))) { - return 1; - } - if (str_eq(ch, EL_STR("L"))) { - return 1; - } - if (str_eq(ch, EL_STR("M"))) { - return 1; - } - if (str_eq(ch, EL_STR("N"))) { - return 1; - } - if (str_eq(ch, EL_STR("O"))) { - return 1; - } - if (str_eq(ch, EL_STR("P"))) { - return 1; - } - if (str_eq(ch, EL_STR("Q"))) { - return 1; - } - if (str_eq(ch, EL_STR("R"))) { - return 1; - } - if (str_eq(ch, EL_STR("S"))) { - return 1; - } - if (str_eq(ch, EL_STR("T"))) { - return 1; - } - if (str_eq(ch, EL_STR("U"))) { - return 1; - } - if (str_eq(ch, EL_STR("V"))) { - return 1; - } - if (str_eq(ch, EL_STR("W"))) { - return 1; - } - if (str_eq(ch, EL_STR("X"))) { - return 1; - } - if (str_eq(ch, EL_STR("Y"))) { - return 1; - } - if (str_eq(ch, EL_STR("Z"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_alnum_or_underscore(el_val_t ch) { - if (lex_is_digit(ch)) { - return 1; - } - if (lex_is_alpha(ch)) { - return 1; - } - if (str_eq(ch, EL_STR("_"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t lex_is_whitespace(el_val_t ch) { - if (str_eq(ch, EL_STR(" "))) { - return 1; - } - if (str_eq(ch, EL_STR("\t"))) { - return 1; - } - if (str_eq(ch, EL_STR("\n"))) { - return 1; - } - if (str_eq(ch, EL_STR("\r"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t make_tok(el_val_t kind, el_val_t value) { - return el_map_new(2, "kind", kind, "value", value); - return 0; -} - -el_val_t keyword_kind(el_val_t word) { - if (str_eq(word, EL_STR("let"))) { - return EL_STR("Let"); - } - if (str_eq(word, EL_STR("fn"))) { - return EL_STR("Fn"); - } - if (str_eq(word, EL_STR("type"))) { - return EL_STR("Type"); - } - if (str_eq(word, EL_STR("enum"))) { - return EL_STR("Enum"); - } - if (str_eq(word, EL_STR("match"))) { - return EL_STR("Match"); - } - if (str_eq(word, EL_STR("return"))) { - return EL_STR("Return"); - } - if (str_eq(word, EL_STR("if"))) { - return EL_STR("If"); - } - if (str_eq(word, EL_STR("else"))) { - return EL_STR("Else"); - } - if (str_eq(word, EL_STR("for"))) { - return EL_STR("For"); - } - if (str_eq(word, EL_STR("in"))) { - return EL_STR("In"); - } - if (str_eq(word, EL_STR("while"))) { - return EL_STR("While"); - } - if (str_eq(word, EL_STR("import"))) { - return EL_STR("Import"); - } - if (str_eq(word, EL_STR("from"))) { - return EL_STR("From"); - } - if (str_eq(word, EL_STR("as"))) { - return EL_STR("As"); - } - if (str_eq(word, EL_STR("with"))) { - return EL_STR("With"); - } - if (str_eq(word, EL_STR("sealed"))) { - return EL_STR("Sealed"); - } - if (str_eq(word, EL_STR("activate"))) { - return EL_STR("Activate"); - } - if (str_eq(word, EL_STR("where"))) { - return EL_STR("Where"); - } - if (str_eq(word, EL_STR("test"))) { - return EL_STR("Test"); - } - if (str_eq(word, EL_STR("seed"))) { - return EL_STR("Seed"); - } - if (str_eq(word, EL_STR("assert"))) { - return EL_STR("Assert"); - } - if (str_eq(word, EL_STR("protocol"))) { - return EL_STR("Protocol"); - } - if (str_eq(word, EL_STR("impl"))) { - return EL_STR("Impl"); - } - if (str_eq(word, EL_STR("retry"))) { - return EL_STR("Retry"); - } - if (str_eq(word, EL_STR("times"))) { - return EL_STR("Times"); - } - if (str_eq(word, EL_STR("fallback"))) { - return EL_STR("Fallback"); - } - if (str_eq(word, EL_STR("reason"))) { - return EL_STR("Reason"); - } - if (str_eq(word, EL_STR("parallel"))) { - return EL_STR("Parallel"); - } - if (str_eq(word, EL_STR("trace"))) { - return EL_STR("Trace"); - } - if (str_eq(word, EL_STR("requires"))) { - return EL_STR("Requires"); - } - if (str_eq(word, EL_STR("deploy"))) { - return EL_STR("Deploy"); - } - if (str_eq(word, EL_STR("to"))) { - return EL_STR("To"); - } - if (str_eq(word, EL_STR("via"))) { - return EL_STR("Via"); - } - if (str_eq(word, EL_STR("target"))) { - return EL_STR("Target"); - } - if (str_eq(word, EL_STR("true"))) { - return EL_STR("Bool"); - } - if (str_eq(word, EL_STR("false"))) { - return EL_STR("Bool"); - } - if (str_eq(word, EL_STR("cgi"))) { - return EL_STR("Cgi"); - } - if (str_eq(word, EL_STR("service"))) { - return EL_STR("Service"); - } - if (str_eq(word, EL_STR("manager"))) { - return EL_STR("Manager"); - } - if (str_eq(word, EL_STR("engine"))) { - return EL_STR("Engine"); - } - if (str_eq(word, EL_STR("accessor"))) { - return EL_STR("Accessor"); - } - if (str_eq(word, EL_STR("vessel"))) { - return EL_STR("Vessel"); - } - if (str_eq(word, EL_STR("extern"))) { - return EL_STR("Extern"); - } - return EL_STR(""); - return 0; -} - -el_val_t scan_digits(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t parts = native_list_empty(); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (lex_is_digit(ch)) { - parts = native_list_append(parts, ch); - i = (i + 1); - } else { - running = 0; - } - } - } - return el_map_new(2, "text", str_join(parts, EL_STR("")), "pos", i); - return 0; -} - -el_val_t scan_ident(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t parts = native_list_empty(); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (is_alnum_or_underscore(ch)) { - parts = native_list_append(parts, ch); - i = (i + 1); - } else { - running = 0; - } - } - } - return el_map_new(2, "text", str_join(parts, EL_STR("")), "pos", i); - return 0; -} - -el_val_t substr_at(el_val_t chars, el_val_t start, el_val_t total, el_val_t needle) { - el_val_t nchars = native_string_chars(needle); - el_val_t nlen = native_list_len(nchars); - if ((start + nlen) > total) { - return 0; - } - el_val_t i = 0; - el_val_t matched = 1; - while (i < nlen) { - el_val_t a = native_list_get(chars, (start + i)); - el_val_t b = native_list_get(nchars, i); - if (str_eq(a, b)) { - i = (i + 1); - } else { - matched = 0; - EL_NULL; - i = nlen; - } - } - return matched; - return 0; -} - -el_val_t str_has(el_val_t s, el_val_t needle) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t i = 0; - el_val_t found = 0; - while (i < total) { - if (substr_at(chars, i, total, needle)) { - found = 1; - i = total; - } else { - i = (i + 1); - } - } - return found; - return 0; -} - -el_val_t looks_like_code(el_val_t s) { - if (str_has(s, EL_STR("= total) { - scanning = 0; - } else { - el_val_t lc = native_list_get(chars, i); - if (str_eq(lc, EL_STR("\n"))) { - scanning = 0; - } else { - i = (i + 1); - } - } - } - prev = EL_STR(""); - } - } else { - if (str_eq(next_ch, EL_STR("*"))) { - i = (i + 2); - el_val_t scanning2 = 1; - while (scanning2) { - if (i >= total) { - scanning2 = 0; - } else { - el_val_t bc = native_list_get(chars, i); - if (str_eq(bc, EL_STR("*"))) { - el_val_t after = (i + 1); - if (after < total) { - el_val_t nc2 = native_list_get(chars, after); - if (str_eq(nc2, EL_STR("/"))) { - i = (after + 1); - scanning2 = 0; - } else { - i = (i + 1); - } - } else { - i = (i + 1); - } - } else { - i = (i + 1); - } - } - } - prev = EL_STR(""); - } else { - out_parts = native_list_append(out_parts, ch); - prev = ch; - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("'"))) { - in_squote = 1; - out_parts = native_list_append(out_parts, ch); - prev = ch; - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("\""))) { - in_dquote = 1; - out_parts = native_list_append(out_parts, ch); - prev = ch; - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("`"))) { - in_btick = 1; - out_parts = native_list_append(out_parts, ch); - prev = ch; - i = (i + 1); - } else { - out_parts = native_list_append(out_parts, ch); - prev = ch; - i = (i + 1); - } - } - } - } - } - } - return str_join(out_parts, EL_STR("")); - return 0; -} - -el_val_t scan_string(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t parts = native_list_empty(); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\\"))) { - el_val_t next_i = (i + 1); - if (next_i < total) { - el_val_t next_ch = native_list_get(chars, next_i); - if (str_eq(next_ch, EL_STR("\""))) { - parts = native_list_append(parts, EL_STR("\"")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("n"))) { - parts = native_list_append(parts, EL_STR("\n")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("t"))) { - parts = native_list_append(parts, EL_STR("\t")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("r"))) { - parts = native_list_append(parts, EL_STR("\r")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("\\"))) { - parts = native_list_append(parts, EL_STR("\\")); - i = (next_i + 1); - } else { - parts = native_list_append(parts, next_ch); - i = (next_i + 1); - } - } - } - } - } - } else { - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("\""))) { - i = (i + 1); - running = 0; - } else { - parts = native_list_append(parts, ch); - i = (i + 1); - } - } - } - } - return el_map_new(2, "text", str_join(parts, EL_STR("")), "pos", i); - return 0; -} - -el_val_t lex(el_val_t source) { - el_val_t chars = native_string_chars(source); - el_val_t total = native_list_len(chars); - el_val_t tokens = native_list_empty(); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (lex_is_whitespace(ch)) { - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("/"))) { - el_val_t next_i = (i + 1); - if (next_i < total) { - el_val_t next_ch = native_list_get(chars, next_i); - if (str_eq(next_ch, EL_STR("/"))) { - i = (i + 2); - el_val_t running2 = 1; - while (running2) { - if (i >= total) { - running2 = 0; - } else { - el_val_t lch = native_list_get(chars, i); - if (str_eq(lch, EL_STR("\n"))) { - running2 = 0; - } else { - i = (i + 1); - } - } - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Slash"), EL_STR("/"))); - i = (i + 1); - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Slash"), EL_STR("/"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("\""))) { - el_val_t result = scan_string(chars, (i + 1), total); - el_val_t str_text = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - el_val_t clean_text = str_text; - if (looks_like_code(str_text)) { - clean_text = strip_code_comments(str_text); - } - tokens = native_list_append(tokens, make_tok(EL_STR("Str"), clean_text)); - i = new_pos; - } else { - if (lex_is_digit(ch)) { - el_val_t result = scan_digits(chars, i, total); - el_val_t num_text = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - if (new_pos < total) { - el_val_t dot_ch = native_list_get(chars, new_pos); - if (str_eq(dot_ch, EL_STR("."))) { - el_val_t after_dot = (new_pos + 1); - if (after_dot < total) { - el_val_t after_dot_ch = native_list_get(chars, after_dot); - if (lex_is_digit(after_dot_ch)) { - el_val_t frac_result = scan_digits(chars, after_dot, total); - el_val_t frac_text = el_get_field(frac_result, EL_STR("text")); - el_val_t frac_pos = el_get_field(frac_result, EL_STR("pos")); - tokens = native_list_append(tokens, make_tok(EL_STR("Float"), el_str_concat(el_str_concat(num_text, EL_STR(".")), frac_text))); - i = frac_pos; - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - if (lex_is_alpha(ch) || str_eq(ch, EL_STR("_"))) { - el_val_t result = scan_ident(chars, i, total); - el_val_t word = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - el_val_t kw = keyword_kind(word); - if (str_eq(kw, EL_STR(""))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Ident"), word)); - } else { - tokens = native_list_append(tokens, make_tok(kw, word)); - } - i = new_pos; - } else { - el_val_t peek_i = (i + 1); - el_val_t peek_ch = EL_STR(""); - if (peek_i < total) { - peek_ch = native_list_get(chars, peek_i); - } - if (str_eq(ch, EL_STR("="))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("EqEq"), EL_STR("=="))); - i = (i + 2); - } else { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("FatArrow"), EL_STR("=>"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Eq"), EL_STR("="))); - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("!"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("NotEq"), EL_STR("!="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Not"), EL_STR("!"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("<"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LtEq"), EL_STR("<="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Lt"), EL_STR("<"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR(">"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("GtEq"), EL_STR(">="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Gt"), EL_STR(">"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("&"))) { - if (str_eq(peek_ch, EL_STR("&"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("And"), EL_STR("&&"))); - i = (i + 2); - } else { - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("|"))) { - if (str_eq(peek_ch, EL_STR("|"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Or"), EL_STR("||"))); - i = (i + 2); - } else { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("PipeOp"), EL_STR("|>"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Pipe"), EL_STR("|"))); - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("-"))) { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Arrow"), EL_STR("->"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Minus"), EL_STR("-"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR(":"))) { - if (str_eq(peek_ch, EL_STR(":"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("ColonColon"), EL_STR("::"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Colon"), EL_STR(":"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("+"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Plus"), EL_STR("+"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("*"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Star"), EL_STR("*"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("%"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Percent"), EL_STR("%"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("("))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LParen"), EL_STR("("))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(")"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RParen"), EL_STR(")"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("{"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LBrace"), EL_STR("{"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("}"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RBrace"), EL_STR("}"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("["))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LBracket"), EL_STR("["))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("]"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RBracket"), EL_STR("]"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(","))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Comma"), EL_STR(","))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("."))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Dot"), EL_STR("."))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(";"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Semicolon"), EL_STR(";"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("@"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("At"), EL_STR("@"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("?"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("QuestionMark"), EL_STR("?"))); - i = (i + 1); - } else { - i = (i + 1); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - tokens = native_list_append(tokens, make_tok(EL_STR("Eof"), EL_STR(""))); - return tokens; - return 0; -} - -el_val_t tok_at(el_val_t tokens, el_val_t pos) { - return native_list_get(tokens, pos); - return 0; -} - -el_val_t tok_kind(el_val_t tokens, el_val_t pos) { - el_val_t t = native_list_get(tokens, pos); - return el_get_field(t, EL_STR("kind")); - return 0; -} - -el_val_t tok_value(el_val_t tokens, el_val_t pos) { - el_val_t t = native_list_get(tokens, pos); - return el_get_field(t, EL_STR("value")); - return 0; -} - -el_val_t expect(el_val_t tokens, el_val_t pos, el_val_t kind) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, kind)) { - return (pos + 1); - } - return (pos + 1); - return 0; -} - -el_val_t make_result(el_val_t node, el_val_t pos) { - return el_map_new(2, "node", node, "pos", pos); - return 0; -} - -el_val_t skip_type(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t p = (pos + 1); - p = skip_type(tokens, p); - p = expect(tokens, p, EL_STR("RBracket")); - return p; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Lt"))) { - p = (p + 1); - el_val_t depth = 1; - el_val_t running = 1; - while (running) { - el_val_t kk = tok_kind(tokens, p); - if (str_eq(kk, EL_STR("Eof"))) { - running = 0; - } else { - if (str_eq(kk, EL_STR("Lt"))) { - depth = (depth + 1); - p = (p + 1); - } else { - if (str_eq(kk, EL_STR("Gt"))) { - depth = (depth - 1); - p = (p + 1); - if (depth <= 0) { - running = 0; - } - } else { - p = (p + 1); - } - } - } - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("QuestionMark"))) { - p = (p + 1); - } - return p; - } - if (str_eq(k2, EL_STR("QuestionMark"))) { - return (p + 1); - } - return p; - } - return (pos + 1); - return 0; -} - -el_val_t parse_params(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("LParen")); - el_val_t params = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RParen"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t pname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t ptype = EL_STR(""); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ptype = tok_value(tokens, p); - } - p = skip_type(tokens, p); - el_val_t param = el_map_new(2, "name", pname, "type", ptype); - params = native_list_append(params, param); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RParen")); - return el_map_new(2, "params", params, "pos", p); - return 0; -} - -el_val_t parse_primary(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - el_val_t v = tok_value(tokens, pos); - if (str_eq(k, EL_STR("Int"))) { - return make_result(el_map_new(2, "expr", EL_STR("Int"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Float"))) { - return make_result(el_map_new(2, "expr", EL_STR("Float"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Str"))) { - return make_result(el_map_new(2, "expr", EL_STR("Str"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Bool"))) { - return make_result(el_map_new(2, "expr", EL_STR("Bool"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Ident"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("LParen"))) { - el_val_t r = parse_expr(tokens, (pos + 1)); - el_val_t node = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - p = expect(tokens, p, EL_STR("RParen")); - return make_result(node, p); - } - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t p = (pos + 1); - el_val_t elems = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBracket"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_expr(tokens, p); - el_val_t elem = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - elems = native_list_append(elems, elem); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBracket")); - return make_result(el_map_new(2, "expr", EL_STR("Array"), "elems", elems), p); - } - if (str_eq(k, EL_STR("LBrace"))) { - el_val_t no_block = state_get(EL_STR("__no_block_expr")); - if (str_eq(no_block, EL_STR("1"))) { - return make_result(el_map_new(1, "expr", EL_STR("Nil")), pos); - } - el_val_t p = (pos + 1); - el_val_t pairs = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t key = tok_value(tokens, p); - el_val_t new_p = (p + 1); - new_p = expect(tokens, new_p, EL_STR("Colon")); - el_val_t r = parse_expr(tokens, new_p); - el_val_t val_node = el_get_field(r, EL_STR("node")); - new_p = el_get_field(r, EL_STR("pos")); - el_val_t pair = el_map_new(2, "key", key, "value", val_node); - pairs = native_list_append(pairs, pair); - el_val_t k3 = tok_kind(tokens, new_p); - if (str_eq(k3, EL_STR("Comma"))) { - new_p = (new_p + 1); - } - if (new_p <= p) { - p = (p + 1); - } else { - p = new_p; - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(2, "expr", EL_STR("Map"), "pairs", pairs), p); - } - if (str_eq(k, EL_STR("If"))) { - el_val_t r = parse_if(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("Match"))) { - el_val_t r = parse_match(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("For"))) { - el_val_t r = parse_for_expr(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("Not"))) { - el_val_t r = parse_primary(tokens, (pos + 1)); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "expr", EL_STR("Not"), "inner", inner), p); - } - if (str_eq(k, EL_STR("Minus"))) { - el_val_t r = parse_primary(tokens, (pos + 1)); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "expr", EL_STR("Neg"), "inner", inner), p); - } - if (str_eq(k, EL_STR("Target"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("To"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Via"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Deploy"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Reason"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Times"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Fallback"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Retry"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Parallel"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Trace"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Requires"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Where"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("As"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("With"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Manager"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Engine"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Accessor"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Vessel"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - return make_result(el_map_new(1, "expr", EL_STR("Nil")), (pos + 1)); - return 0; -} - -el_val_t parse_if(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("If")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t cond = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t then_stmts = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - el_val_t has_else = 0; - el_val_t else_stmts = native_list_empty(); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Else"))) { - p = (p + 1); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("If"))) { - el_val_t r3 = parse_if(tokens, p); - el_val_t nested = el_get_field(r3, EL_STR("node")); - p = el_get_field(r3, EL_STR("pos")); - else_stmts = native_list_append(else_stmts, el_map_new(2, "stmt", EL_STR("Expr"), "value", nested)); - has_else = 1; - } else { - el_val_t r3 = parse_block(tokens, p); - else_stmts = el_get_field(r3, EL_STR("stmts")); - p = el_get_field(r3, EL_STR("pos")); - has_else = 1; - } - } - return make_result(el_map_new(5, "expr", EL_STR("If"), "cond", cond, "then", then_stmts, "else", else_stmts, "has_else", has_else), p); - return 0; -} - -el_val_t parse_match(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("Match")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t subject = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t arms = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r2 = parse_pattern(tokens, p); - el_val_t pattern = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - p = expect(tokens, p, EL_STR("FatArrow")); - el_val_t r3 = parse_expr(tokens, p); - el_val_t body = el_get_field(r3, EL_STR("node")); - p = el_get_field(r3, EL_STR("pos")); - el_val_t arm = el_map_new(2, "pattern", pattern, "body", body); - arms = native_list_append(arms, arm); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "expr", EL_STR("Match"), "subject", subject, "arms", arms), p); - return 0; -} - -el_val_t parse_pattern(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Ident"))) { - el_val_t v = tok_value(tokens, pos); - if (str_eq(v, EL_STR("_"))) { - return make_result(el_map_new(1, "pattern", EL_STR("Wildcard")), (pos + 1)); - } - return make_result(el_map_new(2, "pattern", EL_STR("Binding"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Int"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitInt"), "value", tok_value(tokens, pos)), (pos + 1)); - } - if (str_eq(k, EL_STR("Str"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitStr"), "value", tok_value(tokens, pos)), (pos + 1)); - } - if (str_eq(k, EL_STR("Bool"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitBool"), "value", tok_value(tokens, pos)), (pos + 1)); - } - return make_result(el_map_new(1, "pattern", EL_STR("Wildcard")), (pos + 1)); - return 0; -} - -el_val_t parse_for_expr(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("For")); - el_val_t item_name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("In")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t list_expr = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(4, "expr", EL_STR("For"), "item", item_name, "list", list_expr, "body", body), p); - return 0; -} - -el_val_t parse_block(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("LBrace")); - el_val_t stmts = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_stmt(tokens, p); - el_val_t stmt = el_get_field(r, EL_STR("node")); - el_val_t new_p = el_get_field(r, EL_STR("pos")); - stmts = native_list_append(stmts, stmt); - if (new_p <= p) { - p = (p + 1); - } else { - p = new_p; - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return el_map_new(2, "stmts", stmts, "pos", p); - return 0; -} - -el_val_t is_duration_unit(el_val_t name) { - if (str_eq(name, EL_STR("nanos"))) { - return 1; - } - if (str_eq(name, EL_STR("nano"))) { - return 1; - } - if (str_eq(name, EL_STR("millis"))) { - return 1; - } - if (str_eq(name, EL_STR("milli"))) { - return 1; - } - if (str_eq(name, EL_STR("millisecond"))) { - return 1; - } - if (str_eq(name, EL_STR("milliseconds"))) { - return 1; - } - if (str_eq(name, EL_STR("second"))) { - return 1; - } - if (str_eq(name, EL_STR("seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("minute"))) { - return 1; - } - if (str_eq(name, EL_STR("minutes"))) { - return 1; - } - if (str_eq(name, EL_STR("hour"))) { - return 1; - } - if (str_eq(name, EL_STR("hours"))) { - return 1; - } - if (str_eq(name, EL_STR("day"))) { - return 1; - } - if (str_eq(name, EL_STR("days"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t parse_postfix(el_val_t tokens, el_val_t pos) { - el_val_t r = parse_primary(tokens, pos); - el_val_t node = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - el_val_t primary_kind = el_get_field(node, EL_STR("expr")); - if (str_eq(primary_kind, EL_STR("Int"))) { - el_val_t dot_kind = tok_kind(tokens, p); - if (str_eq(dot_kind, EL_STR("Dot"))) { - el_val_t unit_kind = tok_kind(tokens, (p + 1)); - if (str_eq(unit_kind, EL_STR("Ident"))) { - el_val_t unit_name = tok_value(tokens, (p + 1)); - if (is_duration_unit(unit_name)) { - el_val_t count_str = el_get_field(node, EL_STR("value")); - node = el_map_new(3, "expr", EL_STR("DurationLit"), "count", count_str, "unit", unit_name); - p = (p + 2); - } - } - } - } - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("LParen"))) { - p = (p + 1); - el_val_t args = native_list_empty(); - el_val_t run2 = 1; - while (run2) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RParen"))) { - run2 = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - run2 = 0; - } else { - el_val_t r2 = parse_expr(tokens, p); - el_val_t arg = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - args = native_list_append(args, arg); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RParen")); - node = el_map_new(3, "expr", EL_STR("Call"), "func", node, "args", args); - } else { - if (str_eq(k, EL_STR("Dot"))) { - el_val_t field = tok_value(tokens, (p + 1)); - p = (p + 2); - node = el_map_new(3, "expr", EL_STR("Field"), "object", node, "field", field); - } else { - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t r2 = parse_expr(tokens, (p + 1)); - el_val_t idx = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - p = expect(tokens, p, EL_STR("RBracket")); - node = el_map_new(3, "expr", EL_STR("Index"), "object", node, "index", idx); - } else { - if (str_eq(k, EL_STR("QuestionMark"))) { - p = (p + 1); - node = el_map_new(2, "expr", EL_STR("Try"), "inner", node); - } else { - running = 0; - } - } - } - } - } - return make_result(node, p); - return 0; -} - -el_val_t op_precedence(el_val_t kind) { - if (str_eq(kind, EL_STR("Or"))) { - return 1; - } - if (str_eq(kind, EL_STR("And"))) { - return 2; - } - if (str_eq(kind, EL_STR("EqEq"))) { - return 3; - } - if (str_eq(kind, EL_STR("NotEq"))) { - return 3; - } - if (str_eq(kind, EL_STR("Lt"))) { - return 4; - } - if (str_eq(kind, EL_STR("Gt"))) { - return 4; - } - if (str_eq(kind, EL_STR("LtEq"))) { - return 4; - } - if (str_eq(kind, EL_STR("GtEq"))) { - return 4; - } - if (str_eq(kind, EL_STR("Plus"))) { - return 5; - } - if (str_eq(kind, EL_STR("Minus"))) { - return 5; - } - if (str_eq(kind, EL_STR("Star"))) { - return 6; - } - if (str_eq(kind, EL_STR("Slash"))) { - return 6; - } - return 0; - return 0; -} - -el_val_t is_binop(el_val_t kind) { - if (str_eq(kind, EL_STR("Or"))) { - return 1; - } - if (str_eq(kind, EL_STR("And"))) { - return 1; - } - if (str_eq(kind, EL_STR("EqEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("NotEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("Lt"))) { - return 1; - } - if (str_eq(kind, EL_STR("Gt"))) { - return 1; - } - if (str_eq(kind, EL_STR("LtEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("GtEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("Plus"))) { - return 1; - } - if (str_eq(kind, EL_STR("Minus"))) { - return 1; - } - if (str_eq(kind, EL_STR("Star"))) { - return 1; - } - if (str_eq(kind, EL_STR("Slash"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t parse_binop(el_val_t tokens, el_val_t pos, el_val_t min_prec) { - el_val_t r = parse_postfix(tokens, pos); - el_val_t left = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - el_val_t prec = op_precedence(k); - if (is_binop(k)) { - if (prec >= min_prec) { - el_val_t op = k; - el_val_t r2 = parse_binop(tokens, (p + 1), (prec + 1)); - el_val_t right = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - left = el_map_new(4, "expr", EL_STR("BinOp"), "op", op, "left", left, "right", right); - } else { - running = 0; - } - } else { - running = 0; - } - } - return make_result(left, p); - return 0; -} - -el_val_t parse_expr(el_val_t tokens, el_val_t pos) { - return parse_binop(tokens, pos, 1); - return 0; -} - -el_val_t parse_stmt(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Let"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t ltype = EL_STR(""); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Colon"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ltype = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - p = expect(tokens, p, EL_STR("Eq")); - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(4, "stmt", EL_STR("Let"), "name", name, "value", val, "type", ltype), p); - } - if (str_eq(k, EL_STR("Return"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", el_map_new(1, "expr", EL_STR("Nil"))), p); - } - if (str_eq(k2, EL_STR("Eof"))) { - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", el_map_new(1, "expr", EL_STR("Nil"))), p); - } - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", val), p); - } - if (str_eq(k, EL_STR("Extern"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Fn"))) { - p = (p + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_params(tokens, p); - el_val_t params = el_get_field(r, EL_STR("params")); - p = el_get_field(r, EL_STR("pos")); - el_val_t ret_type = EL_STR(""); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Arrow"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ret_type = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - return make_result(el_map_new(4, "stmt", EL_STR("ExternFn"), "name", name, "params", params, "ret_type", ret_type), p); - } - } - if (str_eq(k, EL_STR("Fn"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_params(tokens, p); - el_val_t params = el_get_field(r, EL_STR("params")); - p = el_get_field(r, EL_STR("pos")); - el_val_t ret_type = EL_STR(""); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Arrow"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ret_type = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(5, "stmt", EL_STR("FnDef"), "name", name, "params", params, "body", body, "ret_type", ret_type), p); - } - if (str_eq(k, EL_STR("Type"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t fields = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - p = skip_type(tokens, p); - fields = native_list_append(fields, el_map_new(1, "name", fname)); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "stmt", EL_STR("TypeDef"), "name", name, "fields", fields), p); - } - if (str_eq(k, EL_STR("Enum"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t variants = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t vname = tok_value(tokens, p); - p = (p + 1); - variants = native_list_append(variants, el_map_new(1, "name", vname)); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "stmt", EL_STR("EnumDef"), "name", name, "variants", variants), p); - } - if (str_eq(k, EL_STR("Import"))) { - el_val_t p = (pos + 1); - el_val_t path = tok_value(tokens, p); - p = (p + 1); - return make_result(el_map_new(2, "stmt", EL_STR("Import"), "path", path), p); - } - if (str_eq(k, EL_STR("From"))) { - el_val_t p = (pos + 1); - el_val_t module_name = tok_value(tokens, p); - p = (p + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Import"))) { - p = (p + 1); - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("LBrace"))) { - p = (p + 1); - el_val_t running = 1; - while (running) { - el_val_t k4 = tok_kind(tokens, p); - if (str_eq(k4, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k4, EL_STR("Eof"))) { - running = 0; - } else { - p = (p + 1); - el_val_t k5 = tok_kind(tokens, p); - if (str_eq(k5, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - } - return make_result(el_map_new(2, "stmt", EL_STR("Import"), "path", module_name), p); - } - if (str_eq(k, EL_STR("While"))) { - el_val_t p = (pos + 1); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t cond = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(3, "stmt", EL_STR("While"), "cond", cond, "body", body), p); - } - if (str_eq(k, EL_STR("For"))) { - el_val_t p = (pos + 1); - el_val_t item_name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("In")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t list_expr = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(4, "stmt", EL_STR("For"), "item", item_name, "list", list_expr, "body", body), p); - } - if (str_eq(k, EL_STR("At"))) { - el_val_t p = (pos + 1); - el_val_t dec_name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_stmt(tokens, p); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p2 = el_get_field(r, EL_STR("pos")); - el_val_t inner_kind = el_get_field(inner, EL_STR("stmt")); - if (str_eq(inner_kind, EL_STR("FnDef"))) { - el_val_t with_dec = el_map_new(6, "stmt", EL_STR("FnDef"), "name", el_get_field(inner, EL_STR("name")), "params", el_get_field(inner, EL_STR("params")), "body", el_get_field(inner, EL_STR("body")), "ret_type", el_get_field(inner, EL_STR("ret_type")), "decorator", dec_name); - return make_result(with_dec, p2); - } - return r; - } - if (str_eq(k, EL_STR("Cgi"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t dharma_id = EL_STR(""); - el_val_t principal = EL_STR(""); - el_val_t network = EL_STR(""); - el_val_t engram = EL_STR(""); - el_val_t has_dharma_id = 0; - el_val_t has_principal = 0; - el_val_t has_network = 0; - el_val_t has_engram = 0; - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t fval = tok_value(tokens, p); - p = (p + 1); - if (str_eq(fname, EL_STR("dharma_id"))) { - dharma_id = fval; - has_dharma_id = 1; - } - if (str_eq(fname, EL_STR("principal"))) { - principal = fval; - has_principal = 1; - } - if (str_eq(fname, EL_STR("network"))) { - network = fval; - has_network = 1; - } - if (str_eq(fname, EL_STR("engram"))) { - engram = fval; - has_engram = 1; - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(10, "stmt", EL_STR("CgiBlock"), "name", name, "dharma_id", dharma_id, "principal", principal, "network", network, "engram", engram, "has_dharma_id", has_dharma_id, "has_principal", has_principal, "has_network", has_network, "has_engram", has_engram), p); - } - if (str_eq(k, EL_STR("Service"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t sponsor = EL_STR(""); - el_val_t domain = EL_STR(""); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t fval = tok_value(tokens, p); - p = (p + 1); - if (str_eq(fname, EL_STR("sponsor"))) { - sponsor = fval; - } - if (str_eq(fname, EL_STR("domain"))) { - domain = fval; - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(4, "stmt", EL_STR("ServiceBlock"), "name", name, "sponsor", sponsor, "domain", domain), p); - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t k2 = tok_kind(tokens, (pos + 1)); - if (str_eq(k2, EL_STR("Eq"))) { - el_val_t name = tok_value(tokens, pos); - el_val_t p = (pos + 2); - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(3, "stmt", EL_STR("Assign"), "name", name, "value", val), p); - } - } - el_val_t r = parse_expr(tokens, pos); - el_val_t val = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "stmt", EL_STR("Expr"), "value", val), p); - return 0; -} - -el_val_t parse(el_val_t tokens) { - el_val_t total = native_list_len(tokens); - el_val_t stmts = native_list_empty(); - el_val_t pos = 0; - el_val_t running = 1; - while (running) { - if (pos >= total) { - running = 0; - } else { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_stmt(tokens, pos); - el_val_t stmt = el_get_field(r, EL_STR("node")); - el_val_t new_pos = el_get_field(r, EL_STR("pos")); - stmts = native_list_append(stmts, stmt); - if (new_pos <= pos) { - pos = (pos + 1); - } else { - pos = new_pos; - } - } - } - } - return stmts; - return 0; -} - -el_val_t nibble_to_hex(el_val_t n) { - return str_char_at(EL_STR("0123456789abcdef"), n); - return 0; -} - -el_val_t byte_to_hex2(el_val_t b) { - el_val_t hi = (b / 16); - el_val_t lo = (b - (hi * 16)); - return el_str_concat(nibble_to_hex(hi), nibble_to_hex(lo)); - return 0; -} - -el_val_t is_hex_digit_byte(el_val_t b) { - if (b >= 48) { - if (b <= 57) { - return 1; - } - } - if (b >= 65) { - if (b <= 70) { - return 1; - } - } - if (b >= 97) { - if (b <= 102) { - return 1; - } - } - return 0; - return 0; -} - -el_val_t c_escape(el_val_t s) { - el_val_t total = str_len(s); - el_val_t parts = native_list_empty(); - el_val_t i = 0; - el_val_t prev_was_hex_escape = 0; - while (i < total) { - el_val_t bval = str_char_code(s, i); - if (prev_was_hex_escape) { - if (is_hex_digit_byte(bval)) { - parts = native_list_append(parts, EL_STR("\"\"")); - } - } - prev_was_hex_escape = 0; - if (bval == 34) { - parts = native_list_append(parts, EL_STR("\\\"")); - } else { - if (bval == 92) { - parts = native_list_append(parts, EL_STR("\\\\")); - } else { - if (bval == 10) { - parts = native_list_append(parts, EL_STR("\\n")); - } else { - if (bval == 13) { - parts = native_list_append(parts, EL_STR("\\r")); - } else { - if (bval == 9) { - parts = native_list_append(parts, EL_STR("\\t")); - } else { - if (bval >= 128) { - parts = native_list_append(parts, el_str_concat(EL_STR("\\x"), byte_to_hex2(bval))); - prev_was_hex_escape = 1; - } else { - parts = native_list_append(parts, str_char_at(s, i)); - } - } - } - } - } - } - i = (i + 1); - } - return str_join(parts, EL_STR("")); - return 0; -} - -el_val_t c_str_lit(el_val_t s) { - return el_str_concat(el_str_concat(EL_STR("\""), c_escape(s)), EL_STR("\"")); - return 0; -} - -el_val_t el_type_to_c(el_val_t type_str) { - if (str_eq(type_str, EL_STR("String"))) { - return EL_STR("const char*"); - } - if (str_eq(type_str, EL_STR("Int"))) { - return EL_STR("int64_t"); - } - if (str_eq(type_str, EL_STR("Bool"))) { - return EL_STR("int"); - } - if (str_eq(type_str, EL_STR("Float"))) { - return EL_STR("double"); - } - if (str_eq(type_str, EL_STR("Void"))) { - return EL_STR("void"); - } - if (str_eq(type_str, EL_STR("void"))) { - return EL_STR("void"); - } - return EL_STR("void*"); - return 0; -} - -el_val_t emit_line(el_val_t line) { - println(line); - return 0; -} - -el_val_t emit_blank(void) { - println(EL_STR("")); - return 0; -} - -el_val_t binop_to_c(el_val_t op) { - if (str_eq(op, EL_STR("Plus"))) { - return EL_STR("+"); - } - if (str_eq(op, EL_STR("Minus"))) { - return EL_STR("-"); - } - if (str_eq(op, EL_STR("Star"))) { - return EL_STR("*"); - } - if (str_eq(op, EL_STR("Slash"))) { - return EL_STR("/"); - } - if (str_eq(op, EL_STR("EqEq"))) { - return EL_STR("=="); - } - if (str_eq(op, EL_STR("NotEq"))) { - return EL_STR("!="); - } - if (str_eq(op, EL_STR("Lt"))) { - return EL_STR("<"); - } - if (str_eq(op, EL_STR("Gt"))) { - return EL_STR(">"); - } - if (str_eq(op, EL_STR("LtEq"))) { - return EL_STR("<="); - } - if (str_eq(op, EL_STR("GtEq"))) { - return EL_STR(">="); - } - if (str_eq(op, EL_STR("And"))) { - return EL_STR("&&"); - } - if (str_eq(op, EL_STR("Or"))) { - return EL_STR("||"); - } - return op; - return 0; -} - -el_val_t duration_unit_nanos(el_val_t unit) { - if (str_eq(unit, EL_STR("nano"))) { - return EL_STR("1LL"); - } - if (str_eq(unit, EL_STR("nanos"))) { - return EL_STR("1LL"); - } - if (str_eq(unit, EL_STR("milli"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("millis"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("millisecond"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("milliseconds"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("second"))) { - return EL_STR("1000000000LL"); - } - if (str_eq(unit, EL_STR("seconds"))) { - return EL_STR("1000000000LL"); - } - if (str_eq(unit, EL_STR("minute"))) { - return EL_STR("60000000000LL"); - } - if (str_eq(unit, EL_STR("minutes"))) { - return EL_STR("60000000000LL"); - } - if (str_eq(unit, EL_STR("hour"))) { - return EL_STR("3600000000000LL"); - } - if (str_eq(unit, EL_STR("hours"))) { - return EL_STR("3600000000000LL"); - } - if (str_eq(unit, EL_STR("day"))) { - return EL_STR("86400000000000LL"); - } - if (str_eq(unit, EL_STR("days"))) { - return EL_STR("86400000000000LL"); - } - return EL_STR("1LL"); - return 0; -} - -el_val_t cg_expr(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Int"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("DurationLit"))) { - el_val_t count = el_get_field(expr, EL_STR("count")); - el_val_t unit = el_get_field(expr, EL_STR("unit")); - el_val_t mult = duration_unit_nanos(unit); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_from_nanos((el_val_t)("), count), EL_STR("LL * ")), mult), EL_STR("))")); - } - if (str_eq(kind, EL_STR("Float"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("el_from_float("), v), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Str"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(v)), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Bool"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - if (str_eq(v, EL_STR("true"))) { - return EL_STR("1"); - } - return EL_STR("0"); - } - if (str_eq(kind, EL_STR("Nil"))) { - return EL_STR("EL_NULL"); - } - if (str_eq(kind, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return name; - } - if (str_eq(kind, EL_STR("Not"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = cg_expr(inner); - return el_str_concat(EL_STR("!"), inner_c); - } - if (str_eq(kind, EL_STR("Neg"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = cg_expr(inner); - return el_str_concat(el_str_concat(EL_STR("(-"), inner_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - el_val_t left = el_get_field(expr, EL_STR("left")); - el_val_t right = el_get_field(expr, EL_STR("right")); - el_val_t left_c = cg_expr(left); - el_val_t right_c = cg_expr(right); - el_val_t left_kind = el_get_field(left, EL_STR("expr")); - el_val_t right_kind = el_get_field(right, EL_STR("expr")); - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - el_val_t left_is_inst = is_instant_expr(left); - el_val_t right_is_inst = is_instant_expr(right); - el_val_t left_is_dur = is_duration_expr(left); - el_val_t right_is_dur = is_duration_expr(right); - el_val_t left_is_ld = is_localdate_expr(left); - el_val_t right_is_ld = is_localdate_expr(right); - el_val_t left_is_lt = is_localtime_expr(left); - el_val_t right_is_lt = is_localtime_expr(right); - el_val_t left_is_ct = is_caltime_expr(left); - el_val_t right_is_ct = is_caltime_expr(right); - if (left_is_ld) { - if (str_eq(op, EL_STR("Plus"))) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_date_add_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("Lt"))) { - if (right_is_ld) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_date_lt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (right_is_ld) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_date_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (left_is_lt) { - if (str_eq(op, EL_STR("Plus"))) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_time_add_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (left_is_ct) { - if (str_eq(op, EL_STR("Plus"))) { - if (right_is_ct) { - time_record_violation(EL_STR("caltime_plus_caltime"), EL_STR("CalendarTime + CalendarTime is not allowed (use cal_to_instant + Duration)")); - return EL_STR("0 /* TIME_TYPE_ERROR: CalendarTime + CalendarTime */"); - } - } - } - el_val_t any_temporal = 0; - if (left_is_inst) { - any_temporal = 1; - } - if (right_is_inst) { - any_temporal = 1; - } - if (left_is_dur) { - any_temporal = 1; - } - if (right_is_dur) { - any_temporal = 1; - } - if (any_temporal) { - if (str_eq(op, EL_STR("Plus"))) { - if (left_is_inst) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_add_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_inst) { - time_record_violation(EL_STR("instant_plus_instant"), EL_STR("Instant + Instant is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Instant + Instant */"); - } - } - if (left_is_dur) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_add_dur("), right_c), EL_STR(", ")), left_c), EL_STR(")")); - } - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_add("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(right)) { - time_record_violation(EL_STR("duration_plus_int"), EL_STR("Duration + Int is not allowed (use duration_seconds(n) or N.seconds)")); - return EL_STR("0 /* TIME_TYPE_ERROR: Duration + Int */"); - } - } - if (right_is_dur) { - if (is_int_expr(left)) { - time_record_violation(EL_STR("duration_plus_int"), EL_STR("Int + Duration is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Int + Duration */"); - } - } - } - if (str_eq(op, EL_STR("Minus"))) { - if (left_is_inst) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_sub_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_diff("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_sub("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(right)) { - time_record_violation(EL_STR("duration_minus_int"), EL_STR("Duration - Int is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Duration - Int */"); - } - } - } - if (str_eq(op, EL_STR("Star"))) { - if (left_is_dur) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_scale("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (right_is_dur) { - if (is_int_expr(left)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_scale("), right_c), EL_STR(", ")), left_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("Slash"))) { - if (left_is_dur) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_div("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("Lt"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_lt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_dur) { - time_record_violation(EL_STR("instant_cmp_duration"), EL_STR("Instant < Duration is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Instant < Duration */"); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_lt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_inst) { - time_record_violation(EL_STR("duration_cmp_instant"), EL_STR("Duration < Instant is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Duration < Instant */"); - } - } - } - if (str_eq(op, EL_STR("LtEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_le("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_le("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("Gt"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_gt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_gt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("GtEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_ge("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_ge("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("NotEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_ne("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_ne("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Int"))) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("BinOp"))) { - el_val_t left_op = el_get_field(left, EL_STR("op")); - if (str_eq(left_op, EL_STR("Plus"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(right_kind, EL_STR("BinOp"))) { - el_val_t right_op = el_get_field(right, EL_STR("op")); - if (str_eq(right_op, EL_STR("Plus"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (is_int_name(lname)) { - if (is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - } - } - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (is_int_name(lname)) { - if (is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - } - } - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t arity = native_list_len(args); - el_val_t func_kind = el_get_field(func, EL_STR("expr")); - el_val_t args_parts = native_list_empty(); - el_val_t i = 0; - while (i < arity) { - el_val_t arg = native_list_get(args, i); - el_val_t arg_c = cg_expr(arg); - args_parts = native_list_append(args_parts, arg_c); - i = (i + 1); - } - el_val_t args_c = str_join(args_parts, EL_STR(", ")); - if (str_eq(func_kind, EL_STR("Ident"))) { - el_val_t fn_name = el_get_field(func, EL_STR("name")); - cap_check_call(fn_name); - arity_check_call(fn_name, arity); - if (str_eq(fn_name, EL_STR("sleep"))) { - if (arity == 1) { - el_val_t only_arg = native_list_get(args, 0); - if (is_duration_expr(only_arg)) { - return el_str_concat(el_str_concat(EL_STR("el_sleep_duration("), args_c), EL_STR(")")); - } - } - } - if (str_eq(fn_name, EL_STR("el_from_float"))) { - if (arity == 1) { - el_val_t only_arg = native_list_get(args, 0); - el_val_t arg_kind = el_get_field(only_arg, EL_STR("expr")); - if (str_eq(arg_kind, EL_STR("Float"))) { - el_val_t v = el_get_field(only_arg, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("el_from_float("), v), EL_STR(")")); - } - } - } - return el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(func_kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(func, EL_STR("object")); - el_val_t field = el_get_field(func, EL_STR("field")); - el_val_t obj_c = cg_expr(obj); - if (arity > 0) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(", ")), args_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(")")); - } - el_val_t fn_c = cg_expr(func); - return el_str_concat(el_str_concat(el_str_concat(fn_c, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t field = el_get_field(expr, EL_STR("field")); - el_val_t obj_c = cg_expr(obj); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", EL_STR(")), c_str_lit(field)), EL_STR("))")); - } - if (str_eq(kind, EL_STR("Index"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t idx = el_get_field(expr, EL_STR("index")); - el_val_t obj_c = cg_expr(obj); - el_val_t idx_c = cg_expr(idx); - el_val_t idx_kind = el_get_field(idx, EL_STR("expr")); - if (str_eq(idx_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_get("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - if (n == 0) { - return EL_STR("el_list_empty()"); - } - el_val_t items_parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t elem = native_list_get(elems, i); - el_val_t elem_c = cg_expr(elem); - items_parts = native_list_append(items_parts, elem_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_new("), native_int_to_str(n)), EL_STR(", ")), str_join(items_parts, EL_STR(", "))), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - if (n == 0) { - return EL_STR("el_map_new(0)"); - } - el_val_t items_parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t key = el_get_field(pair, EL_STR("key")); - el_val_t val = el_get_field(pair, EL_STR("value")); - el_val_t val_c = cg_expr(val); - items_parts = native_list_append(items_parts, el_str_concat(el_str_concat(c_str_lit(key), EL_STR(", ")), val_c)); - i = (i + 1); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_map_new("), native_int_to_str(n)), EL_STR(", ")), str_join(items_parts, EL_STR(", "))), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Try"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - return cg_expr(inner); - } - if (str_eq(kind, EL_STR("If"))) { - return cg_if_expr(expr); - } - if (str_eq(kind, EL_STR("Match"))) { - return cg_match(expr); - } - return EL_STR("EL_NULL"); - return 0; -} - -el_val_t next_match_id(void) { - el_val_t csv = state_get(EL_STR("__match_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__match_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t cg_match(el_val_t expr) { - el_val_t subject = el_get_field(expr, EL_STR("subject")); - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t subj_c = cg_expr(subject); - el_val_t id = next_match_id(); - el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id); - el_val_t result_var = el_str_concat(EL_STR("_match_result_"), id); - el_val_t done_label = el_str_concat(EL_STR("_match_done_"), id); - el_val_t parts = native_list_empty(); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), subj_var), EL_STR(" = ")), subj_c), EL_STR("; el_val_t ")), result_var), EL_STR(" = 0; "))); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t pat = el_get_field(arm, EL_STR("pattern")); - el_val_t body = el_get_field(arm, EL_STR("body")); - el_val_t pkind = el_get_field(pat, EL_STR("pattern")); - el_val_t body_c = cg_expr(body); - if (str_eq(pkind, EL_STR("Wildcard"))) { - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{ "), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "))); - } else { - if (str_eq(pkind, EL_STR("Binding"))) { - el_val_t bname = el_get_field(pat, EL_STR("name")); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{ el_val_t "), bname), EL_STR(" = ")), subj_var), EL_STR("; ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "))); - } else { - if (str_eq(pkind, EL_STR("LitInt"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("if ("), subj_var), EL_STR(" == ")), v), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "))); - } else { - if (str_eq(pkind, EL_STR("LitStr"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("if (str_eq("), subj_var), EL_STR(", EL_STR(")), c_str_lit(v)), EL_STR("))) { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "))); - } else { - if (str_eq(pkind, EL_STR("LitBool"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - el_val_t bv = EL_STR("0"); - if (str_eq(v, EL_STR("true"))) { - bv = EL_STR("1"); - } - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("if ("), subj_var), EL_STR(" == ")), bv), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "))); - } else { - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{ "), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "))); - } - } - } - } - } - i = (i + 1); - } - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(done_label, EL_STR(":; ")), result_var), EL_STR("; })"))); - return str_join(parts, EL_STR("")); - return 0; -} - -el_val_t next_if_id(void) { - el_val_t csv = state_get(EL_STR("__if_expr_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__if_expr_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t cg_if_expr_arm(el_val_t stmts, el_val_t result_var) { - el_val_t n = native_list_len(stmts); - el_val_t parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t s = native_list_get(stmts, i); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - el_val_t is_last = 0; - if (i == (n - 1)) { - is_last = 1; - } - if (str_eq(sk, EL_STR("Let"))) { - el_val_t name = el_get_field(s, EL_STR("name")); - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), name), EL_STR(" = ")), val_c), EL_STR("; "))); - } else { - if (str_eq(sk, EL_STR("Return"))) { - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(result_var, EL_STR(" = (")), val_c), EL_STR("); "))); - } else { - if (str_eq(sk, EL_STR("Expr"))) { - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - if (is_last) { - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(result_var, EL_STR(" = (")), val_c), EL_STR("); "))); - } else { - parts = native_list_append(parts, el_str_concat(el_str_concat(EL_STR("(void)("), val_c), EL_STR("); "))); - } - } else { - if (str_eq(sk, EL_STR("Assign"))) { - el_val_t aname = el_get_field(s, EL_STR("name")); - el_val_t aval = el_get_field(s, EL_STR("value")); - el_val_t aval_c = cg_expr(aval); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(aname, EL_STR(" = ")), aval_c), EL_STR("; "))); - } else { - } - } - } - } - i = (i + 1); - } - return str_join(parts, EL_STR("")); - return 0; -} - -el_val_t cg_if_expr(el_val_t expr) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = cg_expr(cond); - el_val_t id = next_if_id(); - el_val_t result_var = el_str_concat(EL_STR("_if_result_"), id); - el_val_t then_c = cg_if_expr_arm(then_stmts, result_var); - el_val_t else_c = EL_STR(""); - if (has_else) { - else_c = cg_if_expr_arm(else_stmts, result_var); - } - el_val_t out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), result_var), EL_STR(" = 0; if (")), cond_c), EL_STR(") { ")), then_c), EL_STR("} else { ")), else_c), EL_STR("} ")), result_var), EL_STR("; })")); - return out; - return 0; -} - -el_val_t list_contains(el_val_t lst, el_val_t s) { - el_val_t n = native_list_len(lst); - el_val_t i = 0; - while (i < n) { - el_val_t item = native_list_get(lst, i); - if (str_eq(item, s)) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = cg_expr(val); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - add_int_name(name); - } - if (str_eq(ltype, EL_STR("Instant"))) { - add_instant_name(name); - } - if (str_eq(ltype, EL_STR("Duration"))) { - add_duration_name(name); - } - if (str_eq(ltype, EL_STR("Calendar"))) { - add_calendar_name(name); - } - if (str_eq(ltype, EL_STR("CalendarTime"))) { - add_caltime_name(name); - } - if (str_eq(ltype, EL_STR("Rhythm"))) { - add_rhythm_name(name); - } - if (str_eq(ltype, EL_STR("LocalDate"))) { - add_localdate_name(name); - } - if (str_eq(ltype, EL_STR("LocalTime"))) { - add_localtime_name(name); - } - if (str_eq(ltype, EL_STR("LocalDateTime"))) { - add_localdt_name(name); - } - if (str_eq(ltype, EL_STR("Zone"))) { - add_zone_name(name); - } - if (is_instant_expr(val)) { - add_instant_name(name); - } - if (is_duration_expr(val)) { - add_duration_name(name); - } - if (is_calendar_expr(val)) { - add_calendar_name(name); - } - if (is_caltime_expr(val)) { - add_caltime_name(name); - } - if (is_rhythm_expr(val)) { - add_rhythm_name(name); - } - if (is_localdate_expr(val)) { - add_localdate_name(name); - } - if (is_localtime_expr(val)) { - add_localtime_name(name); - } - if (is_localdt_expr(val)) { - add_localdt_name(name); - } - if (is_zone_expr(val)) { - add_zone_name(name); - } - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - add_int_name(name); - } - if (list_contains(declared, name)) { - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } else { - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("el_val_t ")), name), EL_STR(" = ")), val_c), EL_STR(";"))); - return native_list_append(declared, name); - } - } - if (str_eq(kind, EL_STR("Return"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("Nil"))) { - emit_line(el_str_concat(indent, EL_STR("return 0;"))); - } else { - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("return ")), val_c), EL_STR(";"))); - } - return declared; - } - if (str_eq(kind, EL_STR("Assign"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - cg_if_stmt(val, indent, declared); - return declared; - } - if (str_eq(val_kind, EL_STR("For"))) { - cg_for_stmt(val, indent, declared); - return declared; - } - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(indent, val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("While"))) { - el_val_t cond = el_get_field(stmt, EL_STR("cond")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t cond_c = cg_expr(cond); - cond_c = strip_outer_parens(cond_c); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("while (")), cond_c), EL_STR(") {"))); - cg_stmts(body, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - emit_line(el_str_concat(indent, EL_STR("}"))); - return declared; - } - if (str_eq(kind, EL_STR("For"))) { - el_val_t item = el_get_field(stmt, EL_STR("item")); - el_val_t list_expr = el_get_field(stmt, EL_STR("list")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - cg_for_body(item, list_expr, body, indent, declared); - return declared; - } - if (str_eq(kind, EL_STR("FnDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("TypeDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("Import"))) { - return declared; - } - if (str_eq(kind, EL_STR("ExternFn"))) { - return declared; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return declared; - } - return declared; - return 0; -} - -el_val_t strip_outer_parens(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t n = native_list_len(chars); - if (n < 2) { - return s; - } - el_val_t first = native_list_get(chars, 0); - el_val_t last = native_list_get(chars, (n - 1)); - if (str_eq(first, EL_STR("("))) { - if (str_eq(last, EL_STR(")"))) { - el_val_t depth = 1; - el_val_t i = 1; - el_val_t balanced = 1; - while (i < (n - 1)) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("("))) { - depth = (depth + 1); - } - if (str_eq(ch, EL_STR(")"))) { - depth = (depth - 1); - if (depth == 0) { - balanced = 0; - i = n; - } - } - i = (i + 1); - } - if (balanced) { - return str_slice(s, 1, (n - 1)); - } - } - } - return s; - return 0; -} - -el_val_t cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = cg_expr(cond); - cond_c = strip_outer_parens(cond_c); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("if (")), cond_c), EL_STR(") {"))); - cg_stmts(then_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - if (has_else) { - emit_line(el_str_concat(indent, EL_STR("} else {"))); - cg_stmts(else_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - } - emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared) { - el_val_t list_c = cg_expr(list_expr); - el_val_t idx = EL_STR("_el_i"); - el_val_t list_tmp = EL_STR("_el_lst"); - el_val_t len_tmp = EL_STR("_el_len"); - emit_line(el_str_concat(indent, EL_STR("{"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), list_tmp), EL_STR(" = ")), list_c), EL_STR(";"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), len_tmp), EL_STR(" = el_list_len(")), list_tmp), EL_STR(");"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" for (el_val_t ")), idx), EL_STR(" = 0; ")), idx), EL_STR(" < ")), len_tmp), EL_STR("; ")), idx), EL_STR("++) {"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), item), EL_STR(" = el_list_get(")), list_tmp), EL_STR(", ")), idx), EL_STR(");"))); - el_val_t body_decl = native_list_clone(declared); - body_decl = native_list_append(body_decl, item); - cg_stmts(body, el_str_concat(indent, EL_STR(" ")), body_decl); - emit_line(el_str_concat(indent, EL_STR(" }"))); - emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t item = el_get_field(expr, EL_STR("item")); - el_val_t list_expr = el_get_field(expr, EL_STR("list")); - el_val_t body = el_get_field(expr, EL_STR("body")); - cg_for_body(item, list_expr, body, indent, declared); - return 0; -} - -el_val_t cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t decl = declared; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - decl = cg_stmt(stmt, indent, decl); - i = (i + 1); - } - return decl; - return 0; -} - -el_val_t param_decl(el_val_t param, el_val_t idx) { - el_val_t name = el_get_field(param, EL_STR("name")); - return el_str_concat(EL_STR("el_val_t "), name); - return 0; -} - -el_val_t params_to_c(el_val_t params) { - el_val_t n = native_list_len(params); - if (n == 0) { - return EL_STR("void"); - } - el_val_t parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t param = native_list_get(params, i); - el_val_t decl = param_decl(param, i); - parts = native_list_append(parts, decl); - i = (i + 1); - } - return str_join(parts, EL_STR(", ")); - return 0; -} - -el_val_t transform_implicit_return(el_val_t body) { - el_val_t n = native_list_len(body); - if (n == 0) { - return body; - } - el_val_t last = native_list_get(body, (n - 1)); - el_val_t last_kind = el_get_field(last, EL_STR("stmt")); - if (str_eq(last_kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(last, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - return body; - } - if (str_eq(val_kind, EL_STR("For"))) { - return body; - } - el_val_t new_body = native_list_empty(); - el_val_t i = 0; - while (i < (n - 1)) { - new_body = native_list_append(new_body, native_list_get(body, i)); - i = (i + 1); - } - el_val_t return_stmt = el_map_new(2, "stmt", EL_STR("Return"), "value", val); - new_body = native_list_append(new_body, return_stmt); - return new_body; - } - return body; - return 0; -} - -el_val_t is_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__int_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_instant_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__instant_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_duration_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__duration_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_int_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_lines"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_words"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_letters"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_digits"))) { - return 1; - } - if (str_eq(name, EL_STR("str_last_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_find_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 1; - } - if (str_eq(name, EL_STR("json_array_len"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_node_count"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_edge_count"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("time_diff"))) { - return 1; - } - if (str_eq(name, EL_STR("time_add"))) { - return 1; - } - if (str_eq(name, EL_STR("time_from_parts"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 1; - } - if (str_eq(name, EL_STR("el_min"))) { - return 1; - } - if (str_eq(name, EL_STR("float_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("unix_timestamp"))) { - return 1; - } - if (str_eq(name, EL_STR("instant_to_unix_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("instant_to_unix_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_to_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_to_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_to_nanos"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_instant_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("now"))) { - return 1; - } - if (str_eq(name, EL_STR("el_now_instant"))) { - return 1; - } - if (str_eq(name, EL_STR("unix_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("unix_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("instant_from_iso8601"))) { - return 1; - } - if (str_eq(name, EL_STR("el_instant_add_dur"))) { - return 1; - } - if (str_eq(name, EL_STR("el_instant_sub_dur"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_duration_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("el_duration_from_nanos"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_nanos"))) { - return 1; - } - if (str_eq(name, EL_STR("el_instant_diff"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_add"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_sub"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_scale"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_div"))) { - return 1; - } - if (str_eq(name, EL_STR("ttl_cache_age"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_calendar_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__calendar_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_caltime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__caltime_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_rhythm_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__rhythm_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_localdate_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdate_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_localtime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localtime_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_localdt_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdt_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_zone_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__zone_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_calendar_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("earth_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("earth_calendar_default"))) { - return 1; - } - if (str_eq(name, EL_STR("mars_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("cycle_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("no_cycle_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("relative_calendar"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_caltime_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("now_in"))) { - return 1; - } - if (str_eq(name, EL_STR("in_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("cal_in"))) { - return 1; - } - if (str_eq(name, EL_STR("zoned"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_rhythm_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("rhythm_cycle_start"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_cycle_phase"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_duration"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_session_start"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_event"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_and"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_or"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_weekday"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_weekly_at"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_localdate_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("local_date"))) { - return 1; - } - if (str_eq(name, EL_STR("el_local_date_add_dur"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_localtime_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("local_time"))) { - return 1; - } - if (str_eq(name, EL_STR("el_local_time_add_dur"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_localdt_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("local_datetime"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_zone_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("zone"))) { - return 1; - } - if (str_eq(name, EL_STR("zone_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("zone_local"))) { - return 1; - } - if (str_eq(name, EL_STR("zone_offset"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_calendar_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_calendar_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_calendar_call(expr); - } - return 0; - return 0; -} - -el_val_t is_caltime_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_caltime_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_caltime_call(expr); - } - return 0; - return 0; -} - -el_val_t is_rhythm_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_rhythm_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_rhythm_call(expr); - } - return 0; - return 0; -} - -el_val_t is_localdate_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_localdate_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_localdate_call(expr); - } - return 0; - return 0; -} - -el_val_t is_localtime_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_localtime_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_localtime_call(expr); - } - return 0; - return 0; -} - -el_val_t is_localdt_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_localdt_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_localdt_call(expr); - } - return 0; - return 0; -} - -el_val_t is_zone_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_zone_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_zone_call(expr); - } - return 0; - return 0; -} - -el_val_t is_instant_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_instant_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_instant_call(expr); - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("Plus"))) { - if (is_instant_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_instant_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_instant_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t is_duration_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("DurationLit"))) { - return 1; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_duration_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_duration_call(expr); - } - if (str_eq(k, EL_STR("Neg"))) { - return is_duration_expr(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("Plus"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - if (is_instant_expr(el_get_field(expr, EL_STR("left")))) { - if (is_instant_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Star"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Slash"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t time_record_violation(el_val_t kind, el_val_t detail) { - el_val_t csv = state_get(EL_STR("__time_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(kind, EL_STR(":")), detail); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__time_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t is_int_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Int"))) { - return 1; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_int_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_int_call(expr); - } - if (str_eq(k, EL_STR("Neg"))) { - return is_int_expr(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(k, EL_STR("Not"))) { - return 1; - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("EqEq"))) { - return 1; - } - if (str_eq(op, EL_STR("NotEq"))) { - return 1; - } - if (str_eq(op, EL_STR("Lt"))) { - return 1; - } - if (str_eq(op, EL_STR("Gt"))) { - return 1; - } - if (str_eq(op, EL_STR("LtEq"))) { - return 1; - } - if (str_eq(op, EL_STR("GtEq"))) { - return 1; - } - if (str_eq(op, EL_STR("And"))) { - return 1; - } - if (str_eq(op, EL_STR("Or"))) { - return 1; - } - if (str_eq(op, EL_STR("Plus"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Star"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Slash"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t cap_record_violation(el_val_t kind, el_val_t fn_name) { - el_val_t csv = state_get(EL_STR("__cap_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(kind, EL_STR(":")), fn_name); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__cap_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t is_self_formation_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("llm_call_agentic"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_register_tool"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_field"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_dharma_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("dharma_connect"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_send"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_activate"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_field"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_strengthen"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_relationship"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_peers"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_llm_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("llm_call"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_call_system"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_call_agentic"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_vision"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_register_tool"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_models"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t cap_check_call(el_val_t fn_name) { - el_val_t kind = state_get(EL_STR("__program_kind")); - if (str_eq(kind, EL_STR("cgi"))) { - return 1; - } - if (str_eq(kind, EL_STR("service"))) { - if (is_self_formation_call(fn_name)) { - cap_record_violation(EL_STR("service"), fn_name); - return 0; - } - return 1; - } - if (is_dharma_call(fn_name)) { - cap_record_violation(EL_STR("utility"), fn_name); - return 0; - } - if (is_llm_call(fn_name)) { - cap_record_violation(EL_STR("utility"), fn_name); - return 0; - } - return 1; - return 0; -} - -el_val_t emit_cap_violations(void) { - el_val_t csv = state_get(EL_STR("__cap_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon > 0) { - el_val_t kind = str_slice(entry, 0, colon); - el_val_t fn_name = str_slice(entry, (colon + 1), str_len(entry)); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("#error \"capability violation: '"), kind), EL_STR("' programs may not call '")), fn_name), EL_STR("' (self-formation primitive - only 'cgi' programs may use it)\""))); - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t emit_time_violations(void) { - el_val_t csv = state_get(EL_STR("__time_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon > 0) { - el_val_t detail = str_slice(entry, (colon + 1), str_len(entry)); - emit_line(el_str_concat(el_str_concat(EL_STR("#error \"temporal type error: "), detail), EL_STR("\""))); - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t builtin_arity(el_val_t name) { - if (str_eq(name, EL_STR("println"))) { - return 1; - } - if (str_eq(name, EL_STR("print"))) { - return 1; - } - if (str_eq(name, EL_STR("readline"))) { - return 0; - } - if (str_eq(name, EL_STR("el_str_concat"))) { - return 2; - } - if (str_eq(name, EL_STR("str_eq"))) { - return 2; - } - if (str_eq(name, EL_STR("str_starts_with"))) { - return 2; - } - if (str_eq(name, EL_STR("str_ends_with"))) { - return 2; - } - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_concat"))) { - return 2; - } - if (str_eq(name, EL_STR("int_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_slice"))) { - return 3; - } - if (str_eq(name, EL_STR("str_contains"))) { - return 2; - } - if (str_eq(name, EL_STR("str_replace"))) { - return 3; - } - if (str_eq(name, EL_STR("str_to_upper"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_lower"))) { - return 1; - } - if (str_eq(name, EL_STR("str_trim"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 2; - } - if (str_eq(name, EL_STR("str_split"))) { - return 2; - } - if (str_eq(name, EL_STR("str_char_at"))) { - return 2; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 2; - } - if (str_eq(name, EL_STR("str_pad_left"))) { - return 3; - } - if (str_eq(name, EL_STR("str_pad_right"))) { - return 3; - } - if (str_eq(name, EL_STR("str_format"))) { - return 2; - } - if (str_eq(name, EL_STR("str_lower"))) { - return 1; - } - if (str_eq(name, EL_STR("str_upper"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count"))) { - return 2; - } - if (str_eq(name, EL_STR("str_count_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_lines"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_words"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_letters"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_digits"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of_all"))) { - return 2; - } - if (str_eq(name, EL_STR("str_last_index_of"))) { - return 2; - } - if (str_eq(name, EL_STR("str_find_chars"))) { - return 2; - } - if (str_eq(name, EL_STR("str_repeat"))) { - return 2; - } - if (str_eq(name, EL_STR("str_reverse"))) { - return 1; - } - if (str_eq(name, EL_STR("str_strip_prefix"))) { - return 2; - } - if (str_eq(name, EL_STR("str_strip_suffix"))) { - return 2; - } - if (str_eq(name, EL_STR("str_strip_chars"))) { - return 2; - } - if (str_eq(name, EL_STR("str_lstrip"))) { - return 1; - } - if (str_eq(name, EL_STR("str_rstrip"))) { - return 1; - } - if (str_eq(name, EL_STR("is_letter"))) { - return 1; - } - if (str_eq(name, EL_STR("is_digit"))) { - return 1; - } - if (str_eq(name, EL_STR("is_alphanumeric"))) { - return 1; - } - if (str_eq(name, EL_STR("is_whitespace"))) { - return 1; - } - if (str_eq(name, EL_STR("is_punctuation"))) { - return 1; - } - if (str_eq(name, EL_STR("is_uppercase"))) { - return 1; - } - if (str_eq(name, EL_STR("is_lowercase"))) { - return 1; - } - if (str_eq(name, EL_STR("str_split_lines"))) { - return 1; - } - if (str_eq(name, EL_STR("str_split_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("str_split_n"))) { - return 3; - } - if (str_eq(name, EL_STR("str_join"))) { - return 2; - } - if (str_eq(name, EL_STR("el_html_sanitize"))) { - return 2; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 2; - } - if (str_eq(name, EL_STR("el_min"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_get"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_append"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_empty"))) { - return 0; - } - if (str_eq(name, EL_STR("el_list_clone"))) { - return 1; - } - if (str_eq(name, EL_STR("list_push"))) { - return 2; - } - if (str_eq(name, EL_STR("list_push_front"))) { - return 2; - } - if (str_eq(name, EL_STR("list_join"))) { - return 2; - } - if (str_eq(name, EL_STR("list_range"))) { - return 2; - } - if (str_eq(name, EL_STR("el_get_field"))) { - return 2; - } - if (str_eq(name, EL_STR("el_map_get"))) { - return 2; - } - if (str_eq(name, EL_STR("el_map_set"))) { - return 3; - } - if (str_eq(name, EL_STR("http_get"))) { - return 1; - } - if (str_eq(name, EL_STR("http_post"))) { - return 2; - } - if (str_eq(name, EL_STR("http_post_json"))) { - return 2; - } - if (str_eq(name, EL_STR("http_get_with_headers"))) { - return 2; - } - if (str_eq(name, EL_STR("http_post_with_headers"))) { - return 3; - } - if (str_eq(name, EL_STR("http_post_form_auth"))) { - return 3; - } - if (str_eq(name, EL_STR("http_serve"))) { - return 2; - } - if (str_eq(name, EL_STR("http_set_handler"))) { - return 1; - } - if (str_eq(name, EL_STR("fs_read"))) { - return 1; - } - if (str_eq(name, EL_STR("fs_write"))) { - return 2; - } - if (str_eq(name, EL_STR("fs_list"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get"))) { - return 2; - } - if (str_eq(name, EL_STR("json_parse"))) { - return 1; - } - if (str_eq(name, EL_STR("json_stringify"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_string"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_float"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_bool"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_raw"))) { - return 2; - } - if (str_eq(name, EL_STR("json_set"))) { - return 3; - } - if (str_eq(name, EL_STR("json_array_len"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 0; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 0; - } - if (str_eq(name, EL_STR("sleep_secs"))) { - return 1; - } - if (str_eq(name, EL_STR("sleep_ms"))) { - return 1; - } - if (str_eq(name, EL_STR("time_format"))) { - return 2; - } - if (str_eq(name, EL_STR("time_to_parts"))) { - return 1; - } - if (str_eq(name, EL_STR("time_from_parts"))) { - return 3; - } - if (str_eq(name, EL_STR("time_add"))) { - return 3; - } - if (str_eq(name, EL_STR("time_diff"))) { - return 3; - } - if (str_eq(name, EL_STR("uuid_new"))) { - return 0; - } - if (str_eq(name, EL_STR("uuid_v4"))) { - return 0; - } - if (str_eq(name, EL_STR("env"))) { - return 1; - } - if (str_eq(name, EL_STR("state_set"))) { - return 2; - } - if (str_eq(name, EL_STR("state_get"))) { - return 1; - } - if (str_eq(name, EL_STR("state_del"))) { - return 1; - } - if (str_eq(name, EL_STR("state_keys"))) { - return 0; - } - if (str_eq(name, EL_STR("float_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("int_to_float"))) { - return 1; - } - if (str_eq(name, EL_STR("float_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("format_float"))) { - return 2; - } - if (str_eq(name, EL_STR("decimal_round"))) { - return 2; - } - if (str_eq(name, EL_STR("str_to_float"))) { - return 1; - } - if (str_eq(name, EL_STR("math_sqrt"))) { - return 1; - } - if (str_eq(name, EL_STR("math_log"))) { - return 1; - } - if (str_eq(name, EL_STR("math_ln"))) { - return 1; - } - if (str_eq(name, EL_STR("math_sin"))) { - return 1; - } - if (str_eq(name, EL_STR("math_cos"))) { - return 1; - } - if (str_eq(name, EL_STR("math_pi"))) { - return 0; - } - if (str_eq(name, EL_STR("bool_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("exit_program"))) { - return 1; - } - if (str_eq(name, EL_STR("exec_command"))) { - return 1; - } - if (str_eq(name, EL_STR("exec_capture"))) { - return 1; - } - if (str_eq(name, EL_STR("exec"))) { - return 1; - } - if (str_eq(name, EL_STR("exec_bg"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_connect"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_send"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_activate"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_emit"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_field"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_strengthen"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_relationship"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_peers"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_node"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_node_full"))) { - return 8; - } - if (str_eq(name, EL_STR("engram_get_node"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_strengthen"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_forget"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_node_count"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_search"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_scan_nodes"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_connect"))) { - return 4; - } - if (str_eq(name, EL_STR("engram_edge_between"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_neighbors"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_neighbors_filtered"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_edge_count"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_activate"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_save"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_load"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_get_node_json"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_search_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_scan_nodes_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_neighbors_json"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_activate_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_stats_json"))) { - return 0; - } - if (str_eq(name, EL_STR("llm_call"))) { - return 2; - } - if (str_eq(name, EL_STR("llm_call_system"))) { - return 3; - } - if (str_eq(name, EL_STR("llm_call_agentic"))) { - return 4; - } - if (str_eq(name, EL_STR("llm_vision"))) { - return 4; - } - if (str_eq(name, EL_STR("llm_models"))) { - return 0; - } - if (str_eq(name, EL_STR("llm_register_tool"))) { - return 2; - } - if (str_eq(name, EL_STR("sha256_hex"))) { - return 1; - } - if (str_eq(name, EL_STR("sha256_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("hmac_sha256_hex"))) { - return 2; - } - if (str_eq(name, EL_STR("hmac_sha256_bytes"))) { - return 2; - } - if (str_eq(name, EL_STR("base64_encode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64_decode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64url_encode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64url_decode"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_get"))) { - return 2; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_append"))) { - return 2; - } - if (str_eq(name, EL_STR("native_list_empty"))) { - return 0; - } - if (str_eq(name, EL_STR("native_list_clone"))) { - return 1; - } - if (str_eq(name, EL_STR("native_string_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("native_int_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("append"))) { - return 2; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("get"))) { - return 2; - } - if (str_eq(name, EL_STR("map_get"))) { - return 2; - } - if (str_eq(name, EL_STR("map_set"))) { - return 3; - } - return (-1); - return 0; -} - -el_val_t arity_record_violation(el_val_t fn_name, el_val_t expected, el_val_t actual) { - el_val_t csv = state_get(EL_STR("__arity_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("|")), native_int_to_str(expected)), EL_STR("|")), native_int_to_str(actual)); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__arity_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t arity_check_call(el_val_t fn_name, el_val_t actual) { - el_val_t expected = builtin_arity(fn_name); - if (expected < 0) { - return 1; - } - if (expected == actual) { - return 1; - } - arity_record_violation(fn_name, expected, actual); - return 1; - return 0; -} - -el_val_t emit_arity_violations(void) { - el_val_t csv = state_get(EL_STR("__arity_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t p1 = str_index_of(entry, EL_STR("|")); - if (p1 > 0) { - el_val_t fn_name = str_slice(entry, 0, p1); - el_val_t rest = str_slice(entry, (p1 + 1), str_len(entry)); - el_val_t p2 = str_index_of(rest, EL_STR("|")); - if (p2 > 0) { - el_val_t exp_s = str_slice(rest, 0, p2); - el_val_t act_s = str_slice(rest, (p2 + 1), str_len(rest)); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("#error \"arity error: '"), fn_name), EL_STR("' takes ")), exp_s), EL_STR(" arguments, but called with ")), act_s), EL_STR("\""))); - } - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t add_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__int_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__int_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_instant_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__instant_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__instant_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_duration_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__duration_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__duration_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_calendar_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__calendar_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__calendar_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_caltime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__caltime_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__caltime_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_rhythm_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__rhythm_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__rhythm_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_localdate_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdate_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__localdate_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_localtime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localtime_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__localtime_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_localdt_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdt_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__localdt_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_zone_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__zone_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__zone_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t build_int_names_for_params(el_val_t params) { - state_set(EL_STR("__int_names"), EL_STR(",")); - state_set(EL_STR("__instant_names"), EL_STR(",")); - state_set(EL_STR("__duration_names"), EL_STR(",")); - state_set(EL_STR("__calendar_names"), EL_STR(",")); - state_set(EL_STR("__caltime_names"), EL_STR(",")); - state_set(EL_STR("__rhythm_names"), EL_STR(",")); - state_set(EL_STR("__localdate_names"), EL_STR(",")); - state_set(EL_STR("__localtime_names"), EL_STR(",")); - state_set(EL_STR("__localdt_names"), EL_STR(",")); - state_set(EL_STR("__zone_names"), EL_STR(",")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR("Int"))) { - add_int_name(pname); - } - if (str_eq(ptype, EL_STR("Instant"))) { - add_instant_name(pname); - } - if (str_eq(ptype, EL_STR("Duration"))) { - add_duration_name(pname); - } - if (str_eq(ptype, EL_STR("Calendar"))) { - add_calendar_name(pname); - } - if (str_eq(ptype, EL_STR("CalendarTime"))) { - add_caltime_name(pname); - } - if (str_eq(ptype, EL_STR("Rhythm"))) { - add_rhythm_name(pname); - } - if (str_eq(ptype, EL_STR("LocalDate"))) { - add_localdate_name(pname); - } - if (str_eq(ptype, EL_STR("LocalTime"))) { - add_localtime_name(pname); - } - if (str_eq(ptype, EL_STR("LocalDateTime"))) { - add_localdt_name(pname); - } - if (str_eq(ptype, EL_STR("Zone"))) { - add_zone_name(pname); - } - pi = (pi + 1); - } - return 1; - return 0; -} - -el_val_t cg_fn(el_val_t stmt) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - return 0; - } - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t params_c = params_to_c(params); - el_val_t decorator = el_get_field(stmt, EL_STR("decorator")); - if (vbd_has_restricted_call(body)) { - if (!str_eq(decorator, EL_STR("manager"))) { - emit_line(el_str_concat(el_str_concat(EL_STR("#error \"VBD violation: dharma_emit/dharma_field called from non-@manager fn '"), fn_name), EL_STR("'\""))); - } - } - build_int_names_for_params(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(") {"))); - el_val_t decl = native_list_empty(); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - decl = native_list_append(decl, pname); - pi = (pi + 1); - } - el_val_t body_xformed = body; - if (!str_eq(ret_type, EL_STR("Void"))) { - body_xformed = transform_implicit_return(body); - } - cg_stmts(body_xformed, EL_STR(" "), decl); - emit_line(EL_STR(" return 0;")); - emit_line(EL_STR("}")); - emit_blank(); - return 0; -} - -el_val_t is_fndef(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_top_level_decl(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("TypeDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("Import"))) { - return 1; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return 1; - } - if (str_eq(kind, EL_STR("ExternFn"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t cgi_arg(el_val_t value, el_val_t has_value) { - if (has_value) { - return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(value)), EL_STR(")")); - } - return EL_STR("EL_NULL"); - return 0; -} - -el_val_t vbd_is_restricted_name(el_val_t name) { - if (str_eq(name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_field"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t vbd_expr_has_restricted_call(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (str_eq(fk, EL_STR("Ident"))) { - el_val_t fname = el_get_field(func, EL_STR("name")); - if (vbd_is_restricted_name(fname)) { - return 1; - } - } - if (vbd_expr_has_restricted_call(func)) { - return 1; - } - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t an = native_list_len(args); - el_val_t ai = 0; - while (ai < an) { - el_val_t a = native_list_get(args, ai); - if (vbd_expr_has_restricted_call(a)) { - return 1; - } - ai = (ai + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t l = el_get_field(expr, EL_STR("left")); - el_val_t r = el_get_field(expr, EL_STR("right")); - if (vbd_expr_has_restricted_call(l)) { - return 1; - } - if (vbd_expr_has_restricted_call(r)) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Not"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Neg"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Field"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object"))); - } - if (str_eq(kind, EL_STR("Index"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object")))) { - return 1; - } - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("index")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Try"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - el_val_t i = 0; - while (i < n) { - el_val_t e = native_list_get(elems, i); - if (vbd_expr_has_restricted_call(e)) { - return 1; - } - i = (i + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t v = el_get_field(pair, EL_STR("value")); - if (vbd_expr_has_restricted_call(v)) { - return 1; - } - i = (i + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("If"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("cond")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("then")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("else")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("For"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("list")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("body")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Match"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("subject")))) { - return 1; - } - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t body = el_get_field(arm, EL_STR("body")); - if (vbd_expr_has_restricted_call(body)) { - return 1; - } - i = (i + 1); - } - return 0; - } - return 0; - return 0; -} - -el_val_t vbd_has_restricted_call(el_val_t stmts) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t s = native_list_get(stmts, i); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - if (str_eq(sk, EL_STR("Let"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("Return"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("Expr"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("While"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("cond")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("For"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("list")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) { - return 1; - } - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t codegen(el_val_t stmts, el_val_t source) { - el_val_t n_top = native_list_len(stmts); - el_val_t cgi_count = 0; - el_val_t cgi_block = el_map_new(1, "stmt", EL_STR("None")); - el_val_t svc_count = 0; - el_val_t svc_block = el_map_new(1, "stmt", EL_STR("None")); - el_val_t ti = 0; - while (ti < n_top) { - el_val_t s = native_list_get(stmts, ti); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - if (str_eq(sk, EL_STR("CgiBlock"))) { - cgi_count = (cgi_count + 1); - if (cgi_count == 1) { - cgi_block = s; - } - } - if (str_eq(sk, EL_STR("ServiceBlock"))) { - svc_count = (svc_count + 1); - if (svc_count == 1) { - svc_block = s; - } - } - ti = (ti + 1); - } - if (cgi_count > 1) { - emit_line(EL_STR("#error \"El: multiple cgi blocks in program (only one allowed)\"")); - } - if (svc_count > 1) { - emit_line(EL_STR("#error \"El: multiple service blocks in program (only one allowed)\"")); - } - if (cgi_count >= 1) { - if (svc_count >= 1) { - emit_line(EL_STR("#error \"El: program declares both cgi and service blocks (mutually exclusive - pick one)\"")); - } - } - el_val_t kind = EL_STR("utility"); - if (cgi_count >= 1) { - kind = EL_STR("cgi"); - } - if (svc_count >= 1) { - kind = EL_STR("service"); - } - state_set(EL_STR("__program_kind"), kind); - state_set(EL_STR("__cap_violations"), EL_STR("")); - state_set(EL_STR("__arity_violations"), EL_STR("")); - state_set(EL_STR("__time_violations"), EL_STR("")); - emit_line(EL_STR("#include ")); - emit_line(EL_STR("#include ")); - emit_line(EL_STR("#include \"el_runtime.h\"")); - el_val_t imp_n = native_list_len(stmts); - el_val_t imp_i = 0; - while (imp_i < imp_n) { - el_val_t imp_stmt = native_list_get(stmts, imp_i); - el_val_t imp_kind = el_get_field(imp_stmt, EL_STR("stmt")); - if (str_eq(imp_kind, EL_STR("Import"))) { - el_val_t imp_path = el_get_field(imp_stmt, EL_STR("path")); - el_val_t imp_path_len = str_len(imp_path); - el_val_t imp_last_slash = (-1); - el_val_t imp_j = 0; - while (imp_j < imp_path_len) { - el_val_t imp_c = str_slice(imp_path, imp_j, (imp_j + 1)); - if (str_eq(imp_c, EL_STR("/"))) { - imp_last_slash = imp_j; - } - imp_j = (imp_j + 1); - } - el_val_t imp_base = str_slice(imp_path, (imp_last_slash + 1), imp_path_len); - el_val_t imp_base_len = str_len(imp_base); - el_val_t imp_bname = imp_base; - if (str_ends_with(imp_base, EL_STR(".el"))) { - imp_bname = str_slice(imp_base, 0, (imp_base_len - 3)); - } - emit_line(el_str_concat(el_str_concat(EL_STR("#include \""), imp_bname), EL_STR(".elh\""))); - } - imp_i = (imp_i + 1); - } - emit_blank(); - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (!str_eq(fn_name, EL_STR("main"))) { - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t params_c = params_to_c(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(");"))); - } - } - if (str_eq(kind, EL_STR("ExternFn"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t params_c = params_to_c(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(");"))); - } - i = (i + 1); - } - emit_blank(); - el_val_t has_toplevel_lets = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - add_int_name(name); - } - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - add_int_name(name); - } - emit_line(el_str_concat(el_str_concat(EL_STR("el_val_t "), name), EL_STR(";"))); - has_toplevel_lets = 1; - } - i = (i + 1); - } - if (has_toplevel_lets) { - emit_blank(); - } - el_val_t has_el_main = 0; - el_val_t has_toplevel_stmts = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - el_val_t sk = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(sk, EL_STR("FnDef"))) { - el_val_t fn_name_chk = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name_chk, EL_STR("main"))) { - has_el_main = 1; - } - } - if (!is_fndef(stmt)) { - if (!is_top_level_decl(stmt)) { - if (!str_eq(sk, EL_STR("Let"))) { - has_toplevel_stmts = 1; - } - } - } - i = (i + 1); - } - el_val_t is_library = 0; - if (!has_el_main) { - if (!has_toplevel_stmts) { - is_library = 1; - } - } - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - cg_fn(stmt); - } - i = (i + 1); - } - if (is_library) { - return EL_STR(""); - } - emit_line(EL_STR("int main(int _argc, char** _argv) {")); - emit_line(EL_STR(" el_runtime_init_args(_argc, _argv);")); - if (cgi_count >= 1) { - el_val_t cname = el_get_field(cgi_block, EL_STR("name")); - el_val_t cdid = el_get_field(cgi_block, EL_STR("dharma_id")); - el_val_t cprin = el_get_field(cgi_block, EL_STR("principal")); - el_val_t cnet = el_get_field(cgi_block, EL_STR("network")); - el_val_t ceng = el_get_field(cgi_block, EL_STR("engram")); - el_val_t has_did = el_get_field(cgi_block, EL_STR("has_dharma_id")); - el_val_t has_prin = el_get_field(cgi_block, EL_STR("has_principal")); - el_val_t has_net = el_get_field(cgi_block, EL_STR("has_network")); - el_val_t has_eng = el_get_field(cgi_block, EL_STR("has_engram")); - el_val_t arg_name = el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(cname)), EL_STR(")")); - el_val_t arg_did = cgi_arg(cdid, has_did); - el_val_t arg_prin = cgi_arg(cprin, has_prin); - el_val_t arg_net = cgi_arg(cnet, has_net); - el_val_t arg_eng = cgi_arg(ceng, has_eng); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR(" el_cgi_init("), arg_name), EL_STR(", ")), arg_did), EL_STR(", ")), arg_prin), EL_STR(", ")), arg_net), EL_STR(", ")), arg_eng), EL_STR(");"))); - } - el_val_t main_decl = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - main_decl = native_list_append(main_decl, name); - } - i = (i + 1); - } - el_val_t el_main_body = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t bn = native_list_len(body); - el_val_t bi = 0; - while (bi < bn) { - el_main_body = native_list_append(el_main_body, native_list_get(body, bi)); - bi = (bi + 1); - } - } - } - i = (i + 1); - } - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - } else { - if (is_top_level_decl(stmt)) { - } else { - main_decl = cg_stmt(stmt, EL_STR(" "), main_decl); - } - } - el_release(stmt); - i = (i + 1); - } - el_val_t mn = native_list_len(el_main_body); - el_val_t mi = 0; - while (mi < mn) { - el_val_t mstmt = native_list_get(el_main_body, mi); - main_decl = cg_stmt(mstmt, EL_STR(" "), main_decl); - mi = (mi + 1); - } - emit_line(EL_STR(" return 0;")); - emit_line(EL_STR("}")); - emit_blank(); - emit_cap_violations(); - emit_arity_violations(); - emit_time_violations(); - return EL_STR(""); - return 0; -} - -el_val_t js_escape(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t parts = native_list_empty(); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\""))) { - parts = native_list_append(parts, EL_STR("\\\"")); - } else { - if (str_eq(ch, EL_STR("\\"))) { - parts = native_list_append(parts, EL_STR("\\\\")); - } else { - if (str_eq(ch, EL_STR("\n"))) { - parts = native_list_append(parts, EL_STR("\\n")); - } else { - if (str_eq(ch, EL_STR("\r"))) { - parts = native_list_append(parts, EL_STR("\\r")); - } else { - if (str_eq(ch, EL_STR("\t"))) { - parts = native_list_append(parts, EL_STR("\\t")); - } else { - parts = native_list_append(parts, ch); - } - } - } - } - } - i = (i + 1); - } - return str_join(parts, EL_STR("")); - return 0; -} - -el_val_t js_str_lit(el_val_t s) { - return el_str_concat(el_str_concat(EL_STR("\""), js_escape(s)), EL_STR("\"")); - return 0; -} - -el_val_t js_emit_line(el_val_t line) { - println(line); - return 0; -} - -el_val_t js_emit_blank(void) { - println(EL_STR("")); - return 0; -} - -el_val_t js_binop(el_val_t op) { - if (str_eq(op, EL_STR("Plus"))) { - return EL_STR("+"); - } - if (str_eq(op, EL_STR("Minus"))) { - return EL_STR("-"); - } - if (str_eq(op, EL_STR("Star"))) { - return EL_STR("*"); - } - if (str_eq(op, EL_STR("Slash"))) { - return EL_STR("/"); - } - if (str_eq(op, EL_STR("Percent"))) { - return EL_STR("%"); - } - if (str_eq(op, EL_STR("EqEq"))) { - return EL_STR("==="); - } - if (str_eq(op, EL_STR("NotEq"))) { - return EL_STR("!=="); - } - if (str_eq(op, EL_STR("Lt"))) { - return EL_STR("<"); - } - if (str_eq(op, EL_STR("Gt"))) { - return EL_STR(">"); - } - if (str_eq(op, EL_STR("LtEq"))) { - return EL_STR("<="); - } - if (str_eq(op, EL_STR("GtEq"))) { - return EL_STR(">="); - } - if (str_eq(op, EL_STR("And"))) { - return EL_STR("&&"); - } - if (str_eq(op, EL_STR("Or"))) { - return EL_STR("||"); - } - return op; - return 0; -} - -el_val_t js_is_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__js_int_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t js_add_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__js_int_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__js_int_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t js_build_int_names_for_params(el_val_t params) { - state_set(EL_STR("__js_int_names"), EL_STR(",")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR("Int"))) { - js_add_int_name(pname); - } - pi = (pi + 1); - } - return 1; - return 0; -} - -el_val_t js_is_int_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 1; - } - if (str_eq(name, EL_STR("el_min"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t js_cg_expr(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Int"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("DurationLit"))) { - el_val_t count = el_get_field(expr, EL_STR("count")); - el_val_t unit = el_get_field(expr, EL_STR("unit")); - el_val_t mult_ns = EL_STR("1"); - if (str_eq(unit, EL_STR("nano"))) { - mult_ns = EL_STR("1"); - } - if (str_eq(unit, EL_STR("nanos"))) { - mult_ns = EL_STR("1"); - } - if (str_eq(unit, EL_STR("milli"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("millis"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("millisecond"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("milliseconds"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("second"))) { - mult_ns = EL_STR("1000000000"); - } - if (str_eq(unit, EL_STR("seconds"))) { - mult_ns = EL_STR("1000000000"); - } - if (str_eq(unit, EL_STR("minute"))) { - mult_ns = EL_STR("60000000000"); - } - if (str_eq(unit, EL_STR("minutes"))) { - mult_ns = EL_STR("60000000000"); - } - if (str_eq(unit, EL_STR("hour"))) { - mult_ns = EL_STR("3600000000000"); - } - if (str_eq(unit, EL_STR("hours"))) { - mult_ns = EL_STR("3600000000000"); - } - if (str_eq(unit, EL_STR("day"))) { - mult_ns = EL_STR("86400000000000"); - } - if (str_eq(unit, EL_STR("days"))) { - mult_ns = EL_STR("86400000000000"); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), count), EL_STR(" * ")), mult_ns), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Float"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("Str"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return js_str_lit(v); - } - if (str_eq(kind, EL_STR("Bool"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - if (str_eq(v, EL_STR("true"))) { - return EL_STR("true"); - } - return EL_STR("false"); - } - if (str_eq(kind, EL_STR("Nil"))) { - return EL_STR("null"); - } - if (str_eq(kind, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return name; - } - if (str_eq(kind, EL_STR("Not"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = js_cg_expr(inner); - return el_str_concat(EL_STR("!"), inner_c); - } - if (str_eq(kind, EL_STR("Neg"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = js_cg_expr(inner); - return el_str_concat(el_str_concat(EL_STR("(-"), inner_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - el_val_t left = el_get_field(expr, EL_STR("left")); - el_val_t right = el_get_field(expr, EL_STR("right")); - el_val_t left_c = js_cg_expr(left); - el_val_t right_c = js_cg_expr(right); - el_val_t left_kind = el_get_field(left, EL_STR("expr")); - el_val_t right_kind = el_get_field(right, EL_STR("expr")); - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Call"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_call(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(right_kind, EL_STR("Ident"))) { - if (str_eq(left_kind, EL_STR("Call"))) { - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(rname)) { - if (js_is_int_call(left)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Call"))) { - if (str_eq(right_kind, EL_STR("Call"))) { - if (js_is_int_call(left)) { - if (js_is_int_call(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - el_val_t op_c = js_binop(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t arity = native_list_len(args); - el_val_t func_kind = el_get_field(func, EL_STR("expr")); - el_val_t args_parts = native_list_empty(); - el_val_t i = 0; - while (i < arity) { - el_val_t arg = native_list_get(args, i); - el_val_t arg_c = js_cg_expr(arg); - args_parts = native_list_append(args_parts, arg_c); - i = (i + 1); - } - el_val_t args_c = str_join(args_parts, EL_STR(", ")); - if (str_eq(func_kind, EL_STR("Ident"))) { - el_val_t fn_name = el_get_field(func, EL_STR("name")); - return el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(func_kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(func, EL_STR("object")); - el_val_t field = el_get_field(func, EL_STR("field")); - el_val_t obj_c = js_cg_expr(obj); - if (arity > 0) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(", ")), args_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(")")); - } - el_val_t fn_c = js_cg_expr(func); - return el_str_concat(el_str_concat(el_str_concat(fn_c, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t field = el_get_field(expr, EL_STR("field")); - el_val_t obj_c = js_cg_expr(obj); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), js_str_lit(field)), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Index"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t idx = el_get_field(expr, EL_STR("index")); - el_val_t obj_c = js_cg_expr(obj); - el_val_t idx_c = js_cg_expr(idx); - el_val_t idx_kind = el_get_field(idx, EL_STR("expr")); - if (str_eq(idx_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_get("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - if (n == 0) { - return EL_STR("[]"); - } - el_val_t items_parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t elem = native_list_get(elems, i); - el_val_t elem_c = js_cg_expr(elem); - items_parts = native_list_append(items_parts, elem_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("["), str_join(items_parts, EL_STR(", "))), EL_STR("]")); - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - if (n == 0) { - return EL_STR("{}"); - } - el_val_t items_parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t key = el_get_field(pair, EL_STR("key")); - el_val_t val = el_get_field(pair, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - items_parts = native_list_append(items_parts, el_str_concat(el_str_concat(js_str_lit(key), EL_STR(": ")), val_c)); - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("{"), str_join(items_parts, EL_STR(", "))), EL_STR("}")); - } - if (str_eq(kind, EL_STR("Try"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - return js_cg_expr(inner); - } - if (str_eq(kind, EL_STR("If"))) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t cond_c = js_cg_expr(cond); - return el_str_concat(el_str_concat(EL_STR("("), cond_c), EL_STR(" ? 1 : 0)")); - } - if (str_eq(kind, EL_STR("Match"))) { - return js_cg_match(expr); - } - return EL_STR("null"); - return 0; -} - -el_val_t js_next_match_id(void) { - el_val_t csv = state_get(EL_STR("__js_match_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__js_match_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t js_cg_match(el_val_t expr) { - el_val_t subject = el_get_field(expr, EL_STR("subject")); - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t subj_c = js_cg_expr(subject); - el_val_t id = js_next_match_id(); - el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id); - el_val_t parts = native_list_empty(); - parts = native_list_append(parts, el_str_concat(el_str_concat(EL_STR("(("), subj_var), EL_STR(") => { "))); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t pat = el_get_field(arm, EL_STR("pattern")); - el_val_t body = el_get_field(arm, EL_STR("body")); - el_val_t pkind = el_get_field(pat, EL_STR("pattern")); - el_val_t body_c = js_cg_expr(body); - if (str_eq(pkind, EL_STR("Wildcard"))) { - parts = native_list_append(parts, el_str_concat(el_str_concat(EL_STR("return ("), body_c), EL_STR("); "))); - } else { - if (str_eq(pkind, EL_STR("Binding"))) { - el_val_t bname = el_get_field(pat, EL_STR("name")); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{ const "), bname), EL_STR(" = ")), subj_var), EL_STR("; return (")), body_c), EL_STR("); } "))); - } else { - if (str_eq(pkind, EL_STR("LitInt"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("if ("), subj_var), EL_STR(" === ")), v), EL_STR(") return (")), body_c), EL_STR("); "))); - } else { - if (str_eq(pkind, EL_STR("LitStr"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("if (str_eq("), subj_var), EL_STR(", ")), js_str_lit(v)), EL_STR(")) return (")), body_c), EL_STR("); "))); - } else { - if (str_eq(pkind, EL_STR("LitBool"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - el_val_t bv = EL_STR("false"); - if (str_eq(v, EL_STR("true"))) { - bv = EL_STR("true"); - } - parts = native_list_append(parts, el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("if ("), subj_var), EL_STR(" === ")), bv), EL_STR(") return (")), body_c), EL_STR("); "))); - } else { - parts = native_list_append(parts, el_str_concat(el_str_concat(EL_STR("return ("), body_c), EL_STR("); "))); - } - } - } - } - } - i = (i + 1); - } - parts = native_list_append(parts, el_str_concat(el_str_concat(EL_STR("return null; })("), subj_c), EL_STR(")"))); - return str_join(parts, EL_STR("")); - return 0; -} - -el_val_t js_list_contains(el_val_t lst, el_val_t s) { - el_val_t n = native_list_len(lst); - el_val_t i = 0; - while (i < n) { - el_val_t item = native_list_get(lst, i); - if (str_eq(item, s)) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t js_cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - js_add_int_name(name); - } - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - js_add_int_name(name); - } - if (js_list_contains(declared, name)) { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } else { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("let ")), name), EL_STR(" = ")), val_c), EL_STR(";"))); - return native_list_append(declared, name); - } - } - if (str_eq(kind, EL_STR("Return"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("Nil"))) { - js_emit_line(el_str_concat(indent, EL_STR("return null;"))); - } else { - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("return ")), val_c), EL_STR(";"))); - } - return declared; - } - if (str_eq(kind, EL_STR("Assign"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - js_cg_if_stmt(val, indent, declared); - return declared; - } - if (str_eq(val_kind, EL_STR("For"))) { - js_cg_for_stmt(val, indent, declared); - return declared; - } - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(indent, val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("While"))) { - el_val_t cond = el_get_field(stmt, EL_STR("cond")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t cond_c = js_cg_expr(cond); - cond_c = js_strip_outer_parens(cond_c); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("while (")), cond_c), EL_STR(") {"))); - js_cg_stmts(body, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return declared; - } - if (str_eq(kind, EL_STR("For"))) { - el_val_t item = el_get_field(stmt, EL_STR("item")); - el_val_t list_expr = el_get_field(stmt, EL_STR("list")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - js_cg_for_body(item, list_expr, body, indent, declared); - return declared; - } - if (str_eq(kind, EL_STR("FnDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("TypeDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("Import"))) { - return declared; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - el_val_t cname = el_get_field(stmt, EL_STR("name")); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("// cgi block '")), cname), EL_STR("' - no-op in JS target (server-side concept)"))); - return declared; - } - if (str_eq(kind, EL_STR("ServiceBlock"))) { - el_val_t sname = el_get_field(stmt, EL_STR("name")); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("// service block '")), sname), EL_STR("' - no-op in JS target"))); - return declared; - } - return declared; - return 0; -} - -el_val_t js_strip_outer_parens(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t n = native_list_len(chars); - if (n < 2) { - return s; - } - el_val_t first = native_list_get(chars, 0); - el_val_t last = native_list_get(chars, (n - 1)); - if (str_eq(first, EL_STR("("))) { - if (str_eq(last, EL_STR(")"))) { - el_val_t depth = 1; - el_val_t i = 1; - el_val_t balanced = 1; - while (i < (n - 1)) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("("))) { - depth = (depth + 1); - } - if (str_eq(ch, EL_STR(")"))) { - depth = (depth - 1); - if (depth == 0) { - balanced = 0; - i = n; - } - } - i = (i + 1); - } - if (balanced) { - return str_slice(s, 1, (n - 1)); - } - } - } - return s; - return 0; -} - -el_val_t js_cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = js_cg_expr(cond); - cond_c = js_strip_outer_parens(cond_c); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("if (")), cond_c), EL_STR(") {"))); - js_cg_stmts(then_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - if (has_else) { - js_emit_line(el_str_concat(indent, EL_STR("} else {"))); - js_cg_stmts(else_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - } - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t js_cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared) { - el_val_t list_c = js_cg_expr(list_expr); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("for (const ")), item), EL_STR(" of ")), list_c), EL_STR(") {"))); - el_val_t body_decl = native_list_clone(declared); - body_decl = native_list_append(body_decl, item); - js_cg_stmts(body, el_str_concat(indent, EL_STR(" ")), body_decl); - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t js_cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t item = el_get_field(expr, EL_STR("item")); - el_val_t list_expr = el_get_field(expr, EL_STR("list")); - el_val_t body = el_get_field(expr, EL_STR("body")); - js_cg_for_body(item, list_expr, body, indent, declared); - return 0; -} - -el_val_t js_cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t decl = declared; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - decl = js_cg_stmt(stmt, indent, decl); - i = (i + 1); - } - return decl; - return 0; -} - -el_val_t js_params_str(el_val_t params) { - el_val_t n = native_list_len(params); - if (n == 0) { - return EL_STR(""); - } - el_val_t parts = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t param = native_list_get(params, i); - el_val_t name = el_get_field(param, EL_STR("name")); - parts = native_list_append(parts, name); - i = (i + 1); - } - return str_join(parts, EL_STR(", ")); - return 0; -} - -el_val_t js_transform_implicit_return(el_val_t body) { - el_val_t n = native_list_len(body); - if (n == 0) { - return body; - } - el_val_t last = native_list_get(body, (n - 1)); - el_val_t last_kind = el_get_field(last, EL_STR("stmt")); - if (str_eq(last_kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(last, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - return body; - } - if (str_eq(val_kind, EL_STR("For"))) { - return body; - } - el_val_t new_body = native_list_empty(); - el_val_t i = 0; - while (i < (n - 1)) { - new_body = native_list_append(new_body, native_list_get(body, i)); - i = (i + 1); - } - el_val_t return_stmt = el_map_new(2, "stmt", EL_STR("Return"), "value", val); - new_body = native_list_append(new_body, return_stmt); - return new_body; - } - return body; - return 0; -} - -el_val_t js_cg_fn(el_val_t stmt) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t params_str = js_params_str(params); - js_build_int_names_for_params(params); - if (str_eq(fn_name, EL_STR("main"))) { - js_emit_line(el_str_concat(el_str_concat(EL_STR("function main("), params_str), EL_STR(") {"))); - } else { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("function "), fn_name), EL_STR("(")), params_str), EL_STR(") {"))); - } - el_val_t decl = native_list_empty(); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - decl = native_list_append(decl, pname); - pi = (pi + 1); - } - el_val_t body_xformed = body; - if (!str_eq(ret_type, EL_STR("Void"))) { - body_xformed = js_transform_implicit_return(body); - } - js_cg_stmts(body_xformed, EL_STR(" "), decl); - js_emit_line(EL_STR("}")); - js_emit_blank(); - return 0; -} - -el_val_t js_is_fndef(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t js_is_top_level_decl(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("TypeDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("Import"))) { - return 1; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return 1; - } - if (str_eq(kind, EL_STR("ServiceBlock"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t codegen_js(el_val_t stmts, el_val_t source) { - state_set(EL_STR("__js_int_names"), EL_STR("")); - state_set(EL_STR("__js_match_counter"), EL_STR("")); - js_emit_line(EL_STR("// Generated by elc --target=js")); - js_emit_line(EL_STR("// Runtime: foundation/el/el-compiler/runtime/el_runtime.js")); - js_emit_line(EL_STR("import \"./el_runtime.js\";")); - js_emit_line(EL_STR("const {")); - js_emit_line(EL_STR(" println, print, el_str_concat, str_concat, str_eq, str_starts_with, str_ends_with,")); - js_emit_line(EL_STR(" str_len, int_to_str, str_to_int, str_slice, str_contains, str_replace,")); - js_emit_line(EL_STR(" str_to_upper, str_to_lower, str_trim, str_index_of, str_split, str_char_at,")); - js_emit_line(EL_STR(" str_char_code, str_lower, str_upper, el_abs, el_max, el_min,")); - js_emit_line(EL_STR(" el_list_new, el_list_len, el_list_get, el_list_append, el_list_empty, el_list_clone,")); - js_emit_line(EL_STR(" list_push, list_join, list_range,")); - js_emit_line(EL_STR(" el_map_new, el_get_field, el_map_get, el_map_set,")); - js_emit_line(EL_STR(" http_get, http_post, http_post_json,")); - js_emit_line(EL_STR(" fs_read, fs_write, fs_list,")); - js_emit_line(EL_STR(" json_parse, json_stringify, json_get, json_get_string, json_get_int,")); - js_emit_line(EL_STR(" time_now, time_now_utc, sleep_ms, bool_to_str, exit_program,")); - js_emit_line(EL_STR(" el_retain, el_release,")); - js_emit_line(EL_STR(" append, len, get, map_get, map_set,")); - js_emit_line(EL_STR(" native_list_get, native_list_len, native_list_append, native_list_empty,")); - js_emit_line(EL_STR(" native_list_clone, native_string_chars, native_int_to_str,")); - js_emit_line(EL_STR(" args, state_set, state_get, state_del, state_keys, env,")); - js_emit_line(EL_STR(" dharma_connect, dharma_send, dharma_emit, dharma_field, dharma_activate,")); - js_emit_line(EL_STR(" engram_node, engram_search, engram_activate,")); - js_emit_line(EL_STR(" llm_call, llm_call_system,")); - js_emit_line(EL_STR("} = globalThis.__el;")); - js_emit_blank(); - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (js_is_fndef(stmt)) { - js_cg_fn(stmt); - } - i = (i + 1); - } - el_val_t has_main = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - el_val_t sk = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(sk, EL_STR("FnDef"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - has_main = 1; - } - } - i = (i + 1); - } - el_val_t main_decl = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (js_is_fndef(stmt)) { - } else { - if (js_is_top_level_decl(stmt)) { - } else { - main_decl = js_cg_stmt(stmt, EL_STR(""), main_decl); - } - } - i = (i + 1); - } - if (has_main) { - js_emit_blank(); - js_emit_line(EL_STR("main();")); - } - return EL_STR(""); - return 0; -} - -el_val_t compile(el_val_t source) { - el_val_t tokens = lex(source); - el_val_t stmts = parse(tokens); - el_release(tokens); - return codegen(stmts, source); - return 0; -} - -el_val_t compile_js(el_val_t source) { - el_val_t tokens = lex(source); - el_val_t stmts = parse(tokens); - el_release(tokens); - return codegen_js(stmts, source); - return 0; -} - -el_val_t compile_dispatch(el_val_t tgt, el_val_t source) { - if (str_eq(tgt, EL_STR("js"))) { - return compile_js(source); - } - return compile(source); - return 0; -} - -el_val_t detect_target(el_val_t argv) { - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (str_starts_with(a, EL_STR("--target="))) { - el_val_t v = str_slice(a, 9, str_len(a)); - return v; - } - i = (i + 1); - } - return EL_STR("c"); - return 0; -} - -el_val_t strip_flags(el_val_t argv) { - el_val_t out = native_list_empty(); - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (!str_starts_with(a, EL_STR("--"))) { - out = native_list_append(out, a); - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t detect_emit_header(el_val_t argv) { - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (str_eq(a, EL_STR("--emit-header"))) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t type_node_to_el(el_val_t t) { - el_val_t k = el_get_field(t, EL_STR("kind")); - if (str_eq(k, EL_STR("Simple"))) { - return el_get_field(t, EL_STR("name")); - } - if (str_eq(k, EL_STR("List"))) { - el_val_t inner = type_node_to_el(el_get_field(t, EL_STR("inner"))); - return el_str_concat(el_str_concat(EL_STR("["), inner), EL_STR("]")); - } - if (str_eq(k, EL_STR("Map"))) { - el_val_t kt = type_node_to_el(el_get_field(t, EL_STR("key"))); - el_val_t vt = type_node_to_el(el_get_field(t, EL_STR("val"))); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("Map<"), kt), EL_STR(", ")), vt), EL_STR(">")); - } - return EL_STR("Any"); - return 0; -} - -el_val_t emit_header(el_val_t stmts, el_val_t hdr_path) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t parts = native_list_empty(); - parts = native_list_append(parts, EL_STR("// auto-generated by elc --emit-header - do not edit\n")); - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - if (!str_eq(name, EL_STR("main"))) { - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - el_val_t param_parts = native_list_empty(); - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR(""))) { - ptype = EL_STR("Any"); - } - param_parts = native_list_append(param_parts, el_str_concat(el_str_concat(pname, EL_STR(": ")), ptype)); - pi = (pi + 1); - } - el_val_t params_str = str_join(param_parts, EL_STR(", ")); - el_val_t ret_str = ret_type; - if (str_eq(ret_str, EL_STR(""))) { - ret_str = EL_STR("Any"); - } - el_val_t sig = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("extern fn "), name), EL_STR("(")), params_str), EL_STR(") -> ")), ret_str); - parts = native_list_append(parts, el_str_concat(sig, EL_STR("\n"))); - } - } - i = (i + 1); - } - el_val_t content = str_join(parts, EL_STR("")); - el_val_t ok = fs_write(hdr_path, content); - return 0; -} - -el_val_t dirname_of(el_val_t path) { - el_val_t n = str_len(path); - el_val_t i = (n - 1); - while (i >= 0) { - el_val_t c = str_slice(path, i, (i + 1)); - if (str_eq(c, EL_STR("/"))) { - return str_slice(path, 0, i); - } - i = (i - 1); - } - return EL_STR("."); - return 0; -} - -el_val_t parse_import_line(el_val_t trimmed, el_val_t dir) { - if (str_starts_with(trimmed, EL_STR("import \""))) { - el_val_t after = str_slice(trimmed, 8, str_len(trimmed)); - el_val_t q = str_index_of(after, EL_STR("\"")); - if (q > 0) { - el_val_t mod = str_slice(after, 0, q); - return el_str_concat(el_str_concat(dir, EL_STR("/")), mod); - } - } - if (str_starts_with(trimmed, EL_STR("from "))) { - el_val_t after = str_slice(trimmed, 5, str_len(trimmed)); - el_val_t sp = str_index_of(after, EL_STR(" ")); - if (sp > 0) { - el_val_t mod_raw = str_slice(after, 0, sp); - el_val_t mod = str_trim(mod_raw); - if (!str_eq(mod, EL_STR(""))) { - return el_str_concat(el_str_concat(el_str_concat(dir, EL_STR("/")), mod), EL_STR(".el")); - } - } - } - return EL_STR(""); - return 0; -} - -el_val_t resolve_imports(el_val_t src_path) { - el_val_t seen_key = el_str_concat(EL_STR("__elc_imp__:"), src_path); - el_val_t already = state_get(seen_key); - if (!str_eq(already, EL_STR(""))) { - return EL_STR(""); - } - state_set(seen_key, EL_STR("1")); - el_val_t source = fs_read(src_path); - el_val_t dir = dirname_of(src_path); - el_val_t lines = str_split(source, EL_STR("\n")); - el_val_t n = native_list_len(lines); - el_val_t prefix_chunks = native_list_empty(); - el_val_t body_chunks = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t line = native_list_get(lines, i); - el_val_t trimmed = str_trim(line); - el_val_t imp_path = parse_import_line(trimmed, dir); - if (!str_eq(imp_path, EL_STR(""))) { - el_val_t imp_elh_path = el_str_concat(str_slice(imp_path, 0, (str_len(imp_path) - 3)), EL_STR(".elh")); - el_val_t imp_elh = fs_read(imp_elh_path); - if (!str_eq(imp_elh, EL_STR(""))) { - el_val_t seen_imp_key = el_str_concat(EL_STR("__elc_imp__:"), imp_path); - state_set(seen_imp_key, EL_STR("1")); - prefix_chunks = native_list_append(prefix_chunks, imp_elh); - } else { - el_val_t imp_body = resolve_imports(imp_path); - prefix_chunks = native_list_append(prefix_chunks, imp_body); - } - } else { - body_chunks = native_list_append(body_chunks, el_str_concat(line, EL_STR("\n"))); - } - i = (i + 1); - } - return el_str_concat(str_join(prefix_chunks, EL_STR("")), str_join(body_chunks, EL_STR(""))); - return 0; -} - -int main(int _argc, char** _argv) { - el_runtime_init_args(_argc, _argv); - el_val_t argv = args(); - el_val_t tgt = detect_target(argv); - el_val_t do_emit_header = detect_emit_header(argv); - el_val_t positional = strip_flags(argv); - el_val_t argc = native_list_len(positional); - if (argc < 1) { - println(EL_STR("el-compiler: usage: elc [--target=c|js] [--emit-header] []")); - exit(1); - } - el_val_t src_path = native_list_get(positional, 0); - if (do_emit_header) { - el_val_t raw_source = fs_read(src_path); - el_val_t hdr_tokens = lex(raw_source); - el_val_t hdr_stmts = parse(hdr_tokens); - el_release(hdr_tokens); - el_val_t hdr_path = el_str_concat(str_slice(src_path, 0, (str_len(src_path) - 3)), EL_STR(".elh")); - emit_header(hdr_stmts, hdr_path); - el_release(hdr_stmts); - } - el_val_t source = resolve_imports(src_path); - el_val_t out = compile_dispatch(tgt, source); - if (argc >= 2) { - el_val_t out_path = native_list_get(positional, 1); - el_val_t ok = fs_write(out_path, out); - if (ok) { - exit(0); - } else { - println(EL_STR("el-compiler: failed to write output")); - exit(1); - } - } - return 0; -} - diff --git a/lang/dist/platform/el_runtime.js b/lang/dist/platform/el_runtime.js deleted file mode 100644 index a223fdb..0000000 --- a/lang/dist/platform/el_runtime.js +++ /dev/null @@ -1,1049 +0,0 @@ -/* - * el_runtime.js — El language JS runtime. - * - * The browser/Node analog of el_runtime.c. Compiled-from-El JS source - * imports this file once; it side-effects globalThis.__el with every - * builtin, so generated programs can destructure the names they need - * (see codegen-js.el's preamble). - * - * Value model: - * El's tagged el_val_t collapses into JS native types here: - * String -> string - * Int -> number (caveat: only 53 bits of integer precision) - * Float -> number (already a double) - * Bool -> boolean - * [T] -> Array - * Map<,> -> plain object - * Void -> undefined - * null -> null - * - * Runtime mode auto-detection: - * typeof window === 'undefined' -> Node mode - * otherwise -> Browser mode - * - * See spec/codegen-js.md for the full design rationale. - */ - -const IS_NODE = typeof window === 'undefined' && typeof process !== 'undefined' && process.versions != null && process.versions.node != null; - -// ── I/O ───────────────────────────────────────────────────────────────────── - -function println(s) { - if (IS_NODE) { - process.stdout.write(String(s) + '\n'); - } else { - console.log(String(s)); - } -} - -function print(s) { - if (IS_NODE) { - process.stdout.write(String(s)); - } else { - // Browser has no stdout — fall back to console with no newline group - console.log(String(s)); - } -} - -// ── String builtins ───────────────────────────────────────────────────────── - -// Coerce both args to string and concat. Mirrors el_str_concat in C; -// the C version handles both string-and-string and string-and-int. -function el_str_concat(a, b) { - return String(a) + String(b); -} - -function str_concat(a, b) { return el_str_concat(a, b); } - -// Strict equality with string coercion. Matches str_eq() in C — which -// strcmp's the underlying char*. Here we just === after coercion. -function str_eq(a, b) { - if (a === null || b === null) return a === b; - return String(a) === String(b); -} - -function str_starts_with(s, prefix) { - return String(s).startsWith(String(prefix)); -} - -function str_ends_with(s, suffix) { - return String(s).endsWith(String(suffix)); -} - -function str_len(s) { - return String(s).length; -} - -function int_to_str(n) { - return String(n); -} - -function str_to_int(s) { - const n = parseInt(String(s), 10); - return Number.isNaN(n) ? 0 : n; -} - -function str_slice(s, start, end) { - return String(s).slice(start, end); -} - -function str_contains(s, sub) { - return String(s).indexOf(String(sub)) >= 0; -} - -function str_replace(s, from, to) { - // Replace ALL occurrences (matches C runtime semantics). - return String(s).split(String(from)).join(String(to)); -} - -function str_to_upper(s) { return String(s).toUpperCase(); } -function str_to_lower(s) { return String(s).toLowerCase(); } -function str_upper(s) { return String(s).toUpperCase(); } -function str_lower(s) { return String(s).toLowerCase(); } - -function str_trim(s) { return String(s).trim(); } - -function str_index_of(s, sub) { - return String(s).indexOf(String(sub)); -} - -function str_split(s, sep) { - return String(s).split(String(sep)); -} - -function str_char_at(s, i) { - return String(s).charAt(i); -} - -function str_char_code(s, i) { - const c = String(s).charCodeAt(i); - return Number.isNaN(c) ? 0 : c; -} - -function str_pad_left(s, width, pad) { - return String(s).padStart(width, String(pad)); -} - -function str_pad_right(s, width, pad) { - return String(s).padEnd(width, String(pad)); -} - -// ── Math ──────────────────────────────────────────────────────────────────── - -function el_abs(n) { return Math.abs(n); } -function el_max(a, b) { return a > b ? a : b; } -function el_min(a, b) { return a < b ? a : b; } - -// ── Refcount (no-op — JS has GC) ──────────────────────────────────────────── - -function el_retain(_v) { /* no-op */ } -function el_release(_v) { /* no-op */ } - -// ── List ──────────────────────────────────────────────────────────────────── - -// Variadic constructor matching el_list_new(count, items...). Exposed so -// codegen-js can emit the same call shape if we ever want it (currently -// codegen-js emits JS array literals directly). -function el_list_new(_count, ...items) { - return items.slice(0); -} - -function el_list_empty() { return []; } -function el_list_clone(list) { return Array.isArray(list) ? list.slice() : []; } -function el_list_len(list) { return Array.isArray(list) ? list.length : 0; } - -function el_list_get(list, index) { - if (!Array.isArray(list)) return null; - if (index < 0 || index >= list.length) return null; - return list[index]; -} - -function el_list_append(list, elem) { - if (!Array.isArray(list)) return [elem]; - const out = list.slice(); - out.push(elem); - return out; -} - -function list_push(list, elem) { return el_list_append(list, elem); } - -function list_push_front(list, elem) { - if (!Array.isArray(list)) return [elem]; - return [elem, ...list]; -} - -function list_join(list, sep) { - if (!Array.isArray(list)) return ''; - return list.map(String).join(String(sep)); -} - -function list_range(start, end) { - const out = []; - for (let i = start; i < end; i++) out.push(i); - return out; -} - -// ── Map ───────────────────────────────────────────────────────────────────── - -// Variadic constructor (key, val, key, val, ...). -function el_map_new(_pairCount, ...kvs) { - const out = {}; - for (let i = 0; i < kvs.length; i += 2) { - out[String(kvs[i])] = kvs[i + 1]; - } - return out; -} - -function el_get_field(map, key) { - if (map === null || map === undefined) return null; - if (typeof map !== 'object') return null; - const k = String(key); - if (Object.prototype.hasOwnProperty.call(map, k)) return map[k]; - return null; -} - -function el_map_get(map, key) { return el_get_field(map, key); } - -function el_map_set(map, key, value) { - // Match the C runtime: shallow-copy + set, persistent semantics. - const out = (map && typeof map === 'object') ? { ...map } : {}; - out[String(key)] = value; - return out; -} - -// ── Method-call shorthand aliases ────────────────────────────────────────── -// `obj.method(args)` compiles to `method(obj, args)` per El convention. - -function append(list, elem) { return el_list_append(list, elem); } -function len(v) { - if (Array.isArray(v)) return v.length; - if (typeof v === 'string') return v.length; - if (v && typeof v === 'object') return Object.keys(v).length; - return 0; -} -function get(list, index) { return el_list_get(list, index); } -function map_get(m, k) { return el_get_field(m, k); } -function map_set(m, k, v) { return el_map_set(m, k, v); } - -// ── Native VM aliases ────────────────────────────────────────────────────── - -function native_list_get(list, index) { return el_list_get(list, index); } -function native_list_len(list) { return el_list_len(list); } -function native_list_append(list, elem) { return el_list_append(list, elem); } -function native_list_empty() { return []; } -function native_list_clone(list) { return el_list_clone(list); } -function native_string_chars(s) { return String(s).split(''); } -function native_int_to_str(n) { return String(n); } - -// ── HTTP ─────────────────────────────────────────────────────────────────── -// -// fetch() is async. These return Promise. Generated El code does -// not yet emit await — that's the async-taint pass (see spec §5). For -// programs that don't touch HTTP this is fine; for programs that do, -// the value will appear as "[object Promise]" until the taint pass lands. - -function http_get(url) { - if (typeof fetch === 'undefined') { - throw new Error('http_get: fetch() not available in this runtime'); - } - return fetch(String(url)).then(r => r.text()); -} - -function http_post(url, body) { - if (typeof fetch === 'undefined') { - throw new Error('http_post: fetch() not available in this runtime'); - } - return fetch(String(url), { method: 'POST', body: String(body) }).then(r => r.text()); -} - -function http_post_json(url, jsonBody) { - if (typeof fetch === 'undefined') { - throw new Error('http_post_json: fetch() not available in this runtime'); - } - return fetch(String(url), { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: String(jsonBody), - }).then(r => r.text()); -} - -function http_get_with_headers(url, headersMap) { - if (typeof fetch === 'undefined') { - throw new Error('http_get_with_headers: fetch() not available'); - } - return fetch(String(url), { headers: headersMap || {} }).then(r => r.text()); -} - -function http_post_with_headers(url, body, headersMap) { - if (typeof fetch === 'undefined') { - throw new Error('http_post_with_headers: fetch() not available'); - } - return fetch(String(url), { - method: 'POST', - headers: headersMap || {}, - body: String(body), - }).then(r => r.text()); -} - -function http_serve(_port, _handler) { - throw new Error('http_serve: not supported in JS target — needs server-side runtime mode'); -} - -function http_set_handler(_name) { - throw new Error('http_set_handler: not supported in JS target'); -} - -// ── Filesystem (Node-only) ───────────────────────────────────────────────── - -function _ensureNode(name) { - if (!IS_NODE) { - throw new Error(`${name}: not supported in browser runtime`); - } -} - -function fs_read(path) { - _ensureNode('fs_read'); - const fs = require('node:fs'); - try { - return fs.readFileSync(String(path), 'utf8'); - } catch (_e) { - return ''; - } -} - -function fs_write(path, content) { - _ensureNode('fs_write'); - const fs = require('node:fs'); - try { - fs.writeFileSync(String(path), String(content)); - return true; - } catch (_e) { - return false; - } -} - -function fs_list(path) { - _ensureNode('fs_list'); - const fs = require('node:fs'); - try { - return fs.readdirSync(String(path)); - } catch (_e) { - return []; - } -} - -// ── JSON ─────────────────────────────────────────────────────────────────── - -function json_parse(s) { - try { return JSON.parse(String(s)); } - catch (_e) { return null; } -} - -function json_stringify(v) { - try { return JSON.stringify(v); } - catch (_e) { return ''; } -} - -function json_get(jsonStr, key) { - const o = json_parse(jsonStr); - if (o === null) return null; - return el_get_field(o, key); -} - -function json_get_string(jsonStr, key) { - const v = json_get(jsonStr, key); - return v === null ? '' : String(v); -} - -function json_get_int(jsonStr, key) { - const v = json_get(jsonStr, key); - if (typeof v === 'number') return Math.trunc(v); - if (typeof v === 'string') return str_to_int(v); - return 0; -} - -function json_get_float(jsonStr, key) { - const v = json_get(jsonStr, key); - return typeof v === 'number' ? v : 0; -} - -function json_get_bool(jsonStr, key) { - const v = json_get(jsonStr, key); - return v === true; -} - -function json_get_raw(jsonStr, key) { - const v = json_get(jsonStr, key); - return v === null ? '' : json_stringify(v); -} - -function json_set(jsonStr, key, value) { - const o = json_parse(jsonStr) ?? {}; - o[String(key)] = value; - return json_stringify(o); -} - -function json_array_len(jsonStr) { - const o = json_parse(jsonStr); - return Array.isArray(o) ? o.length : 0; -} - -// ── Time ─────────────────────────────────────────────────────────────────── - -function time_now() { - return Math.floor(Date.now() / 1000); -} - -function time_now_utc() { - // In the C runtime this returns nanoseconds since epoch. JS number - // can't represent that range past ~2^53. We return milliseconds — a - // safe range — and document the divergence. - return Date.now(); -} - -function sleep_secs(secs) { - if (!IS_NODE) { - throw new Error('sleep_secs: blocking sleep not supported in browser'); - } - // Simple sync sleep via Atomics.wait on a SharedArrayBuffer-backed Int32. - const sab = new SharedArrayBuffer(4); - const i32 = new Int32Array(sab); - Atomics.wait(i32, 0, 0, Math.floor(secs * 1000)); - return secs; -} - -function sleep_ms(ms) { - if (!IS_NODE) { - throw new Error('sleep_ms: blocking sleep not supported in browser'); - } - const sab = new SharedArrayBuffer(4); - const i32 = new Int32Array(sab); - Atomics.wait(i32, 0, 0, Math.floor(ms)); - return ms; -} - -// ── Bool ─────────────────────────────────────────────────────────────────── - -function bool_to_str(b) { return b ? 'true' : 'false'; } - -// ── Process ──────────────────────────────────────────────────────────────── - -function exit_program(code) { - if (IS_NODE) { - process.exit(code | 0); - } else { - throw new Error(`exit_program(${code}) called in browser`); - } -} - -// ── args() ───────────────────────────────────────────────────────────────── - -function args() { - if (IS_NODE) { - // process.argv is [node, script, ...args] — slice off node + script. - return process.argv.slice(2); - } - return []; -} - -// ── env ──────────────────────────────────────────────────────────────────── - -function env(key) { - if (IS_NODE) { - const v = process.env[String(key)]; - return v === undefined ? null : v; - } - return null; -} - -// ── In-process state K/V ─────────────────────────────────────────────────── - -const _stateMap = new Map(); - -function state_set(key, value) { - _stateMap.set(String(key), value); - return value; -} - -function state_get(key) { - const v = _stateMap.get(String(key)); - return v === undefined ? '' : v; -} - -function state_del(key) { - return _stateMap.delete(String(key)); -} - -function state_keys() { - return Array.from(_stateMap.keys()); -} - -// ── UUID ─────────────────────────────────────────────────────────────────── - -function uuid_v4() { - // RFC 4122-ish — uses crypto when available, falls back to Math.random. - if (typeof crypto !== 'undefined' && crypto.randomUUID) { - return crypto.randomUUID(); - } - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { - const r = Math.random() * 16 | 0; - const v = c === 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); -} -function uuid_new() { return uuid_v4(); } - -// ── Float formatting ─────────────────────────────────────────────────────── - -function float_to_str(f) { return String(f); } -function int_to_float(n) { return n; } -function float_to_int(f) { return Math.trunc(f); } - -function format_float(f, decimals) { - return Number(f).toFixed(decimals); -} - -function decimal_round(f, decimals) { - const m = Math.pow(10, decimals); - return Math.round(f * m) / m; -} - -function str_to_float(s) { - const n = parseFloat(String(s)); - return Number.isNaN(n) ? 0 : n; -} - -// ── Math (Float-aware) ───────────────────────────────────────────────────── - -function math_sqrt(f) { return Math.sqrt(f); } -function math_log(f) { return Math.log10(f); } -function math_ln(f) { return Math.log(f); } -function math_sin(f) { return Math.sin(f); } -function math_cos(f) { return Math.cos(f); } -function math_pi() { return Math.PI; } - -// ── DOM bridge (browser-only) ────────────────────────────────────────────── -// -// These functions wrap the browser DOM API. Each throws a descriptive error -// when called from a Node environment, mirroring the pattern used by fs_* -// in browser mode. - -function _ensureBrowser(name) { - if (IS_NODE) { - throw new Error(`${name}: not supported in Node runtime — DOM is browser-only`); - } -} - -function dom_get_element(id) { - _ensureBrowser('dom_get_element'); - return document.getElementById(String(id)); -} - -function dom_get_value(el) { - _ensureBrowser('dom_get_value'); - return el == null ? '' : String(el.value ?? ''); -} - -function dom_set_value(el, v) { - _ensureBrowser('dom_set_value'); - if (el != null) el.value = String(v); -} - -function dom_get_text(el) { - _ensureBrowser('dom_get_text'); - return el == null ? '' : String(el.textContent ?? ''); -} - -function dom_set_text(el, text) { - _ensureBrowser('dom_set_text'); - if (el != null) el.textContent = String(text); -} - -function dom_set_prop(el, prop, val) { - _ensureBrowser('dom_set_prop'); - if (el != null) el[String(prop)] = val; -} - -function dom_get_prop(el, prop) { - _ensureBrowser('dom_get_prop'); - if (el == null) return null; - const v = el[String(prop)]; - return v === undefined ? null : v; -} - -function dom_set_style(el, prop, val) { - _ensureBrowser('dom_set_style'); - if (el != null) el.style[String(prop)] = String(val); -} - -function dom_add_class(el, cls) { - _ensureBrowser('dom_add_class'); - if (el != null) el.classList.add(String(cls)); -} - -function dom_remove_class(el, cls) { - _ensureBrowser('dom_remove_class'); - if (el != null) el.classList.remove(String(cls)); -} - -function dom_show(el) { - _ensureBrowser('dom_show'); - if (el != null) el.style.display = ''; -} - -function dom_hide(el) { - _ensureBrowser('dom_hide'); - if (el != null) el.style.display = 'none'; -} - -function dom_listen(el, event, handler) { - _ensureBrowser('dom_listen'); - if (el != null) el.addEventListener(String(event), handler); -} - -function dom_query(selector) { - _ensureBrowser('dom_query'); - return document.querySelector(String(selector)); -} - -function dom_query_all(selector) { - _ensureBrowser('dom_query_all'); - return Array.from(document.querySelectorAll(String(selector))); -} - -function dom_create(tag) { - _ensureBrowser('dom_create'); - return document.createElement(String(tag)); -} - -function dom_append(parent, child) { - _ensureBrowser('dom_append'); - if (parent != null && child != null) parent.appendChild(child); -} - -function dom_remove(el) { - _ensureBrowser('dom_remove'); - if (el != null) el.remove(); -} - -function dom_is_null(el) { - return el === null || el === undefined; -} - -// ── Extended DOM API (browser-only) ─────────────────────────────────────── - -function dom_set_attr(el, attr, val) { - _ensureBrowser('dom_set_attr'); - if (el != null) el.setAttribute(String(attr), String(val)); -} - -function dom_get_attr(el, attr) { - _ensureBrowser('dom_get_attr'); - if (el == null) return ''; - return el.getAttribute(String(attr)) ?? ''; -} - -function dom_remove_attr(el, attr) { - _ensureBrowser('dom_remove_attr'); - if (el != null) el.removeAttribute(String(attr)); -} - -function dom_set_html(el, html) { - _ensureBrowser('dom_set_html'); - if (el != null) el.innerHTML = String(html); -} - -function dom_get_html(el) { - _ensureBrowser('dom_get_html'); - return el == null ? '' : String(el.innerHTML ?? ''); -} - -function dom_get_parent(el) { - _ensureBrowser('dom_get_parent'); - return el == null ? null : (el.parentElement ?? null); -} - -function dom_contains_class(el, cls) { - _ensureBrowser('dom_contains_class'); - if (el == null) return false; - return el.classList.contains(String(cls)); -} - -function dom_get_checked(el) { - _ensureBrowser('dom_get_checked'); - return el == null ? false : Boolean(el.checked); -} - -function dom_set_checked(el, val) { - _ensureBrowser('dom_set_checked'); - if (el != null) el.checked = Boolean(val); -} - -// ── Timer API (browser + Node) ───────────────────────────────────────────── - -function set_timeout(ms, cb) { - if (typeof setTimeout === 'undefined') { - throw new Error('set_timeout: setTimeout not available in this environment'); - } - setTimeout(cb, ms | 0); -} - -function set_interval(ms, cb) { - if (typeof setInterval === 'undefined') { - throw new Error('set_interval: setInterval not available in this environment'); - } - return setInterval(cb, ms | 0); -} - -function clear_interval(handle) { - if (typeof clearInterval !== 'undefined') clearInterval(handle); -} - -// ── Local storage (browser-only) ─────────────────────────────────────────── - -function local_storage_get(key) { - _ensureBrowser('local_storage_get'); - return localStorage.getItem(String(key)) ?? ''; -} - -function local_storage_set(key, val) { - _ensureBrowser('local_storage_set'); - localStorage.setItem(String(key), String(val)); -} - -function local_storage_remove(key) { - _ensureBrowser('local_storage_remove'); - localStorage.removeItem(String(key)); -} - -// ── Window location / navigation (browser-only) ──────────────────────────── - -function window_location() { - _ensureBrowser('window_location'); - return window.location.href; -} - -function window_redirect(url) { - _ensureBrowser('window_redirect'); - window.location.href = String(url); -} - -function window_on_load(cb) { - if (typeof document !== 'undefined') { - document.addEventListener('DOMContentLoaded', cb); - } else if (typeof window !== 'undefined') { - window.addEventListener('load', cb); - } - // In Node: no-op -} - -// ── console_log (explicit debug log, distinct from println) ──────────────── - -function console_log(msg) { - // eslint-disable-next-line no-console - console.log(String(msg)); -} - -// ── Window export helpers ────────────────────────────────────────────────── -// -// Expose El functions to the browser's global scope so they can be called -// from inline event handlers (onclick="increment()") or by external JS. -// In Node mode, writes to globalThis so the same pattern works in tests. - -function window_set(name, val) { - if (typeof window !== 'undefined') { - window[String(name)] = val; - } else if (typeof globalThis !== 'undefined') { - globalThis[String(name)] = val; - } -} - -function window_get(name) { - if (typeof window !== 'undefined') { - const v = window[String(name)]; - return v === undefined ? null : v; - } - return null; -} - -// ── Promise helpers ──────────────────────────────────────────────────────── -// -// Third-party APIs often return Promises but are not El @async functions. -// These helpers let El programs chain .then / .catch without needing -// native_js, and without requiring the callee to be @async. - -function promise_then(p, cb) { - return Promise.resolve(p).then(cb); -} - -function promise_catch(p, cb) { - return Promise.resolve(p).catch(cb); -} - -function promise_resolve(val) { - return Promise.resolve(val); -} - -function promise_reject(msg) { - return Promise.reject(new Error(String(msg))); -} - -// ── Object / Array utilities ─────────────────────────────────────────────── -// -// Structural operations on Any-typed JS values. These complement the -// El map/list primitives for interop with third-party library objects. - -function object_assign(target, source) { - return Object.assign(Object.assign({}, target), source); -} - -function object_keys(obj) { - if (obj === null || obj === undefined) return []; - return Object.keys(obj); -} - -function object_values(obj) { - if (obj === null || obj === undefined) return []; - return Object.values(obj); -} - -function json_deep_clone(obj) { - if (obj === null || obj === undefined) return null; - return JSON.parse(JSON.stringify(obj)); -} - -function array_from(iterable) { - if (iterable === null || iterable === undefined) return []; - return Array.from(iterable); -} - -function type_of(val) { - return typeof val; -} - -function instanceof_check(val, constructor_name) { - if (typeof globalThis[constructor_name] === 'function') { - return val instanceof globalThis[constructor_name]; - } - return false; -} - -// ── native_js escape hatch ───────────────────────────────────────────────── -// -// Evaluate arbitrary JS from El source. Intended for calling third-party -// browser libraries (Supabase, Stripe, etc.) until proper El bindings exist. -// Use sparingly — this bypasses El's type system entirely. - -function native_js(code) { - // eslint-disable-next-line no-eval - return eval(String(code)); -} - -function native_js_call(obj, method, args) { - if (obj == null) throw new Error('native_js_call: object is null'); - return obj[String(method)](...(Array.isArray(args) ? args : [])); -} - -// ── Stubs for not-yet-supported features ─────────────────────────────────── -// -// These compile but throw when called. See spec/codegen-js.md §7. - -function _notSupported(name) { - return () => { throw new Error(`${name}: not supported in JS target — needs server-side delegation`); }; -} - -// CGI identity -function el_cgi_init(_name, _did, _principal, _network, _engram) { - // No-op — UI code is not a CGI principal. See spec §7. -} - -// DHARMA — all stubbed. -const dharma_connect = _notSupported('dharma_connect'); -const dharma_send = _notSupported('dharma_send'); -const dharma_activate = _notSupported('dharma_activate'); -const dharma_emit = _notSupported('dharma_emit'); -const dharma_field = _notSupported('dharma_field'); -const dharma_strengthen = _notSupported('dharma_strengthen'); -const dharma_relationship = _notSupported('dharma_relationship'); -const dharma_peers = _notSupported('dharma_peers'); - -// Engram — stubbed (could be ported to in-browser later). -const engram_node = _notSupported('engram_node'); -const engram_node_full = _notSupported('engram_node_full'); -const engram_get_node = _notSupported('engram_get_node'); -const engram_strengthen = _notSupported('engram_strengthen'); -const engram_forget = _notSupported('engram_forget'); -const engram_node_count = _notSupported('engram_node_count'); -const engram_search = _notSupported('engram_search'); -const engram_scan_nodes = _notSupported('engram_scan_nodes'); -const engram_connect = _notSupported('engram_connect'); -const engram_edge_between = _notSupported('engram_edge_between'); -const engram_neighbors = _notSupported('engram_neighbors'); -const engram_neighbors_filtered = _notSupported('engram_neighbors_filtered'); -const engram_edge_count = _notSupported('engram_edge_count'); -const engram_activate = _notSupported('engram_activate'); -const engram_save = _notSupported('engram_save'); -const engram_load = _notSupported('engram_load'); - -// LLM — stubbed (browser cannot hold API keys safely). -const llm_call = _notSupported('llm_call'); -const llm_call_system = _notSupported('llm_call_system'); -const llm_call_agentic = _notSupported('llm_call_agentic'); -const llm_vision = _notSupported('llm_vision'); -const llm_models = _notSupported('llm_models'); -const llm_register_tool = _notSupported('llm_register_tool'); - -// Crypto — stubbed; could be backed by SubtleCrypto later. -const sha256_hex = _notSupported('sha256_hex'); -const sha256_bytes = _notSupported('sha256_bytes'); -const hmac_sha256_hex = _notSupported('hmac_sha256_hex'); -const hmac_sha256_bytes = _notSupported('hmac_sha256_bytes'); -const base64_encode = _notSupported('base64_encode'); -const base64_decode = _notSupported('base64_decode'); -const base64url_encode = _notSupported('base64url_encode'); -const base64url_decode = _notSupported('base64url_decode'); - -// ── Export to globalThis.__el ────────────────────────────────────────────── -// -// Generated programs destructure off this object. Keeping it on globalThis -// means a single `import "./el_runtime.js"` is enough; no per-call namespace -// prefix is required at codegen time. - -const __el = { - // I/O - println, print, - // String - el_str_concat, str_concat, str_eq, str_starts_with, str_ends_with, - str_len, int_to_str, str_to_int, str_slice, str_contains, str_replace, - str_to_upper, str_to_lower, str_trim, str_index_of, str_split, str_char_at, - str_char_code, str_lower, str_upper, str_pad_left, str_pad_right, - // Math - el_abs, el_max, el_min, - // Refcount - el_retain, el_release, - // List - el_list_new, el_list_empty, el_list_clone, el_list_len, el_list_get, - el_list_append, list_push, list_push_front, list_join, list_range, - // Map - el_map_new, el_get_field, el_map_get, el_map_set, - // Method-call shortforms - append, len, get, map_get, map_set, - // Native VM aliases - native_list_get, native_list_len, native_list_append, native_list_empty, - native_list_clone, native_string_chars, native_int_to_str, - // HTTP - http_get, http_post, http_post_json, http_get_with_headers, - http_post_with_headers, http_serve, http_set_handler, - // FS - fs_read, fs_write, fs_list, - // JSON - json_parse, json_stringify, json_get, json_get_string, json_get_int, - json_get_float, json_get_bool, json_get_raw, json_set, json_array_len, - // Time - time_now, time_now_utc, sleep_secs, sleep_ms, - // Bool - bool_to_str, - // Process - exit_program, - // Args / env - args, env, - // State - state_set, state_get, state_del, state_keys, - // UUID - uuid_v4, uuid_new, - // Float / math - float_to_str, int_to_float, float_to_int, format_float, decimal_round, - str_to_float, math_sqrt, math_log, math_ln, math_sin, math_cos, math_pi, - // DOM bridge (browser-only) - dom_get_element, dom_get_value, dom_set_value, dom_get_text, dom_set_text, - dom_set_prop, dom_get_prop, dom_set_style, dom_add_class, dom_remove_class, - dom_show, dom_hide, dom_listen, dom_query, dom_query_all, dom_create, - dom_append, dom_remove, dom_is_null, - // Extended DOM - dom_set_attr, dom_get_attr, dom_remove_attr, dom_set_html, dom_get_html, - dom_get_parent, dom_contains_class, dom_get_checked, dom_set_checked, - // Timers - set_timeout, set_interval, clear_interval, - // Local storage - local_storage_get, local_storage_set, local_storage_remove, - // Window location - window_location, window_redirect, window_on_load, - // Debug - console_log, - // Window export helpers - window_set, window_get, - // Promise helpers - promise_then, promise_catch, promise_resolve, promise_reject, - // Object / Array utilities - object_assign, object_keys, object_values, json_deep_clone, - array_from, type_of, instanceof_check, - // native_js escape hatch - native_js, native_js_call, - // CGI / DHARMA / Engram / LLM (stubs) - el_cgi_init, - dharma_connect, dharma_send, dharma_activate, dharma_emit, dharma_field, - dharma_strengthen, dharma_relationship, dharma_peers, - engram_node, engram_node_full, engram_get_node, engram_strengthen, - engram_forget, engram_node_count, engram_search, engram_scan_nodes, - engram_connect, engram_edge_between, engram_neighbors, - engram_neighbors_filtered, engram_edge_count, engram_activate, - engram_save, engram_load, - llm_call, llm_call_system, llm_call_agentic, llm_vision, - llm_models, llm_register_tool, - // Crypto (stubs) - sha256_hex, sha256_bytes, hmac_sha256_hex, hmac_sha256_bytes, - base64_encode, base64_decode, base64url_encode, base64url_decode, -}; - -globalThis.__el = __el; - -// Also re-export as ES module exports for consumers that prefer that style. -export { __el as default }; -export { - println, print, - el_str_concat, str_concat, str_eq, str_starts_with, str_ends_with, - str_len, int_to_str, str_to_int, str_slice, str_contains, str_replace, - str_to_upper, str_to_lower, str_trim, str_index_of, str_split, str_char_at, - str_char_code, str_lower, str_upper, - el_abs, el_max, el_min, - el_retain, el_release, - el_list_new, el_list_empty, el_list_clone, el_list_len, el_list_get, - el_list_append, list_push, list_push_front, list_join, list_range, - el_map_new, el_get_field, el_map_get, el_map_set, - append, len, get, map_get, map_set, - native_list_get, native_list_len, native_list_append, native_list_empty, - native_list_clone, native_string_chars, native_int_to_str, - http_get, http_post, http_post_json, - fs_read, fs_write, fs_list, - json_parse, json_stringify, json_get, json_get_string, json_get_int, - time_now, time_now_utc, sleep_ms, - bool_to_str, exit_program, args, env, - state_set, state_get, state_del, state_keys, - el_cgi_init, - dharma_connect, dharma_send, dharma_activate, dharma_emit, dharma_field, - engram_node, engram_search, engram_activate, - llm_call, llm_call_system, - // DOM bridge - dom_get_element, dom_get_value, dom_set_value, dom_get_text, dom_set_text, - dom_set_prop, dom_get_prop, dom_set_style, dom_add_class, dom_remove_class, - dom_show, dom_hide, dom_listen, dom_query, dom_query_all, dom_create, - dom_append, dom_remove, dom_is_null, - // Extended DOM - dom_set_attr, dom_get_attr, dom_remove_attr, dom_set_html, dom_get_html, - dom_get_parent, dom_contains_class, dom_get_checked, dom_set_checked, - // Timers - set_timeout, set_interval, clear_interval, - // Local storage - local_storage_get, local_storage_set, local_storage_remove, - // Window location - window_location, window_redirect, window_on_load, - // Debug - console_log, - // Window / native_js - window_set, window_get, native_js, native_js_call, - // Promise helpers - promise_then, promise_catch, promise_resolve, promise_reject, - // Object / Array utilities - object_assign, object_keys, object_values, json_deep_clone, - array_from, type_of, instanceof_check, -}; diff --git a/lang/dist/platform/elb b/lang/dist/platform/elb deleted file mode 100755 index 187092f..0000000 Binary files a/lang/dist/platform/elb and /dev/null differ diff --git a/lang/dist/platform/elb-darwin-arm64 b/lang/dist/platform/elb-darwin-arm64 deleted file mode 100755 index 5d62fdd..0000000 Binary files a/lang/dist/platform/elb-darwin-arm64 and /dev/null differ diff --git a/lang/dist/platform/elb-linux-amd64 b/lang/dist/platform/elb-linux-amd64 deleted file mode 100755 index bd41f82..0000000 Binary files a/lang/dist/platform/elb-linux-amd64 and /dev/null differ diff --git a/lang/dist/platform/elc b/lang/dist/platform/elc deleted file mode 100755 index 4a791fb..0000000 Binary files a/lang/dist/platform/elc and /dev/null differ diff --git a/lang/dist/platform/elc-asan b/lang/dist/platform/elc-asan deleted file mode 100755 index 8b4727a..0000000 Binary files a/lang/dist/platform/elc-asan and /dev/null differ diff --git a/lang/dist/platform/elc-asan.dSYM/Contents/Info.plist b/lang/dist/platform/elc-asan.dSYM/Contents/Info.plist deleted file mode 100644 index 509e0bc..0000000 --- a/lang/dist/platform/elc-asan.dSYM/Contents/Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.apple.xcode.dsym.elc-asan - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - dSYM - CFBundleSignature - ???? - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/lang/dist/platform/elc-asan.dSYM/Contents/Resources/DWARF/elc-asan b/lang/dist/platform/elc-asan.dSYM/Contents/Resources/DWARF/elc-asan deleted file mode 100644 index aac088b..0000000 Binary files a/lang/dist/platform/elc-asan.dSYM/Contents/Resources/DWARF/elc-asan and /dev/null differ diff --git a/lang/dist/platform/elc-asan.dSYM/Contents/Resources/Relocations/aarch64/elc-asan.yml b/lang/dist/platform/elc-asan.dSYM/Contents/Resources/Relocations/aarch64/elc-asan.yml deleted file mode 100644 index b55aedf..0000000 --- a/lang/dist/platform/elc-asan.dSYM/Contents/Resources/Relocations/aarch64/elc-asan.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -triple: 'arm64-apple-darwin' -binary-path: '/Users/will/Development/neuron-technologies/foundation/el/dist/platform/elc-asan' -relocations: [] -... diff --git a/lang/dist/platform/elc-darwin-arm64 b/lang/dist/platform/elc-darwin-arm64 deleted file mode 100755 index 9ec7b43..0000000 Binary files a/lang/dist/platform/elc-darwin-arm64 and /dev/null differ diff --git a/lang/dist/platform/elc-linux-amd64 b/lang/dist/platform/elc-linux-amd64 deleted file mode 100755 index b2efc54..0000000 Binary files a/lang/dist/platform/elc-linux-amd64 and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-0130-self-host b/lang/dist/platform/elc.20260502-0130-self-host deleted file mode 100755 index a4de585..0000000 Binary files a/lang/dist/platform/elc.20260502-0130-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-1104-self-host b/lang/dist/platform/elc.20260502-1104-self-host deleted file mode 100755 index 44b0d57..0000000 Binary files a/lang/dist/platform/elc.20260502-1104-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-1231-self-host b/lang/dist/platform/elc.20260502-1231-self-host deleted file mode 100755 index 417485d..0000000 Binary files a/lang/dist/platform/elc.20260502-1231-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-1249-self-host b/lang/dist/platform/elc.20260502-1249-self-host deleted file mode 100755 index 9b68a40..0000000 Binary files a/lang/dist/platform/elc.20260502-1249-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-1256-self-host b/lang/dist/platform/elc.20260502-1256-self-host deleted file mode 100755 index b4d96ab..0000000 Binary files a/lang/dist/platform/elc.20260502-1256-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-1321-self-host b/lang/dist/platform/elc.20260502-1321-self-host deleted file mode 100755 index 7992a4e..0000000 Binary files a/lang/dist/platform/elc.20260502-1321-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260502-1916-self-host b/lang/dist/platform/elc.20260502-1916-self-host deleted file mode 100755 index 04c36ef..0000000 Binary files a/lang/dist/platform/elc.20260502-1916-self-host and /dev/null differ diff --git a/lang/dist/platform/elc.20260503-1555-post-sprint b/lang/dist/platform/elc.20260503-1555-post-sprint deleted file mode 100755 index e331ae6..0000000 Binary files a/lang/dist/platform/elc.20260503-1555-post-sprint and /dev/null differ diff --git a/lang/dist/platform/elc.20260503-1603-post-lsp b/lang/dist/platform/elc.20260503-1603-post-lsp deleted file mode 100755 index d2f167f..0000000 Binary files a/lang/dist/platform/elc.20260503-1603-post-lsp and /dev/null differ diff --git a/lang/dist/platform/elc.c b/lang/dist/platform/elc.c deleted file mode 100644 index 52ef58a..0000000 --- a/lang/dist/platform/elc.c +++ /dev/null @@ -1,6450 +0,0 @@ -#include -#include -#include "el_runtime.h" - -el_val_t lex_is_digit(el_val_t ch); -el_val_t lex_is_alpha(el_val_t ch); -el_val_t is_alnum_or_underscore(el_val_t ch); -el_val_t lex_is_whitespace(el_val_t ch); -el_val_t make_tok(el_val_t kind, el_val_t value); -el_val_t keyword_kind(el_val_t word); -el_val_t scan_digits(el_val_t chars, el_val_t start, el_val_t total); -el_val_t scan_ident(el_val_t chars, el_val_t start, el_val_t total); -el_val_t substr_at(el_val_t chars, el_val_t start, el_val_t total, el_val_t needle); -el_val_t str_has(el_val_t s, el_val_t needle); -el_val_t looks_like_code(el_val_t s); -el_val_t strip_code_comments(el_val_t s); -el_val_t scan_string(el_val_t chars, el_val_t start, el_val_t total); -el_val_t lex(el_val_t source); -el_val_t tok_at(el_val_t tokens, el_val_t pos); -el_val_t tok_kind(el_val_t tokens, el_val_t pos); -el_val_t tok_value(el_val_t tokens, el_val_t pos); -el_val_t expect(el_val_t tokens, el_val_t pos, el_val_t kind); -el_val_t make_result(el_val_t node, el_val_t pos); -el_val_t skip_type(el_val_t tokens, el_val_t pos); -el_val_t parse_params(el_val_t tokens, el_val_t pos); -el_val_t parse_primary(el_val_t tokens, el_val_t pos); -el_val_t parse_if(el_val_t tokens, el_val_t pos); -el_val_t parse_match(el_val_t tokens, el_val_t pos); -el_val_t parse_pattern(el_val_t tokens, el_val_t pos); -el_val_t parse_for_expr(el_val_t tokens, el_val_t pos); -el_val_t parse_block(el_val_t tokens, el_val_t pos); -el_val_t is_duration_unit(el_val_t name); -el_val_t parse_postfix(el_val_t tokens, el_val_t pos); -el_val_t op_precedence(el_val_t kind); -el_val_t is_binop(el_val_t kind); -el_val_t parse_binop(el_val_t tokens, el_val_t pos, el_val_t min_prec); -el_val_t parse_expr(el_val_t tokens, el_val_t pos); -el_val_t parse_stmt(el_val_t tokens, el_val_t pos); -el_val_t parse(el_val_t tokens); -el_val_t c_escape(el_val_t s); -el_val_t c_str_lit(el_val_t s); -el_val_t el_type_to_c(el_val_t type_str); -el_val_t emit_line(el_val_t line); -el_val_t emit_blank(void); -el_val_t binop_to_c(el_val_t op); -el_val_t duration_unit_nanos(el_val_t unit); -el_val_t cg_expr(el_val_t expr); -el_val_t next_match_id(void); -el_val_t cg_match(el_val_t expr); -el_val_t next_if_id(void); -el_val_t cg_if_expr_arm(el_val_t stmts, el_val_t result_var); -el_val_t cg_if_expr(el_val_t expr); -el_val_t list_contains(el_val_t lst, el_val_t s); -el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared); -el_val_t strip_outer_parens(el_val_t s); -el_val_t cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared); -el_val_t cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared); -el_val_t param_decl(el_val_t param, el_val_t idx); -el_val_t params_to_c(el_val_t params); -el_val_t transform_implicit_return(el_val_t body); -el_val_t is_int_name(el_val_t name); -el_val_t is_instant_name(el_val_t name); -el_val_t is_duration_name(el_val_t name); -el_val_t is_int_call(el_val_t call_expr); -el_val_t is_instant_call(el_val_t call_expr); -el_val_t is_duration_call(el_val_t call_expr); -el_val_t is_calendar_name(el_val_t name); -el_val_t is_caltime_name(el_val_t name); -el_val_t is_rhythm_name(el_val_t name); -el_val_t is_localdate_name(el_val_t name); -el_val_t is_localtime_name(el_val_t name); -el_val_t is_localdt_name(el_val_t name); -el_val_t is_zone_name(el_val_t name); -el_val_t is_calendar_call(el_val_t call_expr); -el_val_t is_caltime_call(el_val_t call_expr); -el_val_t is_rhythm_call(el_val_t call_expr); -el_val_t is_localdate_call(el_val_t call_expr); -el_val_t is_localtime_call(el_val_t call_expr); -el_val_t is_localdt_call(el_val_t call_expr); -el_val_t is_zone_call(el_val_t call_expr); -el_val_t is_calendar_expr(el_val_t expr); -el_val_t is_caltime_expr(el_val_t expr); -el_val_t is_rhythm_expr(el_val_t expr); -el_val_t is_localdate_expr(el_val_t expr); -el_val_t is_localtime_expr(el_val_t expr); -el_val_t is_localdt_expr(el_val_t expr); -el_val_t is_zone_expr(el_val_t expr); -el_val_t is_instant_expr(el_val_t expr); -el_val_t is_duration_expr(el_val_t expr); -el_val_t time_record_violation(el_val_t kind, el_val_t detail); -el_val_t is_int_expr(el_val_t expr); -el_val_t cap_record_violation(el_val_t kind, el_val_t fn_name); -el_val_t is_self_formation_call(el_val_t fn_name); -el_val_t is_dharma_call(el_val_t fn_name); -el_val_t is_llm_call(el_val_t fn_name); -el_val_t cap_check_call(el_val_t fn_name); -el_val_t emit_cap_violations(void); -el_val_t emit_time_violations(void); -el_val_t builtin_arity(el_val_t name); -el_val_t arity_record_violation(el_val_t fn_name, el_val_t expected, el_val_t actual); -el_val_t arity_check_call(el_val_t fn_name, el_val_t actual); -el_val_t emit_arity_violations(void); -el_val_t add_int_name(el_val_t name); -el_val_t add_instant_name(el_val_t name); -el_val_t add_duration_name(el_val_t name); -el_val_t add_calendar_name(el_val_t name); -el_val_t add_caltime_name(el_val_t name); -el_val_t add_rhythm_name(el_val_t name); -el_val_t add_localdate_name(el_val_t name); -el_val_t add_localtime_name(el_val_t name); -el_val_t add_localdt_name(el_val_t name); -el_val_t add_zone_name(el_val_t name); -el_val_t build_int_names_for_params(el_val_t params); -el_val_t cg_fn(el_val_t stmt); -el_val_t is_fndef(el_val_t stmt); -el_val_t is_top_level_decl(el_val_t stmt); -el_val_t cgi_arg(el_val_t value, el_val_t has_value); -el_val_t vbd_is_restricted_name(el_val_t name); -el_val_t vbd_expr_has_restricted_call(el_val_t expr); -el_val_t vbd_has_restricted_call(el_val_t stmts); -el_val_t codegen(el_val_t stmts, el_val_t source); -el_val_t js_escape(el_val_t s); -el_val_t js_str_lit(el_val_t s); -el_val_t js_emit_line(el_val_t line); -el_val_t js_emit_blank(void); -el_val_t js_binop(el_val_t op); -el_val_t js_is_int_name(el_val_t name); -el_val_t js_add_int_name(el_val_t name); -el_val_t js_build_int_names_for_params(el_val_t params); -el_val_t js_is_int_call(el_val_t call_expr); -el_val_t js_cg_expr(el_val_t expr); -el_val_t js_next_match_id(void); -el_val_t js_cg_match(el_val_t expr); -el_val_t js_list_contains(el_val_t lst, el_val_t s); -el_val_t js_cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared); -el_val_t js_strip_outer_parens(el_val_t s); -el_val_t js_cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t js_cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared); -el_val_t js_cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared); -el_val_t js_cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared); -el_val_t js_params_str(el_val_t params); -el_val_t js_transform_implicit_return(el_val_t body); -el_val_t js_cg_fn(el_val_t stmt); -el_val_t js_is_fndef(el_val_t stmt); -el_val_t js_is_top_level_decl(el_val_t stmt); -el_val_t codegen_js(el_val_t stmts, el_val_t source); -el_val_t compile(el_val_t source); -el_val_t compile_js(el_val_t source); -el_val_t compile_dispatch(el_val_t tgt, el_val_t source); -el_val_t detect_target(el_val_t argv); -el_val_t strip_flags(el_val_t argv); -el_val_t dirname_of(el_val_t path); -el_val_t parse_import_line(el_val_t trimmed, el_val_t dir); -el_val_t resolve_imports(el_val_t src_path); - -el_val_t lex_is_digit(el_val_t ch) { - if (str_eq(ch, EL_STR("0"))) { - return 1; - } - if (str_eq(ch, EL_STR("1"))) { - return 1; - } - if (str_eq(ch, EL_STR("2"))) { - return 1; - } - if (str_eq(ch, EL_STR("3"))) { - return 1; - } - if (str_eq(ch, EL_STR("4"))) { - return 1; - } - if (str_eq(ch, EL_STR("5"))) { - return 1; - } - if (str_eq(ch, EL_STR("6"))) { - return 1; - } - if (str_eq(ch, EL_STR("7"))) { - return 1; - } - if (str_eq(ch, EL_STR("8"))) { - return 1; - } - if (str_eq(ch, EL_STR("9"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t lex_is_alpha(el_val_t ch) { - if (str_eq(ch, EL_STR("a"))) { - return 1; - } - if (str_eq(ch, EL_STR("b"))) { - return 1; - } - if (str_eq(ch, EL_STR("c"))) { - return 1; - } - if (str_eq(ch, EL_STR("d"))) { - return 1; - } - if (str_eq(ch, EL_STR("e"))) { - return 1; - } - if (str_eq(ch, EL_STR("f"))) { - return 1; - } - if (str_eq(ch, EL_STR("g"))) { - return 1; - } - if (str_eq(ch, EL_STR("h"))) { - return 1; - } - if (str_eq(ch, EL_STR("i"))) { - return 1; - } - if (str_eq(ch, EL_STR("j"))) { - return 1; - } - if (str_eq(ch, EL_STR("k"))) { - return 1; - } - if (str_eq(ch, EL_STR("l"))) { - return 1; - } - if (str_eq(ch, EL_STR("m"))) { - return 1; - } - if (str_eq(ch, EL_STR("n"))) { - return 1; - } - if (str_eq(ch, EL_STR("o"))) { - return 1; - } - if (str_eq(ch, EL_STR("p"))) { - return 1; - } - if (str_eq(ch, EL_STR("q"))) { - return 1; - } - if (str_eq(ch, EL_STR("r"))) { - return 1; - } - if (str_eq(ch, EL_STR("s"))) { - return 1; - } - if (str_eq(ch, EL_STR("t"))) { - return 1; - } - if (str_eq(ch, EL_STR("u"))) { - return 1; - } - if (str_eq(ch, EL_STR("v"))) { - return 1; - } - if (str_eq(ch, EL_STR("w"))) { - return 1; - } - if (str_eq(ch, EL_STR("x"))) { - return 1; - } - if (str_eq(ch, EL_STR("y"))) { - return 1; - } - if (str_eq(ch, EL_STR("z"))) { - return 1; - } - if (str_eq(ch, EL_STR("A"))) { - return 1; - } - if (str_eq(ch, EL_STR("B"))) { - return 1; - } - if (str_eq(ch, EL_STR("C"))) { - return 1; - } - if (str_eq(ch, EL_STR("D"))) { - return 1; - } - if (str_eq(ch, EL_STR("E"))) { - return 1; - } - if (str_eq(ch, EL_STR("F"))) { - return 1; - } - if (str_eq(ch, EL_STR("G"))) { - return 1; - } - if (str_eq(ch, EL_STR("H"))) { - return 1; - } - if (str_eq(ch, EL_STR("I"))) { - return 1; - } - if (str_eq(ch, EL_STR("J"))) { - return 1; - } - if (str_eq(ch, EL_STR("K"))) { - return 1; - } - if (str_eq(ch, EL_STR("L"))) { - return 1; - } - if (str_eq(ch, EL_STR("M"))) { - return 1; - } - if (str_eq(ch, EL_STR("N"))) { - return 1; - } - if (str_eq(ch, EL_STR("O"))) { - return 1; - } - if (str_eq(ch, EL_STR("P"))) { - return 1; - } - if (str_eq(ch, EL_STR("Q"))) { - return 1; - } - if (str_eq(ch, EL_STR("R"))) { - return 1; - } - if (str_eq(ch, EL_STR("S"))) { - return 1; - } - if (str_eq(ch, EL_STR("T"))) { - return 1; - } - if (str_eq(ch, EL_STR("U"))) { - return 1; - } - if (str_eq(ch, EL_STR("V"))) { - return 1; - } - if (str_eq(ch, EL_STR("W"))) { - return 1; - } - if (str_eq(ch, EL_STR("X"))) { - return 1; - } - if (str_eq(ch, EL_STR("Y"))) { - return 1; - } - if (str_eq(ch, EL_STR("Z"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_alnum_or_underscore(el_val_t ch) { - if (lex_is_digit(ch)) { - return 1; - } - if (lex_is_alpha(ch)) { - return 1; - } - if (str_eq(ch, EL_STR("_"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t lex_is_whitespace(el_val_t ch) { - if (str_eq(ch, EL_STR(" "))) { - return 1; - } - if (str_eq(ch, EL_STR("\t"))) { - return 1; - } - if (str_eq(ch, EL_STR("\n"))) { - return 1; - } - if (str_eq(ch, EL_STR("\r"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t make_tok(el_val_t kind, el_val_t value) { - return el_map_new(2, "kind", kind, "value", value); - return 0; -} - -el_val_t keyword_kind(el_val_t word) { - if (str_eq(word, EL_STR("let"))) { - return EL_STR("Let"); - } - if (str_eq(word, EL_STR("fn"))) { - return EL_STR("Fn"); - } - if (str_eq(word, EL_STR("type"))) { - return EL_STR("Type"); - } - if (str_eq(word, EL_STR("enum"))) { - return EL_STR("Enum"); - } - if (str_eq(word, EL_STR("match"))) { - return EL_STR("Match"); - } - if (str_eq(word, EL_STR("return"))) { - return EL_STR("Return"); - } - if (str_eq(word, EL_STR("if"))) { - return EL_STR("If"); - } - if (str_eq(word, EL_STR("else"))) { - return EL_STR("Else"); - } - if (str_eq(word, EL_STR("for"))) { - return EL_STR("For"); - } - if (str_eq(word, EL_STR("in"))) { - return EL_STR("In"); - } - if (str_eq(word, EL_STR("while"))) { - return EL_STR("While"); - } - if (str_eq(word, EL_STR("import"))) { - return EL_STR("Import"); - } - if (str_eq(word, EL_STR("from"))) { - return EL_STR("From"); - } - if (str_eq(word, EL_STR("as"))) { - return EL_STR("As"); - } - if (str_eq(word, EL_STR("with"))) { - return EL_STR("With"); - } - if (str_eq(word, EL_STR("sealed"))) { - return EL_STR("Sealed"); - } - if (str_eq(word, EL_STR("activate"))) { - return EL_STR("Activate"); - } - if (str_eq(word, EL_STR("where"))) { - return EL_STR("Where"); - } - if (str_eq(word, EL_STR("test"))) { - return EL_STR("Test"); - } - if (str_eq(word, EL_STR("seed"))) { - return EL_STR("Seed"); - } - if (str_eq(word, EL_STR("assert"))) { - return EL_STR("Assert"); - } - if (str_eq(word, EL_STR("protocol"))) { - return EL_STR("Protocol"); - } - if (str_eq(word, EL_STR("impl"))) { - return EL_STR("Impl"); - } - if (str_eq(word, EL_STR("retry"))) { - return EL_STR("Retry"); - } - if (str_eq(word, EL_STR("times"))) { - return EL_STR("Times"); - } - if (str_eq(word, EL_STR("fallback"))) { - return EL_STR("Fallback"); - } - if (str_eq(word, EL_STR("reason"))) { - return EL_STR("Reason"); - } - if (str_eq(word, EL_STR("parallel"))) { - return EL_STR("Parallel"); - } - if (str_eq(word, EL_STR("trace"))) { - return EL_STR("Trace"); - } - if (str_eq(word, EL_STR("requires"))) { - return EL_STR("Requires"); - } - if (str_eq(word, EL_STR("deploy"))) { - return EL_STR("Deploy"); - } - if (str_eq(word, EL_STR("to"))) { - return EL_STR("To"); - } - if (str_eq(word, EL_STR("via"))) { - return EL_STR("Via"); - } - if (str_eq(word, EL_STR("target"))) { - return EL_STR("Target"); - } - if (str_eq(word, EL_STR("true"))) { - return EL_STR("Bool"); - } - if (str_eq(word, EL_STR("false"))) { - return EL_STR("Bool"); - } - if (str_eq(word, EL_STR("cgi"))) { - return EL_STR("Cgi"); - } - if (str_eq(word, EL_STR("service"))) { - return EL_STR("Service"); - } - if (str_eq(word, EL_STR("manager"))) { - return EL_STR("Manager"); - } - if (str_eq(word, EL_STR("engine"))) { - return EL_STR("Engine"); - } - if (str_eq(word, EL_STR("accessor"))) { - return EL_STR("Accessor"); - } - if (str_eq(word, EL_STR("vessel"))) { - return EL_STR("Vessel"); - } - return EL_STR(""); - return 0; -} - -el_val_t scan_digits(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t text = EL_STR(""); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (lex_is_digit(ch)) { - text = el_str_concat(text, ch); - i = (i + 1); - } else { - running = 0; - } - } - } - return el_map_new(2, "text", text, "pos", i); - return 0; -} - -el_val_t scan_ident(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t text = EL_STR(""); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (is_alnum_or_underscore(ch)) { - text = el_str_concat(text, ch); - i = (i + 1); - } else { - running = 0; - } - } - } - return el_map_new(2, "text", text, "pos", i); - return 0; -} - -el_val_t substr_at(el_val_t chars, el_val_t start, el_val_t total, el_val_t needle) { - el_val_t nchars = native_string_chars(needle); - el_val_t nlen = native_list_len(nchars); - if ((start + nlen) > total) { - return 0; - } - el_val_t i = 0; - el_val_t matched = 1; - while (i < nlen) { - el_val_t a = native_list_get(chars, (start + i)); - el_val_t b = native_list_get(nchars, i); - if (str_eq(a, b)) { - i = (i + 1); - } else { - matched = 0; - EL_NULL; - i = nlen; - } - } - return matched; - return 0; -} - -el_val_t str_has(el_val_t s, el_val_t needle) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t i = 0; - el_val_t found = 0; - while (i < total) { - if (substr_at(chars, i, total, needle)) { - found = 1; - i = total; - } else { - i = (i + 1); - } - } - return found; - return 0; -} - -el_val_t looks_like_code(el_val_t s) { - if (str_has(s, EL_STR("= total) { - scanning = 0; - } else { - el_val_t lc = native_list_get(chars, i); - if (str_eq(lc, EL_STR("\n"))) { - scanning = 0; - } else { - i = (i + 1); - } - } - } - prev = EL_STR(""); - } - } else { - if (str_eq(next_ch, EL_STR("*"))) { - i = (i + 2); - el_val_t scanning2 = 1; - while (scanning2) { - if (i >= total) { - scanning2 = 0; - } else { - el_val_t bc = native_list_get(chars, i); - if (str_eq(bc, EL_STR("*"))) { - el_val_t after = (i + 1); - if (after < total) { - el_val_t nc2 = native_list_get(chars, after); - if (str_eq(nc2, EL_STR("/"))) { - i = (after + 1); - scanning2 = 0; - } else { - i = (i + 1); - } - } else { - i = (i + 1); - } - } else { - i = (i + 1); - } - } - } - prev = EL_STR(""); - } else { - out = el_str_concat(out, ch); - prev = ch; - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("'"))) { - in_squote = 1; - out = el_str_concat(out, ch); - prev = ch; - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("\""))) { - in_dquote = 1; - out = el_str_concat(out, ch); - prev = ch; - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("`"))) { - in_btick = 1; - out = el_str_concat(out, ch); - prev = ch; - i = (i + 1); - } else { - out = el_str_concat(out, ch); - prev = ch; - i = (i + 1); - } - } - } - } - } - } - return out; - return 0; -} - -el_val_t scan_string(el_val_t chars, el_val_t start, el_val_t total) { - el_val_t i = start; - el_val_t text = EL_STR(""); - el_val_t running = 1; - while (running) { - if (i >= total) { - running = 0; - } else { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\\"))) { - el_val_t next_i = (i + 1); - if (next_i < total) { - el_val_t next_ch = native_list_get(chars, next_i); - if (str_eq(next_ch, EL_STR("\""))) { - text = el_str_concat(text, EL_STR("\"")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("n"))) { - text = el_str_concat(text, EL_STR("\n")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("t"))) { - text = el_str_concat(text, EL_STR("\t")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("r"))) { - text = el_str_concat(text, EL_STR("\r")); - i = (next_i + 1); - } else { - if (str_eq(next_ch, EL_STR("\\"))) { - text = el_str_concat(text, EL_STR("\\")); - i = (next_i + 1); - } else { - text = el_str_concat(text, next_ch); - i = (next_i + 1); - } - } - } - } - } - } else { - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("\""))) { - i = (i + 1); - running = 0; - } else { - text = el_str_concat(text, ch); - i = (i + 1); - } - } - } - } - return el_map_new(2, "text", text, "pos", i); - return 0; -} - -el_val_t lex(el_val_t source) { - el_val_t chars = native_string_chars(source); - el_val_t total = native_list_len(chars); - el_val_t tokens = native_list_empty(); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (lex_is_whitespace(ch)) { - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("/"))) { - el_val_t next_i = (i + 1); - if (next_i < total) { - el_val_t next_ch = native_list_get(chars, next_i); - if (str_eq(next_ch, EL_STR("/"))) { - i = (i + 2); - el_val_t running2 = 1; - while (running2) { - if (i >= total) { - running2 = 0; - } else { - el_val_t lch = native_list_get(chars, i); - if (str_eq(lch, EL_STR("\n"))) { - running2 = 0; - } else { - i = (i + 1); - } - } - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Slash"), EL_STR("/"))); - i = (i + 1); - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Slash"), EL_STR("/"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("\""))) { - el_val_t result = scan_string(chars, (i + 1), total); - el_val_t str_text = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - el_val_t clean_text = str_text; - if (looks_like_code(str_text)) { - clean_text = strip_code_comments(str_text); - } - tokens = native_list_append(tokens, make_tok(EL_STR("Str"), clean_text)); - i = new_pos; - } else { - if (lex_is_digit(ch)) { - el_val_t result = scan_digits(chars, i, total); - el_val_t num_text = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - if (new_pos < total) { - el_val_t dot_ch = native_list_get(chars, new_pos); - if (str_eq(dot_ch, EL_STR("."))) { - el_val_t after_dot = (new_pos + 1); - if (after_dot < total) { - el_val_t after_dot_ch = native_list_get(chars, after_dot); - if (lex_is_digit(after_dot_ch)) { - el_val_t frac_result = scan_digits(chars, after_dot, total); - el_val_t frac_text = el_get_field(frac_result, EL_STR("text")); - el_val_t frac_pos = el_get_field(frac_result, EL_STR("pos")); - tokens = native_list_append(tokens, make_tok(EL_STR("Float"), el_str_concat(el_str_concat(num_text, EL_STR(".")), frac_text))); - i = frac_pos; - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Int"), num_text)); - i = new_pos; - } - } else { - if (lex_is_alpha(ch) || str_eq(ch, EL_STR("_"))) { - el_val_t result = scan_ident(chars, i, total); - el_val_t word = el_get_field(result, EL_STR("text")); - el_val_t new_pos = el_get_field(result, EL_STR("pos")); - el_val_t kw = keyword_kind(word); - if (str_eq(kw, EL_STR(""))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Ident"), word)); - } else { - tokens = native_list_append(tokens, make_tok(kw, word)); - } - i = new_pos; - } else { - el_val_t peek_i = (i + 1); - el_val_t peek_ch = EL_STR(""); - if (peek_i < total) { - peek_ch = native_list_get(chars, peek_i); - } - if (str_eq(ch, EL_STR("="))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("EqEq"), EL_STR("=="))); - i = (i + 2); - } else { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("FatArrow"), EL_STR("=>"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Eq"), EL_STR("="))); - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("!"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("NotEq"), EL_STR("!="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Not"), EL_STR("!"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("<"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LtEq"), EL_STR("<="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Lt"), EL_STR("<"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR(">"))) { - if (str_eq(peek_ch, EL_STR("="))) { - tokens = native_list_append(tokens, make_tok(EL_STR("GtEq"), EL_STR(">="))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Gt"), EL_STR(">"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("&"))) { - if (str_eq(peek_ch, EL_STR("&"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("And"), EL_STR("&&"))); - i = (i + 2); - } else { - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("|"))) { - if (str_eq(peek_ch, EL_STR("|"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Or"), EL_STR("||"))); - i = (i + 2); - } else { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("PipeOp"), EL_STR("|>"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Pipe"), EL_STR("|"))); - i = (i + 1); - } - } - } else { - if (str_eq(ch, EL_STR("-"))) { - if (str_eq(peek_ch, EL_STR(">"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Arrow"), EL_STR("->"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Minus"), EL_STR("-"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR(":"))) { - if (str_eq(peek_ch, EL_STR(":"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("ColonColon"), EL_STR("::"))); - i = (i + 2); - } else { - tokens = native_list_append(tokens, make_tok(EL_STR("Colon"), EL_STR(":"))); - i = (i + 1); - } - } else { - if (str_eq(ch, EL_STR("+"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Plus"), EL_STR("+"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("*"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Star"), EL_STR("*"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("%"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Percent"), EL_STR("%"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("("))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LParen"), EL_STR("("))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(")"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RParen"), EL_STR(")"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("{"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LBrace"), EL_STR("{"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("}"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RBrace"), EL_STR("}"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("["))) { - tokens = native_list_append(tokens, make_tok(EL_STR("LBracket"), EL_STR("["))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("]"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("RBracket"), EL_STR("]"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(","))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Comma"), EL_STR(","))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("."))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Dot"), EL_STR("."))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR(";"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("Semicolon"), EL_STR(";"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("@"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("At"), EL_STR("@"))); - i = (i + 1); - } else { - if (str_eq(ch, EL_STR("?"))) { - tokens = native_list_append(tokens, make_tok(EL_STR("QuestionMark"), EL_STR("?"))); - i = (i + 1); - } else { - i = (i + 1); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - tokens = native_list_append(tokens, make_tok(EL_STR("Eof"), EL_STR(""))); - return tokens; - return 0; -} - -el_val_t tok_at(el_val_t tokens, el_val_t pos) { - return native_list_get(tokens, pos); - return 0; -} - -el_val_t tok_kind(el_val_t tokens, el_val_t pos) { - el_val_t t = native_list_get(tokens, pos); - return el_get_field(t, EL_STR("kind")); - return 0; -} - -el_val_t tok_value(el_val_t tokens, el_val_t pos) { - el_val_t t = native_list_get(tokens, pos); - return el_get_field(t, EL_STR("value")); - return 0; -} - -el_val_t expect(el_val_t tokens, el_val_t pos, el_val_t kind) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, kind)) { - return (pos + 1); - } - return (pos + 1); - return 0; -} - -el_val_t make_result(el_val_t node, el_val_t pos) { - return el_map_new(2, "node", node, "pos", pos); - return 0; -} - -el_val_t skip_type(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t p = (pos + 1); - p = skip_type(tokens, p); - p = expect(tokens, p, EL_STR("RBracket")); - return p; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Lt"))) { - p = (p + 1); - el_val_t depth = 1; - el_val_t running = 1; - while (running) { - el_val_t kk = tok_kind(tokens, p); - if (str_eq(kk, EL_STR("Eof"))) { - running = 0; - } else { - if (str_eq(kk, EL_STR("Lt"))) { - depth = (depth + 1); - p = (p + 1); - } else { - if (str_eq(kk, EL_STR("Gt"))) { - depth = (depth - 1); - p = (p + 1); - if (depth <= 0) { - running = 0; - } - } else { - p = (p + 1); - } - } - } - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("QuestionMark"))) { - p = (p + 1); - } - return p; - } - if (str_eq(k2, EL_STR("QuestionMark"))) { - return (p + 1); - } - return p; - } - return (pos + 1); - return 0; -} - -el_val_t parse_params(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("LParen")); - el_val_t params = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RParen"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t pname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t ptype = EL_STR(""); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ptype = tok_value(tokens, p); - } - p = skip_type(tokens, p); - el_val_t param = el_map_new(2, "name", pname, "type", ptype); - params = native_list_append(params, param); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RParen")); - return el_map_new(2, "params", params, "pos", p); - return 0; -} - -el_val_t parse_primary(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - el_val_t v = tok_value(tokens, pos); - if (str_eq(k, EL_STR("Int"))) { - return make_result(el_map_new(2, "expr", EL_STR("Int"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Float"))) { - return make_result(el_map_new(2, "expr", EL_STR("Float"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Str"))) { - return make_result(el_map_new(2, "expr", EL_STR("Str"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Bool"))) { - return make_result(el_map_new(2, "expr", EL_STR("Bool"), "value", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Ident"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("LParen"))) { - el_val_t r = parse_expr(tokens, (pos + 1)); - el_val_t node = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - p = expect(tokens, p, EL_STR("RParen")); - return make_result(node, p); - } - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t p = (pos + 1); - el_val_t elems = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBracket"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_expr(tokens, p); - el_val_t elem = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - elems = native_list_append(elems, elem); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBracket")); - return make_result(el_map_new(2, "expr", EL_STR("Array"), "elems", elems), p); - } - if (str_eq(k, EL_STR("LBrace"))) { - el_val_t no_block = state_get(EL_STR("__no_block_expr")); - if (str_eq(no_block, EL_STR("1"))) { - return make_result(el_map_new(1, "expr", EL_STR("Nil")), pos); - } - el_val_t p = (pos + 1); - el_val_t pairs = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t key = tok_value(tokens, p); - el_val_t new_p = (p + 1); - new_p = expect(tokens, new_p, EL_STR("Colon")); - el_val_t r = parse_expr(tokens, new_p); - el_val_t val_node = el_get_field(r, EL_STR("node")); - new_p = el_get_field(r, EL_STR("pos")); - el_val_t pair = el_map_new(2, "key", key, "value", val_node); - pairs = native_list_append(pairs, pair); - el_val_t k3 = tok_kind(tokens, new_p); - if (str_eq(k3, EL_STR("Comma"))) { - new_p = (new_p + 1); - } - if (new_p <= p) { - p = (p + 1); - } else { - p = new_p; - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(2, "expr", EL_STR("Map"), "pairs", pairs), p); - } - if (str_eq(k, EL_STR("If"))) { - el_val_t r = parse_if(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("Match"))) { - el_val_t r = parse_match(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("For"))) { - el_val_t r = parse_for_expr(tokens, pos); - return r; - } - if (str_eq(k, EL_STR("Not"))) { - el_val_t r = parse_primary(tokens, (pos + 1)); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "expr", EL_STR("Not"), "inner", inner), p); - } - if (str_eq(k, EL_STR("Minus"))) { - el_val_t r = parse_primary(tokens, (pos + 1)); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "expr", EL_STR("Neg"), "inner", inner), p); - } - if (str_eq(k, EL_STR("Target"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("To"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Via"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Deploy"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Reason"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Times"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Fallback"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Retry"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Parallel"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Trace"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Requires"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Where"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("As"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("With"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Manager"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Engine"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Accessor"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Vessel"))) { - return make_result(el_map_new(2, "expr", EL_STR("Ident"), "name", v), (pos + 1)); - } - return make_result(el_map_new(1, "expr", EL_STR("Nil")), (pos + 1)); - return 0; -} - -el_val_t parse_if(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("If")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t cond = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t then_stmts = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - el_val_t has_else = 0; - el_val_t else_stmts = native_list_empty(); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Else"))) { - p = (p + 1); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("If"))) { - el_val_t r3 = parse_if(tokens, p); - el_val_t nested = el_get_field(r3, EL_STR("node")); - p = el_get_field(r3, EL_STR("pos")); - else_stmts = native_list_append(else_stmts, el_map_new(2, "stmt", EL_STR("Expr"), "value", nested)); - has_else = 1; - } else { - el_val_t r3 = parse_block(tokens, p); - else_stmts = el_get_field(r3, EL_STR("stmts")); - p = el_get_field(r3, EL_STR("pos")); - has_else = 1; - } - } - return make_result(el_map_new(5, "expr", EL_STR("If"), "cond", cond, "then", then_stmts, "else", else_stmts, "has_else", has_else), p); - return 0; -} - -el_val_t parse_match(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("Match")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t subject = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t arms = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r2 = parse_pattern(tokens, p); - el_val_t pattern = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - p = expect(tokens, p, EL_STR("FatArrow")); - el_val_t r3 = parse_expr(tokens, p); - el_val_t body = el_get_field(r3, EL_STR("node")); - p = el_get_field(r3, EL_STR("pos")); - el_val_t arm = el_map_new(2, "pattern", pattern, "body", body); - arms = native_list_append(arms, arm); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "expr", EL_STR("Match"), "subject", subject, "arms", arms), p); - return 0; -} - -el_val_t parse_pattern(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Ident"))) { - el_val_t v = tok_value(tokens, pos); - if (str_eq(v, EL_STR("_"))) { - return make_result(el_map_new(1, "pattern", EL_STR("Wildcard")), (pos + 1)); - } - return make_result(el_map_new(2, "pattern", EL_STR("Binding"), "name", v), (pos + 1)); - } - if (str_eq(k, EL_STR("Int"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitInt"), "value", tok_value(tokens, pos)), (pos + 1)); - } - if (str_eq(k, EL_STR("Str"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitStr"), "value", tok_value(tokens, pos)), (pos + 1)); - } - if (str_eq(k, EL_STR("Bool"))) { - return make_result(el_map_new(2, "pattern", EL_STR("LitBool"), "value", tok_value(tokens, pos)), (pos + 1)); - } - return make_result(el_map_new(1, "pattern", EL_STR("Wildcard")), (pos + 1)); - return 0; -} - -el_val_t parse_for_expr(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("For")); - el_val_t item_name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("In")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t list_expr = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(4, "expr", EL_STR("For"), "item", item_name, "list", list_expr, "body", body), p); - return 0; -} - -el_val_t parse_block(el_val_t tokens, el_val_t pos) { - el_val_t p = expect(tokens, pos, EL_STR("LBrace")); - el_val_t stmts = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_stmt(tokens, p); - el_val_t stmt = el_get_field(r, EL_STR("node")); - el_val_t new_p = el_get_field(r, EL_STR("pos")); - stmts = native_list_append(stmts, stmt); - if (new_p <= p) { - p = (p + 1); - } else { - p = new_p; - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return el_map_new(2, "stmts", stmts, "pos", p); - return 0; -} - -el_val_t is_duration_unit(el_val_t name) { - if (str_eq(name, EL_STR("nanos"))) { - return 1; - } - if (str_eq(name, EL_STR("nano"))) { - return 1; - } - if (str_eq(name, EL_STR("millis"))) { - return 1; - } - if (str_eq(name, EL_STR("milli"))) { - return 1; - } - if (str_eq(name, EL_STR("millisecond"))) { - return 1; - } - if (str_eq(name, EL_STR("milliseconds"))) { - return 1; - } - if (str_eq(name, EL_STR("second"))) { - return 1; - } - if (str_eq(name, EL_STR("seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("minute"))) { - return 1; - } - if (str_eq(name, EL_STR("minutes"))) { - return 1; - } - if (str_eq(name, EL_STR("hour"))) { - return 1; - } - if (str_eq(name, EL_STR("hours"))) { - return 1; - } - if (str_eq(name, EL_STR("day"))) { - return 1; - } - if (str_eq(name, EL_STR("days"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t parse_postfix(el_val_t tokens, el_val_t pos) { - el_val_t r = parse_primary(tokens, pos); - el_val_t node = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - el_val_t primary_kind = el_get_field(node, EL_STR("expr")); - if (str_eq(primary_kind, EL_STR("Int"))) { - el_val_t dot_kind = tok_kind(tokens, p); - if (str_eq(dot_kind, EL_STR("Dot"))) { - el_val_t unit_kind = tok_kind(tokens, (p + 1)); - if (str_eq(unit_kind, EL_STR("Ident"))) { - el_val_t unit_name = tok_value(tokens, (p + 1)); - if (is_duration_unit(unit_name)) { - el_val_t count_str = el_get_field(node, EL_STR("value")); - node = el_map_new(3, "expr", EL_STR("DurationLit"), "count", count_str, "unit", unit_name); - p = (p + 2); - } - } - } - } - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - if (str_eq(k, EL_STR("LParen"))) { - p = (p + 1); - el_val_t args = native_list_empty(); - el_val_t run2 = 1; - while (run2) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RParen"))) { - run2 = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - run2 = 0; - } else { - el_val_t r2 = parse_expr(tokens, p); - el_val_t arg = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - args = native_list_append(args, arg); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RParen")); - node = el_map_new(3, "expr", EL_STR("Call"), "func", node, "args", args); - } else { - if (str_eq(k, EL_STR("Dot"))) { - el_val_t field = tok_value(tokens, (p + 1)); - p = (p + 2); - node = el_map_new(3, "expr", EL_STR("Field"), "object", node, "field", field); - } else { - if (str_eq(k, EL_STR("LBracket"))) { - el_val_t r2 = parse_expr(tokens, (p + 1)); - el_val_t idx = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - p = expect(tokens, p, EL_STR("RBracket")); - node = el_map_new(3, "expr", EL_STR("Index"), "object", node, "index", idx); - } else { - if (str_eq(k, EL_STR("QuestionMark"))) { - p = (p + 1); - node = el_map_new(2, "expr", EL_STR("Try"), "inner", node); - } else { - running = 0; - } - } - } - } - } - return make_result(node, p); - return 0; -} - -el_val_t op_precedence(el_val_t kind) { - if (str_eq(kind, EL_STR("Or"))) { - return 1; - } - if (str_eq(kind, EL_STR("And"))) { - return 2; - } - if (str_eq(kind, EL_STR("EqEq"))) { - return 3; - } - if (str_eq(kind, EL_STR("NotEq"))) { - return 3; - } - if (str_eq(kind, EL_STR("Lt"))) { - return 4; - } - if (str_eq(kind, EL_STR("Gt"))) { - return 4; - } - if (str_eq(kind, EL_STR("LtEq"))) { - return 4; - } - if (str_eq(kind, EL_STR("GtEq"))) { - return 4; - } - if (str_eq(kind, EL_STR("Plus"))) { - return 5; - } - if (str_eq(kind, EL_STR("Minus"))) { - return 5; - } - if (str_eq(kind, EL_STR("Star"))) { - return 6; - } - if (str_eq(kind, EL_STR("Slash"))) { - return 6; - } - return 0; - return 0; -} - -el_val_t is_binop(el_val_t kind) { - if (str_eq(kind, EL_STR("Or"))) { - return 1; - } - if (str_eq(kind, EL_STR("And"))) { - return 1; - } - if (str_eq(kind, EL_STR("EqEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("NotEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("Lt"))) { - return 1; - } - if (str_eq(kind, EL_STR("Gt"))) { - return 1; - } - if (str_eq(kind, EL_STR("LtEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("GtEq"))) { - return 1; - } - if (str_eq(kind, EL_STR("Plus"))) { - return 1; - } - if (str_eq(kind, EL_STR("Minus"))) { - return 1; - } - if (str_eq(kind, EL_STR("Star"))) { - return 1; - } - if (str_eq(kind, EL_STR("Slash"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t parse_binop(el_val_t tokens, el_val_t pos, el_val_t min_prec) { - el_val_t r = parse_postfix(tokens, pos); - el_val_t left = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - el_val_t running = 1; - while (running) { - el_val_t k = tok_kind(tokens, p); - el_val_t prec = op_precedence(k); - if (is_binop(k)) { - if (prec >= min_prec) { - el_val_t op = k; - el_val_t r2 = parse_binop(tokens, (p + 1), (prec + 1)); - el_val_t right = el_get_field(r2, EL_STR("node")); - p = el_get_field(r2, EL_STR("pos")); - left = el_map_new(4, "expr", EL_STR("BinOp"), "op", op, "left", left, "right", right); - } else { - running = 0; - } - } else { - running = 0; - } - } - return make_result(left, p); - return 0; -} - -el_val_t parse_expr(el_val_t tokens, el_val_t pos) { - return parse_binop(tokens, pos, 1); - return 0; -} - -el_val_t parse_stmt(el_val_t tokens, el_val_t pos) { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Let"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t ltype = EL_STR(""); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Colon"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ltype = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - p = expect(tokens, p, EL_STR("Eq")); - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(4, "stmt", EL_STR("Let"), "name", name, "value", val, "type", ltype), p); - } - if (str_eq(k, EL_STR("Return"))) { - el_val_t p = (pos + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", el_map_new(1, "expr", EL_STR("Nil"))), p); - } - if (str_eq(k2, EL_STR("Eof"))) { - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", el_map_new(1, "expr", EL_STR("Nil"))), p); - } - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "stmt", EL_STR("Return"), "value", val), p); - } - if (str_eq(k, EL_STR("Fn"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_params(tokens, p); - el_val_t params = el_get_field(r, EL_STR("params")); - p = el_get_field(r, EL_STR("pos")); - el_val_t ret_type = EL_STR(""); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Arrow"))) { - p = (p + 1); - el_val_t kt = tok_kind(tokens, p); - if (str_eq(kt, EL_STR("Ident"))) { - ret_type = tok_value(tokens, p); - } - p = skip_type(tokens, p); - } - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(5, "stmt", EL_STR("FnDef"), "name", name, "params", params, "body", body, "ret_type", ret_type), p); - } - if (str_eq(k, EL_STR("Type"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t fields = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - p = skip_type(tokens, p); - fields = native_list_append(fields, el_map_new(1, "name", fname)); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "stmt", EL_STR("TypeDef"), "name", name, "fields", fields), p); - } - if (str_eq(k, EL_STR("Enum"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t variants = native_list_empty(); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t vname = tok_value(tokens, p); - p = (p + 1); - variants = native_list_append(variants, el_map_new(1, "name", vname)); - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(3, "stmt", EL_STR("EnumDef"), "name", name, "variants", variants), p); - } - if (str_eq(k, EL_STR("Import"))) { - el_val_t p = (pos + 1); - el_val_t path = tok_value(tokens, p); - p = (p + 1); - return make_result(el_map_new(2, "stmt", EL_STR("Import"), "path", path), p); - } - if (str_eq(k, EL_STR("From"))) { - el_val_t p = (pos + 1); - el_val_t module_name = tok_value(tokens, p); - p = (p + 1); - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("Import"))) { - p = (p + 1); - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("LBrace"))) { - p = (p + 1); - el_val_t running = 1; - while (running) { - el_val_t k4 = tok_kind(tokens, p); - if (str_eq(k4, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k4, EL_STR("Eof"))) { - running = 0; - } else { - p = (p + 1); - el_val_t k5 = tok_kind(tokens, p); - if (str_eq(k5, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - } - return make_result(el_map_new(2, "stmt", EL_STR("Import"), "path", module_name), p); - } - if (str_eq(k, EL_STR("While"))) { - el_val_t p = (pos + 1); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t cond = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(3, "stmt", EL_STR("While"), "cond", cond, "body", body), p); - } - if (str_eq(k, EL_STR("For"))) { - el_val_t p = (pos + 1); - el_val_t item_name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("In")); - el_val_t prev_no_block = state_get(EL_STR("__no_block_expr")); - state_set(EL_STR("__no_block_expr"), EL_STR("1")); - el_val_t r = parse_expr(tokens, p); - state_set(EL_STR("__no_block_expr"), prev_no_block); - el_val_t list_expr = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - el_val_t r2 = parse_block(tokens, p); - el_val_t body = el_get_field(r2, EL_STR("stmts")); - p = el_get_field(r2, EL_STR("pos")); - return make_result(el_map_new(4, "stmt", EL_STR("For"), "item", item_name, "list", list_expr, "body", body), p); - } - if (str_eq(k, EL_STR("At"))) { - el_val_t p = (pos + 1); - el_val_t dec_name = tok_value(tokens, p); - p = (p + 1); - el_val_t r = parse_stmt(tokens, p); - el_val_t inner = el_get_field(r, EL_STR("node")); - el_val_t p2 = el_get_field(r, EL_STR("pos")); - el_val_t inner_kind = el_get_field(inner, EL_STR("stmt")); - if (str_eq(inner_kind, EL_STR("FnDef"))) { - el_val_t with_dec = el_map_new(6, "stmt", EL_STR("FnDef"), "name", el_get_field(inner, EL_STR("name")), "params", el_get_field(inner, EL_STR("params")), "body", el_get_field(inner, EL_STR("body")), "ret_type", el_get_field(inner, EL_STR("ret_type")), "decorator", dec_name); - return make_result(with_dec, p2); - } - return r; - } - if (str_eq(k, EL_STR("Cgi"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t dharma_id = EL_STR(""); - el_val_t principal = EL_STR(""); - el_val_t network = EL_STR(""); - el_val_t engram = EL_STR(""); - el_val_t has_dharma_id = 0; - el_val_t has_principal = 0; - el_val_t has_network = 0; - el_val_t has_engram = 0; - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t fval = tok_value(tokens, p); - p = (p + 1); - if (str_eq(fname, EL_STR("dharma_id"))) { - dharma_id = fval; - has_dharma_id = 1; - } - if (str_eq(fname, EL_STR("principal"))) { - principal = fval; - has_principal = 1; - } - if (str_eq(fname, EL_STR("network"))) { - network = fval; - has_network = 1; - } - if (str_eq(fname, EL_STR("engram"))) { - engram = fval; - has_engram = 1; - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(10, "stmt", EL_STR("CgiBlock"), "name", name, "dharma_id", dharma_id, "principal", principal, "network", network, "engram", engram, "has_dharma_id", has_dharma_id, "has_principal", has_principal, "has_network", has_network, "has_engram", has_engram), p); - } - if (str_eq(k, EL_STR("Service"))) { - el_val_t p = (pos + 1); - el_val_t name = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("LBrace")); - el_val_t sponsor = EL_STR(""); - el_val_t domain = EL_STR(""); - el_val_t running = 1; - while (running) { - el_val_t k2 = tok_kind(tokens, p); - if (str_eq(k2, EL_STR("RBrace"))) { - running = 0; - } else { - if (str_eq(k2, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t fname = tok_value(tokens, p); - p = (p + 1); - p = expect(tokens, p, EL_STR("Colon")); - el_val_t fval = tok_value(tokens, p); - p = (p + 1); - if (str_eq(fname, EL_STR("sponsor"))) { - sponsor = fval; - } - if (str_eq(fname, EL_STR("domain"))) { - domain = fval; - } - el_val_t k3 = tok_kind(tokens, p); - if (str_eq(k3, EL_STR("Comma"))) { - p = (p + 1); - } - } - } - } - p = expect(tokens, p, EL_STR("RBrace")); - return make_result(el_map_new(4, "stmt", EL_STR("ServiceBlock"), "name", name, "sponsor", sponsor, "domain", domain), p); - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t k2 = tok_kind(tokens, (pos + 1)); - if (str_eq(k2, EL_STR("Eq"))) { - el_val_t name = tok_value(tokens, pos); - el_val_t p = (pos + 2); - el_val_t r = parse_expr(tokens, p); - el_val_t val = el_get_field(r, EL_STR("node")); - p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(3, "stmt", EL_STR("Assign"), "name", name, "value", val), p); - } - } - el_val_t r = parse_expr(tokens, pos); - el_val_t val = el_get_field(r, EL_STR("node")); - el_val_t p = el_get_field(r, EL_STR("pos")); - return make_result(el_map_new(2, "stmt", EL_STR("Expr"), "value", val), p); - return 0; -} - -el_val_t parse(el_val_t tokens) { - el_val_t total = native_list_len(tokens); - el_val_t stmts = native_list_empty(); - el_val_t pos = 0; - el_val_t running = 1; - while (running) { - if (pos >= total) { - running = 0; - } else { - el_val_t k = tok_kind(tokens, pos); - if (str_eq(k, EL_STR("Eof"))) { - running = 0; - } else { - el_val_t r = parse_stmt(tokens, pos); - el_val_t stmt = el_get_field(r, EL_STR("node")); - el_val_t new_pos = el_get_field(r, EL_STR("pos")); - stmts = native_list_append(stmts, stmt); - if (new_pos <= pos) { - pos = (pos + 1); - } else { - pos = new_pos; - } - } - } - } - return stmts; - return 0; -} - -el_val_t c_escape(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\""))) { - out = el_str_concat(out, EL_STR("\\\"")); - } else { - if (str_eq(ch, EL_STR("\\"))) { - out = el_str_concat(out, EL_STR("\\\\")); - } else { - if (str_eq(ch, EL_STR("\n"))) { - out = el_str_concat(out, EL_STR("\\n")); - } else { - if (str_eq(ch, EL_STR("\r"))) { - out = el_str_concat(out, EL_STR("\\r")); - } else { - if (str_eq(ch, EL_STR("\t"))) { - out = el_str_concat(out, EL_STR("\\t")); - } else { - out = el_str_concat(out, ch); - } - } - } - } - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t c_str_lit(el_val_t s) { - return el_str_concat(el_str_concat(EL_STR("\""), c_escape(s)), EL_STR("\"")); - return 0; -} - -el_val_t el_type_to_c(el_val_t type_str) { - if (str_eq(type_str, EL_STR("String"))) { - return EL_STR("const char*"); - } - if (str_eq(type_str, EL_STR("Int"))) { - return EL_STR("int64_t"); - } - if (str_eq(type_str, EL_STR("Bool"))) { - return EL_STR("int"); - } - if (str_eq(type_str, EL_STR("Float"))) { - return EL_STR("double"); - } - if (str_eq(type_str, EL_STR("Void"))) { - return EL_STR("void"); - } - if (str_eq(type_str, EL_STR("void"))) { - return EL_STR("void"); - } - return EL_STR("void*"); - return 0; -} - -el_val_t emit_line(el_val_t line) { - println(line); - return 0; -} - -el_val_t emit_blank(void) { - println(EL_STR("")); - return 0; -} - -el_val_t binop_to_c(el_val_t op) { - if (str_eq(op, EL_STR("Plus"))) { - return EL_STR("+"); - } - if (str_eq(op, EL_STR("Minus"))) { - return EL_STR("-"); - } - if (str_eq(op, EL_STR("Star"))) { - return EL_STR("*"); - } - if (str_eq(op, EL_STR("Slash"))) { - return EL_STR("/"); - } - if (str_eq(op, EL_STR("EqEq"))) { - return EL_STR("=="); - } - if (str_eq(op, EL_STR("NotEq"))) { - return EL_STR("!="); - } - if (str_eq(op, EL_STR("Lt"))) { - return EL_STR("<"); - } - if (str_eq(op, EL_STR("Gt"))) { - return EL_STR(">"); - } - if (str_eq(op, EL_STR("LtEq"))) { - return EL_STR("<="); - } - if (str_eq(op, EL_STR("GtEq"))) { - return EL_STR(">="); - } - if (str_eq(op, EL_STR("And"))) { - return EL_STR("&&"); - } - if (str_eq(op, EL_STR("Or"))) { - return EL_STR("||"); - } - return op; - return 0; -} - -el_val_t duration_unit_nanos(el_val_t unit) { - if (str_eq(unit, EL_STR("nano"))) { - return EL_STR("1LL"); - } - if (str_eq(unit, EL_STR("nanos"))) { - return EL_STR("1LL"); - } - if (str_eq(unit, EL_STR("milli"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("millis"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("millisecond"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("milliseconds"))) { - return EL_STR("1000000LL"); - } - if (str_eq(unit, EL_STR("second"))) { - return EL_STR("1000000000LL"); - } - if (str_eq(unit, EL_STR("seconds"))) { - return EL_STR("1000000000LL"); - } - if (str_eq(unit, EL_STR("minute"))) { - return EL_STR("60000000000LL"); - } - if (str_eq(unit, EL_STR("minutes"))) { - return EL_STR("60000000000LL"); - } - if (str_eq(unit, EL_STR("hour"))) { - return EL_STR("3600000000000LL"); - } - if (str_eq(unit, EL_STR("hours"))) { - return EL_STR("3600000000000LL"); - } - if (str_eq(unit, EL_STR("day"))) { - return EL_STR("86400000000000LL"); - } - if (str_eq(unit, EL_STR("days"))) { - return EL_STR("86400000000000LL"); - } - return EL_STR("1LL"); - return 0; -} - -el_val_t cg_expr(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Int"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("DurationLit"))) { - el_val_t count = el_get_field(expr, EL_STR("count")); - el_val_t unit = el_get_field(expr, EL_STR("unit")); - el_val_t mult = duration_unit_nanos(unit); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_from_nanos((el_val_t)("), count), EL_STR("LL * ")), mult), EL_STR("))")); - } - if (str_eq(kind, EL_STR("Float"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("el_from_float("), v), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Str"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(v)), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Bool"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - if (str_eq(v, EL_STR("true"))) { - return EL_STR("1"); - } - return EL_STR("0"); - } - if (str_eq(kind, EL_STR("Nil"))) { - return EL_STR("EL_NULL"); - } - if (str_eq(kind, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return name; - } - if (str_eq(kind, EL_STR("Not"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = cg_expr(inner); - return el_str_concat(EL_STR("!"), inner_c); - } - if (str_eq(kind, EL_STR("Neg"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = cg_expr(inner); - return el_str_concat(el_str_concat(EL_STR("(-"), inner_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - el_val_t left = el_get_field(expr, EL_STR("left")); - el_val_t right = el_get_field(expr, EL_STR("right")); - el_val_t left_c = cg_expr(left); - el_val_t right_c = cg_expr(right); - el_val_t left_kind = el_get_field(left, EL_STR("expr")); - el_val_t right_kind = el_get_field(right, EL_STR("expr")); - el_val_t left_is_inst = is_instant_expr(left); - el_val_t right_is_inst = is_instant_expr(right); - el_val_t left_is_dur = is_duration_expr(left); - el_val_t right_is_dur = is_duration_expr(right); - el_val_t left_is_ld = is_localdate_expr(left); - el_val_t right_is_ld = is_localdate_expr(right); - el_val_t left_is_lt = is_localtime_expr(left); - el_val_t right_is_lt = is_localtime_expr(right); - el_val_t left_is_ct = is_caltime_expr(left); - el_val_t right_is_ct = is_caltime_expr(right); - if (left_is_ld) { - if (str_eq(op, EL_STR("Plus"))) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_date_add_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("Lt"))) { - if (right_is_ld) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_date_lt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (right_is_ld) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_date_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (left_is_lt) { - if (str_eq(op, EL_STR("Plus"))) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_local_time_add_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (left_is_ct) { - if (str_eq(op, EL_STR("Plus"))) { - if (right_is_ct) { - time_record_violation(EL_STR("caltime_plus_caltime"), EL_STR("CalendarTime + CalendarTime is not allowed (use cal_to_instant + Duration)")); - return EL_STR("0 /* TIME_TYPE_ERROR: CalendarTime + CalendarTime */"); - } - } - } - el_val_t any_temporal = 0; - if (left_is_inst) { - any_temporal = 1; - } - if (right_is_inst) { - any_temporal = 1; - } - if (left_is_dur) { - any_temporal = 1; - } - if (right_is_dur) { - any_temporal = 1; - } - if (any_temporal) { - if (str_eq(op, EL_STR("Plus"))) { - if (left_is_inst) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_add_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_inst) { - time_record_violation(EL_STR("instant_plus_instant"), EL_STR("Instant + Instant is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Instant + Instant */"); - } - } - if (left_is_dur) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_add_dur("), right_c), EL_STR(", ")), left_c), EL_STR(")")); - } - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_add("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(right)) { - time_record_violation(EL_STR("duration_plus_int"), EL_STR("Duration + Int is not allowed (use duration_seconds(n) or N.seconds)")); - return EL_STR("0 /* TIME_TYPE_ERROR: Duration + Int */"); - } - } - if (right_is_dur) { - if (is_int_expr(left)) { - time_record_violation(EL_STR("duration_plus_int"), EL_STR("Int + Duration is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Int + Duration */"); - } - } - } - if (str_eq(op, EL_STR("Minus"))) { - if (left_is_inst) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_sub_dur("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_diff("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_sub("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(right)) { - time_record_violation(EL_STR("duration_minus_int"), EL_STR("Duration - Int is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Duration - Int */"); - } - } - } - if (str_eq(op, EL_STR("Star"))) { - if (left_is_dur) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_scale("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (right_is_dur) { - if (is_int_expr(left)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_scale("), right_c), EL_STR(", ")), left_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("Slash"))) { - if (left_is_dur) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_div("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("Lt"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_lt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_dur) { - time_record_violation(EL_STR("instant_cmp_duration"), EL_STR("Instant < Duration is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Instant < Duration */"); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_lt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (right_is_inst) { - time_record_violation(EL_STR("duration_cmp_instant"), EL_STR("Duration < Instant is not allowed")); - return EL_STR("0 /* TIME_TYPE_ERROR: Duration < Instant */"); - } - } - } - if (str_eq(op, EL_STR("LtEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_le("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_le("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("Gt"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_gt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_gt("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("GtEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_ge("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_ge("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - if (str_eq(op, EL_STR("NotEq"))) { - if (left_is_inst) { - if (right_is_inst) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_instant_ne("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (left_is_dur) { - if (right_is_dur) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_duration_ne("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Int"))) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("BinOp"))) { - el_val_t left_op = el_get_field(left, EL_STR("op")); - if (str_eq(left_op, EL_STR("Plus"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(right_kind, EL_STR("BinOp"))) { - el_val_t right_op = el_get_field(right, EL_STR("op")); - if (str_eq(right_op, EL_STR("Plus"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (is_int_name(lname)) { - if (is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - } - } - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (is_int_name(lname)) { - if (is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - } - } - } - if (is_int_expr(left)) { - if (is_int_expr(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")")); - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - el_val_t op_c = binop_to_c(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t arity = native_list_len(args); - el_val_t func_kind = el_get_field(func, EL_STR("expr")); - el_val_t args_c = EL_STR(""); - el_val_t i = 0; - while (i < arity) { - el_val_t arg = native_list_get(args, i); - el_val_t arg_c = cg_expr(arg); - if (i > 0) { - args_c = el_str_concat(args_c, EL_STR(", ")); - } - args_c = el_str_concat(args_c, arg_c); - i = (i + 1); - } - if (str_eq(func_kind, EL_STR("Ident"))) { - el_val_t fn_name = el_get_field(func, EL_STR("name")); - cap_check_call(fn_name); - arity_check_call(fn_name, arity); - if (str_eq(fn_name, EL_STR("sleep"))) { - if (arity == 1) { - el_val_t only_arg = native_list_get(args, 0); - if (is_duration_expr(only_arg)) { - return el_str_concat(el_str_concat(EL_STR("el_sleep_duration("), args_c), EL_STR(")")); - } - } - } - return el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(func_kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(func, EL_STR("object")); - el_val_t field = el_get_field(func, EL_STR("field")); - el_val_t obj_c = cg_expr(obj); - if (arity > 0) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(", ")), args_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(")")); - } - el_val_t fn_c = cg_expr(func); - return el_str_concat(el_str_concat(el_str_concat(fn_c, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t field = el_get_field(expr, EL_STR("field")); - el_val_t obj_c = cg_expr(obj); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", EL_STR(")), c_str_lit(field)), EL_STR("))")); - } - if (str_eq(kind, EL_STR("Index"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t idx = el_get_field(expr, EL_STR("index")); - el_val_t obj_c = cg_expr(obj); - el_val_t idx_c = cg_expr(idx); - el_val_t idx_kind = el_get_field(idx, EL_STR("expr")); - if (str_eq(idx_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_get("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - if (n == 0) { - return EL_STR("el_list_empty()"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t elem = native_list_get(elems, i); - el_val_t elem_c = cg_expr(elem); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(items, elem_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_new("), native_int_to_str(n)), EL_STR(", ")), items), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - if (n == 0) { - return EL_STR("el_map_new(0)"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t key = el_get_field(pair, EL_STR("key")); - el_val_t val = el_get_field(pair, EL_STR("value")); - el_val_t val_c = cg_expr(val); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(el_str_concat(el_str_concat(items, c_str_lit(key)), EL_STR(", ")), val_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_map_new("), native_int_to_str(n)), EL_STR(", ")), items), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Try"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - return cg_expr(inner); - } - if (str_eq(kind, EL_STR("If"))) { - return cg_if_expr(expr); - } - if (str_eq(kind, EL_STR("Match"))) { - return cg_match(expr); - } - return EL_STR("EL_NULL"); - return 0; -} - -el_val_t next_match_id(void) { - el_val_t csv = state_get(EL_STR("__match_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__match_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t cg_match(el_val_t expr) { - el_val_t subject = el_get_field(expr, EL_STR("subject")); - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t subj_c = cg_expr(subject); - el_val_t id = next_match_id(); - el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id); - el_val_t result_var = el_str_concat(EL_STR("_match_result_"), id); - el_val_t done_label = el_str_concat(EL_STR("_match_done_"), id); - el_val_t out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), subj_var), EL_STR(" = ")), subj_c), EL_STR("; el_val_t ")), result_var), EL_STR(" = 0; ")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t pat = el_get_field(arm, EL_STR("pattern")); - el_val_t body = el_get_field(arm, EL_STR("body")); - el_val_t pkind = el_get_field(pat, EL_STR("pattern")); - el_val_t body_c = cg_expr(body); - if (str_eq(pkind, EL_STR("Wildcard"))) { - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("Binding"))) { - el_val_t bname = el_get_field(pat, EL_STR("name")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ el_val_t ")), bname), EL_STR(" = ")), subj_var), EL_STR("; ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("LitInt"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" == ")), v), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("LitStr"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (str_eq(")), subj_var), EL_STR(", EL_STR(")), c_str_lit(v)), EL_STR("))) { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - if (str_eq(pkind, EL_STR("LitBool"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - el_val_t bv = EL_STR("0"); - if (str_eq(v, EL_STR("true"))) { - bv = EL_STR("1"); - } - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" == ")), bv), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } else { - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } ")); - } - } - } - } - } - i = (i + 1); - } - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, done_label), EL_STR(":; ")), result_var), EL_STR("; })")); - return out; - return 0; -} - -el_val_t next_if_id(void) { - el_val_t csv = state_get(EL_STR("__if_expr_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__if_expr_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t cg_if_expr_arm(el_val_t stmts, el_val_t result_var) { - el_val_t n = native_list_len(stmts); - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t s = native_list_get(stmts, i); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - el_val_t is_last = 0; - if (i == (n - 1)) { - is_last = 1; - } - if (str_eq(sk, EL_STR("Let"))) { - el_val_t name = el_get_field(s, EL_STR("name")); - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("el_val_t ")), name), EL_STR(" = ")), val_c), EL_STR("; ")); - } else { - if (str_eq(sk, EL_STR("Return"))) { - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, result_var), EL_STR(" = (")), val_c), EL_STR("); ")); - } else { - if (str_eq(sk, EL_STR("Expr"))) { - el_val_t val = el_get_field(s, EL_STR("value")); - el_val_t val_c = cg_expr(val); - if (is_last) { - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, result_var), EL_STR(" = (")), val_c), EL_STR("); ")); - } else { - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("(void)(")), val_c), EL_STR("); ")); - } - } else { - if (str_eq(sk, EL_STR("Assign"))) { - el_val_t aname = el_get_field(s, EL_STR("name")); - el_val_t aval = el_get_field(s, EL_STR("value")); - el_val_t aval_c = cg_expr(aval); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, aname), EL_STR(" = ")), aval_c), EL_STR("; ")); - } else { - } - } - } - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t cg_if_expr(el_val_t expr) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = cg_expr(cond); - el_val_t id = next_if_id(); - el_val_t result_var = el_str_concat(EL_STR("_if_result_"), id); - el_val_t then_c = cg_if_expr_arm(then_stmts, result_var); - el_val_t else_c = EL_STR(""); - if (has_else) { - else_c = cg_if_expr_arm(else_stmts, result_var); - } - el_val_t out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), result_var), EL_STR(" = 0; if (")), cond_c), EL_STR(") { ")), then_c), EL_STR("} else { ")), else_c), EL_STR("} ")), result_var), EL_STR("; })")); - return out; - return 0; -} - -el_val_t list_contains(el_val_t lst, el_val_t s) { - el_val_t n = native_list_len(lst); - el_val_t i = 0; - while (i < n) { - el_val_t item = native_list_get(lst, i); - if (str_eq(item, s)) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = cg_expr(val); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - add_int_name(name); - } - if (str_eq(ltype, EL_STR("Instant"))) { - add_instant_name(name); - } - if (str_eq(ltype, EL_STR("Duration"))) { - add_duration_name(name); - } - if (str_eq(ltype, EL_STR("Calendar"))) { - add_calendar_name(name); - } - if (str_eq(ltype, EL_STR("CalendarTime"))) { - add_caltime_name(name); - } - if (str_eq(ltype, EL_STR("Rhythm"))) { - add_rhythm_name(name); - } - if (str_eq(ltype, EL_STR("LocalDate"))) { - add_localdate_name(name); - } - if (str_eq(ltype, EL_STR("LocalTime"))) { - add_localtime_name(name); - } - if (str_eq(ltype, EL_STR("LocalDateTime"))) { - add_localdt_name(name); - } - if (str_eq(ltype, EL_STR("Zone"))) { - add_zone_name(name); - } - if (is_instant_expr(val)) { - add_instant_name(name); - } - if (is_duration_expr(val)) { - add_duration_name(name); - } - if (is_calendar_expr(val)) { - add_calendar_name(name); - } - if (is_caltime_expr(val)) { - add_caltime_name(name); - } - if (is_rhythm_expr(val)) { - add_rhythm_name(name); - } - if (is_localdate_expr(val)) { - add_localdate_name(name); - } - if (is_localtime_expr(val)) { - add_localtime_name(name); - } - if (is_localdt_expr(val)) { - add_localdt_name(name); - } - if (is_zone_expr(val)) { - add_zone_name(name); - } - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - add_int_name(name); - } - if (list_contains(declared, name)) { - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } else { - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("el_val_t ")), name), EL_STR(" = ")), val_c), EL_STR(";"))); - return native_list_append(declared, name); - } - } - if (str_eq(kind, EL_STR("Return"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("Nil"))) { - emit_line(el_str_concat(indent, EL_STR("return 0;"))); - } else { - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("return ")), val_c), EL_STR(";"))); - } - return declared; - } - if (str_eq(kind, EL_STR("Assign"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - cg_if_stmt(val, indent, declared); - return declared; - } - if (str_eq(val_kind, EL_STR("For"))) { - cg_for_stmt(val, indent, declared); - return declared; - } - el_val_t val_c = cg_expr(val); - emit_line(el_str_concat(el_str_concat(indent, val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("While"))) { - el_val_t cond = el_get_field(stmt, EL_STR("cond")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t cond_c = cg_expr(cond); - cond_c = strip_outer_parens(cond_c); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("while (")), cond_c), EL_STR(") {"))); - cg_stmts(body, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - emit_line(el_str_concat(indent, EL_STR("}"))); - return declared; - } - if (str_eq(kind, EL_STR("For"))) { - el_val_t item = el_get_field(stmt, EL_STR("item")); - el_val_t list_expr = el_get_field(stmt, EL_STR("list")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - cg_for_body(item, list_expr, body, indent, declared); - return declared; - } - if (str_eq(kind, EL_STR("FnDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("TypeDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("Import"))) { - return declared; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return declared; - } - return declared; - return 0; -} - -el_val_t strip_outer_parens(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t n = native_list_len(chars); - if (n < 2) { - return s; - } - el_val_t first = native_list_get(chars, 0); - el_val_t last = native_list_get(chars, (n - 1)); - if (str_eq(first, EL_STR("("))) { - if (str_eq(last, EL_STR(")"))) { - el_val_t depth = 1; - el_val_t i = 1; - el_val_t balanced = 1; - while (i < (n - 1)) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("("))) { - depth = (depth + 1); - } - if (str_eq(ch, EL_STR(")"))) { - depth = (depth - 1); - if (depth == 0) { - balanced = 0; - i = n; - } - } - i = (i + 1); - } - if (balanced) { - el_val_t inner = EL_STR(""); - el_val_t j = 1; - while (j < (n - 1)) { - el_val_t ch = native_list_get(chars, j); - inner = el_str_concat(inner, ch); - j = (j + 1); - } - return inner; - } - } - } - return s; - return 0; -} - -el_val_t cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = cg_expr(cond); - cond_c = strip_outer_parens(cond_c); - emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("if (")), cond_c), EL_STR(") {"))); - cg_stmts(then_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - if (has_else) { - emit_line(el_str_concat(indent, EL_STR("} else {"))); - cg_stmts(else_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - } - emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared) { - el_val_t list_c = cg_expr(list_expr); - el_val_t idx = EL_STR("_el_i"); - el_val_t list_tmp = EL_STR("_el_lst"); - el_val_t len_tmp = EL_STR("_el_len"); - emit_line(el_str_concat(indent, EL_STR("{"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), list_tmp), EL_STR(" = ")), list_c), EL_STR(";"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), len_tmp), EL_STR(" = el_list_len(")), list_tmp), EL_STR(");"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" for (el_val_t ")), idx), EL_STR(" = 0; ")), idx), EL_STR(" < ")), len_tmp), EL_STR("; ")), idx), EL_STR("++) {"))); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR(" el_val_t ")), item), EL_STR(" = el_list_get(")), list_tmp), EL_STR(", ")), idx), EL_STR(");"))); - el_val_t body_decl = native_list_clone(declared); - body_decl = native_list_append(body_decl, item); - cg_stmts(body, el_str_concat(indent, EL_STR(" ")), body_decl); - emit_line(el_str_concat(indent, EL_STR(" }"))); - emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t item = el_get_field(expr, EL_STR("item")); - el_val_t list_expr = el_get_field(expr, EL_STR("list")); - el_val_t body = el_get_field(expr, EL_STR("body")); - cg_for_body(item, list_expr, body, indent, declared); - return 0; -} - -el_val_t cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t decl = declared; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - decl = cg_stmt(stmt, indent, decl); - i = (i + 1); - } - return decl; - return 0; -} - -el_val_t param_decl(el_val_t param, el_val_t idx) { - el_val_t name = el_get_field(param, EL_STR("name")); - return el_str_concat(EL_STR("el_val_t "), name); - return 0; -} - -el_val_t params_to_c(el_val_t params) { - el_val_t n = native_list_len(params); - if (n == 0) { - return EL_STR("void"); - } - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t param = native_list_get(params, i); - el_val_t decl = param_decl(param, i); - if (i > 0) { - out = el_str_concat(out, EL_STR(", ")); - } - out = el_str_concat(out, decl); - i = (i + 1); - } - return out; - return 0; -} - -el_val_t transform_implicit_return(el_val_t body) { - el_val_t n = native_list_len(body); - if (n == 0) { - return body; - } - el_val_t last = native_list_get(body, (n - 1)); - el_val_t last_kind = el_get_field(last, EL_STR("stmt")); - if (str_eq(last_kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(last, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - return body; - } - if (str_eq(val_kind, EL_STR("For"))) { - return body; - } - el_val_t new_body = native_list_empty(); - el_val_t i = 0; - while (i < (n - 1)) { - new_body = native_list_append(new_body, native_list_get(body, i)); - i = (i + 1); - } - el_val_t return_stmt = el_map_new(2, "stmt", EL_STR("Return"), "value", val); - new_body = native_list_append(new_body, return_stmt); - return new_body; - } - return body; - return 0; -} - -el_val_t is_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__int_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_instant_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__instant_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_duration_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__duration_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_int_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_lines"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_words"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_letters"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_digits"))) { - return 1; - } - if (str_eq(name, EL_STR("str_last_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_find_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 1; - } - if (str_eq(name, EL_STR("json_array_len"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_node_count"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_edge_count"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("time_diff"))) { - return 1; - } - if (str_eq(name, EL_STR("time_add"))) { - return 1; - } - if (str_eq(name, EL_STR("time_from_parts"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 1; - } - if (str_eq(name, EL_STR("el_min"))) { - return 1; - } - if (str_eq(name, EL_STR("float_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("unix_timestamp"))) { - return 1; - } - if (str_eq(name, EL_STR("instant_to_unix_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("instant_to_unix_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_to_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_to_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_to_nanos"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_instant_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("now"))) { - return 1; - } - if (str_eq(name, EL_STR("el_now_instant"))) { - return 1; - } - if (str_eq(name, EL_STR("unix_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("unix_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("instant_from_iso8601"))) { - return 1; - } - if (str_eq(name, EL_STR("el_instant_add_dur"))) { - return 1; - } - if (str_eq(name, EL_STR("el_instant_sub_dur"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_duration_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("el_duration_from_nanos"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_seconds"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_millis"))) { - return 1; - } - if (str_eq(name, EL_STR("duration_nanos"))) { - return 1; - } - if (str_eq(name, EL_STR("el_instant_diff"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_add"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_sub"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_scale"))) { - return 1; - } - if (str_eq(name, EL_STR("el_duration_div"))) { - return 1; - } - if (str_eq(name, EL_STR("ttl_cache_age"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_calendar_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__calendar_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_caltime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__caltime_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_rhythm_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__rhythm_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_localdate_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdate_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_localtime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localtime_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_localdt_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdt_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_zone_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__zone_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t is_calendar_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("earth_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("earth_calendar_default"))) { - return 1; - } - if (str_eq(name, EL_STR("mars_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("cycle_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("no_cycle_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("relative_calendar"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_caltime_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("now_in"))) { - return 1; - } - if (str_eq(name, EL_STR("in_calendar"))) { - return 1; - } - if (str_eq(name, EL_STR("cal_in"))) { - return 1; - } - if (str_eq(name, EL_STR("zoned"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_rhythm_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("rhythm_cycle_start"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_cycle_phase"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_duration"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_session_start"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_event"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_and"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_or"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_weekday"))) { - return 1; - } - if (str_eq(name, EL_STR("rhythm_weekly_at"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_localdate_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("local_date"))) { - return 1; - } - if (str_eq(name, EL_STR("el_local_date_add_dur"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_localtime_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("local_time"))) { - return 1; - } - if (str_eq(name, EL_STR("el_local_time_add_dur"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_localdt_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("local_datetime"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_zone_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("zone"))) { - return 1; - } - if (str_eq(name, EL_STR("zone_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("zone_local"))) { - return 1; - } - if (str_eq(name, EL_STR("zone_offset"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_calendar_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_calendar_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_calendar_call(expr); - } - return 0; - return 0; -} - -el_val_t is_caltime_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_caltime_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_caltime_call(expr); - } - return 0; - return 0; -} - -el_val_t is_rhythm_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_rhythm_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_rhythm_call(expr); - } - return 0; - return 0; -} - -el_val_t is_localdate_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_localdate_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_localdate_call(expr); - } - return 0; - return 0; -} - -el_val_t is_localtime_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_localtime_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_localtime_call(expr); - } - return 0; - return 0; -} - -el_val_t is_localdt_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_localdt_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_localdt_call(expr); - } - return 0; - return 0; -} - -el_val_t is_zone_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - return is_zone_name(el_get_field(expr, EL_STR("name"))); - } - if (str_eq(k, EL_STR("Call"))) { - return is_zone_call(expr); - } - return 0; - return 0; -} - -el_val_t is_instant_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_instant_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_instant_call(expr); - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("Plus"))) { - if (is_instant_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_instant_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_instant_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t is_duration_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("DurationLit"))) { - return 1; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_duration_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_duration_call(expr); - } - if (str_eq(k, EL_STR("Neg"))) { - return is_duration_expr(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("Plus"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - if (is_instant_expr(el_get_field(expr, EL_STR("left")))) { - if (is_instant_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Star"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_duration_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Slash"))) { - if (is_duration_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t time_record_violation(el_val_t kind, el_val_t detail) { - el_val_t csv = state_get(EL_STR("__time_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(kind, EL_STR(":")), detail); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__time_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t is_int_expr(el_val_t expr) { - el_val_t k = el_get_field(expr, EL_STR("expr")); - if (str_eq(k, EL_STR("Int"))) { - return 1; - } - if (str_eq(k, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return is_int_name(name); - } - if (str_eq(k, EL_STR("Call"))) { - return is_int_call(expr); - } - if (str_eq(k, EL_STR("Neg"))) { - return is_int_expr(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(k, EL_STR("Not"))) { - return 1; - } - if (str_eq(k, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - if (str_eq(op, EL_STR("EqEq"))) { - return 1; - } - if (str_eq(op, EL_STR("NotEq"))) { - return 1; - } - if (str_eq(op, EL_STR("Lt"))) { - return 1; - } - if (str_eq(op, EL_STR("Gt"))) { - return 1; - } - if (str_eq(op, EL_STR("LtEq"))) { - return 1; - } - if (str_eq(op, EL_STR("GtEq"))) { - return 1; - } - if (str_eq(op, EL_STR("And"))) { - return 1; - } - if (str_eq(op, EL_STR("Or"))) { - return 1; - } - if (str_eq(op, EL_STR("Plus"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Minus"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Star"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - if (str_eq(op, EL_STR("Slash"))) { - if (is_int_expr(el_get_field(expr, EL_STR("left")))) { - if (is_int_expr(el_get_field(expr, EL_STR("right")))) { - return 1; - } - } - return 0; - } - return 0; - } - return 0; - return 0; -} - -el_val_t cap_record_violation(el_val_t kind, el_val_t fn_name) { - el_val_t csv = state_get(EL_STR("__cap_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(kind, EL_STR(":")), fn_name); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__cap_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t is_self_formation_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("llm_call_agentic"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_register_tool"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_field"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_dharma_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("dharma_connect"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_send"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_activate"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_field"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_strengthen"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_relationship"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("dharma_peers"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_llm_call(el_val_t fn_name) { - if (str_eq(fn_name, EL_STR("llm_call"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_call_system"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_call_agentic"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_vision"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_register_tool"))) { - return 1; - } - if (str_eq(fn_name, EL_STR("llm_models"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t cap_check_call(el_val_t fn_name) { - el_val_t kind = state_get(EL_STR("__program_kind")); - if (str_eq(kind, EL_STR("cgi"))) { - return 1; - } - if (str_eq(kind, EL_STR("service"))) { - if (is_self_formation_call(fn_name)) { - cap_record_violation(EL_STR("service"), fn_name); - return 0; - } - return 1; - } - if (is_dharma_call(fn_name)) { - cap_record_violation(EL_STR("utility"), fn_name); - return 0; - } - if (is_llm_call(fn_name)) { - cap_record_violation(EL_STR("utility"), fn_name); - return 0; - } - return 1; - return 0; -} - -el_val_t emit_cap_violations(void) { - el_val_t csv = state_get(EL_STR("__cap_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon > 0) { - el_val_t kind = str_slice(entry, 0, colon); - el_val_t fn_name = str_slice(entry, (colon + 1), str_len(entry)); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("#error \"capability violation: '"), kind), EL_STR("' programs may not call '")), fn_name), EL_STR("' (self-formation primitive — only 'cgi' programs may use it)\""))); - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t emit_time_violations(void) { - el_val_t csv = state_get(EL_STR("__time_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon > 0) { - el_val_t detail = str_slice(entry, (colon + 1), str_len(entry)); - emit_line(el_str_concat(el_str_concat(EL_STR("#error \"temporal type error: "), detail), EL_STR("\""))); - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t builtin_arity(el_val_t name) { - if (str_eq(name, EL_STR("println"))) { - return 1; - } - if (str_eq(name, EL_STR("print"))) { - return 1; - } - if (str_eq(name, EL_STR("readline"))) { - return 0; - } - if (str_eq(name, EL_STR("el_str_concat"))) { - return 2; - } - if (str_eq(name, EL_STR("str_eq"))) { - return 2; - } - if (str_eq(name, EL_STR("str_starts_with"))) { - return 2; - } - if (str_eq(name, EL_STR("str_ends_with"))) { - return 2; - } - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_concat"))) { - return 2; - } - if (str_eq(name, EL_STR("int_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_slice"))) { - return 3; - } - if (str_eq(name, EL_STR("str_contains"))) { - return 2; - } - if (str_eq(name, EL_STR("str_replace"))) { - return 3; - } - if (str_eq(name, EL_STR("str_to_upper"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_lower"))) { - return 1; - } - if (str_eq(name, EL_STR("str_trim"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 2; - } - if (str_eq(name, EL_STR("str_split"))) { - return 2; - } - if (str_eq(name, EL_STR("str_char_at"))) { - return 2; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 2; - } - if (str_eq(name, EL_STR("str_pad_left"))) { - return 3; - } - if (str_eq(name, EL_STR("str_pad_right"))) { - return 3; - } - if (str_eq(name, EL_STR("str_format"))) { - return 2; - } - if (str_eq(name, EL_STR("str_lower"))) { - return 1; - } - if (str_eq(name, EL_STR("str_upper"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count"))) { - return 2; - } - if (str_eq(name, EL_STR("str_count_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_lines"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_words"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_letters"))) { - return 1; - } - if (str_eq(name, EL_STR("str_count_digits"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of_all"))) { - return 2; - } - if (str_eq(name, EL_STR("str_last_index_of"))) { - return 2; - } - if (str_eq(name, EL_STR("str_find_chars"))) { - return 2; - } - if (str_eq(name, EL_STR("str_repeat"))) { - return 2; - } - if (str_eq(name, EL_STR("str_reverse"))) { - return 1; - } - if (str_eq(name, EL_STR("str_strip_prefix"))) { - return 2; - } - if (str_eq(name, EL_STR("str_strip_suffix"))) { - return 2; - } - if (str_eq(name, EL_STR("str_strip_chars"))) { - return 2; - } - if (str_eq(name, EL_STR("str_lstrip"))) { - return 1; - } - if (str_eq(name, EL_STR("str_rstrip"))) { - return 1; - } - if (str_eq(name, EL_STR("is_letter"))) { - return 1; - } - if (str_eq(name, EL_STR("is_digit"))) { - return 1; - } - if (str_eq(name, EL_STR("is_alphanumeric"))) { - return 1; - } - if (str_eq(name, EL_STR("is_whitespace"))) { - return 1; - } - if (str_eq(name, EL_STR("is_punctuation"))) { - return 1; - } - if (str_eq(name, EL_STR("is_uppercase"))) { - return 1; - } - if (str_eq(name, EL_STR("is_lowercase"))) { - return 1; - } - if (str_eq(name, EL_STR("str_split_lines"))) { - return 1; - } - if (str_eq(name, EL_STR("str_split_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("str_split_n"))) { - return 3; - } - if (str_eq(name, EL_STR("str_join"))) { - return 2; - } - if (str_eq(name, EL_STR("el_html_sanitize"))) { - return 2; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 2; - } - if (str_eq(name, EL_STR("el_min"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_get"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_append"))) { - return 2; - } - if (str_eq(name, EL_STR("el_list_empty"))) { - return 0; - } - if (str_eq(name, EL_STR("el_list_clone"))) { - return 1; - } - if (str_eq(name, EL_STR("list_push"))) { - return 2; - } - if (str_eq(name, EL_STR("list_push_front"))) { - return 2; - } - if (str_eq(name, EL_STR("list_join"))) { - return 2; - } - if (str_eq(name, EL_STR("list_range"))) { - return 2; - } - if (str_eq(name, EL_STR("el_get_field"))) { - return 2; - } - if (str_eq(name, EL_STR("el_map_get"))) { - return 2; - } - if (str_eq(name, EL_STR("el_map_set"))) { - return 3; - } - if (str_eq(name, EL_STR("http_get"))) { - return 1; - } - if (str_eq(name, EL_STR("http_post"))) { - return 2; - } - if (str_eq(name, EL_STR("http_post_json"))) { - return 2; - } - if (str_eq(name, EL_STR("http_get_with_headers"))) { - return 2; - } - if (str_eq(name, EL_STR("http_post_with_headers"))) { - return 3; - } - if (str_eq(name, EL_STR("http_post_form_auth"))) { - return 3; - } - if (str_eq(name, EL_STR("http_serve"))) { - return 2; - } - if (str_eq(name, EL_STR("http_set_handler"))) { - return 1; - } - if (str_eq(name, EL_STR("fs_read"))) { - return 1; - } - if (str_eq(name, EL_STR("fs_write"))) { - return 2; - } - if (str_eq(name, EL_STR("fs_list"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get"))) { - return 2; - } - if (str_eq(name, EL_STR("json_parse"))) { - return 1; - } - if (str_eq(name, EL_STR("json_stringify"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_string"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_float"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_bool"))) { - return 2; - } - if (str_eq(name, EL_STR("json_get_raw"))) { - return 2; - } - if (str_eq(name, EL_STR("json_set"))) { - return 3; - } - if (str_eq(name, EL_STR("json_array_len"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 0; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 0; - } - if (str_eq(name, EL_STR("sleep_secs"))) { - return 1; - } - if (str_eq(name, EL_STR("sleep_ms"))) { - return 1; - } - if (str_eq(name, EL_STR("time_format"))) { - return 2; - } - if (str_eq(name, EL_STR("time_to_parts"))) { - return 1; - } - if (str_eq(name, EL_STR("time_from_parts"))) { - return 3; - } - if (str_eq(name, EL_STR("time_add"))) { - return 3; - } - if (str_eq(name, EL_STR("time_diff"))) { - return 3; - } - if (str_eq(name, EL_STR("uuid_new"))) { - return 0; - } - if (str_eq(name, EL_STR("uuid_v4"))) { - return 0; - } - if (str_eq(name, EL_STR("env"))) { - return 1; - } - if (str_eq(name, EL_STR("state_set"))) { - return 2; - } - if (str_eq(name, EL_STR("state_get"))) { - return 1; - } - if (str_eq(name, EL_STR("state_del"))) { - return 1; - } - if (str_eq(name, EL_STR("state_keys"))) { - return 0; - } - if (str_eq(name, EL_STR("float_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("int_to_float"))) { - return 1; - } - if (str_eq(name, EL_STR("float_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("format_float"))) { - return 2; - } - if (str_eq(name, EL_STR("decimal_round"))) { - return 2; - } - if (str_eq(name, EL_STR("str_to_float"))) { - return 1; - } - if (str_eq(name, EL_STR("math_sqrt"))) { - return 1; - } - if (str_eq(name, EL_STR("math_log"))) { - return 1; - } - if (str_eq(name, EL_STR("math_ln"))) { - return 1; - } - if (str_eq(name, EL_STR("math_sin"))) { - return 1; - } - if (str_eq(name, EL_STR("math_cos"))) { - return 1; - } - if (str_eq(name, EL_STR("math_pi"))) { - return 0; - } - if (str_eq(name, EL_STR("bool_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("exit_program"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_connect"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_send"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_activate"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_emit"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_field"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_strengthen"))) { - return 2; - } - if (str_eq(name, EL_STR("dharma_relationship"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_peers"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_node"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_node_full"))) { - return 8; - } - if (str_eq(name, EL_STR("engram_get_node"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_strengthen"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_forget"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_node_count"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_search"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_scan_nodes"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_connect"))) { - return 4; - } - if (str_eq(name, EL_STR("engram_edge_between"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_neighbors"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_neighbors_filtered"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_edge_count"))) { - return 0; - } - if (str_eq(name, EL_STR("engram_activate"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_save"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_load"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_get_node_json"))) { - return 1; - } - if (str_eq(name, EL_STR("engram_search_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_scan_nodes_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_neighbors_json"))) { - return 3; - } - if (str_eq(name, EL_STR("engram_activate_json"))) { - return 2; - } - if (str_eq(name, EL_STR("engram_stats_json"))) { - return 0; - } - if (str_eq(name, EL_STR("llm_call"))) { - return 2; - } - if (str_eq(name, EL_STR("llm_call_system"))) { - return 3; - } - if (str_eq(name, EL_STR("llm_call_agentic"))) { - return 4; - } - if (str_eq(name, EL_STR("llm_vision"))) { - return 4; - } - if (str_eq(name, EL_STR("llm_models"))) { - return 0; - } - if (str_eq(name, EL_STR("llm_register_tool"))) { - return 2; - } - if (str_eq(name, EL_STR("sha256_hex"))) { - return 1; - } - if (str_eq(name, EL_STR("sha256_bytes"))) { - return 1; - } - if (str_eq(name, EL_STR("hmac_sha256_hex"))) { - return 2; - } - if (str_eq(name, EL_STR("hmac_sha256_bytes"))) { - return 2; - } - if (str_eq(name, EL_STR("base64_encode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64_decode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64url_encode"))) { - return 1; - } - if (str_eq(name, EL_STR("base64url_decode"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_get"))) { - return 2; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_append"))) { - return 2; - } - if (str_eq(name, EL_STR("native_list_empty"))) { - return 0; - } - if (str_eq(name, EL_STR("native_list_clone"))) { - return 1; - } - if (str_eq(name, EL_STR("native_string_chars"))) { - return 1; - } - if (str_eq(name, EL_STR("native_int_to_str"))) { - return 1; - } - if (str_eq(name, EL_STR("append"))) { - return 2; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("get"))) { - return 2; - } - if (str_eq(name, EL_STR("map_get"))) { - return 2; - } - if (str_eq(name, EL_STR("map_set"))) { - return 3; - } - return (-1); - return 0; -} - -el_val_t arity_record_violation(el_val_t fn_name, el_val_t expected, el_val_t actual) { - el_val_t csv = state_get(EL_STR("__arity_violations")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t entry = el_str_concat(el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("|")), native_int_to_str(expected)), EL_STR("|")), native_int_to_str(actual)); - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), entry), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__arity_violations"), el_str_concat(el_str_concat(csv, entry), EL_STR(","))); - return 1; - return 0; -} - -el_val_t arity_check_call(el_val_t fn_name, el_val_t actual) { - el_val_t expected = builtin_arity(fn_name); - if (expected < 0) { - return 1; - } - if (expected == actual) { - return 1; - } - arity_record_violation(fn_name, expected, actual); - return 1; - return 0; -} - -el_val_t emit_arity_violations(void) { - el_val_t csv = state_get(EL_STR("__arity_violations")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - if (str_eq(csv, EL_STR(","))) { - return 0; - } - el_val_t n = str_len(csv); - el_val_t i = 1; - while (i < n) { - el_val_t next_comma = str_index_of(str_slice(csv, i, n), EL_STR(",")); - if (next_comma < 0) { - return 0; - } - el_val_t entry = str_slice(csv, i, (i + next_comma)); - el_val_t p1 = str_index_of(entry, EL_STR("|")); - if (p1 > 0) { - el_val_t fn_name = str_slice(entry, 0, p1); - el_val_t rest = str_slice(entry, (p1 + 1), str_len(entry)); - el_val_t p2 = str_index_of(rest, EL_STR("|")); - if (p2 > 0) { - el_val_t exp_s = str_slice(rest, 0, p2); - el_val_t act_s = str_slice(rest, (p2 + 1), str_len(rest)); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("#error \"arity error: '"), fn_name), EL_STR("' takes ")), exp_s), EL_STR(" arguments, but called with ")), act_s), EL_STR("\""))); - } - } - i = ((i + next_comma) + 1); - } - return 0; -} - -el_val_t add_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__int_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__int_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_instant_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__instant_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__instant_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_duration_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__duration_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__duration_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_calendar_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__calendar_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__calendar_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_caltime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__caltime_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__caltime_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_rhythm_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__rhythm_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__rhythm_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_localdate_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdate_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__localdate_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_localtime_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localtime_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__localtime_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_localdt_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__localdt_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__localdt_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t add_zone_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__zone_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__zone_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t build_int_names_for_params(el_val_t params) { - state_set(EL_STR("__int_names"), EL_STR(",")); - state_set(EL_STR("__instant_names"), EL_STR(",")); - state_set(EL_STR("__duration_names"), EL_STR(",")); - state_set(EL_STR("__calendar_names"), EL_STR(",")); - state_set(EL_STR("__caltime_names"), EL_STR(",")); - state_set(EL_STR("__rhythm_names"), EL_STR(",")); - state_set(EL_STR("__localdate_names"), EL_STR(",")); - state_set(EL_STR("__localtime_names"), EL_STR(",")); - state_set(EL_STR("__localdt_names"), EL_STR(",")); - state_set(EL_STR("__zone_names"), EL_STR(",")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR("Int"))) { - add_int_name(pname); - } - if (str_eq(ptype, EL_STR("Instant"))) { - add_instant_name(pname); - } - if (str_eq(ptype, EL_STR("Duration"))) { - add_duration_name(pname); - } - if (str_eq(ptype, EL_STR("Calendar"))) { - add_calendar_name(pname); - } - if (str_eq(ptype, EL_STR("CalendarTime"))) { - add_caltime_name(pname); - } - if (str_eq(ptype, EL_STR("Rhythm"))) { - add_rhythm_name(pname); - } - if (str_eq(ptype, EL_STR("LocalDate"))) { - add_localdate_name(pname); - } - if (str_eq(ptype, EL_STR("LocalTime"))) { - add_localtime_name(pname); - } - if (str_eq(ptype, EL_STR("LocalDateTime"))) { - add_localdt_name(pname); - } - if (str_eq(ptype, EL_STR("Zone"))) { - add_zone_name(pname); - } - pi = (pi + 1); - } - return 1; - return 0; -} - -el_val_t cg_fn(el_val_t stmt) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - return 0; - } - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t params_c = params_to_c(params); - el_val_t decorator = el_get_field(stmt, EL_STR("decorator")); - if (vbd_has_restricted_call(body)) { - if (!str_eq(decorator, EL_STR("manager"))) { - emit_line(el_str_concat(el_str_concat(EL_STR("#error \"VBD violation: dharma_emit/dharma_field called from non-@manager fn '"), fn_name), EL_STR("'\""))); - } - } - build_int_names_for_params(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(") {"))); - el_val_t decl = native_list_empty(); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - decl = native_list_append(decl, pname); - pi = (pi + 1); - } - el_val_t body_xformed = body; - if (!str_eq(ret_type, EL_STR("Void"))) { - body_xformed = transform_implicit_return(body); - } - cg_stmts(body_xformed, EL_STR(" "), decl); - emit_line(EL_STR(" return 0;")); - emit_line(EL_STR("}")); - emit_blank(); - return 0; -} - -el_val_t is_fndef(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t is_top_level_decl(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("TypeDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("Import"))) { - return 1; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t cgi_arg(el_val_t value, el_val_t has_value) { - if (has_value) { - return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(value)), EL_STR(")")); - } - return EL_STR("EL_NULL"); - return 0; -} - -el_val_t vbd_is_restricted_name(el_val_t name) { - if (str_eq(name, EL_STR("dharma_emit"))) { - return 1; - } - if (str_eq(name, EL_STR("dharma_field"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t vbd_expr_has_restricted_call(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (str_eq(fk, EL_STR("Ident"))) { - el_val_t fname = el_get_field(func, EL_STR("name")); - if (vbd_is_restricted_name(fname)) { - return 1; - } - } - if (vbd_expr_has_restricted_call(func)) { - return 1; - } - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t an = native_list_len(args); - el_val_t ai = 0; - while (ai < an) { - el_val_t a = native_list_get(args, ai); - if (vbd_expr_has_restricted_call(a)) { - return 1; - } - ai = (ai + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t l = el_get_field(expr, EL_STR("left")); - el_val_t r = el_get_field(expr, EL_STR("right")); - if (vbd_expr_has_restricted_call(l)) { - return 1; - } - if (vbd_expr_has_restricted_call(r)) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Not"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Neg"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Field"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object"))); - } - if (str_eq(kind, EL_STR("Index"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object")))) { - return 1; - } - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("index")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Try"))) { - return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner"))); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - el_val_t i = 0; - while (i < n) { - el_val_t e = native_list_get(elems, i); - if (vbd_expr_has_restricted_call(e)) { - return 1; - } - i = (i + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t v = el_get_field(pair, EL_STR("value")); - if (vbd_expr_has_restricted_call(v)) { - return 1; - } - i = (i + 1); - } - return 0; - } - if (str_eq(kind, EL_STR("If"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("cond")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("then")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("else")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("For"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("list")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(expr, EL_STR("body")))) { - return 1; - } - return 0; - } - if (str_eq(kind, EL_STR("Match"))) { - if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("subject")))) { - return 1; - } - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t body = el_get_field(arm, EL_STR("body")); - if (vbd_expr_has_restricted_call(body)) { - return 1; - } - i = (i + 1); - } - return 0; - } - return 0; - return 0; -} - -el_val_t vbd_has_restricted_call(el_val_t stmts) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t s = native_list_get(stmts, i); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - if (str_eq(sk, EL_STR("Let"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("Return"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("Expr"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("While"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("cond")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) { - return 1; - } - } - if (str_eq(sk, EL_STR("For"))) { - if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("list")))) { - return 1; - } - if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) { - return 1; - } - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t codegen(el_val_t stmts, el_val_t source) { - el_val_t n_top = native_list_len(stmts); - el_val_t cgi_count = 0; - el_val_t cgi_block = el_map_new(1, "stmt", EL_STR("None")); - el_val_t svc_count = 0; - el_val_t svc_block = el_map_new(1, "stmt", EL_STR("None")); - el_val_t ti = 0; - while (ti < n_top) { - el_val_t s = native_list_get(stmts, ti); - el_val_t sk = el_get_field(s, EL_STR("stmt")); - if (str_eq(sk, EL_STR("CgiBlock"))) { - cgi_count = (cgi_count + 1); - if (cgi_count == 1) { - cgi_block = s; - } - } - if (str_eq(sk, EL_STR("ServiceBlock"))) { - svc_count = (svc_count + 1); - if (svc_count == 1) { - svc_block = s; - } - } - ti = (ti + 1); - } - if (cgi_count > 1) { - emit_line(EL_STR("#error \"El: multiple cgi blocks in program (only one allowed)\"")); - } - if (svc_count > 1) { - emit_line(EL_STR("#error \"El: multiple service blocks in program (only one allowed)\"")); - } - if (cgi_count >= 1) { - if (svc_count >= 1) { - emit_line(EL_STR("#error \"El: program declares both cgi and service blocks (mutually exclusive — pick one)\"")); - } - } - el_val_t kind = EL_STR("utility"); - if (cgi_count >= 1) { - kind = EL_STR("cgi"); - } - if (svc_count >= 1) { - kind = EL_STR("service"); - } - state_set(EL_STR("__program_kind"), kind); - state_set(EL_STR("__cap_violations"), EL_STR("")); - state_set(EL_STR("__arity_violations"), EL_STR("")); - state_set(EL_STR("__time_violations"), EL_STR("")); - emit_line(EL_STR("#include ")); - emit_line(EL_STR("#include ")); - emit_line(EL_STR("#include \"el_runtime.h\"")); - emit_blank(); - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (!str_eq(fn_name, EL_STR("main"))) { - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t params_c = params_to_c(params); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(");"))); - } - } - i = (i + 1); - } - emit_blank(); - el_val_t has_toplevel_lets = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - add_int_name(name); - } - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - add_int_name(name); - } - emit_line(el_str_concat(el_str_concat(EL_STR("el_val_t "), name), EL_STR(";"))); - has_toplevel_lets = 1; - } - i = (i + 1); - } - if (has_toplevel_lets) { - emit_blank(); - } - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - cg_fn(stmt); - } - i = (i + 1); - } - emit_line(EL_STR("int main(int _argc, char** _argv) {")); - emit_line(EL_STR(" el_runtime_init_args(_argc, _argv);")); - if (cgi_count >= 1) { - el_val_t cname = el_get_field(cgi_block, EL_STR("name")); - el_val_t cdid = el_get_field(cgi_block, EL_STR("dharma_id")); - el_val_t cprin = el_get_field(cgi_block, EL_STR("principal")); - el_val_t cnet = el_get_field(cgi_block, EL_STR("network")); - el_val_t ceng = el_get_field(cgi_block, EL_STR("engram")); - el_val_t has_did = el_get_field(cgi_block, EL_STR("has_dharma_id")); - el_val_t has_prin = el_get_field(cgi_block, EL_STR("has_principal")); - el_val_t has_net = el_get_field(cgi_block, EL_STR("has_network")); - el_val_t has_eng = el_get_field(cgi_block, EL_STR("has_engram")); - el_val_t arg_name = el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(cname)), EL_STR(")")); - el_val_t arg_did = cgi_arg(cdid, has_did); - el_val_t arg_prin = cgi_arg(cprin, has_prin); - el_val_t arg_net = cgi_arg(cnet, has_net); - el_val_t arg_eng = cgi_arg(ceng, has_eng); - emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR(" el_cgi_init("), arg_name), EL_STR(", ")), arg_did), EL_STR(", ")), arg_prin), EL_STR(", ")), arg_net), EL_STR(", ")), arg_eng), EL_STR(");"))); - } - el_val_t main_decl = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - main_decl = native_list_append(main_decl, name); - } - i = (i + 1); - } - el_val_t el_main_body = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t bn = native_list_len(body); - el_val_t bi = 0; - while (bi < bn) { - el_main_body = native_list_append(el_main_body, native_list_get(body, bi)); - bi = (bi + 1); - } - } - } - i = (i + 1); - } - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (is_fndef(stmt)) { - } else { - if (is_top_level_decl(stmt)) { - } else { - main_decl = cg_stmt(stmt, EL_STR(" "), main_decl); - } - } - el_release(stmt); - i = (i + 1); - } - el_val_t mn = native_list_len(el_main_body); - el_val_t mi = 0; - while (mi < mn) { - el_val_t mstmt = native_list_get(el_main_body, mi); - main_decl = cg_stmt(mstmt, EL_STR(" "), main_decl); - mi = (mi + 1); - } - emit_line(EL_STR(" return 0;")); - emit_line(EL_STR("}")); - emit_blank(); - emit_cap_violations(); - emit_arity_violations(); - emit_time_violations(); - return EL_STR(""); - return 0; -} - -el_val_t js_escape(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t total = native_list_len(chars); - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < total) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("\""))) { - out = el_str_concat(out, EL_STR("\\\"")); - } else { - if (str_eq(ch, EL_STR("\\"))) { - out = el_str_concat(out, EL_STR("\\\\")); - } else { - if (str_eq(ch, EL_STR("\n"))) { - out = el_str_concat(out, EL_STR("\\n")); - } else { - if (str_eq(ch, EL_STR("\r"))) { - out = el_str_concat(out, EL_STR("\\r")); - } else { - if (str_eq(ch, EL_STR("\t"))) { - out = el_str_concat(out, EL_STR("\\t")); - } else { - out = el_str_concat(out, ch); - } - } - } - } - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t js_str_lit(el_val_t s) { - return el_str_concat(el_str_concat(EL_STR("\""), js_escape(s)), EL_STR("\"")); - return 0; -} - -el_val_t js_emit_line(el_val_t line) { - println(line); - return 0; -} - -el_val_t js_emit_blank(void) { - println(EL_STR("")); - return 0; -} - -el_val_t js_binop(el_val_t op) { - if (str_eq(op, EL_STR("Plus"))) { - return EL_STR("+"); - } - if (str_eq(op, EL_STR("Minus"))) { - return EL_STR("-"); - } - if (str_eq(op, EL_STR("Star"))) { - return EL_STR("*"); - } - if (str_eq(op, EL_STR("Slash"))) { - return EL_STR("/"); - } - if (str_eq(op, EL_STR("Percent"))) { - return EL_STR("%"); - } - if (str_eq(op, EL_STR("EqEq"))) { - return EL_STR("==="); - } - if (str_eq(op, EL_STR("NotEq"))) { - return EL_STR("!=="); - } - if (str_eq(op, EL_STR("Lt"))) { - return EL_STR("<"); - } - if (str_eq(op, EL_STR("Gt"))) { - return EL_STR(">"); - } - if (str_eq(op, EL_STR("LtEq"))) { - return EL_STR("<="); - } - if (str_eq(op, EL_STR("GtEq"))) { - return EL_STR(">="); - } - if (str_eq(op, EL_STR("And"))) { - return EL_STR("&&"); - } - if (str_eq(op, EL_STR("Or"))) { - return EL_STR("||"); - } - return op; - return 0; -} - -el_val_t js_is_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__js_int_names")); - if (str_eq(csv, EL_STR(""))) { - return 0; - } - return str_contains(csv, el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(","))); - return 0; -} - -el_val_t js_add_int_name(el_val_t name) { - el_val_t csv = state_get(EL_STR("__js_int_names")); - if (str_eq(csv, EL_STR(""))) { - csv = EL_STR(","); - } - el_val_t key = el_str_concat(el_str_concat(EL_STR(","), name), EL_STR(",")); - if (str_contains(csv, key)) { - return 1; - } - state_set(EL_STR("__js_int_names"), el_str_concat(el_str_concat(csv, name), EL_STR(","))); - return 1; - return 0; -} - -el_val_t js_build_int_names_for_params(el_val_t params) { - state_set(EL_STR("__js_int_names"), EL_STR(",")); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - el_val_t ptype = el_get_field(param, EL_STR("type")); - if (str_eq(ptype, EL_STR("Int"))) { - js_add_int_name(pname); - } - pi = (pi + 1); - } - return 1; - return 0; -} - -el_val_t js_is_int_call(el_val_t call_expr) { - el_val_t func = el_get_field(call_expr, EL_STR("func")); - el_val_t fk = el_get_field(func, EL_STR("expr")); - if (!str_eq(fk, EL_STR("Ident"))) { - return 0; - } - el_val_t name = el_get_field(func, EL_STR("name")); - if (str_eq(name, EL_STR("str_len"))) { - return 1; - } - if (str_eq(name, EL_STR("str_index_of"))) { - return 1; - } - if (str_eq(name, EL_STR("str_to_int"))) { - return 1; - } - if (str_eq(name, EL_STR("str_char_code"))) { - return 1; - } - if (str_eq(name, EL_STR("native_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("el_list_len"))) { - return 1; - } - if (str_eq(name, EL_STR("len"))) { - return 1; - } - if (str_eq(name, EL_STR("json_get_int"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now"))) { - return 1; - } - if (str_eq(name, EL_STR("time_now_utc"))) { - return 1; - } - if (str_eq(name, EL_STR("el_abs"))) { - return 1; - } - if (str_eq(name, EL_STR("el_max"))) { - return 1; - } - if (str_eq(name, EL_STR("el_min"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t js_cg_expr(el_val_t expr) { - el_val_t kind = el_get_field(expr, EL_STR("expr")); - if (str_eq(kind, EL_STR("Int"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("DurationLit"))) { - el_val_t count = el_get_field(expr, EL_STR("count")); - el_val_t unit = el_get_field(expr, EL_STR("unit")); - el_val_t mult_ns = EL_STR("1"); - if (str_eq(unit, EL_STR("nano"))) { - mult_ns = EL_STR("1"); - } - if (str_eq(unit, EL_STR("nanos"))) { - mult_ns = EL_STR("1"); - } - if (str_eq(unit, EL_STR("milli"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("millis"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("millisecond"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("milliseconds"))) { - mult_ns = EL_STR("1000000"); - } - if (str_eq(unit, EL_STR("second"))) { - mult_ns = EL_STR("1000000000"); - } - if (str_eq(unit, EL_STR("seconds"))) { - mult_ns = EL_STR("1000000000"); - } - if (str_eq(unit, EL_STR("minute"))) { - mult_ns = EL_STR("60000000000"); - } - if (str_eq(unit, EL_STR("minutes"))) { - mult_ns = EL_STR("60000000000"); - } - if (str_eq(unit, EL_STR("hour"))) { - mult_ns = EL_STR("3600000000000"); - } - if (str_eq(unit, EL_STR("hours"))) { - mult_ns = EL_STR("3600000000000"); - } - if (str_eq(unit, EL_STR("day"))) { - mult_ns = EL_STR("86400000000000"); - } - if (str_eq(unit, EL_STR("days"))) { - mult_ns = EL_STR("86400000000000"); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), count), EL_STR(" * ")), mult_ns), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Float"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return v; - } - if (str_eq(kind, EL_STR("Str"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - return js_str_lit(v); - } - if (str_eq(kind, EL_STR("Bool"))) { - el_val_t v = el_get_field(expr, EL_STR("value")); - if (str_eq(v, EL_STR("true"))) { - return EL_STR("true"); - } - return EL_STR("false"); - } - if (str_eq(kind, EL_STR("Nil"))) { - return EL_STR("null"); - } - if (str_eq(kind, EL_STR("Ident"))) { - el_val_t name = el_get_field(expr, EL_STR("name")); - return name; - } - if (str_eq(kind, EL_STR("Not"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = js_cg_expr(inner); - return el_str_concat(EL_STR("!"), inner_c); - } - if (str_eq(kind, EL_STR("Neg"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - el_val_t inner_c = js_cg_expr(inner); - return el_str_concat(el_str_concat(EL_STR("(-"), inner_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("BinOp"))) { - el_val_t op = el_get_field(expr, EL_STR("op")); - el_val_t left = el_get_field(expr, EL_STR("left")); - el_val_t right = el_get_field(expr, EL_STR("right")); - el_val_t left_c = js_cg_expr(left); - el_val_t right_c = js_cg_expr(right); - el_val_t left_kind = el_get_field(left, EL_STR("expr")); - el_val_t right_kind = el_get_field(right, EL_STR("expr")); - if (str_eq(op, EL_STR("Plus"))) { - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Call"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_call(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(right_kind, EL_STR("Ident"))) { - if (str_eq(left_kind, EL_STR("Call"))) { - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(rname)) { - if (js_is_int_call(left)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Call"))) { - if (str_eq(right_kind, EL_STR("Call"))) { - if (js_is_int_call(left)) { - if (js_is_int_call(right)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" + ")), right_c), EL_STR(")")); - } - } - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Call"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Ident"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_str_concat("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - } - if (str_eq(op, EL_STR("EqEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" === ")), right_c), EL_STR(")")); - } - if (str_eq(op, EL_STR("NotEq"))) { - if (str_eq(left_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Int"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Bool"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Nil"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - if (str_eq(left_kind, EL_STR("Ident"))) { - if (str_eq(right_kind, EL_STR("Ident"))) { - el_val_t lname = el_get_field(left, EL_STR("name")); - el_val_t rname = el_get_field(right, EL_STR("name")); - if (js_is_int_name(lname)) { - if (js_is_int_name(rname)) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - } - } - } - if (str_eq(left_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - if (str_eq(right_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" !== ")), right_c), EL_STR(")")); - } - el_val_t op_c = js_binop(op); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" ")), op_c), EL_STR(" ")), right_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Call"))) { - el_val_t func = el_get_field(expr, EL_STR("func")); - el_val_t args = el_get_field(expr, EL_STR("args")); - el_val_t arity = native_list_len(args); - el_val_t func_kind = el_get_field(func, EL_STR("expr")); - el_val_t args_c = EL_STR(""); - el_val_t i = 0; - while (i < arity) { - el_val_t arg = native_list_get(args, i); - el_val_t arg_c = js_cg_expr(arg); - if (i > 0) { - args_c = el_str_concat(args_c, EL_STR(", ")); - } - args_c = el_str_concat(args_c, arg_c); - i = (i + 1); - } - if (str_eq(func_kind, EL_STR("Ident"))) { - el_val_t fn_name = el_get_field(func, EL_STR("name")); - return el_str_concat(el_str_concat(el_str_concat(fn_name, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(func_kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(func, EL_STR("object")); - el_val_t field = el_get_field(func, EL_STR("field")); - el_val_t obj_c = js_cg_expr(obj); - if (arity > 0) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(", ")), args_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(field, EL_STR("(")), obj_c), EL_STR(")")); - } - el_val_t fn_c = js_cg_expr(func); - return el_str_concat(el_str_concat(el_str_concat(fn_c, EL_STR("(")), args_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Field"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t field = el_get_field(expr, EL_STR("field")); - el_val_t obj_c = js_cg_expr(obj); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), js_str_lit(field)), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Index"))) { - el_val_t obj = el_get_field(expr, EL_STR("object")); - el_val_t idx = el_get_field(expr, EL_STR("index")); - el_val_t obj_c = js_cg_expr(obj); - el_val_t idx_c = js_cg_expr(idx); - el_val_t idx_kind = el_get_field(idx, EL_STR("expr")); - if (str_eq(idx_kind, EL_STR("Str"))) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_list_get("), obj_c), EL_STR(", ")), idx_c), EL_STR(")")); - } - if (str_eq(kind, EL_STR("Array"))) { - el_val_t elems = el_get_field(expr, EL_STR("elems")); - el_val_t n = native_list_len(elems); - if (n == 0) { - return EL_STR("[]"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t elem = native_list_get(elems, i); - el_val_t elem_c = js_cg_expr(elem); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(items, elem_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("["), items), EL_STR("]")); - } - if (str_eq(kind, EL_STR("Map"))) { - el_val_t pairs = el_get_field(expr, EL_STR("pairs")); - el_val_t n = native_list_len(pairs); - if (n == 0) { - return EL_STR("{}"); - } - el_val_t items = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t pair = native_list_get(pairs, i); - el_val_t key = el_get_field(pair, EL_STR("key")); - el_val_t val = el_get_field(pair, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - if (i > 0) { - items = el_str_concat(items, EL_STR(", ")); - } - items = el_str_concat(el_str_concat(el_str_concat(items, js_str_lit(key)), EL_STR(": ")), val_c); - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("{"), items), EL_STR("}")); - } - if (str_eq(kind, EL_STR("Try"))) { - el_val_t inner = el_get_field(expr, EL_STR("inner")); - return js_cg_expr(inner); - } - if (str_eq(kind, EL_STR("If"))) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t cond_c = js_cg_expr(cond); - return el_str_concat(el_str_concat(EL_STR("("), cond_c), EL_STR(" ? 1 : 0)")); - } - if (str_eq(kind, EL_STR("Match"))) { - return js_cg_match(expr); - } - return EL_STR("null"); - return 0; -} - -el_val_t js_next_match_id(void) { - el_val_t csv = state_get(EL_STR("__js_match_counter")); - el_val_t n = 0; - if (!str_eq(csv, EL_STR(""))) { - n = str_to_int(csv); - } - n = (n + 1); - state_set(EL_STR("__js_match_counter"), native_int_to_str(n)); - return native_int_to_str(n); - return 0; -} - -el_val_t js_cg_match(el_val_t expr) { - el_val_t subject = el_get_field(expr, EL_STR("subject")); - el_val_t arms = el_get_field(expr, EL_STR("arms")); - el_val_t subj_c = js_cg_expr(subject); - el_val_t id = js_next_match_id(); - el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id); - el_val_t out = el_str_concat(el_str_concat(EL_STR("(("), subj_var), EL_STR(") => { ")); - el_val_t n = native_list_len(arms); - el_val_t i = 0; - while (i < n) { - el_val_t arm = native_list_get(arms, i); - el_val_t pat = el_get_field(arm, EL_STR("pattern")); - el_val_t body = el_get_field(arm, EL_STR("body")); - el_val_t pkind = el_get_field(pat, EL_STR("pattern")); - el_val_t body_c = js_cg_expr(body); - if (str_eq(pkind, EL_STR("Wildcard"))) { - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("return (")), body_c), EL_STR("); ")); - } else { - if (str_eq(pkind, EL_STR("Binding"))) { - el_val_t bname = el_get_field(pat, EL_STR("name")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ const ")), bname), EL_STR(" = ")), subj_var), EL_STR("; return (")), body_c), EL_STR("); } ")); - } else { - if (str_eq(pkind, EL_STR("LitInt"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" === ")), v), EL_STR(") return (")), body_c), EL_STR("); ")); - } else { - if (str_eq(pkind, EL_STR("LitStr"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (str_eq(")), subj_var), EL_STR(", ")), js_str_lit(v)), EL_STR(")) return (")), body_c), EL_STR("); ")); - } else { - if (str_eq(pkind, EL_STR("LitBool"))) { - el_val_t v = el_get_field(pat, EL_STR("value")); - el_val_t bv = EL_STR("false"); - if (str_eq(v, EL_STR("true"))) { - bv = EL_STR("true"); - } - out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" === ")), bv), EL_STR(") return (")), body_c), EL_STR("); ")); - } else { - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("return (")), body_c), EL_STR("); ")); - } - } - } - } - } - i = (i + 1); - } - out = el_str_concat(el_str_concat(el_str_concat(out, EL_STR("return null; })(")), subj_c), EL_STR(")")); - return out; - return 0; -} - -el_val_t js_list_contains(el_val_t lst, el_val_t s) { - el_val_t n = native_list_len(lst); - el_val_t i = 0; - while (i < n) { - el_val_t item = native_list_get(lst, i); - if (str_eq(item, s)) { - return 1; - } - i = (i + 1); - } - return 0; - return 0; -} - -el_val_t js_cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("Let"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - el_val_t ltype = el_get_field(stmt, EL_STR("type")); - if (str_eq(ltype, EL_STR("Int"))) { - js_add_int_name(name); - } - el_val_t vk = el_get_field(val, EL_STR("expr")); - if (str_eq(vk, EL_STR("Int"))) { - js_add_int_name(name); - } - if (js_list_contains(declared, name)) { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } else { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("let ")), name), EL_STR(" = ")), val_c), EL_STR(";"))); - return native_list_append(declared, name); - } - } - if (str_eq(kind, EL_STR("Return"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("Nil"))) { - js_emit_line(el_str_concat(indent, EL_STR("return null;"))); - } else { - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("return ")), val_c), EL_STR(";"))); - } - return declared; - } - if (str_eq(kind, EL_STR("Assign"))) { - el_val_t name = el_get_field(stmt, EL_STR("name")); - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, name), EL_STR(" = ")), val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(stmt, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - js_cg_if_stmt(val, indent, declared); - return declared; - } - if (str_eq(val_kind, EL_STR("For"))) { - js_cg_for_stmt(val, indent, declared); - return declared; - } - el_val_t val_c = js_cg_expr(val); - js_emit_line(el_str_concat(el_str_concat(indent, val_c), EL_STR(";"))); - return declared; - } - if (str_eq(kind, EL_STR("While"))) { - el_val_t cond = el_get_field(stmt, EL_STR("cond")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t cond_c = js_cg_expr(cond); - cond_c = js_strip_outer_parens(cond_c); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("while (")), cond_c), EL_STR(") {"))); - js_cg_stmts(body, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return declared; - } - if (str_eq(kind, EL_STR("For"))) { - el_val_t item = el_get_field(stmt, EL_STR("item")); - el_val_t list_expr = el_get_field(stmt, EL_STR("list")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - js_cg_for_body(item, list_expr, body, indent, declared); - return declared; - } - if (str_eq(kind, EL_STR("FnDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("TypeDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return declared; - } - if (str_eq(kind, EL_STR("Import"))) { - return declared; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - el_val_t cname = el_get_field(stmt, EL_STR("name")); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("// cgi block '")), cname), EL_STR("' — no-op in JS target (server-side concept)"))); - return declared; - } - if (str_eq(kind, EL_STR("ServiceBlock"))) { - el_val_t sname = el_get_field(stmt, EL_STR("name")); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("// service block '")), sname), EL_STR("' — no-op in JS target"))); - return declared; - } - return declared; - return 0; -} - -el_val_t js_strip_outer_parens(el_val_t s) { - el_val_t chars = native_string_chars(s); - el_val_t n = native_list_len(chars); - if (n < 2) { - return s; - } - el_val_t first = native_list_get(chars, 0); - el_val_t last = native_list_get(chars, (n - 1)); - if (str_eq(first, EL_STR("("))) { - if (str_eq(last, EL_STR(")"))) { - el_val_t depth = 1; - el_val_t i = 1; - el_val_t balanced = 1; - while (i < (n - 1)) { - el_val_t ch = native_list_get(chars, i); - if (str_eq(ch, EL_STR("("))) { - depth = (depth + 1); - } - if (str_eq(ch, EL_STR(")"))) { - depth = (depth - 1); - if (depth == 0) { - balanced = 0; - i = n; - } - } - i = (i + 1); - } - if (balanced) { - el_val_t inner = EL_STR(""); - el_val_t j = 1; - while (j < (n - 1)) { - el_val_t ch = native_list_get(chars, j); - inner = el_str_concat(inner, ch); - j = (j + 1); - } - return inner; - } - } - } - return s; - return 0; -} - -el_val_t js_cg_if_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t cond = el_get_field(expr, EL_STR("cond")); - el_val_t then_stmts = el_get_field(expr, EL_STR("then")); - el_val_t else_stmts = el_get_field(expr, EL_STR("else")); - el_val_t has_else = el_get_field(expr, EL_STR("has_else")); - el_val_t cond_c = js_cg_expr(cond); - cond_c = js_strip_outer_parens(cond_c); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("if (")), cond_c), EL_STR(") {"))); - js_cg_stmts(then_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - if (has_else) { - js_emit_line(el_str_concat(indent, EL_STR("} else {"))); - js_cg_stmts(else_stmts, el_str_concat(indent, EL_STR(" ")), native_list_clone(declared)); - } - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t js_cg_for_body(el_val_t item, el_val_t list_expr, el_val_t body, el_val_t indent, el_val_t declared) { - el_val_t list_c = js_cg_expr(list_expr); - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(indent, EL_STR("for (const ")), item), EL_STR(" of ")), list_c), EL_STR(") {"))); - el_val_t body_decl = native_list_clone(declared); - body_decl = native_list_append(body_decl, item); - js_cg_stmts(body, el_str_concat(indent, EL_STR(" ")), body_decl); - js_emit_line(el_str_concat(indent, EL_STR("}"))); - return 0; -} - -el_val_t js_cg_for_stmt(el_val_t expr, el_val_t indent, el_val_t declared) { - el_val_t item = el_get_field(expr, EL_STR("item")); - el_val_t list_expr = el_get_field(expr, EL_STR("list")); - el_val_t body = el_get_field(expr, EL_STR("body")); - js_cg_for_body(item, list_expr, body, indent, declared); - return 0; -} - -el_val_t js_cg_stmts(el_val_t stmts, el_val_t indent, el_val_t declared) { - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - el_val_t decl = declared; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - decl = js_cg_stmt(stmt, indent, decl); - i = (i + 1); - } - return decl; - return 0; -} - -el_val_t js_params_str(el_val_t params) { - el_val_t n = native_list_len(params); - if (n == 0) { - return EL_STR(""); - } - el_val_t out = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t param = native_list_get(params, i); - el_val_t name = el_get_field(param, EL_STR("name")); - if (i > 0) { - out = el_str_concat(out, EL_STR(", ")); - } - out = el_str_concat(out, name); - i = (i + 1); - } - return out; - return 0; -} - -el_val_t js_transform_implicit_return(el_val_t body) { - el_val_t n = native_list_len(body); - if (n == 0) { - return body; - } - el_val_t last = native_list_get(body, (n - 1)); - el_val_t last_kind = el_get_field(last, EL_STR("stmt")); - if (str_eq(last_kind, EL_STR("Expr"))) { - el_val_t val = el_get_field(last, EL_STR("value")); - el_val_t val_kind = el_get_field(val, EL_STR("expr")); - if (str_eq(val_kind, EL_STR("If"))) { - return body; - } - if (str_eq(val_kind, EL_STR("For"))) { - return body; - } - el_val_t new_body = native_list_empty(); - el_val_t i = 0; - while (i < (n - 1)) { - new_body = native_list_append(new_body, native_list_get(body, i)); - i = (i + 1); - } - el_val_t return_stmt = el_map_new(2, "stmt", EL_STR("Return"), "value", val); - new_body = native_list_append(new_body, return_stmt); - return new_body; - } - return body; - return 0; -} - -el_val_t js_cg_fn(el_val_t stmt) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - el_val_t params = el_get_field(stmt, EL_STR("params")); - el_val_t body = el_get_field(stmt, EL_STR("body")); - el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type")); - el_val_t params_str = js_params_str(params); - js_build_int_names_for_params(params); - if (str_eq(fn_name, EL_STR("main"))) { - js_emit_line(el_str_concat(el_str_concat(EL_STR("function main("), params_str), EL_STR(") {"))); - } else { - js_emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("function "), fn_name), EL_STR("(")), params_str), EL_STR(") {"))); - } - el_val_t decl = native_list_empty(); - el_val_t np = native_list_len(params); - el_val_t pi = 0; - while (pi < np) { - el_val_t param = native_list_get(params, pi); - el_val_t pname = el_get_field(param, EL_STR("name")); - decl = native_list_append(decl, pname); - pi = (pi + 1); - } - el_val_t body_xformed = body; - if (!str_eq(ret_type, EL_STR("Void"))) { - body_xformed = js_transform_implicit_return(body); - } - js_cg_stmts(body_xformed, EL_STR(" "), decl); - js_emit_line(EL_STR("}")); - js_emit_blank(); - return 0; -} - -el_val_t js_is_fndef(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("FnDef"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t js_is_top_level_decl(el_val_t stmt) { - el_val_t kind = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(kind, EL_STR("TypeDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("EnumDef"))) { - return 1; - } - if (str_eq(kind, EL_STR("Import"))) { - return 1; - } - if (str_eq(kind, EL_STR("CgiBlock"))) { - return 1; - } - if (str_eq(kind, EL_STR("ServiceBlock"))) { - return 1; - } - return 0; - return 0; -} - -el_val_t codegen_js(el_val_t stmts, el_val_t source) { - state_set(EL_STR("__js_int_names"), EL_STR("")); - state_set(EL_STR("__js_match_counter"), EL_STR("")); - js_emit_line(EL_STR("// Generated by elc --target=js")); - js_emit_line(EL_STR("// Runtime: foundation/el/el-compiler/runtime/el_runtime.js")); - js_emit_line(EL_STR("import \"./el_runtime.js\";")); - js_emit_line(EL_STR("const {")); - js_emit_line(EL_STR(" println, print, el_str_concat, str_concat, str_eq, str_starts_with, str_ends_with,")); - js_emit_line(EL_STR(" str_len, int_to_str, str_to_int, str_slice, str_contains, str_replace,")); - js_emit_line(EL_STR(" str_to_upper, str_to_lower, str_trim, str_index_of, str_split, str_char_at,")); - js_emit_line(EL_STR(" str_char_code, str_lower, str_upper, el_abs, el_max, el_min,")); - js_emit_line(EL_STR(" el_list_new, el_list_len, el_list_get, el_list_append, el_list_empty, el_list_clone,")); - js_emit_line(EL_STR(" list_push, list_join, list_range,")); - js_emit_line(EL_STR(" el_map_new, el_get_field, el_map_get, el_map_set,")); - js_emit_line(EL_STR(" http_get, http_post, http_post_json,")); - js_emit_line(EL_STR(" fs_read, fs_write, fs_list,")); - js_emit_line(EL_STR(" json_parse, json_stringify, json_get, json_get_string, json_get_int,")); - js_emit_line(EL_STR(" time_now, time_now_utc, sleep_ms, bool_to_str, exit_program,")); - js_emit_line(EL_STR(" el_retain, el_release,")); - js_emit_line(EL_STR(" append, len, get, map_get, map_set,")); - js_emit_line(EL_STR(" native_list_get, native_list_len, native_list_append, native_list_empty,")); - js_emit_line(EL_STR(" native_list_clone, native_string_chars, native_int_to_str,")); - js_emit_line(EL_STR(" args, state_set, state_get, state_del, state_keys, env,")); - js_emit_line(EL_STR(" dharma_connect, dharma_send, dharma_emit, dharma_field, dharma_activate,")); - js_emit_line(EL_STR(" engram_node, engram_search, engram_activate,")); - js_emit_line(EL_STR(" llm_call, llm_call_system,")); - js_emit_line(EL_STR("} = globalThis.__el;")); - js_emit_blank(); - el_val_t n = native_list_len(stmts); - el_val_t i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (js_is_fndef(stmt)) { - js_cg_fn(stmt); - } - i = (i + 1); - } - el_val_t has_main = 0; - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - el_val_t sk = el_get_field(stmt, EL_STR("stmt")); - if (str_eq(sk, EL_STR("FnDef"))) { - el_val_t fn_name = el_get_field(stmt, EL_STR("name")); - if (str_eq(fn_name, EL_STR("main"))) { - has_main = 1; - } - } - i = (i + 1); - } - el_val_t main_decl = native_list_empty(); - i = 0; - while (i < n) { - el_val_t stmt = native_list_get(stmts, i); - if (js_is_fndef(stmt)) { - } else { - if (js_is_top_level_decl(stmt)) { - } else { - main_decl = js_cg_stmt(stmt, EL_STR(""), main_decl); - } - } - i = (i + 1); - } - if (has_main) { - js_emit_blank(); - js_emit_line(EL_STR("main();")); - } - return EL_STR(""); - return 0; -} - -el_val_t compile(el_val_t source) { - el_val_t tokens = lex(source); - el_val_t stmts = parse(tokens); - el_release(tokens); - return codegen(stmts, source); - return 0; -} - -el_val_t compile_js(el_val_t source) { - el_val_t tokens = lex(source); - el_val_t stmts = parse(tokens); - el_release(tokens); - return codegen_js(stmts, source); - return 0; -} - -el_val_t compile_dispatch(el_val_t tgt, el_val_t source) { - if (str_eq(tgt, EL_STR("js"))) { - return compile_js(source); - } - return compile(source); - return 0; -} - -el_val_t detect_target(el_val_t argv) { - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (str_starts_with(a, EL_STR("--target="))) { - el_val_t v = str_slice(a, 9, str_len(a)); - return v; - } - i = (i + 1); - } - return EL_STR("c"); - return 0; -} - -el_val_t strip_flags(el_val_t argv) { - el_val_t out = native_list_empty(); - el_val_t n = native_list_len(argv); - el_val_t i = 0; - while (i < n) { - el_val_t a = native_list_get(argv, i); - if (!str_starts_with(a, EL_STR("--"))) { - out = native_list_append(out, a); - } - i = (i + 1); - } - return out; - return 0; -} - -el_val_t dirname_of(el_val_t path) { - el_val_t n = str_len(path); - el_val_t i = (n - 1); - while (i >= 0) { - el_val_t c = str_slice(path, i, (i + 1)); - if (str_eq(c, EL_STR("/"))) { - return str_slice(path, 0, i); - } - i = (i - 1); - } - return EL_STR("."); - return 0; -} - -el_val_t parse_import_line(el_val_t trimmed, el_val_t dir) { - if (str_starts_with(trimmed, EL_STR("import \""))) { - el_val_t after = str_slice(trimmed, 8, str_len(trimmed)); - el_val_t q = str_index_of(after, EL_STR("\"")); - if (q > 0) { - el_val_t mod = str_slice(after, 0, q); - return el_str_concat(el_str_concat(dir, EL_STR("/")), mod); - } - } - if (str_starts_with(trimmed, EL_STR("from "))) { - el_val_t after = str_slice(trimmed, 5, str_len(trimmed)); - el_val_t sp = str_index_of(after, EL_STR(" ")); - if (sp > 0) { - el_val_t mod_raw = str_slice(after, 0, sp); - el_val_t mod = str_trim(mod_raw); - if (!str_eq(mod, EL_STR(""))) { - return el_str_concat(el_str_concat(el_str_concat(dir, EL_STR("/")), mod), EL_STR(".el")); - } - } - } - return EL_STR(""); - return 0; -} - -el_val_t resolve_imports(el_val_t src_path) { - el_val_t seen_key = el_str_concat(EL_STR("__elc_imp__:"), src_path); - el_val_t already = state_get(seen_key); - if (!str_eq(already, EL_STR(""))) { - return EL_STR(""); - } - state_set(seen_key, EL_STR("1")); - el_val_t source = fs_read(src_path); - el_val_t dir = dirname_of(src_path); - el_val_t lines = str_split(source, EL_STR("\n")); - el_val_t n = native_list_len(lines); - el_val_t prefix = EL_STR(""); - el_val_t body = EL_STR(""); - el_val_t i = 0; - while (i < n) { - el_val_t line = native_list_get(lines, i); - el_val_t trimmed = str_trim(line); - el_val_t imp_path = parse_import_line(trimmed, dir); - if (!str_eq(imp_path, EL_STR(""))) { - prefix = el_str_concat(prefix, resolve_imports(imp_path)); - } else { - body = el_str_concat(el_str_concat(body, line), EL_STR("\n")); - } - i = (i + 1); - } - return el_str_concat(prefix, body); - return 0; -} - -int main(int _argc, char** _argv) { - el_runtime_init_args(_argc, _argv); - el_val_t argv = args(); - el_val_t tgt = detect_target(argv); - el_val_t positional = strip_flags(argv); - el_val_t argc = native_list_len(positional); - if (argc < 1) { - println(EL_STR("el-compiler: usage: elc [--target=c|js] []")); - exit(1); - } - el_val_t src_path = native_list_get(positional, 0); - el_val_t source = resolve_imports(src_path); - el_val_t out = compile_dispatch(tgt, source); - if (argc >= 2) { - el_val_t out_path = native_list_get(positional, 1); - el_val_t ok = fs_write(out_path, out); - if (ok) { - exit(0); - } else { - println(EL_STR("el-compiler: failed to write output")); - exit(1); - } - } - return 0; -} - diff --git a/lang/dist/platform/elc.legacy b/lang/dist/platform/elc.legacy deleted file mode 100755 index b1e1a92..0000000 Binary files a/lang/dist/platform/elc.legacy and /dev/null differ diff --git a/lang/dist/platform/elc.prelaunch.bak b/lang/dist/platform/elc.prelaunch.bak deleted file mode 100755 index 9b68a40..0000000 Binary files a/lang/dist/platform/elc.prelaunch.bak and /dev/null differ diff --git a/lang/dist/platform/elc.preselfhost b/lang/dist/platform/elc.preselfhost deleted file mode 100755 index 68ee155..0000000 Binary files a/lang/dist/platform/elc.preselfhost and /dev/null differ diff --git a/lang/dist/platform/elc.prev5 b/lang/dist/platform/elc.prev5 deleted file mode 100755 index 88d4d3c..0000000 Binary files a/lang/dist/platform/elc.prev5 and /dev/null differ diff --git a/lang/dist/platform/elc.prev6 b/lang/dist/platform/elc.prev6 deleted file mode 100755 index 80ca0d7..0000000 Binary files a/lang/dist/platform/elc.prev6 and /dev/null differ diff --git a/lang/dist/platform/elc.prev7 b/lang/dist/platform/elc.prev7 deleted file mode 100755 index d666bc5..0000000 Binary files a/lang/dist/platform/elc.prev7 and /dev/null differ diff --git a/lang/dist/platform/elc.prev8 b/lang/dist/platform/elc.prev8 deleted file mode 100755 index 68ee155..0000000 Binary files a/lang/dist/platform/elc.prev8 and /dev/null differ diff --git a/lang/dist/platform/elc.prev9 b/lang/dist/platform/elc.prev9 deleted file mode 100755 index 68ee155..0000000 Binary files a/lang/dist/platform/elc.prev9 and /dev/null differ diff --git a/lang/tools/lsp/dist/el-lsp b/lang/tools/lsp/dist/el-lsp deleted file mode 100755 index 6a74145..0000000 Binary files a/lang/tools/lsp/dist/el-lsp and /dev/null differ diff --git a/lang/tools/lsp/dist/el-lsp.c b/lang/tools/lsp/dist/el-lsp.c deleted file mode 100644 index 8dfd6cc..0000000 --- a/lang/tools/lsp/dist/el-lsp.c +++ /dev/null @@ -1,1252 +0,0 @@ -#include -#include -#include "el_runtime.h" - -el_val_t lsp_read_message(void); -el_val_t lsp_write_message(el_val_t body); -el_val_t lsp_json_escape(el_val_t s); -el_val_t lsp_response(el_val_t id, el_val_t result_json); -el_val_t lsp_error_response(el_val_t id, el_val_t code, el_val_t message); -el_val_t lsp_notification(el_val_t method, el_val_t params_json); -el_val_t lsp_doc_key(el_val_t uri); -el_val_t lsp_doc_store(el_val_t uri, el_val_t text); -el_val_t lsp_doc_get(el_val_t uri); -el_val_t lsp_doc_remove(el_val_t uri); -el_val_t lsp_builtin_catalog(void); -el_val_t lsp_builtin_find(el_val_t name, el_val_t catalog); -el_val_t lsp_types_key(el_val_t uri, el_val_t type_name); -el_val_t lsp_vartypes_key(el_val_t uri); -el_val_t lsp_scan_types(el_val_t uri, el_val_t source); -el_val_t lsp_get_type_fields(el_val_t uri, el_val_t type_name); -el_val_t lsp_varentry_name(el_val_t entry); -el_val_t lsp_varentry_type(el_val_t entry); -el_val_t lsp_scan_vartypes(el_val_t uri, el_val_t source); -el_val_t lsp_get_var_type(el_val_t uri, el_val_t var_name); -el_val_t lsp_scan_document(el_val_t uri, el_val_t source); -el_val_t lsp_dot_ident_before(el_val_t text); -el_val_t lsp_line_prefix(el_val_t source, el_val_t line_no, el_val_t char_no); -el_val_t lsp_field_completions(el_val_t uri, el_val_t type_name); -el_val_t lsp_extract_fns(el_val_t source); -el_val_t lsp_find_def(el_val_t source, el_val_t fn_name); -el_val_t lsp_word_at(el_val_t source, el_val_t line_no, el_val_t char_no); -el_val_t lsp_completion_item(el_val_t label, el_val_t kind, el_val_t detail); -el_val_t lsp_build_completions(el_val_t uri, el_val_t catalog, el_val_t line_no, el_val_t char_no); -el_val_t lsp_keyword_hover(el_val_t word); -el_val_t lsp_build_hover(el_val_t uri, el_val_t line_no, el_val_t char_no, el_val_t catalog); -el_val_t lsp_build_definition(el_val_t uri, el_val_t line_no, el_val_t char_no); -el_val_t lsp_make_diag(el_val_t line_no, el_val_t col_start, el_val_t col_end, el_val_t message, el_val_t severity); -el_val_t lsp_compute_diagnostics(el_val_t source); -el_val_t lsp_publish_diagnostics(el_val_t uri); -el_val_t lsp_handle_initialize(el_val_t id); -el_val_t lsp_handle_completion(el_val_t id, el_val_t params, el_val_t catalog); -el_val_t lsp_handle_hover(el_val_t id, el_val_t params, el_val_t catalog); -el_val_t lsp_handle_definition(el_val_t id, el_val_t params); -el_val_t lsp_handle_did_open(el_val_t params, el_val_t catalog); -el_val_t lsp_handle_did_change(el_val_t params); -el_val_t lsp_handle_did_close(el_val_t params); -el_val_t lsp_handle_did_save(el_val_t params); -el_val_t lsp_handle_shutdown(el_val_t id); -el_val_t lsp_dispatch(el_val_t msg, el_val_t catalog); - -el_val_t lsp_read_message(void) { - el_val_t header_buf = EL_STR(""); - el_val_t found_end = 0; - el_val_t max_header = 8192; - el_val_t hi = 0; - while (!found_end) { - if (hi >= max_header) { - return EL_STR(""); - } - el_val_t ch = __read_n(1); - if (str_eq(ch, EL_STR(""))) { - return EL_STR(""); - } - header_buf = el_str_concat(header_buf, ch); - el_val_t hlen = str_len(header_buf); - if (hlen >= 4) { - el_val_t tail = str_slice(header_buf, (hlen - 4), hlen); - if (str_eq(tail, EL_STR("\r\n\r\n"))) { - found_end = 1; - } - } - hi = (hi + 1); - } - el_val_t cl_key = EL_STR("Content-Length: "); - el_val_t cl_pos = str_index_of(header_buf, cl_key); - if (cl_pos < 0) { - return EL_STR(""); - } - el_val_t after = str_slice(header_buf, (cl_pos + str_len(cl_key)), str_len(header_buf)); - el_val_t cr_pos = str_index_of(after, EL_STR("\r")); - el_val_t num_str = EL_STR(""); - if (cr_pos >= 0) { - num_str = str_slice(after, 0, cr_pos); - } else { - el_val_t nl_pos = str_index_of(after, EL_STR("\n")); - if (nl_pos >= 0) { - num_str = str_slice(after, 0, nl_pos); - } - } - el_val_t body_len = str_to_int(str_trim(num_str)); - if (body_len <= 0) { - return EL_STR(""); - } - return __read_n(body_len); - return 0; -} - -el_val_t lsp_write_message(el_val_t body) { - el_val_t len = str_len(body); - __print_raw(el_str_concat(el_str_concat(el_str_concat(EL_STR("Content-Length: "), int_to_str(len)), EL_STR("\r\n\r\n")), body)); - return 0; -} - -el_val_t lsp_json_escape(el_val_t s) { - s = str_replace(s, EL_STR("\\"), EL_STR("\\\\")); - s = str_replace(s, EL_STR("\""), EL_STR("\\\"")); - s = str_replace(s, EL_STR("\n"), EL_STR("\\n")); - s = str_replace(s, EL_STR("\r"), EL_STR("\\r")); - s = str_replace(s, EL_STR("\t"), EL_STR("\\t")); - return s; - return 0; -} - -el_val_t lsp_response(el_val_t id, el_val_t result_json) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"jsonrpc\":\"2.0\",\"id\":"), id), EL_STR(",\"result\":")), result_json), EL_STR("}")); - return 0; -} - -el_val_t lsp_error_response(el_val_t id, el_val_t code, el_val_t message) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"jsonrpc\":\"2.0\",\"id\":"), id), EL_STR(",\"error\":{\"code\":")), int_to_str(code)), EL_STR(",\"message\":\"")), lsp_json_escape(message)), EL_STR("\"}}")); - return 0; -} - -el_val_t lsp_notification(el_val_t method, el_val_t params_json) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"jsonrpc\":\"2.0\",\"method\":\""), method), EL_STR("\",\"params\":")), params_json), EL_STR("}")); - return 0; -} - -el_val_t lsp_doc_key(el_val_t uri) { - return el_str_concat(EL_STR("doc:"), uri); - return 0; -} - -el_val_t lsp_doc_store(el_val_t uri, el_val_t text) { - state_set(lsp_doc_key(uri), text); - return 0; -} - -el_val_t lsp_doc_get(el_val_t uri) { - return state_get(lsp_doc_key(uri)); - return 0; -} - -el_val_t lsp_doc_remove(el_val_t uri) { - state_del(lsp_doc_key(uri)); - return 0; -} - -el_val_t lsp_builtin_catalog(void) { - el_val_t c = native_list_empty(); - c = native_list_append(c, EL_STR("println|println(s: String) -> Void|Print s followed by a newline to stdout.")); - c = native_list_append(c, EL_STR("print|print(s: String) -> Void|Print s to stdout without a newline.")); - c = native_list_append(c, EL_STR("readline|readline() -> String|Read one line from stdin (newline stripped).")); - c = native_list_append(c, EL_STR("str_eq|str_eq(a: String, b: String) -> Bool|Return true if a equals b.")); - c = native_list_append(c, EL_STR("str_len|str_len(s: String) -> Int|Return the byte length of s.")); - c = native_list_append(c, EL_STR("str_concat|str_concat(a: String, b: String) -> String|Concatenate a and b.")); - c = native_list_append(c, EL_STR("str_slice|str_slice(s: String, start: Int, end: Int) -> String|Substring [start, end).")); - c = native_list_append(c, EL_STR("str_contains|str_contains(s: String, sub: String) -> Bool|True if s contains sub.")); - c = native_list_append(c, EL_STR("str_starts_with|str_starts_with(s: String, prefix: String) -> Bool|True if s starts with prefix.")); - c = native_list_append(c, EL_STR("str_ends_with|str_ends_with(s: String, suffix: String) -> Bool|True if s ends with suffix.")); - c = native_list_append(c, EL_STR("str_replace|str_replace(s: String, from: String, to: String) -> String|Replace all occurrences of from with to.")); - c = native_list_append(c, EL_STR("str_to_upper|str_to_upper(s: String) -> String|Convert to uppercase.")); - c = native_list_append(c, EL_STR("str_to_lower|str_to_lower(s: String) -> String|Convert to lowercase.")); - c = native_list_append(c, EL_STR("str_trim|str_trim(s: String) -> String|Strip leading and trailing whitespace.")); - c = native_list_append(c, EL_STR("str_lstrip|str_lstrip(s: String) -> String|Strip leading whitespace.")); - c = native_list_append(c, EL_STR("str_rstrip|str_rstrip(s: String) -> String|Strip trailing whitespace.")); - c = native_list_append(c, EL_STR("str_index_of|str_index_of(s: String, sub: String) -> Int|First byte offset of sub, or -1.")); - c = native_list_append(c, EL_STR("str_last_index_of|str_last_index_of(s: String, sub: String) -> Int|Last byte offset of sub, or -1.")); - c = native_list_append(c, EL_STR("str_split|str_split(s: String, sep: String) -> [String]|Split on sep.")); - c = native_list_append(c, EL_STR("str_split_lines|str_split_lines(s: String) -> [String]|Split into lines.")); - c = native_list_append(c, EL_STR("str_split_n|str_split_n(s: String, sep: String, n: Int) -> [String]|Split at most n times.")); - c = native_list_append(c, EL_STR("str_join|str_join(parts: [String], sep: String) -> String|Join list with sep.")); - c = native_list_append(c, EL_STR("str_char_at|str_char_at(s: String, i: Int) -> String|Single character at byte index i.")); - c = native_list_append(c, EL_STR("str_char_code|str_char_code(s: String, i: Int) -> Int|Byte value at index i.")); - c = native_list_append(c, EL_STR("str_pad_left|str_pad_left(s: String, width: Int, pad: String) -> String|Pad on the left to width.")); - c = native_list_append(c, EL_STR("str_pad_right|str_pad_right(s: String, width: Int, pad: String) -> String|Pad on the right to width.")); - c = native_list_append(c, EL_STR("str_repeat|str_repeat(s: String, n: Int) -> String|Repeat s n times.")); - c = native_list_append(c, EL_STR("str_reverse|str_reverse(s: String) -> String|Reverse by codepoint.")); - c = native_list_append(c, EL_STR("str_strip_prefix|str_strip_prefix(s: String, prefix: String) -> String|Remove prefix if present.")); - c = native_list_append(c, EL_STR("str_strip_suffix|str_strip_suffix(s: String, suffix: String) -> String|Remove suffix if present.")); - c = native_list_append(c, EL_STR("str_strip_chars|str_strip_chars(s: String, chars: String) -> String|Strip chars from both ends.")); - c = native_list_append(c, EL_STR("str_count|str_count(s: String, sub: String) -> Int|Count non-overlapping occurrences.")); - c = native_list_append(c, EL_STR("str_count_lines|str_count_lines(s: String) -> Int|Number of lines.")); - c = native_list_append(c, EL_STR("str_find_chars|str_find_chars(s: String, any_of: String) -> Int|First index of any char in any_of.")); - c = native_list_append(c, EL_STR("str_index_of_all|str_index_of_all(s: String, sub: String) -> [Int]|All byte offsets of sub.")); - c = native_list_append(c, EL_STR("str_upper|str_upper(s: String) -> String|Convert to uppercase (alias).")); - c = native_list_append(c, EL_STR("str_lower|str_lower(s: String) -> String|Convert to lowercase (alias).")); - c = native_list_append(c, EL_STR("is_letter|is_letter(s: String) -> Bool|All ASCII letters.")); - c = native_list_append(c, EL_STR("is_digit|is_digit(s: String) -> Bool|All ASCII digits.")); - c = native_list_append(c, EL_STR("is_alphanumeric|is_alphanumeric(s: String) -> Bool|All ASCII alphanumeric.")); - c = native_list_append(c, EL_STR("is_whitespace|is_whitespace(s: String) -> Bool|All whitespace.")); - c = native_list_append(c, EL_STR("is_uppercase|is_uppercase(s: String) -> Bool|All uppercase ASCII.")); - c = native_list_append(c, EL_STR("is_lowercase|is_lowercase(s: String) -> Bool|All lowercase ASCII.")); - c = native_list_append(c, EL_STR("int_to_str|int_to_str(n: Int) -> String|Integer to decimal string.")); - c = native_list_append(c, EL_STR("str_to_int|str_to_int(s: String) -> Int|Parse decimal string to integer.")); - c = native_list_append(c, EL_STR("float_to_str|float_to_str(f: Float) -> String|Float to string.")); - c = native_list_append(c, EL_STR("str_to_float|str_to_float(s: String) -> Float|Parse string to float.")); - c = native_list_append(c, EL_STR("int_to_float|int_to_float(n: Int) -> Float|Integer to float.")); - c = native_list_append(c, EL_STR("float_to_int|float_to_int(f: Float) -> Int|Truncate float to integer.")); - c = native_list_append(c, EL_STR("format_float|format_float(f: Float, decimals: Int) -> String|Fixed decimal places.")); - c = native_list_append(c, EL_STR("decimal_round|decimal_round(f: Float, decimals: Int) -> Float|Round to N decimal places.")); - c = native_list_append(c, EL_STR("bool_to_str|bool_to_str(b: Bool) -> String|Bool to \"true\" or \"false\".")); - c = native_list_append(c, EL_STR("el_abs|el_abs(n: Int) -> Int|Absolute value.")); - c = native_list_append(c, EL_STR("el_max|el_max(a: Int, b: Int) -> Int|Maximum of two integers.")); - c = native_list_append(c, EL_STR("el_min|el_min(a: Int, b: Int) -> Int|Minimum of two integers.")); - c = native_list_append(c, EL_STR("math_sqrt|math_sqrt(f: Float) -> Float|Square root.")); - c = native_list_append(c, EL_STR("math_log|math_log(f: Float) -> Float|Base-10 logarithm.")); - c = native_list_append(c, EL_STR("math_ln|math_ln(f: Float) -> Float|Natural logarithm.")); - c = native_list_append(c, EL_STR("math_sin|math_sin(f: Float) -> Float|Sine (radians).")); - c = native_list_append(c, EL_STR("math_cos|math_cos(f: Float) -> Float|Cosine (radians).")); - c = native_list_append(c, EL_STR("math_pi|math_pi() -> Float|Value of pi.")); - c = native_list_append(c, EL_STR("el_list_empty|el_list_empty() -> [Any]|Create an empty list.")); - c = native_list_append(c, EL_STR("el_list_append|el_list_append(list: [Any], elem: Any) -> [Any]|Append and return updated list.")); - c = native_list_append(c, EL_STR("el_list_len|el_list_len(list: [Any]) -> Int|Number of elements.")); - c = native_list_append(c, EL_STR("el_list_get|el_list_get(list: [Any], index: Int) -> Any|Element at index.")); - c = native_list_append(c, EL_STR("el_list_clone|el_list_clone(list: [Any]) -> [Any]|Shallow copy.")); - c = native_list_append(c, EL_STR("list_push|list_push(list: [Any], elem: Any) -> [Any]|Append elem (alias).")); - c = native_list_append(c, EL_STR("list_push_front|list_push_front(list: [Any], elem: Any) -> [Any]|Prepend elem.")); - c = native_list_append(c, EL_STR("list_join|list_join(list: [Any], sep: String) -> String|Join list with sep.")); - c = native_list_append(c, EL_STR("list_range|list_range(start: Int, end: Int) -> [Int]|Integers from start to end-1.")); - c = native_list_append(c, EL_STR("el_map_get|el_map_get(map: Map, key: String) -> Any|Get by key.")); - c = native_list_append(c, EL_STR("el_map_set|el_map_set(map: Map, key: String, value: Any) -> Map|Set key.")); - c = native_list_append(c, EL_STR("el_get_field|el_get_field(map: Map, key: String) -> Any|Get field.")); - c = native_list_append(c, EL_STR("state_set|state_set(key: String, value: String) -> Void|Store in process state.")); - c = native_list_append(c, EL_STR("state_get|state_get(key: String) -> String|Retrieve from process state, empty if absent.")); - c = native_list_append(c, EL_STR("state_del|state_del(key: String) -> Void|Delete from process state.")); - c = native_list_append(c, EL_STR("state_keys|state_keys() -> [String]|All keys in process state.")); - c = native_list_append(c, EL_STR("json_get|json_get(json: String, key: String) -> String|Get string field from JSON object.")); - c = native_list_append(c, EL_STR("json_get_string|json_get_string(json: String, key: String) -> String|Get string field.")); - c = native_list_append(c, EL_STR("json_get_int|json_get_int(json: String, key: String) -> Int|Get integer field.")); - c = native_list_append(c, EL_STR("json_get_float|json_get_float(json: String, key: String) -> Float|Get float field.")); - c = native_list_append(c, EL_STR("json_get_bool|json_get_bool(json: String, key: String) -> Bool|Get boolean field.")); - c = native_list_append(c, EL_STR("json_get_raw|json_get_raw(json: String, key: String) -> String|Get raw JSON fragment.")); - c = native_list_append(c, EL_STR("json_set|json_set(json: String, key: String, value: String) -> String|Set key in JSON object.")); - c = native_list_append(c, EL_STR("json_parse|json_parse(s: String) -> String|Parse and validate JSON.")); - c = native_list_append(c, EL_STR("json_stringify|json_stringify(v: Any) -> String|Serialize to JSON.")); - c = native_list_append(c, EL_STR("json_array_len|json_array_len(json: String) -> Int|JSON array length.")); - c = native_list_append(c, EL_STR("json_array_get|json_array_get(json: String, index: Int) -> String|JSON array element.")); - c = native_list_append(c, EL_STR("json_array_get_string|json_array_get_string(json: String, index: Int) -> String|String element at index.")); - c = native_list_append(c, EL_STR("fs_read|fs_read(path: String) -> String|Read file contents.")); - c = native_list_append(c, EL_STR("fs_write|fs_write(path: String, content: String) -> Bool|Write file.")); - c = native_list_append(c, EL_STR("fs_list|fs_list(path: String) -> [String]|List directory entries.")); - c = native_list_append(c, EL_STR("fs_exists|fs_exists(path: String) -> Bool|True if path exists.")); - c = native_list_append(c, EL_STR("fs_mkdir|fs_mkdir(path: String) -> Bool|Create directory (mkdir -p).")); - c = native_list_append(c, EL_STR("http_get|http_get(url: String) -> String|HTTP GET, return response body.")); - c = native_list_append(c, EL_STR("http_post|http_post(url: String, body: String) -> String|HTTP POST with plain body.")); - c = native_list_append(c, EL_STR("http_post_json|http_post_json(url: String, json_body: String) -> String|HTTP POST with JSON.")); - c = native_list_append(c, EL_STR("http_get_with_headers|http_get_with_headers(url: String, headers: Map) -> String|GET with headers.")); - c = native_list_append(c, EL_STR("http_post_with_headers|http_post_with_headers(url: String, body: String, headers: Map) -> String|POST with headers.")); - c = native_list_append(c, EL_STR("http_serve|http_serve(port: Int, handler: Any) -> Void|Start HTTP server.")); - c = native_list_append(c, EL_STR("http_serve_v2|http_serve_v2(port: Int, handler: Any) -> Void|Start HTTP server v2 (method,path,headers,body).")); - c = native_list_append(c, EL_STR("http_response|http_response(status: Int, headers_json: String, body: String) -> String|Build HTTP response envelope.")); - c = native_list_append(c, EL_STR("url_encode|url_encode(s: String) -> String|URL-encode (RFC 3986).")); - c = native_list_append(c, EL_STR("url_decode|url_decode(s: String) -> String|URL-decode.")); - c = native_list_append(c, EL_STR("time_now|time_now() -> String|Current local time as ISO 8601.")); - c = native_list_append(c, EL_STR("time_now_utc|time_now_utc() -> String|Current UTC time as ISO 8601.")); - c = native_list_append(c, EL_STR("sleep_secs|sleep_secs(secs: Int) -> Void|Sleep N seconds.")); - c = native_list_append(c, EL_STR("sleep_ms|sleep_ms(ms: Int) -> Void|Sleep N milliseconds.")); - c = native_list_append(c, EL_STR("time_format|time_format(ts: String, fmt: String) -> String|Format timestamp.")); - c = native_list_append(c, EL_STR("time_add|time_add(ts: String, n: Int, unit: String) -> String|Add time to timestamp.")); - c = native_list_append(c, EL_STR("time_diff|time_diff(ts1: String, ts2: String, unit: String) -> Int|Diff two timestamps.")); - c = native_list_append(c, EL_STR("now|now() -> Instant|Current time as Instant.")); - c = native_list_append(c, EL_STR("unix_seconds|unix_seconds(n: Int) -> Instant|Instant from Unix seconds.")); - c = native_list_append(c, EL_STR("unix_millis|unix_millis(n: Int) -> Instant|Instant from Unix milliseconds.")); - c = native_list_append(c, EL_STR("uuid_new|uuid_new() -> String|Random UUID v4.")); - c = native_list_append(c, EL_STR("uuid_v4|uuid_v4() -> String|Random UUID v4 (alias).")); - c = native_list_append(c, EL_STR("env|env(key: String) -> String|Read environment variable.")); - c = native_list_append(c, EL_STR("args|args() -> [String]|Command-line arguments.")); - c = native_list_append(c, EL_STR("exit_program|exit_program(code: Int) -> Void|Exit with code.")); - c = native_list_append(c, EL_STR("exec_command|exec_command(cmd: String) -> Int|Run shell command, return exit code.")); - c = native_list_append(c, EL_STR("exec_capture|exec_capture(cmd: String) -> String|Run shell command, capture stdout.")); - c = native_list_append(c, EL_STR("sha256_hex|sha256_hex(input: String) -> String|SHA-256 as lowercase hex.")); - c = native_list_append(c, EL_STR("sha256_bytes|sha256_bytes(input: String) -> String|SHA-256 as raw bytes.")); - c = native_list_append(c, EL_STR("hmac_sha256_hex|hmac_sha256_hex(key: String, message: String) -> String|HMAC-SHA-256 hex.")); - c = native_list_append(c, EL_STR("base64_encode|base64_encode(input: String) -> String|Base64 encode.")); - c = native_list_append(c, EL_STR("base64_decode|base64_decode(input: String) -> String|Base64 decode.")); - c = native_list_append(c, EL_STR("base64url_encode|base64url_encode(input: String) -> String|URL-safe base64 encode.")); - c = native_list_append(c, EL_STR("base64url_decode|base64url_decode(input: String) -> String|URL-safe base64 decode.")); - c = native_list_append(c, EL_STR("llm_call|llm_call(model: String, prompt: String) -> String|LLM with user prompt.")); - c = native_list_append(c, EL_STR("llm_call_system|llm_call_system(model: String, system: String, user: String) -> String|LLM with system + user.")); - c = native_list_append(c, EL_STR("llm_call_agentic|llm_call_agentic(model: String, system: String, user: String, tools: String) -> String|Agentic LLM.")); - c = native_list_append(c, EL_STR("llm_vision|llm_vision(model: String, system: String, prompt: String, image: String) -> String|LLM with image.")); - c = native_list_append(c, EL_STR("llm_models|llm_models() -> String|List available LLM models.")); - c = native_list_append(c, EL_STR("llm_register_tool|llm_register_tool(name: String, handler_fn: String) -> Void|Register tool.")); - c = native_list_append(c, EL_STR("engram_node|engram_node(content: String, node_type: String, salience: Float) -> String|Create engram node.")); - c = native_list_append(c, EL_STR("engram_get_node|engram_get_node(id: String) -> Map|Get node by ID.")); - c = native_list_append(c, EL_STR("engram_strengthen|engram_strengthen(node_id: String) -> Void|Increase salience.")); - c = native_list_append(c, EL_STR("engram_forget|engram_forget(node_id: String) -> Void|Remove node.")); - c = native_list_append(c, EL_STR("engram_search|engram_search(query: String, limit: Int) -> [Map]|Semantic search.")); - c = native_list_append(c, EL_STR("engram_connect|engram_connect(from: String, to: String, weight: Float, rel: String) -> Void|Connect nodes.")); - c = native_list_append(c, EL_STR("engram_activate|engram_activate(query: String, depth: Int) -> [Map]|Activate nodes.")); - c = native_list_append(c, EL_STR("engram_save|engram_save(path: String) -> Bool|Save to file.")); - c = native_list_append(c, EL_STR("engram_load|engram_load(path: String) -> Bool|Load from file.")); - c = native_list_append(c, EL_STR("engram_node_count|engram_node_count() -> Int|Total nodes.")); - c = native_list_append(c, EL_STR("engram_edge_count|engram_edge_count() -> Int|Total edges.")); - c = native_list_append(c, EL_STR("engram_neighbors|engram_neighbors(node_id: String) -> [Map]|Neighboring nodes.")); - c = native_list_append(c, EL_STR("engram_search_json|engram_search_json(query: String, limit: Int) -> String|Search as JSON.")); - c = native_list_append(c, EL_STR("engram_stats_json|engram_stats_json() -> String|Graph stats as JSON.")); - c = native_list_append(c, EL_STR("dharma_connect|dharma_connect(cgi_id: String) -> Bool|Connect to peer CGI.")); - c = native_list_append(c, EL_STR("dharma_send|dharma_send(channel: String, content: String) -> String|Send to channel.")); - c = native_list_append(c, EL_STR("dharma_activate|dharma_activate(query: String) -> String|Activate across network.")); - c = native_list_append(c, EL_STR("dharma_emit|dharma_emit(event_type: String, payload: String) -> Void|Emit network event.")); - c = native_list_append(c, EL_STR("dharma_field|dharma_field(event_type: String) -> String|Block until event.")); - c = native_list_append(c, EL_STR("dharma_peers|dharma_peers() -> [String]|Connected peer IDs.")); - c = native_list_append(c, EL_STR("native_list_empty|native_list_empty() -> [Any]|Empty list (VM alias).")); - c = native_list_append(c, EL_STR("native_list_append|native_list_append(list: [Any], elem: Any) -> [Any]|Append (VM alias).")); - c = native_list_append(c, EL_STR("native_list_len|native_list_len(list: [Any]) -> Int|Length (VM alias).")); - c = native_list_append(c, EL_STR("native_list_get|native_list_get(list: [Any], i: Int) -> Any|Get element (VM alias).")); - c = native_list_append(c, EL_STR("native_list_clone|native_list_clone(list: [Any]) -> [Any]|Clone (VM alias).")); - c = native_list_append(c, EL_STR("native_string_chars|native_string_chars(s: String) -> [String]|Split into chars.")); - c = native_list_append(c, EL_STR("native_int_to_str|native_int_to_str(n: Int) -> String|Int to string (VM alias).")); - return c; - return 0; -} - -el_val_t lsp_builtin_find(el_val_t name, el_val_t catalog) { - el_val_t n = native_list_len(catalog); - el_val_t i = 0; - while (i < n) { - el_val_t entry = native_list_get(catalog, i); - el_val_t bar = str_index_of(entry, EL_STR("|")); - if (bar >= 0) { - el_val_t ename = str_slice(entry, 0, bar); - if (str_eq(ename, name)) { - return entry; - } - } - i = (i + 1); - } - return EL_STR(""); - return 0; -} - -el_val_t lsp_types_key(el_val_t uri, el_val_t type_name) { - return el_str_concat(el_str_concat(el_str_concat(EL_STR("types:"), uri), EL_STR(":")), type_name); - return 0; -} - -el_val_t lsp_vartypes_key(el_val_t uri) { - return el_str_concat(EL_STR("vartypes:"), uri); - return 0; -} - -el_val_t lsp_scan_types(el_val_t uri, el_val_t source) { - el_val_t lines = str_split_lines(source); - el_val_t n = native_list_len(lines); - el_val_t i = 0; - el_val_t in_type = 0; - el_val_t cur_type = EL_STR(""); - el_val_t fields = EL_STR(""); - while (i < n) { - el_val_t line = str_trim(native_list_get(lines, i)); - if (in_type) { - if (str_starts_with(line, EL_STR("}"))) { - state_set(lsp_types_key(uri, cur_type), fields); - in_type = 0; - cur_type = EL_STR(""); - fields = EL_STR(""); - } else { - el_val_t colon_pos = str_index_of(line, EL_STR(":")); - if (colon_pos > 0) { - el_val_t raw_name = str_trim(str_slice(line, 0, colon_pos)); - el_val_t after_colon = str_trim(str_slice(line, (colon_pos + 1), str_len(line))); - el_val_t type_name = after_colon; - el_val_t tlen = str_len(after_colon); - if (tlen > 0) { - el_val_t last_ch = str_slice(after_colon, (tlen - 1), tlen); - if (str_eq(last_ch, EL_STR(","))) { - type_name = str_trim(str_slice(after_colon, 0, (tlen - 1))); - } - } - if (str_len(raw_name) > 0) { - el_val_t fc = str_char_code(raw_name, 0); - el_val_t valid_start = 0; - if (fc >= 97) { - if (fc <= 122) { - valid_start = 1; - } - } - if (fc >= 65) { - if (fc <= 90) { - valid_start = 1; - } - } - if (fc == 95) { - valid_start = 1; - } - if (valid_start) { - if (str_len(fields) > 0) { - fields = el_str_concat(fields, EL_STR("|")); - } - fields = el_str_concat(el_str_concat(el_str_concat(fields, raw_name), EL_STR(":")), type_name); - } - } - } - } - } else { - if (str_starts_with(line, EL_STR("type "))) { - el_val_t after = str_slice(line, 5, str_len(line)); - el_val_t brace_pos = str_index_of(after, EL_STR("{")); - if (brace_pos > 0) { - el_val_t tname = str_trim(str_slice(after, 0, brace_pos)); - if (str_len(tname) > 0) { - in_type = 1; - cur_type = tname; - fields = EL_STR(""); - } - } - } - } - i = (i + 1); - } - return 0; -} - -el_val_t lsp_get_type_fields(el_val_t uri, el_val_t type_name) { - return state_get(lsp_types_key(uri, type_name)); - return 0; -} - -el_val_t lsp_varentry_name(el_val_t entry) { - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon <= 0) { - return EL_STR(""); - } - return str_slice(entry, 0, colon); - return 0; -} - -el_val_t lsp_varentry_type(el_val_t entry) { - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon < 0) { - return EL_STR(""); - } - return str_slice(entry, (colon + 1), str_len(entry)); - return 0; -} - -el_val_t lsp_scan_vartypes(el_val_t uri, el_val_t source) { - el_val_t lines = str_split_lines(source); - el_val_t n = native_list_len(lines); - el_val_t i = 0; - el_val_t entries = EL_STR(""); - while (i < n) { - el_val_t line = str_trim(native_list_get(lines, i)); - if (str_starts_with(line, EL_STR("let "))) { - el_val_t after_let = str_slice(line, 4, str_len(line)); - el_val_t colon_pos = str_index_of(after_let, EL_STR(":")); - if (colon_pos > 0) { - el_val_t var_name = str_trim(str_slice(after_let, 0, colon_pos)); - el_val_t after_colon = str_trim(str_slice(after_let, (colon_pos + 1), str_len(after_let))); - el_val_t eq_pos = str_index_of(after_colon, EL_STR("=")); - el_val_t raw_type = after_colon; - if (eq_pos > 0) { - raw_type = str_trim(str_slice(after_colon, 0, eq_pos)); - } else { - el_val_t sp_pos = str_index_of(after_colon, EL_STR(" ")); - if (sp_pos > 0) { - raw_type = str_trim(str_slice(after_colon, 0, sp_pos)); - } - } - if (str_len(var_name) > 0) { - if (str_len(raw_type) > 0) { - if (str_len(entries) > 0) { - entries = el_str_concat(entries, EL_STR("|")); - } - entries = el_str_concat(el_str_concat(el_str_concat(entries, var_name), EL_STR(":")), raw_type); - } - } - } - } - if (str_starts_with(line, EL_STR("fn "))) { - el_val_t paren_open = str_index_of(line, EL_STR("(")); - el_val_t paren_close = str_last_index_of(line, EL_STR(")")); - if (paren_open > 0) { - if (paren_close > paren_open) { - el_val_t params_str = str_slice(line, (paren_open + 1), paren_close); - el_val_t params = str_split(params_str, EL_STR(",")); - el_val_t pn = native_list_len(params); - el_val_t pi = 0; - while (pi < pn) { - el_val_t param = str_trim(native_list_get(params, pi)); - el_val_t pc = str_index_of(param, EL_STR(":")); - if (pc > 0) { - el_val_t pname = str_trim(str_slice(param, 0, pc)); - el_val_t ptype = str_trim(str_slice(param, (pc + 1), str_len(param))); - if (str_len(pname) > 0) { - if (str_len(ptype) > 0) { - if (str_len(entries) > 0) { - entries = el_str_concat(entries, EL_STR("|")); - } - entries = el_str_concat(el_str_concat(el_str_concat(entries, pname), EL_STR(":")), ptype); - } - } - } - pi = (pi + 1); - } - } - } - } - i = (i + 1); - } - state_set(lsp_vartypes_key(uri), entries); - return 0; -} - -el_val_t lsp_get_var_type(el_val_t uri, el_val_t var_name) { - el_val_t entries = state_get(lsp_vartypes_key(uri)); - if (str_eq(entries, EL_STR(""))) { - return EL_STR(""); - } - el_val_t parts = str_split(entries, EL_STR("|")); - el_val_t n = native_list_len(parts); - el_val_t i = 0; - while (i < n) { - el_val_t entry = native_list_get(parts, i); - el_val_t ename = lsp_varentry_name(entry); - if (str_eq(ename, var_name)) { - return lsp_varentry_type(entry); - } - i = (i + 1); - } - return EL_STR(""); - return 0; -} - -el_val_t lsp_scan_document(el_val_t uri, el_val_t source) { - lsp_scan_types(uri, source); - lsp_scan_vartypes(uri, source); - return 0; -} - -el_val_t lsp_dot_ident_before(el_val_t text) { - el_val_t tlen = str_len(text); - if (tlen < 2) { - return EL_STR(""); - } - el_val_t last_ch = str_slice(text, (tlen - 1), tlen); - if (!str_eq(last_ch, EL_STR("."))) { - return EL_STR(""); - } - el_val_t dot_pos = (tlen - 1); - el_val_t end_idx = dot_pos; - el_val_t start_idx = dot_pos; - el_val_t going = 1; - while (going) { - if (start_idx <= 0) { - going = 0; - } else { - el_val_t c = str_char_code(text, (start_idx - 1)); - el_val_t is_word = 0; - if (c >= 97) { - if (c <= 122) { - is_word = 1; - } - } - if (c >= 65) { - if (c <= 90) { - is_word = 1; - } - } - if (c >= 48) { - if (c <= 57) { - is_word = 1; - } - } - if (c == 95) { - is_word = 1; - } - if (is_word) { - start_idx = (start_idx - 1); - } else { - going = 0; - } - } - } - if (start_idx >= end_idx) { - return EL_STR(""); - } - return str_slice(text, start_idx, end_idx); - return 0; -} - -el_val_t lsp_line_prefix(el_val_t source, el_val_t line_no, el_val_t char_no) { - el_val_t lines = str_split_lines(source); - if (line_no >= native_list_len(lines)) { - return EL_STR(""); - } - el_val_t line = native_list_get(lines, line_no); - el_val_t line_len = str_len(line); - el_val_t end = char_no; - if (end > line_len) { - end = line_len; - } - return str_slice(line, 0, end); - return 0; -} - -el_val_t lsp_field_completions(el_val_t uri, el_val_t type_name) { - el_val_t fields_str = lsp_get_type_fields(uri, type_name); - if (str_eq(fields_str, EL_STR(""))) { - return EL_STR(""); - } - el_val_t field_entries = str_split(fields_str, EL_STR("|")); - el_val_t n = native_list_len(field_entries); - el_val_t items = native_list_empty(); - el_val_t i = 0; - while (i < n) { - el_val_t entry = native_list_get(field_entries, i); - el_val_t colon = str_index_of(entry, EL_STR(":")); - if (colon > 0) { - el_val_t fname = str_slice(entry, 0, colon); - el_val_t ftype = str_slice(entry, (colon + 1), str_len(entry)); - items = native_list_append(items, lsp_completion_item(fname, 5, ftype)); - } - i = (i + 1); - } - return el_str_concat(el_str_concat(EL_STR("["), str_join(items, EL_STR(","))), EL_STR("]")); - return 0; -} - -el_val_t lsp_extract_fns(el_val_t source) { - el_val_t result = native_list_empty(); - el_val_t lines = str_split_lines(source); - el_val_t n = native_list_len(lines); - el_val_t i = 0; - while (i < n) { - el_val_t line = str_trim(native_list_get(lines, i)); - if (str_starts_with(line, EL_STR("fn "))) { - el_val_t after = str_slice(line, 3, str_len(line)); - el_val_t paren = str_index_of(after, EL_STR("(")); - if (paren > 0) { - el_val_t name = str_trim(str_slice(after, 0, paren)); - if (str_len(name) > 0) { - result = native_list_append(result, name); - } - } - } - i = (i + 1); - } - return result; - return 0; -} - -el_val_t lsp_find_def(el_val_t source, el_val_t fn_name) { - el_val_t lines = str_split_lines(source); - el_val_t n = native_list_len(lines); - el_val_t target1 = el_str_concat(el_str_concat(EL_STR("fn "), fn_name), EL_STR("(")); - el_val_t target2 = el_str_concat(el_str_concat(EL_STR("fn "), fn_name), EL_STR(" (")); - el_val_t i = 0; - while (i < n) { - el_val_t line = native_list_get(lines, i); - el_val_t trimmed = str_trim(line); - if (str_starts_with(trimmed, target1)) { - el_val_t col = str_index_of(line, target1); - if (col < 0) { - col = 0; - } - return el_str_concat(el_str_concat(int_to_str(i), EL_STR(":")), int_to_str(col)); - } - if (str_starts_with(trimmed, target2)) { - el_val_t col = str_index_of(line, target2); - if (col < 0) { - col = 0; - } - return el_str_concat(el_str_concat(int_to_str(i), EL_STR(":")), int_to_str(col)); - } - i = (i + 1); - } - return EL_STR(""); - return 0; -} - -el_val_t lsp_word_at(el_val_t source, el_val_t line_no, el_val_t char_no) { - el_val_t lines = str_split_lines(source); - if (line_no >= native_list_len(lines)) { - return EL_STR(""); - } - el_val_t line = native_list_get(lines, line_no); - el_val_t line_len = str_len(line); - if (char_no >= line_len) { - return EL_STR(""); - } - el_val_t start = char_no; - el_val_t going_back = 1; - while (going_back) { - if (start <= 0) { - going_back = 0; - } else { - el_val_t c = str_char_code(line, (start - 1)); - el_val_t is_word = 0; - if (c >= 97) { - if (c <= 122) { - is_word = 1; - } - } - if (c >= 65) { - if (c <= 90) { - is_word = 1; - } - } - if (c >= 48) { - if (c <= 57) { - is_word = 1; - } - } - if (c == 95) { - is_word = 1; - } - if (is_word) { - start = (start - 1); - } else { - going_back = 0; - } - } - } - el_val_t end = char_no; - el_val_t going_fwd = 1; - while (going_fwd) { - if (end >= line_len) { - going_fwd = 0; - } else { - el_val_t c = str_char_code(line, end); - el_val_t is_word = 0; - if (c >= 97) { - if (c <= 122) { - is_word = 1; - } - } - if (c >= 65) { - if (c <= 90) { - is_word = 1; - } - } - if (c >= 48) { - if (c <= 57) { - is_word = 1; - } - } - if (c == 95) { - is_word = 1; - } - if (is_word) { - end = (end + 1); - } else { - going_fwd = 0; - } - } - } - if (end <= start) { - return EL_STR(""); - } - return str_slice(line, start, end); - return 0; -} - -el_val_t lsp_completion_item(el_val_t label, el_val_t kind, el_val_t detail) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"label\":\""), lsp_json_escape(label)), EL_STR("\",\"kind\":")), int_to_str(kind)), EL_STR(",\"detail\":\"")), lsp_json_escape(detail)), EL_STR("\"}")); - return 0; -} - -el_val_t lsp_build_completions(el_val_t uri, el_val_t catalog, el_val_t line_no, el_val_t char_no) { - el_val_t source = lsp_doc_get(uri); - el_val_t prefix = lsp_line_prefix(source, line_no, char_no); - el_val_t dot_ident = lsp_dot_ident_before(prefix); - if (!str_eq(dot_ident, EL_STR(""))) { - el_val_t var_type = lsp_get_var_type(uri, dot_ident); - if (!str_eq(var_type, EL_STR(""))) { - el_val_t field_items = lsp_field_completions(uri, var_type); - if (!str_eq(field_items, EL_STR(""))) { - return field_items; - } - } - } - el_val_t items = native_list_empty(); - el_val_t user_fns = lsp_extract_fns(source); - el_val_t fn_n = native_list_len(user_fns); - el_val_t i = 0; - while (i < fn_n) { - el_val_t name = native_list_get(user_fns, i); - items = native_list_append(items, lsp_completion_item(name, 3, EL_STR("user-defined fn"))); - i = (i + 1); - } - el_val_t bn = native_list_len(catalog); - el_val_t j = 0; - while (j < bn) { - el_val_t entry = native_list_get(catalog, j); - el_val_t bar1 = str_index_of(entry, EL_STR("|")); - if (bar1 >= 0) { - el_val_t bname = str_slice(entry, 0, bar1); - el_val_t rest = str_slice(entry, (bar1 + 1), str_len(entry)); - el_val_t bar2 = str_index_of(rest, EL_STR("|")); - el_val_t sig = EL_STR(""); - if (bar2 >= 0) { - sig = str_slice(rest, 0, bar2); - } else { - sig = rest; - } - items = native_list_append(items, lsp_completion_item(bname, 3, sig)); - } - j = (j + 1); - } - el_val_t kws = native_list_empty(); - kws = native_list_append(kws, EL_STR("fn")); - kws = native_list_append(kws, EL_STR("let")); - kws = native_list_append(kws, EL_STR("return")); - kws = native_list_append(kws, EL_STR("if")); - kws = native_list_append(kws, EL_STR("else")); - kws = native_list_append(kws, EL_STR("while")); - kws = native_list_append(kws, EL_STR("for")); - kws = native_list_append(kws, EL_STR("in")); - kws = native_list_append(kws, EL_STR("true")); - kws = native_list_append(kws, EL_STR("false")); - kws = native_list_append(kws, EL_STR("import")); - kws = native_list_append(kws, EL_STR("match")); - kws = native_list_append(kws, EL_STR("break")); - kws = native_list_append(kws, EL_STR("continue")); - el_val_t kw_n = native_list_len(kws); - el_val_t k = 0; - while (k < kw_n) { - el_val_t kw = native_list_get(kws, k); - items = native_list_append(items, lsp_completion_item(kw, 14, EL_STR("keyword"))); - k = (k + 1); - } - el_val_t types = native_list_empty(); - types = native_list_append(types, EL_STR("String")); - types = native_list_append(types, EL_STR("Int")); - types = native_list_append(types, EL_STR("Bool")); - types = native_list_append(types, EL_STR("Float")); - types = native_list_append(types, EL_STR("Void")); - types = native_list_append(types, EL_STR("Any")); - types = native_list_append(types, EL_STR("Instant")); - types = native_list_append(types, EL_STR("Duration")); - el_val_t t_n = native_list_len(types); - el_val_t t = 0; - while (t < t_n) { - el_val_t ty = native_list_get(types, t); - items = native_list_append(items, lsp_completion_item(ty, 8, EL_STR("type"))); - t = (t + 1); - } - return el_str_concat(el_str_concat(EL_STR("["), str_join(items, EL_STR(","))), EL_STR("]")); - return 0; -} - -el_val_t lsp_keyword_hover(el_val_t word) { - if (str_eq(word, EL_STR("fn"))) { - return EL_STR("Declare a function:\n```el\nfn name(param: Type) -> ReturnType { ... }\n```"); - } - if (str_eq(word, EL_STR("let"))) { - return EL_STR("Bind a local variable:\n```el\nlet name: Type = value\n```"); - } - if (str_eq(word, EL_STR("return"))) { - return EL_STR("Return a value from a function."); - } - if (str_eq(word, EL_STR("if"))) { - return EL_STR("Conditional:\n```el\nif condition { ... } else { ... }\n```"); - } - if (str_eq(word, EL_STR("else"))) { - return EL_STR("Else branch of an if statement."); - } - if (str_eq(word, EL_STR("while"))) { - return EL_STR("Loop while condition is true:\n```el\nwhile condition { ... }\n```"); - } - if (str_eq(word, EL_STR("for"))) { - return EL_STR("Range loop:\n```el\nfor i in 0..n { ... }\n```"); - } - if (str_eq(word, EL_STR("in"))) { - return EL_STR("Used in for-in range loops."); - } - if (str_eq(word, EL_STR("true"))) { - return EL_STR("Boolean literal true."); - } - if (str_eq(word, EL_STR("false"))) { - return EL_STR("Boolean literal false."); - } - if (str_eq(word, EL_STR("import"))) { - return EL_STR("Import a module:\n```el\nimport \"path/to/module.el\"\n```"); - } - if (str_eq(word, EL_STR("match"))) { - return EL_STR("Pattern match:\n```el\nmatch value { \"a\" => ... }\n```"); - } - if (str_eq(word, EL_STR("break"))) { - return EL_STR("Break out of the current while loop."); - } - if (str_eq(word, EL_STR("continue"))) { - return EL_STR("Skip to the next iteration of the current while loop."); - } - if (str_eq(word, EL_STR("String"))) { - return EL_STR("Built-in string type. Strings are immutable byte sequences."); - } - if (str_eq(word, EL_STR("Int"))) { - return EL_STR("Built-in 64-bit signed integer type."); - } - if (str_eq(word, EL_STR("Bool"))) { - return EL_STR("Built-in boolean type. Values: true or false."); - } - if (str_eq(word, EL_STR("Float"))) { - return EL_STR("Built-in 64-bit floating-point type (IEEE 754 double)."); - } - if (str_eq(word, EL_STR("Void"))) { - return EL_STR("Return type for functions that produce no value."); - } - if (str_eq(word, EL_STR("Any"))) { - return EL_STR("Dynamically typed value \xe2\x80\x94 accepts any El type."); - } - return EL_STR(""); - return 0; -} - -el_val_t lsp_build_hover(el_val_t uri, el_val_t line_no, el_val_t char_no, el_val_t catalog) { - el_val_t source = lsp_doc_get(uri); - el_val_t word = lsp_word_at(source, line_no, char_no); - if (str_eq(word, EL_STR(""))) { - return EL_STR("null"); - } - el_val_t kw_doc = lsp_keyword_hover(word); - if (!str_eq(kw_doc, EL_STR(""))) { - el_val_t content = el_str_concat(el_str_concat(el_str_concat(EL_STR("**"), word), EL_STR("** (keyword)\n\n")), kw_doc); - return el_str_concat(el_str_concat(EL_STR("{\"contents\":{\"kind\":\"markdown\",\"value\":\""), lsp_json_escape(content)), EL_STR("\"}}")); - } - el_val_t entry = lsp_builtin_find(word, catalog); - if (!str_eq(entry, EL_STR(""))) { - el_val_t bar1 = str_index_of(entry, EL_STR("|")); - el_val_t rest = str_slice(entry, (bar1 + 1), str_len(entry)); - el_val_t bar2 = str_index_of(rest, EL_STR("|")); - el_val_t sig = EL_STR(""); - el_val_t desc = EL_STR(""); - if (bar2 >= 0) { - sig = str_slice(rest, 0, bar2); - desc = str_slice(rest, (bar2 + 1), str_len(rest)); - } else { - sig = rest; - } - el_val_t content = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("**"), word), EL_STR("** (builtin)\n\n```el\n")), sig), EL_STR("\n```\n\n")), desc); - return el_str_concat(el_str_concat(EL_STR("{\"contents\":{\"kind\":\"markdown\",\"value\":\""), lsp_json_escape(content)), EL_STR("\"}}")); - } - el_val_t user_fns = lsp_extract_fns(source); - el_val_t uf_n = native_list_len(user_fns); - el_val_t i = 0; - while (i < uf_n) { - el_val_t fn_name = native_list_get(user_fns, i); - if (str_eq(fn_name, word)) { - el_val_t lines = str_split_lines(source); - el_val_t ln = native_list_len(lines); - el_val_t j = 0; - while (j < ln) { - el_val_t line = str_trim(native_list_get(lines, j)); - if (str_starts_with(line, el_str_concat(el_str_concat(EL_STR("fn "), word), EL_STR("(")))) { - el_val_t content = el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("**"), word), EL_STR("** (user-defined)\n\n```el\n")), line), EL_STR("\n```")); - return el_str_concat(el_str_concat(EL_STR("{\"contents\":{\"kind\":\"markdown\",\"value\":\""), lsp_json_escape(content)), EL_STR("\"}}")); - } - j = (j + 1); - } - el_val_t content = el_str_concat(el_str_concat(EL_STR("**"), word), EL_STR("** (user-defined function)")); - return el_str_concat(el_str_concat(EL_STR("{\"contents\":{\"kind\":\"markdown\",\"value\":\""), lsp_json_escape(content)), EL_STR("\"}}")); - } - i = (i + 1); - } - return EL_STR("null"); - return 0; -} - -el_val_t lsp_build_definition(el_val_t uri, el_val_t line_no, el_val_t char_no) { - el_val_t source = lsp_doc_get(uri); - el_val_t word = lsp_word_at(source, line_no, char_no); - if (str_eq(word, EL_STR(""))) { - return EL_STR("null"); - } - el_val_t pos_str = lsp_find_def(source, word); - if (str_eq(pos_str, EL_STR(""))) { - return EL_STR("null"); - } - el_val_t colon = str_index_of(pos_str, EL_STR(":")); - if (colon < 0) { - return EL_STR("null"); - } - el_val_t def_line = str_to_int(str_slice(pos_str, 0, colon)); - el_val_t def_char = str_to_int(str_slice(pos_str, (colon + 1), str_len(pos_str))); - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"uri\":\""), lsp_json_escape(uri)), EL_STR("\",\"range\":{\"start\":{\"line\":")), int_to_str(def_line)), EL_STR(",\"character\":")), int_to_str(def_char)), EL_STR("},\"end\":{\"line\":")), int_to_str(def_line)), EL_STR(",\"character\":")), int_to_str((def_char + str_len(word)))), EL_STR("}}}")); - return 0; -} - -el_val_t lsp_make_diag(el_val_t line_no, el_val_t col_start, el_val_t col_end, el_val_t message, el_val_t severity) { - return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"range\":{\"start\":{\"line\":"), int_to_str(line_no)), EL_STR(",\"character\":")), int_to_str(col_start)), EL_STR("},\"end\":{\"line\":")), int_to_str(line_no)), EL_STR(",\"character\":")), int_to_str(col_end)), EL_STR("}},\"severity\":")), int_to_str(severity)), EL_STR(",\"source\":\"el-lsp\",\"message\":\"")), lsp_json_escape(message)), EL_STR("\"}")); - return 0; -} - -el_val_t lsp_compute_diagnostics(el_val_t source) { - el_val_t diags = native_list_empty(); - el_val_t lines = str_split_lines(source); - el_val_t n = native_list_len(lines); - el_val_t brace_depth = 0; - el_val_t paren_depth = 0; - el_val_t bracket_depth = 0; - el_val_t brace_line = 0; - el_val_t paren_line = 0; - el_val_t bracket_line = 0; - el_val_t i = 0; - while (i < n) { - el_val_t line = native_list_get(lines, i); - el_val_t line_len = str_len(line); - el_val_t in_str = 0; - el_val_t escape_next = 0; - el_val_t str_start = 0; - el_val_t ci = 0; - while (ci < line_len) { - el_val_t ch = str_char_code(line, ci); - if (escape_next) { - escape_next = 0; - } else { - if (ch == 92) { - if (in_str) { - escape_next = 1; - } - } else { - if (ch == 34) { - if (in_str) { - in_str = 0; - } else { - in_str = 1; - str_start = ci; - } - } else { - if (!in_str) { - if (ch == 123) { - brace_depth = (brace_depth + 1); - brace_line = i; - } - if (ch == 125) { - if (brace_depth > 0) { - brace_depth = (brace_depth - 1); - } else { - diags = native_list_append(diags, lsp_make_diag(i, ci, (ci + 1), EL_STR("Unexpected '}'"), 1)); - } - } - if (ch == 40) { - paren_depth = (paren_depth + 1); - paren_line = i; - } - if (ch == 41) { - if (paren_depth > 0) { - paren_depth = (paren_depth - 1); - } else { - diags = native_list_append(diags, lsp_make_diag(i, ci, (ci + 1), EL_STR("Unexpected ')'"), 1)); - } - } - if (ch == 91) { - bracket_depth = (bracket_depth + 1); - bracket_line = i; - } - if (ch == 93) { - if (bracket_depth > 0) { - bracket_depth = (bracket_depth - 1); - } else { - diags = native_list_append(diags, lsp_make_diag(i, ci, (ci + 1), EL_STR("Unexpected ']'"), 1)); - } - } - } - } - } - } - ci = (ci + 1); - } - if (in_str) { - diags = native_list_append(diags, lsp_make_diag(i, str_start, line_len, EL_STR("Unterminated string literal"), 1)); - } - i = (i + 1); - } - if (brace_depth > 0) { - diags = native_list_append(diags, lsp_make_diag(brace_line, 0, 1, EL_STR("Unclosed '{' (opened near this line)"), 1)); - } - if (paren_depth > 0) { - diags = native_list_append(diags, lsp_make_diag(paren_line, 0, 1, EL_STR("Unclosed '(' (opened near this line)"), 1)); - } - if (bracket_depth > 0) { - diags = native_list_append(diags, lsp_make_diag(bracket_line, 0, 1, EL_STR("Unclosed '[' (opened near this line)"), 1)); - } - return el_str_concat(el_str_concat(EL_STR("["), str_join(diags, EL_STR(","))), EL_STR("]")); - return 0; -} - -el_val_t lsp_publish_diagnostics(el_val_t uri) { - el_val_t source = lsp_doc_get(uri); - el_val_t diags = lsp_compute_diagnostics(source); - el_val_t notif = lsp_notification(EL_STR("textDocument/publishDiagnostics"), el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"uri\":\""), lsp_json_escape(uri)), EL_STR("\",\"diagnostics\":")), diags), EL_STR("}"))); - lsp_write_message(notif); - return 0; -} - -el_val_t lsp_handle_initialize(el_val_t id) { - el_val_t caps = EL_STR("{\"textDocumentSync\":1,\"completionProvider\":{\"triggerCharacters\":[\".\",\"_\",\"(\"]},\"hoverProvider\":true,\"definitionProvider\":true}"); - el_val_t result = el_str_concat(el_str_concat(EL_STR("{\"capabilities\":"), caps), EL_STR(",\"serverInfo\":{\"name\":\"el-lsp\",\"version\":\"1.0.0\"}}")); - lsp_write_message(lsp_response(id, result)); - return 0; -} - -el_val_t lsp_handle_completion(el_val_t id, el_val_t params, el_val_t catalog) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - el_val_t pos = json_get_raw(params, EL_STR("position")); - el_val_t line_no = json_get_int(pos, EL_STR("line")); - el_val_t char_no = json_get_int(pos, EL_STR("character")); - el_val_t items = lsp_build_completions(uri, catalog, line_no, char_no); - el_val_t result = el_str_concat(el_str_concat(EL_STR("{\"isIncomplete\":false,\"items\":"), items), EL_STR("}")); - lsp_write_message(lsp_response(id, result)); - return 0; -} - -el_val_t lsp_handle_hover(el_val_t id, el_val_t params, el_val_t catalog) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - el_val_t pos = json_get_raw(params, EL_STR("position")); - el_val_t line_no = json_get_int(pos, EL_STR("line")); - el_val_t char_no = json_get_int(pos, EL_STR("character")); - el_val_t result = lsp_build_hover(uri, line_no, char_no, catalog); - lsp_write_message(lsp_response(id, result)); - return 0; -} - -el_val_t lsp_handle_definition(el_val_t id, el_val_t params) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - el_val_t pos = json_get_raw(params, EL_STR("position")); - el_val_t line_no = json_get_int(pos, EL_STR("line")); - el_val_t char_no = json_get_int(pos, EL_STR("character")); - el_val_t result = lsp_build_definition(uri, line_no, char_no); - lsp_write_message(lsp_response(id, result)); - return 0; -} - -el_val_t lsp_handle_did_open(el_val_t params, el_val_t catalog) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - el_val_t text = json_get_string(td, EL_STR("text")); - lsp_doc_store(uri, text); - lsp_scan_document(uri, text); - lsp_publish_diagnostics(uri); - return 0; -} - -el_val_t lsp_handle_did_change(el_val_t params) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - el_val_t changes = json_get_raw(params, EL_STR("contentChanges")); - el_val_t first = json_array_get(changes, 0); - el_val_t text = json_get_string(first, EL_STR("text")); - lsp_doc_store(uri, text); - lsp_scan_document(uri, text); - lsp_publish_diagnostics(uri); - return 0; -} - -el_val_t lsp_handle_did_close(el_val_t params) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - lsp_doc_remove(uri); - el_val_t notif = lsp_notification(EL_STR("textDocument/publishDiagnostics"), el_str_concat(el_str_concat(EL_STR("{\"uri\":\""), lsp_json_escape(uri)), EL_STR("\",\"diagnostics\":[]}"))); - lsp_write_message(notif); - return 0; -} - -el_val_t lsp_handle_did_save(el_val_t params) { - el_val_t td = json_get_raw(params, EL_STR("textDocument")); - el_val_t uri = json_get_string(td, EL_STR("uri")); - lsp_publish_diagnostics(uri); - return 0; -} - -el_val_t lsp_handle_shutdown(el_val_t id) { - lsp_write_message(lsp_response(id, EL_STR("null"))); - return 0; -} - -el_val_t lsp_dispatch(el_val_t msg, el_val_t catalog) { - el_val_t method = json_get_string(msg, EL_STR("method")); - el_val_t id_raw = json_get_raw(msg, EL_STR("id")); - el_val_t id = id_raw; - if (str_eq(id, EL_STR(""))) { - id = EL_STR("null"); - } - el_val_t params_raw = json_get_raw(msg, EL_STR("params")); - el_val_t params = params_raw; - if (str_eq(params, EL_STR(""))) { - params = EL_STR("{}"); - } - if (str_eq(method, EL_STR("initialize"))) { - lsp_handle_initialize(id); - return 1; - } - if (str_eq(method, EL_STR("initialized"))) { - return 1; - } - if (str_eq(method, EL_STR("shutdown"))) { - lsp_handle_shutdown(id); - return 1; - } - if (str_eq(method, EL_STR("exit"))) { - return 0; - } - if (str_eq(method, EL_STR("textDocument/didOpen"))) { - lsp_handle_did_open(params, catalog); - return 1; - } - if (str_eq(method, EL_STR("textDocument/didChange"))) { - lsp_handle_did_change(params); - return 1; - } - if (str_eq(method, EL_STR("textDocument/didClose"))) { - lsp_handle_did_close(params); - return 1; - } - if (str_eq(method, EL_STR("textDocument/didSave"))) { - lsp_handle_did_save(params); - return 1; - } - if (str_eq(method, EL_STR("textDocument/completion"))) { - lsp_handle_completion(id, params, catalog); - return 1; - } - if (str_eq(method, EL_STR("textDocument/hover"))) { - lsp_handle_hover(id, params, catalog); - return 1; - } - if (str_eq(method, EL_STR("textDocument/definition"))) { - lsp_handle_definition(id, params); - return 1; - } - if (!str_eq(id, EL_STR("null"))) { - lsp_write_message(lsp_error_response(id, (-32601), el_str_concat(EL_STR("Method not found: "), method))); - } - return 1; - return 0; -} - -int main(int _argc, char** _argv) { - el_runtime_init_args(_argc, _argv); - el_val_t catalog = lsp_builtin_catalog(); - el_val_t running = 1; - while (running) { - el_val_t msg = lsp_read_message(); - if (str_eq(msg, EL_STR(""))) { - running = 0; - } else { - el_val_t cont = lsp_dispatch(msg, catalog); - if (!cont) { - running = 0; - } - } - } - return 0; -} - diff --git a/runtime/el/core.el b/runtime/el/core.el new file mode 100644 index 0000000..675297b --- /dev/null +++ b/runtime/el/core.el @@ -0,0 +1,52 @@ +// core.el — the math floor, rewritten in El (first principles). +// The constructor, the state space, ordered roles — the same relatives +// the substrate was verified with, now expressed in the language itself. + +// term: a structural value is an atom "0"|"1" or a list ["R", a, b] +fn atom0() -> [String] { return ["0"] } +fn atom1() -> [String] { return ["1"] } +fn is_atom(t: [String]) -> Bool { return str_eq(native_list_get(t, 0), "R") == false } +fn is_zero(t: [String]) -> Bool { return is_atom(t) && str_eq(native_list_get(t, 0), "0") } +fn is_unit(t: [String]) -> Bool { return is_atom(t) && str_eq(native_list_get(t, 0), "1") } + +// constructor — REFUSES impossible terms (distinct operands only) +fn R(a: [String], b: [String]) -> [String] { + if str_eq(native_list_get(a, 0), "0") && str_eq(native_list_get(b, 0), "0") { return ["ERROR"] } + if str_eq(native_list_get(a, 0), "1") && str_eq(native_list_get(b, 0), "1") { return ["ERROR"] } + let t: [String] = native_list_empty() + let t = native_list_append(t, "R") + let t = native_list_append(t, native_list_get(a, 0)) + let t = native_list_append(t, native_list_get(b, 0)) + return t +} + +// term equality by serialization (canonical string of the structure) +fn term_str(t: [String]) -> String { + let n: Int = native_list_len(t) + if n == 1 { return native_list_get(t, 0) } + let out: String = "R(" + let out = str_concat(out, str_concat(native_list_get(t, 1), ",")) + let out = str_concat(out, str_concat(native_list_get(t, 2), ")")) + return out +} +fn term_eq(a: [String], b: [String]) -> Bool { return str_eq(term_str(a), term_str(b)) } + +// ordered-role recovery (P-012): defined only on Im(R) +fn L(t: [String]) -> [String] { + if is_atom(t) { return ["ERROR"] } + return [native_list_get(t, 1)] +} +fn RR(t: [String]) -> [String] { + if is_atom(t) { return ["ERROR"] } + return [native_list_get(t, 2)] +} + +fn main() -> Void { + let z: [String] = atom0() + let u: [String] = atom1() + let r1: [String] = R(z, u) + println(term_str(r1)) + println(term_str(L(r1))) + println(term_str(RR(r1))) + println(term_eq(L(r1), z)) +} diff --git a/runtime/el/core_gen.c b/runtime/el/core_gen.c new file mode 100644 index 0000000..e69de29 diff --git a/runtime/el/strings.el b/runtime/el/strings.el new file mode 100644 index 0000000..4c5baa5 --- /dev/null +++ b/runtime/el/strings.el @@ -0,0 +1,69 @@ +// runtime/el/strings.el — the string family, redo in El. +// Replaces the C-builtin string family with El definitions. +// Redo discipline: these define the semantics; the C stubs behind the +// seam become trampolines, then nothing. + +// concat lifting: the El-level join, no C library logic +fn el_join(parts: [String], sep: String) -> String { + let n: Int = native_list_len(parts) + let out: String = "" + let i: Int = 0 + while i < n { + let part: String = native_list_get(parts, i) + let out = if i == 0 { part } else { str_concat(out, str_concat(sep, part)) } + let i = i + 1 + } + return out +} + +// pascal-free, redone slice engine: charwise, pure El +fn el_reverse(s: String) -> String { + let n: Int = str_len(s) + let out: String = "" + let i: Int = n - 1 + while i >= 0 { + let out = str_concat(out, str_slice(s, i, i + 1)) + let i = i - 1 + } + return out +} + +// the family's centerpiece: redo of the builtin, expressed over El +fn el_ends_with(s: String, suf: String) -> Bool { + let n: Int = str_len(s) + let m: Int = str_len(suf) + if m > n { return false } + return str_eq(str_slice(s, n - m, n), suf) +} + +// separator-aware split built on the above, pure El +fn el_split(s: String, sep: String) -> [String] { + let res: [String] = native_list_empty() + let n: Int = str_len(s) + let m: Int = str_len(sep) + let i: Int = 0 + let start: Int = 0 + while i <= n - m { + if m == 0 { + let acc: [String] = native_list_append(res, s) + return acc + } + if str_eq(str_slice(s, i, i + m), sep) { + let res = native_list_append(res, str_slice(s, start, i)) + let start = i + m + let i = i + m + } else { + let i = i + 1 + } + } + let res = native_list_append(res, str_slice(s, start, n)) + return res +} + +fn main() -> Void { + println(el_join(["a", "b", "c"], "-")) + println(el_reverse("hello")) + println(el_ends_with("neuron", "ron")) + let parts: [String] = el_split("a-b-c-d", "-") + println(el_join(parts, ",")) +} diff --git a/runtime/el/strings_gen.c b/runtime/el/strings_gen.c new file mode 100644 index 0000000..34c8baf --- /dev/null +++ b/runtime/el/strings_gen.c @@ -0,0 +1,126 @@ +#include +#include +#include "el_runtime.h" + +el_val_t el_join(el_val_t parts, el_val_t sep); +el_val_t el_reverse(el_val_t s); +el_val_t el_ends_with(el_val_t s, el_val_t suf); +el_val_t el_split(el_val_t s, el_val_t sep); + +static el_val_t __el_body_el_join(el_val_t parts, el_val_t sep) { + el_val_t n = native_list_len(parts); + el_val_t out = EL_STR(""); + el_val_t i = 0; + while (i < n) { + el_val_t part = native_list_get(parts, i); + out = ({ el_val_t _if_result_1 = 0; if ((i == 0)) { _if_result_1 = (part); } else { _if_result_1 = (str_concat(out, str_concat(sep, part))); } _if_result_1; }); + i = (i + 1); + } + return out; + return 0; +} +struct __env_el_join { el_val_t parts; el_val_t sep; }; +static el_val_t __thunk_el_join(void* __v) { + struct __env_el_join* __e = (struct __env_el_join*)__v; (void)__e; + return __el_body_el_join(__e->parts, __e->sep); +} +el_val_t el_join(el_val_t parts, el_val_t sep) { + { el_val_t __s = el_seam_run(EL_STR("el_join"), 0, 0); if (__s) return __s; } + struct __env_el_join __env = { parts, sep }; + el_val_t __r = el_seam_wrap(EL_STR("el_join"), __thunk_el_join, &__env); + __r = el_seam_run(EL_STR("el_join"), 1, __r); + return __r; +} + +static el_val_t __el_body_el_reverse(el_val_t s) { + el_val_t n = str_len(s); + el_val_t out = EL_STR(""); + el_val_t i = (n - 1); + while (i >= 0) { + out = str_concat(out, str_slice(s, i, (i + 1))); + i = (i - 1); + } + return out; + return 0; +} +struct __env_el_reverse { el_val_t s; }; +static el_val_t __thunk_el_reverse(void* __v) { + struct __env_el_reverse* __e = (struct __env_el_reverse*)__v; (void)__e; + return __el_body_el_reverse(__e->s); +} +el_val_t el_reverse(el_val_t s) { + { el_val_t __s = el_seam_run(EL_STR("el_reverse"), 0, 0); if (__s) return __s; } + struct __env_el_reverse __env = { s }; + el_val_t __r = el_seam_wrap(EL_STR("el_reverse"), __thunk_el_reverse, &__env); + __r = el_seam_run(EL_STR("el_reverse"), 1, __r); + return __r; +} + +static el_val_t __el_body_el_ends_with(el_val_t s, el_val_t suf) { + el_val_t n = str_len(s); + el_val_t m = str_len(suf); + if (m > n) { + return 0; + } + return str_eq(str_slice(s, (n - m), n), suf); + return 0; +} +struct __env_el_ends_with { el_val_t s; el_val_t suf; }; +static el_val_t __thunk_el_ends_with(void* __v) { + struct __env_el_ends_with* __e = (struct __env_el_ends_with*)__v; (void)__e; + return __el_body_el_ends_with(__e->s, __e->suf); +} +el_val_t el_ends_with(el_val_t s, el_val_t suf) { + { el_val_t __s = el_seam_run(EL_STR("el_ends_with"), 0, 0); if (__s) return __s; } + struct __env_el_ends_with __env = { s, suf }; + el_val_t __r = el_seam_wrap(EL_STR("el_ends_with"), __thunk_el_ends_with, &__env); + __r = el_seam_run(EL_STR("el_ends_with"), 1, __r); + return __r; +} + +static el_val_t __el_body_el_split(el_val_t s, el_val_t sep) { + el_val_t res = native_list_empty(); + el_val_t n = str_len(s); + el_val_t m = str_len(sep); + el_val_t i = 0; + el_val_t start = 0; + while (i <= (n - m)) { + if (m == 0) { + el_val_t acc = native_list_append(res, s); + return acc; + } + if (str_eq(str_slice(s, i, (i + m)), sep)) { + res = native_list_append(res, str_slice(s, start, i)); + start = (i + m); + i = (i + m); + } else { + i = (i + 1); + } + } + res = native_list_append(res, str_slice(s, start, n)); + return res; + return 0; +} +struct __env_el_split { el_val_t s; el_val_t sep; }; +static el_val_t __thunk_el_split(void* __v) { + struct __env_el_split* __e = (struct __env_el_split*)__v; (void)__e; + return __el_body_el_split(__e->s, __e->sep); +} +el_val_t el_split(el_val_t s, el_val_t sep) { + { el_val_t __s = el_seam_run(EL_STR("el_split"), 0, 0); if (__s) return __s; } + struct __env_el_split __env = { s, sep }; + el_val_t __r = el_seam_wrap(EL_STR("el_split"), __thunk_el_split, &__env); + __r = el_seam_run(EL_STR("el_split"), 1, __r); + return __r; +} + +int main(int _argc, char** _argv) { + el_runtime_init_args(_argc, _argv); + println(el_join(el_list_new(3, EL_STR("a"), EL_STR("b"), EL_STR("c")), EL_STR("-"))); + println(el_reverse(EL_STR("hello"))); + println(el_ends_with(EL_STR("neuron"), EL_STR("ron"))); + el_val_t parts = el_split(EL_STR("a-b-c-d"), EL_STR("-")); + println(el_join(parts, EL_STR(","))); + return 0; +} + diff --git a/runtime/el/strings_gen2.c b/runtime/el/strings_gen2.c new file mode 100644 index 0000000..e69de29 diff --git a/tools/evidence/__pycache__/report.cpython-313.pyc b/tools/evidence/__pycache__/report.cpython-313.pyc new file mode 100644 index 0000000..5a5c44d Binary files /dev/null and b/tools/evidence/__pycache__/report.cpython-313.pyc differ diff --git a/tools/evidence/report-prove.sh b/tools/evidence/report-prove.sh new file mode 100755 index 0000000..b166fc7 --- /dev/null +++ b/tools/evidence/report-prove.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# report-prove.sh — evidence the report generator works. Both directions. +# The negative arms are the point: it must REFUSE, not degrade. +set -uo pipefail +cd "$(git rev-parse --show-toplevel)" +python3 - <<'PY' +import sys, os, shutil, tempfile +sys.path.insert(0, 'tools/evidence') +from report import load, extract, cite, narrative_ok, Unbacked +F=0; N=0 +def chk(name, cond, extra=""): + global F,N; N+=1 + print(f" {'ok ' if cond else 'FAIL'} {name}{'' if cond else ' '+extra}") + if not cond: F+=1 + +EV = 'docs/experiments/evidence' +print("POSITIVE — reads and verifies a real evidence directory") +rows = load(EV) +chk("manifest loaded and every artifact hash re-verified", len(rows) > 0, f"{len(rows)} rows") + +print() +print("POSITIVE — a number is EXTRACTED from an artifact, not typed") +val, r = extract(rows, 'compiler-code-lines', r'^code lines:\s*(\d+)') +chk(f"pulled code-line count from captured stdout: {val}", val.isdigit()) +print(f" source: {cite(r)}") + +print() +print("NEGATIVE — refuses a claim whose artifact does not exist") +try: + extract(rows, 'no-such-artifact-anywhere', r'(\d+)'); chk("refused", False, "it did NOT refuse") +except Unbacked as e: chk("a claim with no artifact raises, does not degrade to blank", True) + +print() +print("NEGATIVE — refuses a pattern that is not present in the artifact") +try: + extract(rows, 'compiler-code-lines', r'^TOTAL COST IN DOLLARS:\s*(\d+)'); chk("refused", False, "it did NOT refuse") +except Unbacked as e: chk("a number not present in the source raises", True) + +print() +print("NEGATIVE — refuses an ALTERED artifact") +tmp = tempfile.mkdtemp() +shutil.copytree(EV, os.path.join(tmp,'ev')) +target = [f for f in os.listdir(os.path.join(tmp,'ev')) if f.endswith('.out')][0] +with open(os.path.join(tmp,'ev',target),'a') as f: f.write("tampered\n") +try: + load(os.path.join(tmp,'ev')); chk("refused", False, "it accepted a tampered artifact") +except Unbacked as e: chk("a tampered artifact halts the report entirely", 'ALTERED' in str(e)) +shutil.rmtree(tmp) + +print() +print("NEGATIVE — refuses an empty manifest") +tmp2 = tempfile.mkdtemp() +open(os.path.join(tmp2,'MANIFEST.tsv'),'w').write("sha256\tbytes\texit\tms\tcommit\ttree\tutc\tartifact\tcommand\n") +try: + load(tmp2); chk("refused", False, "an empty manifest passed") +except Unbacked as e: chk("an empty manifest is a failure, not a clean report", True) +shutil.rmtree(tmp2) + +print() +print("POSITIVE — narrative may not carry a quantity") +ok1,_ = narrative_ok("The seam binds after the build, which is the whole claim.") +ok2,bad = narrative_ok("The compiler shrank by 10.6 percent, which is a lot.") +chk("prose with no digits passes", ok1) +chk("prose containing a bare number is REJECTED", not ok2, f"caught {bad}") + +print() +print(f" {'PROVEN' if F==0 else 'NOT PROVEN'} — {N} checks, {F} failed") +sys.exit(F) +PY diff --git a/tools/evidence/report.py b/tools/evidence/report.py new file mode 100644 index 0000000..193fcfd --- /dev/null +++ b/tools/evidence/report.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +"""report.py — the report is GENERATED from the artifacts. It is never composed. + +Every failure in this project's record lived at the report layer: the primary +data was right and the summary of it was wrong. The enumeration said 7, the +summary said 6. The harness ran 7 assertions and reported 6. The checker listed +the new defect and printed 'ok'. Six agent results arrived and three were dropped. + +So the report layer stops being written by hand. Rules, enforced mechanically: + + 1. A number appears ONLY if it was extracted from a captured artifact. + 2. An artifact whose bytes no longer match its manifest hash is a HARD FAILURE + -- the report refuses to render at all. + 3. A claim naming an artifact that does not exist is a HARD FAILURE. It does + not degrade to a blank, a dash, or 'not available'. + 4. Narrative may say why something matters. It may not contain a digit. +""" +import sys, os, csv, hashlib, re, subprocess + +class Unbacked(Exception): pass + +def sha256(p): + h = hashlib.sha256() + with open(p, 'rb') as f: + for b in iter(lambda: f.read(65536), b''): h.update(b) + return h.hexdigest() + +def load(evdir): + """Read a manifest and VERIFY every artifact before anything may be quoted.""" + man = os.path.join(evdir, 'MANIFEST.tsv') + if not os.path.exists(man): raise Unbacked(f"no manifest at {evdir}") + rows = [] + with open(man) as f: + for r in csv.DictReader(f, delimiter='\t'): + art = os.path.join(evdir, r['artifact']) + if not os.path.exists(art): raise Unbacked(f"artifact missing: {r['artifact']}") + actual = sha256(art) + if actual != r['sha256']: + raise Unbacked(f"artifact ALTERED: {r['artifact']}\n manifest {r['sha256']}\n actual {actual}") + r['_path'] = art + rows.append(r) + if not rows: raise Unbacked(f"manifest at {evdir} has no rows -- nothing to report") + return rows + +def extract(rows, artifact, pattern, group=1): + """Pull a value OUT OF the captured stdout. Cannot be typed, only found.""" + for r in rows: + if r['artifact'].endswith(artifact) or artifact in r['artifact']: + txt = open(r['_path'], errors='replace').read() + m = re.search(pattern, txt, re.M) + if not m: raise Unbacked(f"pattern not found in {r['artifact']}: {pattern!r}") + return m.group(group), r + raise Unbacked(f"no artifact matching {artifact!r} -- the number has no source") + +def cite(r): + return f"`{r['artifact']}` · sha `{r['sha256'][:12]}` · commit `{r['commit']}` · exit `{r['exit']}`" + +def narrative_ok(text): + """Rule 4. Prose may not carry a quantity.""" + stripped = re.sub(r'`[^`]*`', '', text) + bad = re.findall(r'\b\d+(?:\.\d+)?\b', stripped) + return (not bad), bad diff --git a/ui/dist/el-ui.js b/ui/dist/el-ui.js deleted file mode 100644 index 0dc2990..0000000 --- a/ui/dist/el-ui.js +++ /dev/null @@ -1,397 +0,0 @@ -/** - * el-ui v0.1.0 — Activation-based frontend framework. - * State is an Engram graph. Reactivity is spreading activation. - * - * Bundled single-file runtime. Import this from your compiled .el components: - * import { Component, Graph, Renderer, Router, mount } from './el-ui.js'; - * - * Source: runtime/src/ - * Build: cat runtime/src/graph.js runtime/src/activation.js - * runtime/src/renderer.js runtime/src/router.js runtime/src/index.js > dist/el-ui.js - */ - -// ── graph.js ────────────────────────────────────────────────────────────────── - -export class Graph { - constructor() { - this.nodes = new Map(); - this.edges = new Map(); - this.subscribers = new Map(); - } - - seed({ type, name, content, importance = 0.5 }) { - const id = this._uuid(); - this.nodes.set(id, { id, type, name, content, importance, edges: [] }); - return id; - } - - get(id) { - return this.nodes.get(id); - } - - update(id, newContent) { - const node = this.nodes.get(id); - if (!node) return; - node.content = newContent; - node.importance = Math.min(1.0, node.importance + 0.1); - const activated = this.activate(id); - for (const nodeId of activated) { - const subs = this.subscribers.get(nodeId); - if (subs && subs.length > 0) { - const n = this.nodes.get(nodeId); - if (n) subs.forEach(cb => cb(n)); - } - } - // Always notify direct subscribers - const directSubs = this.subscribers.get(id); - if (directSubs && directSubs.length > 0) { - directSubs.forEach(cb => cb(node)); - } - } - - activate(seedId, maxDepth = 3, pruneThreshold = 0.01) { - const result = new Set([seedId]); - const queue = [{ id: seedId, strength: 1.0, depth: 0 }]; - const bestStrength = new Map([[seedId, 1.0]]); - - while (queue.length > 0) { - let bestIdx = 0; - for (let i = 1; i < queue.length; i++) { - if (queue[i].strength > queue[bestIdx].strength) bestIdx = i; - } - const { id, strength, depth } = queue.splice(bestIdx, 1)[0]; - if (depth >= maxDepth) continue; - - const node = this.nodes.get(id); - if (!node) continue; - - for (const edgeId of node.edges) { - const edge = this.edges.get(edgeId); - if (!edge) continue; - const target = this.nodes.get(edge.to); - if (!target) continue; - const targetStrength = strength * edge.weight * Math.max(0, target.importance); - if (targetStrength <= pruneThreshold) continue; - const prevBest = bestStrength.get(edge.to) ?? 0; - if (targetStrength > prevBest) { - bestStrength.set(edge.to, targetStrength); - result.add(edge.to); - queue.push({ id: edge.to, strength: targetStrength, depth: depth + 1 }); - } - } - } - return result; - } - - search(query, nodeType = null) { - const results = []; - const q = query.toLowerCase(); - for (const [, node] of this.nodes) { - if (nodeType && node.type !== nodeType) continue; - const content = String(node.content).toLowerCase(); - const nameMatch = node.name.toLowerCase().includes(q); - const contentMatch = content.includes(q); - if (nameMatch || contentMatch) { - const score = (nameMatch ? 0.6 : 0) + (contentMatch ? 0.4 : 0); - results.push({ ...node, score: score * node.importance }); - } - } - return results.sort((a, b) => b.score - a.score); - } - - subscribe(nodeId, callback) { - if (!this.subscribers.has(nodeId)) this.subscribers.set(nodeId, []); - this.subscribers.get(nodeId).push(callback); - return () => { - const subs = this.subscribers.get(nodeId); - if (!subs) return; - const idx = subs.indexOf(callback); - if (idx >= 0) subs.splice(idx, 1); - }; - } - - connect(fromId, toId, { weight = 1.0, relation = 'related' } = {}) { - const edgeId = this._uuid(); - this.edges.set(edgeId, { id: edgeId, from: fromId, to: toId, weight, relation }); - const node = this.nodes.get(fromId); - if (node) node.edges.push(edgeId); - return edgeId; - } - - dump() { - return [...this.nodes.values()]; - } - - _uuid() { - if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID(); - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { - const r = Math.random() * 16 | 0; - return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); - }); - } -} - -// ── activation.js ───────────────────────────────────────────────────────────── - -export const PRUNE_THRESHOLD = 0.01; - -export function spreadActivation(graph, seeds, { - maxDepth = 3, - limit = 20, - pruneThreshold = PRUNE_THRESHOLD, -} = {}) { - const bestStrength = new Map(); - const queue = []; - const seedSet = new Set(seeds); - - for (const seed of seeds) { - if (!graph.get(seed)) continue; - queue.push({ id: seed, strength: 1.0, hops: 0 }); - bestStrength.set(seed, { strength: 1.0, hops: 0 }); - } - - while (queue.length > 0) { - let bestIdx = 0; - for (let i = 1; i < queue.length; i++) { - if (queue[i].strength > queue[bestIdx].strength) bestIdx = i; - } - const { id, strength, hops } = queue.splice(bestIdx, 1)[0]; - if (hops >= maxDepth) continue; - const node = graph.get(id); - if (!node) continue; - for (const edgeId of node.edges) { - const edge = graph.edges.get(edgeId); - if (!edge) continue; - const target = graph.get(edge.to); - if (!target) continue; - const targetStrength = strength * edge.weight * Math.max(0, target.importance); - if (targetStrength <= pruneThreshold) continue; - const prev = bestStrength.get(edge.to); - if (!prev || targetStrength > prev.strength) { - const nextHops = hops + 1; - bestStrength.set(edge.to, { strength: targetStrength, hops: nextHops }); - queue.push({ id: edge.to, strength: targetStrength, hops: nextHops }); - } - } - } - - const results = []; - for (const [nodeId, { strength, hops }] of bestStrength) { - if (seedSet.has(nodeId)) continue; - const node = graph.get(nodeId); - if (node) results.push({ nodeId, strength, hops, node }); - } - results.sort((a, b) => b.strength - a.strength); - return results.slice(0, limit); -} - -export function activationStrength(graph, fromId, toId, maxDepth = 3) { - const results = spreadActivation(graph, [fromId], { maxDepth }); - const found = results.find(r => r.nodeId === toId); - return found ? found.strength : 0; -} - -export function reachableNodes(graph, seedId, maxDepth = 3) { - return graph.activate(seedId, maxDepth); -} - -// ── renderer.js ─────────────────────────────────────────────────────────────── - -export class Renderer { - constructor(root, component) { - this.root = root; - this.component = component; - this._currentHtml = ''; - this._boundHandlers = new WeakMap(); - } - - mount() { - this._currentHtml = this.component.render(); - this.root.innerHTML = this._currentHtml; - this._bindEvents(); - if (typeof this.component.onMount === 'function') { - this.component.onMount(); - } - } - - patch(_activatedNodes) { - const newHtml = this.component.render(); - if (newHtml !== this._currentHtml) { - const focused = document.activeElement; - const focusedId = focused && focused !== document.body ? focused.id : null; - this.root.innerHTML = newHtml; - this._bindEvents(); - this._currentHtml = newHtml; - if (focusedId) { - const el = this.root.querySelector(`#${CSS.escape(focusedId)}`); - if (el) el.focus(); - } - } - } - - _bindEvents() { - const comp = this.component; - const eventNames = [ - 'click', 'input', 'change', 'mouseenter', 'mouseleave', - 'keydown', 'keyup', 'keypress', 'focus', 'blur', - 'submit', 'mousedown', 'mouseup', 'dblclick', 'contextmenu', - ]; - for (const eventName of eventNames) { - const attr = `data-el-${eventName}`; - this.root.querySelectorAll(`[${attr}]`).forEach(el => { - const handlerExpr = el.getAttribute(attr); - if (!handlerExpr) return; - const handler = this._compileHandler(handlerExpr, comp); - if (handler) { - const prev = this._boundHandlers.get(el); - if (prev && prev[eventName]) el.removeEventListener(eventName, prev[eventName]); - el.addEventListener(eventName, handler); - if (!this._boundHandlers.has(el)) this._boundHandlers.set(el, {}); - this._boundHandlers.get(el)[eventName] = handler; - } - }); - } - } - - _compileHandler(expr, comp) { - try { - const decoded = expr - .replace(/"/g, '"') - .replace(/'/g, "'") - .replace(/&/g, '&') - .replace(/</g, '<') - .replace(/>/g, '>'); - if (decoded.includes('=>')) { - // eslint-disable-next-line no-new-func - const fn = new Function('__self', `return ${decoded}`)(comp); - return typeof fn === 'function' ? fn : null; - } else if (decoded.includes('(')) { - // eslint-disable-next-line no-new-func - return new Function('__self', 'event', `${decoded}`).bind(null, comp); - } else { - return comp[decoded] ? comp[decoded].bind(comp) : null; - } - } catch (e) { - console.warn(`el-ui: failed to compile handler: ${expr}`, e); - return null; - } - } -} - -// ── router.js ───────────────────────────────────────────────────────────────── - -export class Router { - constructor(graph, routes) { - this.graph = graph; - this.routes = routes; - this.currentPath = window.location.pathname; - this._routeNodes = {}; - this._subscribers = []; - - for (const [path] of Object.entries(routes)) { - const id = graph.seed({ type: 'route', name: path, content: path, importance: 0.3 }); - this._routeNodes[path] = id; - } - - const paths = Object.keys(routes).sort(); - for (let i = 0; i < paths.length - 1; i++) { - const parent = paths[i]; - const child = paths[i + 1]; - if (child.startsWith(parent) && parent !== child) { - graph.connect(this._routeNodes[parent], this._routeNodes[child], { - weight: 0.8, - relation: 'subroute', - }); - } - } - - window.addEventListener('popstate', () => this._activate(window.location.pathname)); - } - - navigate(path, replace = false) { - if (path === this.currentPath) return; - if (replace) history.replaceState({}, '', path); - else history.pushState({}, '', path); - this._activate(path); - } - - currentComponent() { - return this.routes[this.currentPath] ?? this.routes['*'] ?? null; - } - - subscribe(callback) { - this._subscribers.push(callback); - return () => { - const idx = this._subscribers.indexOf(callback); - if (idx >= 0) this._subscribers.splice(idx, 1); - }; - } - - href(path) { return path; } - - _activate(path) { - const prevPath = this.currentPath; - this.currentPath = path; - const matchedPath = this._matchPath(path); - if (matchedPath && this._routeNodes[matchedPath]) { - this.graph.activate(this._routeNodes[matchedPath]); - const node = this.graph.get(this._routeNodes[matchedPath]); - if (node) node.importance = Math.min(1.0, node.importance + 0.2); - } - if (path !== prevPath) this._subscribers.forEach(cb => cb(path)); - } - - _matchPath(path) { - if (this.routes[path]) return path; - const candidates = Object.keys(this.routes) - .filter(r => r !== '*' && path.startsWith(r)) - .sort((a, b) => b.length - a.length); - if (candidates.length > 0) return candidates[0]; - return '*'; - } -} - -// ── Component base class & mount() ─────────────────────────────────────────── - -export class Component { - constructor(props = {}) { - this._graph = new Graph(); - this._stateNodes = {}; - this._state = {}; - this.props = props; - this._renderer = null; - } - - setState(name, value) { - if (this._stateNodes[name] !== undefined) { - this._graph.update(this._stateNodes[name], value); - if (this._renderer) this._renderer.patch(); - } - } - - _child(ComponentClass, props = {}) { - try { - const instance = new ComponentClass(props); - instance._graph = this._graph; - return instance.render(); - } catch (e) { - console.warn(`el-ui: failed to render child ${ComponentClass?.name}`, e); - return ``; - } - } - - render() { return ''; } - onMount() {} -} - -export function mount(ComponentClass, selector, props = {}) { - const root = document.querySelector(selector); - if (!root) throw new Error(`el-ui: no element found for selector '${selector}'`); - const component = new ComponentClass(props); - const renderer = new Renderer(root, component); - component._renderer = renderer; - renderer.mount(); - return component; -} - -export default { mount, Component, Graph, Renderer, Router }; diff --git a/ui/tools/dist/el-ui-native-codegen b/ui/tools/dist/el-ui-native-codegen deleted file mode 100755 index 97ced9d..0000000 --- a/ui/tools/dist/el-ui-native-codegen +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -# el-ui-native-codegen — el-ui component DSL → el-native API calls -# Auto-generated by build.sh — do not edit. -exec python3 "/Users/will/Development/neuron-technologies/foundation/el/ui/tools/native-codegen/el_ui_native_codegen.py" "$@"