iter form-a.1 (Tasks 6-12): milestone close
Second half of the form-a-default-authoring milestone-close iter
(Boss-decided strategy C, big-bang). All seven tasks DONE; cargo
test --workspace green at every per-task boundary.
T6 — Bench-driver suffix flip from .ail.json to .ail across 4
Python scripts + run.sh. compile_check.py + cross_lang.py exit 0.
T7 — Re-author e2e.rs raw-JSON-inspect tests:
- diff_detects_changed_def — derive sum.ail.json on-the-fly via
`ail parse examples/sum.ail` into tempdir, then mutate + diff.
- borrow_own_demo_modes_are_metadata_only — same pattern.
- reuse_as_demo_under_rc_uses_inplace_rewrite — same pattern.
- render_parse_round_trip_canonical — RETIRED (subsumed by T1's
cli_parse_then_render_then_parse_is_idempotent over whole corpus).
- ail_run_accepts_ail_source_with_same_stdout_as_ail_json —
re-authored to derive hello.ail.json in a per-process tempdir
from hello.ail via `ail parse`, then assert dual-form stdout.
T8 — Bulk-delete 156 non-carve-out .ail.json. Inventory:
8 .ail.json (carve-outs, alphabetical: broken_unbound + prelude
+ 3× test_22b2_* + 3× test_ct1_*) + 157 .ail. carve_out_inventory
test un-#[ignore]'d and green. Forward-pulled 20 repairs that the
T1-5 dispatch's recon missed (12 Group-B suffix + 5 Group-A
load_workspace + 3 ail_run sites). Also forward-pulled T9 Step 5
(schema_coverage corpus flip from .ail.json to .ail) to satisfy
T8's green-gate.
T9 — Retire obsolete roundtrip tests:
- print_then_parse_round_trips_every_fixture (round_trip.rs)
- every_ail_fixture_matches_its_json_counterpart (round_trip.rs)
- cli_render_then_parse_preserves_canonical_bytes_on_every_fixture
- Dead helpers: list_json_fixtures ×2, round_trip_one,
strip_trailing_newlines.
Schema-coverage corpus already flipped in T8 (forward-pull).
T10 — DESIGN.md §"Roundtrip Invariant" (lines 2027-2109) restated
with parse-determinism + idempotency + CLI-pipeline-idempotency +
carve-out-anchor framing. Five surviving enforcement tests named.
§"Float literals" and §"Why anchored at top level" preserved.
T11 — §A4 doctrine edits: CLAUDE.md:5-6 + DESIGN.md:465-466.
Canonical form remains JSON-AST; authoring projection is .ail;
build derives JSON-AST in-process via ailang_surface::parse.
T12 — Milestone close:
- WhatsNew entry: user-facing language, lead with the change.
- Roadmap: [milestone] form-a struck [x] with closing note.
- Final inventory verified: 8 .ail.json + 157 .ail.
- Final cargo test --workspace: 557 passed, 0 failed, 3 ignored.
- bench/compile_check.py + bench/cross_lang.py: exit 0.
Test math: pre-iter 558 baseline + 3 new T1 tests = 561, − 1
(T7 retire) − 3 (T9 retire) = 557 final.
INDEX.md appended with the full iter summary covering T1-T12 (the
T1-5 commit at 77b28ad deferred the INDEX line to full-iter close).
Milestone [Form-A as the default authoring surface] structurally
closed. The compile-time-embed carve-out (prelude.ail.json) is
the subject of the queued follow-up milestone [Prelude embed:
Form-A as compile-time source]. audit-form-a runs as the next
dispatch.
This commit is contained in:
@@ -2,8 +2,13 @@
|
||||
|
||||
AILang's only author is an LLM, not a human. It is designed for:
|
||||
|
||||
- **Machine readability over human readability.** Source of truth is
|
||||
structured data (`.ail.json`), not text.
|
||||
- **Machine readability over human readability.** The canonical,
|
||||
hashable, content-addressed form is structured data (`.ail.json`);
|
||||
the authoring projection is Form A (`.ail`). Authors write `.ail`;
|
||||
the build derives the JSON-AST in-process via
|
||||
`ailang_surface::parse`, gated by the round-trip invariant. The
|
||||
two forms are byte-isomorphic — picking either does not change
|
||||
the identity of the module.
|
||||
- **Local reasoning.** Every definition carries its full type and
|
||||
effect set, so a signature can be trusted without reading the body.
|
||||
- **Provability.** Pure core, explicit algebraic effects.
|
||||
|
||||
@@ -40,7 +40,7 @@ EXAMPLES = ROOT / "examples"
|
||||
|
||||
# Curated corpus. Pinned by name so the baseline keys are stable across
|
||||
# example-directory churn. Each entry must have a corresponding
|
||||
# `<name>.ail.json` under examples/.
|
||||
# `<name>.ail` under examples/.
|
||||
CORPUS = [
|
||||
# Surface coverage: each fixture exercises a different feature set.
|
||||
"hello", # IO baseline
|
||||
@@ -98,7 +98,7 @@ def measure(num_runs: int) -> dict[str, dict[str, float]]:
|
||||
|
||||
try:
|
||||
for fixture in CORPUS:
|
||||
src = EXAMPLES / f"{fixture}.ail.json"
|
||||
src = EXAMPLES / f"{fixture}.ail"
|
||||
if not src.is_file():
|
||||
print(f"missing fixture: {src}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ REFERENCE = ROOT / "bench" / "reference"
|
||||
OUTDIR = ROOT / "target" / "cross_lang"
|
||||
|
||||
# (ailang fixture stem, C reference stem) — both must exist as
|
||||
# `examples/<ail>.ail.json` and `bench/reference/<c>.c`.
|
||||
# `examples/<ail>.ail` and `bench/reference/<c>.c`.
|
||||
CORPUS = [
|
||||
("bench_list_sum", "list_sum"),
|
||||
("bench_tree_walk", "tree_walk"),
|
||||
@@ -77,7 +77,7 @@ def median_drop_slowest(runs: list[float]) -> float:
|
||||
|
||||
|
||||
def build_ailang(stem: str, alloc: str) -> Path:
|
||||
src = EXAMPLES / f"{stem}.ail.json"
|
||||
src = EXAMPLES / f"{stem}.ail"
|
||||
if not src.is_file():
|
||||
print(f"missing AILang fixture: {src}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
# What this harness measures:
|
||||
# - AILang mono'd binary at -O2 --alloc=rc on
|
||||
# examples/bench_mono_dispatch.ail.json
|
||||
# examples/bench_mono_dispatch.ail
|
||||
# - Hand-C reference, three variants:
|
||||
# direct-inlinable — foo() inlinable, direct call
|
||||
# direct-noinline — foo() noinline, direct call
|
||||
@@ -109,7 +109,7 @@ def main() -> int:
|
||||
ail_bin = OUTDIR / "bench_mono_dispatch_ail"
|
||||
subprocess.run(
|
||||
[str(AIL), "build", "--opt=-O2", "--alloc=rc",
|
||||
str(EXAMPLES / "bench_mono_dispatch.ail.json"), "-o", str(ail_bin)],
|
||||
str(EXAMPLES / "bench_mono_dispatch.ail"), "-o", str(ail_bin)],
|
||||
check=True, capture_output=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
"date": "2026-05-13",
|
||||
"mode": "standard",
|
||||
"outcome": "DONE",
|
||||
"tasks_total": 12,
|
||||
"tasks_completed": 12,
|
||||
"dispatches": [
|
||||
{
|
||||
"task_range": [1, 5],
|
||||
"tasks_total": 5,
|
||||
"tasks_completed": 5,
|
||||
"outcome": "DONE",
|
||||
"reloops_per_task": {
|
||||
"1": 0,
|
||||
"2": 1,
|
||||
@@ -15,16 +18,56 @@
|
||||
},
|
||||
"review_loops_spec": 0,
|
||||
"review_loops_quality": 0,
|
||||
"blocked_reason": null,
|
||||
"notes": "Plan recon defect: load_workspace prefers .ail siblings since ext-cli.1, so bulk-render of .ail siblings broke 7 Group-A tests whose entry was .ail.json. Inline forward-pull of Task-3 migrations + 4 transient #[ignore]'s on workspace.rs mod tests (relocated cleanly in Task 5).",
|
||||
"test_count_pre_dispatch": 558,
|
||||
"test_count_post_dispatch": 560,
|
||||
"test_count_ignored_post_dispatch": 4
|
||||
},
|
||||
{
|
||||
"task_range": [6, 12],
|
||||
"outcome": "DONE",
|
||||
"reloops_per_task": {
|
||||
"6": 0,
|
||||
"7": 1,
|
||||
"8": 1,
|
||||
"9": 0,
|
||||
"10": 0,
|
||||
"11": 0,
|
||||
"12": 0
|
||||
},
|
||||
"review_loops_spec": 0,
|
||||
"review_loops_quality": 0,
|
||||
"notes": {
|
||||
"task2_reloop": "Plan recon defect: load_workspace prefers .ail siblings since ext-cli.1, so bulk-render of .ail siblings broke 7 Group-A tests whose entry was .ail.json. Inline forward-pull of Task-3 migrations + 4 transient #[ignore]'s on workspace.rs mod tests (relocated cleanly in Task 5).",
|
||||
"task7_reloop": "ail_run_accepts_ail_source_with_same_stdout_as_ail_json initial re-author used tempfile-with-PID-suffix path; loader name-checks module-name-vs-file-stem and rejected. Repaired to use per-process tempdir with hello.ail.json as basename.",
|
||||
"task8_reloop": "Pre-T8 cargo-test green pre-deletion required pulling forward 20 stale-.ail.json-reference repairs that T1-5 missed: 12 `let example = X.ail.json` Group-B sites in e2e.rs + 5 ailang_core::load_workspace Group-A sites in e2e.rs + 3 ail_run Group-B sites in typeclass_22b3.rs. Post-deletion failure in schema_coverage required pulling T9 Step 5 (corpus flip + ailang_surface::load_module switch) forward into T8."
|
||||
},
|
||||
"test_count_pre_dispatch": 560,
|
||||
"test_count_post_dispatch": 557,
|
||||
"test_count_ignored_post_dispatch": 3,
|
||||
"test_count_retired": "1 (T7: render_parse_round_trip_canonical) + 3 (T9: print_then_parse_round_trips_every_fixture, every_ail_fixture_matches_its_json_counterpart, cli_render_then_parse_preserves_canonical_bytes_on_every_fixture) = 4 total. Net: 560 + 1 (un-ignore carve_out_inventory) - 4 retired = 557."
|
||||
}
|
||||
],
|
||||
"blocked_reason": null,
|
||||
"iter_totals": {
|
||||
"test_count_pre_iter": 558,
|
||||
"test_count_post_iter_half": 560,
|
||||
"test_count_ignored_post_iter_half": 4,
|
||||
"test_count_ignored_breakdown": "1 carve_out_inventory (T8 un-ignores) + 3 doctests (pre-existing)",
|
||||
"test_count_post_iter": 557,
|
||||
"test_count_ignored_post_iter": 3,
|
||||
"corpus_ail_pre_iter": 58,
|
||||
"corpus_ail_post_iter_half": 157,
|
||||
"corpus_ail_json_post_iter_half": 164,
|
||||
"corpus_ail_json_target_post_T8": 8
|
||||
"corpus_ail_post_iter": 157,
|
||||
"corpus_ail_json_pre_iter": 164,
|
||||
"corpus_ail_json_post_iter": 8,
|
||||
"carve_outs": [
|
||||
"broken_unbound.ail.json",
|
||||
"prelude.ail.json",
|
||||
"test_22b2_invalid_superclass_param.ail.json",
|
||||
"test_22b2_kind_mismatch.ail.json",
|
||||
"test_22b2_unbound_constraint_var.ail.json",
|
||||
"test_ct1_bad_qualifier.ail.json",
|
||||
"test_ct1_bare_xmod_rejected.ail.json",
|
||||
"test_ct1_qualified_class_rejected.ail.json"
|
||||
],
|
||||
"milestone_closed": "Form-A as the default authoring surface",
|
||||
"bench_compile_check_exit": 0,
|
||||
"bench_cross_lang_exit": 0
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -65,7 +65,7 @@ fixtures=(bench_list_sum bench_tree_walk bench_closure_chain bench_hof_pipeline
|
||||
modes=(gc bump rc)
|
||||
echo ">>> compiling fixtures (-O2)"
|
||||
for f in "${fixtures[@]}"; do
|
||||
src="$ROOT/examples/$f.ail.json"
|
||||
src="$ROOT/examples/$f.ail"
|
||||
[[ -f "$src" ]] || { echo "missing fixture: $src" >&2; exit 1; }
|
||||
for m in "${modes[@]}"; do
|
||||
bin="$OUTDIR/${f}_${m}"
|
||||
@@ -179,8 +179,8 @@ done
|
||||
# was added in 18f.2 and may not exist on older branches that share
|
||||
# this script).
|
||||
LAT_HARNESS="$ROOT/bench/latency_harness.py"
|
||||
LAT_IMPL_SRC="$ROOT/examples/bench_latency_implicit.ail.json"
|
||||
LAT_EXPL_SRC="$ROOT/examples/bench_latency_explicit.ail.json"
|
||||
LAT_IMPL_SRC="$ROOT/examples/bench_latency_implicit.ail"
|
||||
LAT_EXPL_SRC="$ROOT/examples/bench_latency_explicit.ail"
|
||||
if [[ -x "$LAT_HARNESS" && -f "$LAT_IMPL_SRC" && -f "$LAT_EXPL_SRC" ]]; then
|
||||
echo
|
||||
echo ">>> latency bench (PTY inter-arrival, 1000 samples per arm)"
|
||||
|
||||
+117
-71
@@ -406,48 +406,12 @@ fn std_list_stress_1000_element_folds() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Iter 15e: `ail render | ail parse` round-trips canonical bytes.
|
||||
/// Property protected: the CLI's `render` is the exact inverse of
|
||||
/// `parse`, not the older human-pretty form. Regression of this
|
||||
/// would mean piping `render` into `parse` no longer yields a
|
||||
/// re-loadable module — a contract the help text now claims.
|
||||
///
|
||||
/// Picks `std_either.ail.json` (richest fixture: 2-type-var data,
|
||||
/// 3-type-var fn, recursive ctors irrelevant) but the round-trip
|
||||
/// test in `ailang-surface` covers all 25 fixtures structurally.
|
||||
/// This test specifically exercises the CLI shell pipeline.
|
||||
#[test]
|
||||
fn render_parse_round_trip_canonical() {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let src = workspace.join("examples").join("std_either.ail.json");
|
||||
let original = std::fs::read(&src).expect("read fixture");
|
||||
|
||||
let render = Command::new(ail_bin())
|
||||
.args(["render", src.to_str().unwrap()])
|
||||
.output()
|
||||
.expect("run ail render");
|
||||
assert!(render.status.success(), "ail render failed");
|
||||
|
||||
let tmp = std::env::temp_dir().join(format!("ailang_render_e2e_{}.ail", std::process::id()));
|
||||
std::fs::write(&tmp, &render.stdout).expect("write rendered ail");
|
||||
|
||||
let parsed = Command::new(ail_bin())
|
||||
.args(["parse", tmp.to_str().unwrap()])
|
||||
.output()
|
||||
.expect("run ail parse");
|
||||
assert!(parsed.status.success(), "ail parse failed on rendered output");
|
||||
|
||||
let mut round = parsed.stdout;
|
||||
while round.last() == Some(&b'\n') {
|
||||
round.pop();
|
||||
}
|
||||
let mut orig = original;
|
||||
while orig.last() == Some(&b'\n') {
|
||||
orig.pop();
|
||||
}
|
||||
assert_eq!(orig, round, "render | parse must produce canonical bytes");
|
||||
}
|
||||
// Retired iter form-a.1 T7: `render_parse_round_trip_canonical` raw-read
|
||||
// `std_either.ail.json` for the byte-roundtrip. The property it pinned
|
||||
// (CLI render→parse byte-roundtrip) is now pinned across the entire
|
||||
// `.ail` corpus by `cli_parse_then_render_then_parse_is_idempotent` in
|
||||
// `crates/ail/tests/roundtrip_cli.rs` (added in T1), which is strictly
|
||||
// stronger (whole-corpus vs. one-fixture).
|
||||
|
||||
/// Iter 16a: nested constructor patterns. Property protected:
|
||||
/// `ailang_core::desugar` flattens `Cons a (Cons b _)` to a chain of
|
||||
@@ -698,12 +662,33 @@ fn nested_let_rec_demo() {
|
||||
fn diff_detects_changed_def() {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let src_a = workspace.join("examples").join("sum.ail.json");
|
||||
|
||||
// Variant: load sum.ail.json, mutate the `then` branch (1 instead of 0)
|
||||
// Form-A migration (iter form-a.1): derive the canonical JSON-AST
|
||||
// from `sum.ail` via `ail parse` rather than reading a pre-existing
|
||||
// `sum.ail.json` (which no longer exists post-iter). The variant is
|
||||
// produced by mutating the parsed AST and writing it back as a JSON
|
||||
// tempfile; `ail diff` runs against the two JSON tempfiles.
|
||||
let tmp_a = std::env::temp_dir().join(format!(
|
||||
"ailang_diff_src_{}.ail.json",
|
||||
std::process::id()
|
||||
));
|
||||
let parse_status = Command::new(ail_bin())
|
||||
.args([
|
||||
"parse",
|
||||
workspace.join("examples").join("sum.ail").to_str().unwrap(),
|
||||
"-o",
|
||||
tmp_a.to_str().unwrap(),
|
||||
])
|
||||
.status()
|
||||
.expect("ail parse failed to run");
|
||||
assert!(parse_status.success(), "ail parse failed on sum.ail");
|
||||
let src_a = tmp_a.clone();
|
||||
|
||||
// Variant: load the derived JSON, mutate the `then` branch (1 instead of 0)
|
||||
// in the `sum` definition. `main` stays bit-identical.
|
||||
let raw = std::fs::read(&src_a).expect("read sum.ail.json");
|
||||
let mut module: serde_json::Value = serde_json::from_slice(&raw).expect("parse sum.ail.json");
|
||||
let raw = std::fs::read(&src_a).expect("read derived sum.ail.json");
|
||||
let mut module: serde_json::Value =
|
||||
serde_json::from_slice(&raw).expect("parse derived sum.ail.json");
|
||||
{
|
||||
let defs = module
|
||||
.get_mut("defs")
|
||||
@@ -1305,13 +1290,30 @@ fn unreachable_demo() {
|
||||
/// wrappers, and the binary prints `3` then `6`.
|
||||
#[test]
|
||||
fn borrow_own_demo_modes_are_metadata_only() {
|
||||
// Sanity-check (2): the on-disk JSON contains `param_modes`
|
||||
// Sanity-check (2): the canonical JSON contains `param_modes`
|
||||
// tokens for both fns. If the schema regressed and the field
|
||||
// were dropped, this would fail before the binary even runs.
|
||||
//
|
||||
// Form-A migration (iter form-a.1): derive the JSON via `ail parse`
|
||||
// on `borrow_own_demo.ail` rather than reading a pre-existing
|
||||
// `.ail.json` (deleted post-iter).
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join("borrow_own_demo.ail.json");
|
||||
let json = std::fs::read_to_string(&json_path).expect("read borrow_own_demo.ail.json");
|
||||
let tmp_json = std::env::temp_dir().join(format!(
|
||||
"ailang_borrow_own_demo_{}.ail.json",
|
||||
std::process::id()
|
||||
));
|
||||
let parse_status = Command::new(ail_bin())
|
||||
.args([
|
||||
"parse",
|
||||
workspace.join("examples").join("borrow_own_demo.ail").to_str().unwrap(),
|
||||
"-o",
|
||||
tmp_json.to_str().unwrap(),
|
||||
])
|
||||
.status()
|
||||
.expect("ail parse failed to run");
|
||||
assert!(parse_status.success(), "ail parse failed on borrow_own_demo.ail");
|
||||
let json = std::fs::read_to_string(&tmp_json).expect("read derived borrow_own_demo.ail.json");
|
||||
assert!(
|
||||
json.contains("\"param_modes\":[\"borrow\"]"),
|
||||
"expected `param_modes:[\"borrow\"]` in canonical JSON; the schema for `(borrow T)` regressed"
|
||||
@@ -1359,7 +1361,7 @@ fn eq_demo() {
|
||||
#[test]
|
||||
fn alloc_rc_produces_same_stdout_as_gc() {
|
||||
// Pick a fixture with non-trivial allocation: list-building + match.
|
||||
let example = "list.ail.json";
|
||||
let example = "list.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc, stdout_rc, "alloc=rc must match alloc=gc");
|
||||
@@ -1405,8 +1407,26 @@ fn clone_demo_is_identity_in_18c1() {
|
||||
fn reuse_as_demo_under_rc_uses_inplace_rewrite() {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join("reuse_as_demo.ail.json");
|
||||
let json = std::fs::read_to_string(&json_path).expect("read reuse_as_demo.ail.json");
|
||||
let ail_path = workspace.join("examples").join("reuse_as_demo.ail");
|
||||
|
||||
// Form-A migration (iter form-a.1): derive the canonical JSON-AST
|
||||
// via `ail parse` on `reuse_as_demo.ail` rather than reading a
|
||||
// pre-existing `.ail.json` (deleted post-iter).
|
||||
let tmp_json = std::env::temp_dir().join(format!(
|
||||
"ailang_reuse_as_demo_{}.ail.json",
|
||||
std::process::id()
|
||||
));
|
||||
let parse_status = Command::new(ail_bin())
|
||||
.args([
|
||||
"parse",
|
||||
ail_path.to_str().unwrap(),
|
||||
"-o",
|
||||
tmp_json.to_str().unwrap(),
|
||||
])
|
||||
.status()
|
||||
.expect("ail parse failed to run");
|
||||
assert!(parse_status.success(), "ail parse failed on reuse_as_demo.ail");
|
||||
let json = std::fs::read_to_string(&tmp_json).expect("read derived reuse_as_demo.ail.json");
|
||||
assert!(
|
||||
json.contains("\"t\":\"reuse-as\""),
|
||||
"expected `\"t\":\"reuse-as\"` in canonical JSON; the schema for `(reuse-as ...)` regressed"
|
||||
@@ -1422,8 +1442,10 @@ fn reuse_as_demo_under_rc_uses_inplace_rewrite() {
|
||||
|
||||
// (5) Inspect the rc IR text. We re-lower via the codegen API
|
||||
// directly so the assertion runs without depending on the
|
||||
// filesystem layout of `ail build`'s tmpdir.
|
||||
let ws = ailang_core::load_workspace(&json_path).expect("load workspace");
|
||||
// filesystem layout of `ail build`'s tmpdir. Use the
|
||||
// extension-dispatching `ailang_surface::load_workspace` so
|
||||
// the `.ail` entry is accepted.
|
||||
let ws = ailang_surface::load_workspace(&ail_path).expect("load workspace");
|
||||
let mut lifted_modules = std::collections::BTreeMap::new();
|
||||
for (mname, m) in &ws.modules {
|
||||
let desugared = ailang_core::desugar::desugar_module(m);
|
||||
@@ -1496,7 +1518,7 @@ fn reuse_as_demo_under_rc_uses_inplace_rewrite() {
|
||||
/// invariant: stdout must be byte-identical to the `gc` build.
|
||||
#[test]
|
||||
fn alloc_rc_matches_gc_on_std_list_demo() {
|
||||
let example = "std_list_demo.ail.json";
|
||||
let example = "std_list_demo.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(
|
||||
@@ -1531,7 +1553,7 @@ fn alloc_rc_matches_gc_on_std_list_demo() {
|
||||
/// this iter.
|
||||
#[test]
|
||||
fn alloc_rc_emits_dec_for_unique_let_bound_box() {
|
||||
let example = "rc_box_drop.ail.json";
|
||||
let example = "rc_box_drop.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "42");
|
||||
@@ -1557,7 +1579,7 @@ fn alloc_rc_emits_dec_for_unique_let_bound_box() {
|
||||
/// the dec path itself.
|
||||
#[test]
|
||||
fn alloc_rc_recursive_list_sum() {
|
||||
let example = "rc_list_drop.ail.json";
|
||||
let example = "rc_list_drop.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "15");
|
||||
@@ -1602,7 +1624,7 @@ fn alloc_rc_recursive_list_sum() {
|
||||
/// pattern-binder dec.
|
||||
#[test]
|
||||
fn alloc_rc_borrow_only_recursive_list_drop() {
|
||||
let example = "rc_list_drop_borrow.ail.json";
|
||||
let example = "rc_list_drop_borrow.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "11");
|
||||
@@ -1622,7 +1644,7 @@ fn alloc_rc_borrow_only_recursive_list_drop() {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join(example);
|
||||
let ws = ailang_core::load_workspace(&json_path).expect("load workspace");
|
||||
let ws = ailang_surface::load_workspace(&json_path).expect("load workspace");
|
||||
let mut lifted_modules = std::collections::BTreeMap::new();
|
||||
for (mname, m) in &ws.modules {
|
||||
let desugared = ailang_core::desugar::desugar_module(m);
|
||||
@@ -1684,7 +1706,7 @@ fn alloc_rc_borrow_only_recursive_list_drop() {
|
||||
/// `drop_<m>_Pair` call against `p`.
|
||||
#[test]
|
||||
fn alloc_rc_partial_drop_skips_moved_keeps_wildcarded() {
|
||||
let example = "pat_extract_partial_drop.ail.json";
|
||||
let example = "pat_extract_partial_drop.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "6");
|
||||
@@ -1698,7 +1720,7 @@ fn alloc_rc_partial_drop_skips_moved_keeps_wildcarded() {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join(example);
|
||||
let ws = ailang_core::load_workspace(&json_path).expect("load workspace");
|
||||
let ws = ailang_surface::load_workspace(&json_path).expect("load workspace");
|
||||
let mut lifted_modules = std::collections::BTreeMap::new();
|
||||
for (mname, m) in &ws.modules {
|
||||
let desugared = ailang_core::desugar::desugar_module(m);
|
||||
@@ -1774,7 +1796,7 @@ fn alloc_rc_partial_drop_skips_moved_keeps_wildcarded() {
|
||||
/// that ANY drop fires.
|
||||
#[test]
|
||||
fn alloc_rc_own_param_dec_at_fn_return() {
|
||||
let example = "rc_own_param_drop.ail.json";
|
||||
let example = "rc_own_param_drop.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "11");
|
||||
@@ -1788,7 +1810,7 @@ fn alloc_rc_own_param_dec_at_fn_return() {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join(example);
|
||||
let ws = ailang_core::load_workspace(&json_path).expect("load workspace");
|
||||
let ws = ailang_surface::load_workspace(&json_path).expect("load workspace");
|
||||
let mut lifted_modules = std::collections::BTreeMap::new();
|
||||
for (mname, m) in &ws.modules {
|
||||
let desugared = ailang_core::desugar::desugar_module(m);
|
||||
@@ -1891,7 +1913,7 @@ fn alloc_rc_own_param_dec_at_fn_return() {
|
||||
/// capacity).
|
||||
#[test]
|
||||
fn alloc_rc_drop_iterative_handles_million_cell_list() {
|
||||
let example = "rc_drop_iterative_long_list.ail.json";
|
||||
let example = "rc_drop_iterative_long_list.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_rc.trim(), "1");
|
||||
@@ -1910,11 +1932,11 @@ fn alloc_rc_drop_iterative_handles_million_cell_list() {
|
||||
/// dispatch.
|
||||
#[test]
|
||||
fn iter18e_drop_iterative_emits_worklist_body_no_self_recursion() {
|
||||
let example = "rc_drop_iterative_long_list.ail.json";
|
||||
let example = "rc_drop_iterative_long_list.ail";
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join(example);
|
||||
let ws = ailang_core::load_workspace(&json_path).expect("load workspace");
|
||||
let ws = ailang_surface::load_workspace(&json_path).expect("load workspace");
|
||||
let mut lifted_modules = std::collections::BTreeMap::new();
|
||||
for (mname, m) in &ws.modules {
|
||||
let desugared = ailang_core::desugar::desugar_module(m);
|
||||
@@ -1987,11 +2009,11 @@ fn iter18e_drop_iterative_emits_worklist_body_no_self_recursion() {
|
||||
/// of any on-disk fixture changes.
|
||||
#[test]
|
||||
fn iter18e_no_annotation_keeps_recursive_drop_body() {
|
||||
let example = "rc_drop_iterative_long_list.ail.json";
|
||||
let example = "rc_drop_iterative_long_list.ail";
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
|
||||
let json_path = workspace.join("examples").join(example);
|
||||
let ws = ailang_core::load_workspace(&json_path).expect("load workspace");
|
||||
let ws = ailang_surface::load_workspace(&json_path).expect("load workspace");
|
||||
// Mutate every TypeDef in every module to clear the annotation.
|
||||
let mut modules = std::collections::BTreeMap::new();
|
||||
for (mname, m) in &ws.modules {
|
||||
@@ -2066,7 +2088,7 @@ fn iter18e_no_annotation_keeps_recursive_drop_body() {
|
||||
/// regression coverage — see CLAUDE.md "Bug fixes — TDD, always".
|
||||
#[test]
|
||||
fn alloc_rc_pattern_bind_in_implicit_fn_does_not_dec_borrowed_children() {
|
||||
let example = "rc_pin_recurse_implicit.ail.json";
|
||||
let example = "rc_pin_recurse_implicit.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "0");
|
||||
@@ -2294,7 +2316,7 @@ fn alloc_rc_let_binder_for_implicit_returning_app_does_not_drop() {
|
||||
/// the arm-close drop. Output matches `--alloc=gc` (`0`).
|
||||
#[test]
|
||||
fn alloc_rc_let_alias_of_implicit_param_does_not_dec_borrowed_children() {
|
||||
let example = "rc_let_alias_implicit_param.ail.json";
|
||||
let example = "rc_let_alias_implicit_param.ail";
|
||||
let stdout_gc = build_and_run_with_alloc(example, "gc");
|
||||
let stdout_rc = build_and_run_with_alloc(example, "rc");
|
||||
assert_eq!(stdout_gc.trim(), "0");
|
||||
@@ -2524,11 +2546,35 @@ fn ail_check_accepts_ail_source() {
|
||||
/// counterpart. Guards against the surface→core dispatch silently
|
||||
/// rewriting the loaded `Module` (e.g. losing imports, dropping defs,
|
||||
/// re-ordering fields) — the binary semantics must be form-agnostic.
|
||||
///
|
||||
/// Form-A migration (iter form-a.1): only the eight carve-out fixtures
|
||||
/// keep `.ail.json` form on disk post-iter. To preserve the dual-form
|
||||
/// property test, derive a parallel `.ail.json` in a tempdir from
|
||||
/// `hello.ail` via `ail parse`, then build and run both forms.
|
||||
#[test]
|
||||
fn ail_run_accepts_ail_source_with_same_stdout_as_ail_json() {
|
||||
let ail_path = workspace_root().join("examples/hello.ail");
|
||||
let json_path = workspace_root().join("examples/hello.ail.json");
|
||||
assert!(ail_path.is_file());
|
||||
|
||||
// The loader name-checks the module name against the file stem, so
|
||||
// the derived JSON must be named `hello.ail.json` even in the temp
|
||||
// location. Use a per-process tempdir to avoid races.
|
||||
let tmpdir = std::env::temp_dir().join(format!(
|
||||
"ailang_dual_form_{}",
|
||||
std::process::id()
|
||||
));
|
||||
std::fs::create_dir_all(&tmpdir).unwrap();
|
||||
let json_path = tmpdir.join("hello.ail.json");
|
||||
let parse_status = Command::new(ail_bin())
|
||||
.args([
|
||||
"parse",
|
||||
ail_path.to_str().unwrap(),
|
||||
"-o",
|
||||
json_path.to_str().unwrap(),
|
||||
])
|
||||
.status()
|
||||
.expect("ail parse failed to run");
|
||||
assert!(parse_status.success(), "ail parse failed on hello.ail");
|
||||
assert!(json_path.is_file());
|
||||
|
||||
let build_and_capture = |src: &Path| -> Vec<u8> {
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
//! CLI roundtrip: every `examples/*.ail.json` survives
|
||||
//! `ail render` → tempfile → `ail parse` with BLAKE3 hash
|
||||
//! identity on canonical bytes.
|
||||
//! CLI-pipeline idempotency gate: every `examples/*.ail` survives
|
||||
//! `ail parse | ail render | ail parse` with byte identity on the
|
||||
//! canonical JSON output.
|
||||
//!
|
||||
//! This is the user-facing-surface defence line. Crate-internal
|
||||
//! roundtrip tests in `ailang-surface` cover the same property
|
||||
//! at the library level; this test additionally protects the
|
||||
//! `ail render` and `ail parse` CLI wrappers from drift (output
|
||||
//! `ail parse` and `ail render` CLI wrappers from drift (output
|
||||
//! formatting, exit codes, stdout framing).
|
||||
//!
|
||||
//! Pure reader: the test writes only to a `tempfile::TempDir`
|
||||
//! that lives outside the repo and is cleaned up by Drop. No
|
||||
//! committed content is mutated.
|
||||
//!
|
||||
//! Retired iter form-a.1 T9:
|
||||
//! `cli_render_then_parse_preserves_canonical_bytes_on_every_fixture`
|
||||
//! (walked `.ail.json` corpus; replaced by the corpus-flipped
|
||||
//! `cli_parse_then_render_then_parse_is_idempotent` below, added in
|
||||
//! T1). The `list_json_fixtures` helper and `roundtrip_one` helper
|
||||
//! were the only consumers of `.ail.json` walks and are retired
|
||||
//! alongside.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
@@ -28,23 +36,6 @@ fn examples_dir() -> PathBuf {
|
||||
workspace_root().join("examples")
|
||||
}
|
||||
|
||||
fn list_json_fixtures() -> Vec<PathBuf> {
|
||||
let dir = examples_dir();
|
||||
let mut paths: Vec<PathBuf> = std::fs::read_dir(&dir)
|
||||
.unwrap_or_else(|e| panic!("read_dir({}): {e}", dir.display()))
|
||||
.filter_map(|entry| entry.ok())
|
||||
.map(|e| e.path())
|
||||
.filter(|p| {
|
||||
p.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.map(|n| n.ends_with(".ail.json"))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect();
|
||||
paths.sort();
|
||||
paths
|
||||
}
|
||||
|
||||
fn list_ail_fixtures() -> Vec<PathBuf> {
|
||||
let dir = examples_dir();
|
||||
let mut paths: Vec<PathBuf> = std::fs::read_dir(&dir)
|
||||
@@ -62,106 +53,6 @@ fn list_ail_fixtures() -> Vec<PathBuf> {
|
||||
paths
|
||||
}
|
||||
|
||||
fn strip_trailing_newlines(mut v: Vec<u8>) -> Vec<u8> {
|
||||
while v.last() == Some(&b'\n') {
|
||||
v.pop();
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
/// Run the full render → parse pipeline for one fixture. Returns
|
||||
/// Ok(()) on hash-identity, Err(reason) otherwise.
|
||||
fn roundtrip_one(fixture: &Path, tmpdir: &Path) -> Result<(), String> {
|
||||
// Step A: load the original fixture and compute canonical bytes
|
||||
// (independent of how the JSON file is formatted on disk).
|
||||
let original_module = ailang_core::load_module(fixture)
|
||||
.map_err(|e| format!("load_module: {e}"))?;
|
||||
let bytes_orig = ailang_core::canonical::to_bytes(&original_module);
|
||||
let h_orig = blake3::hash(&bytes_orig);
|
||||
|
||||
// Step B: `ail render <fixture>` → captured stdout = ail text.
|
||||
let render_out = Command::new(ail_bin())
|
||||
.args(["render", fixture.to_str().unwrap()])
|
||||
.output()
|
||||
.map_err(|e| format!("spawn ail render: {e}"))?;
|
||||
if !render_out.status.success() {
|
||||
return Err(format!(
|
||||
"ail render exit={:?}\nstderr: {}",
|
||||
render_out.status.code(),
|
||||
String::from_utf8_lossy(&render_out.stderr),
|
||||
));
|
||||
}
|
||||
|
||||
// Step C: write the rendered .ail into the tempdir.
|
||||
let stem = fixture
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.and_then(|n| n.strip_suffix(".ail.json"))
|
||||
.unwrap_or("fixture");
|
||||
let tmp_ail = tmpdir.join(format!("{stem}.round.ail"));
|
||||
std::fs::write(&tmp_ail, &render_out.stdout)
|
||||
.map_err(|e| format!("write tempfile {}: {e}", tmp_ail.display()))?;
|
||||
|
||||
// Step D: `ail parse <tmp_ail>` → captured stdout = canonical
|
||||
// bytes + trailing newline.
|
||||
let parse_out = Command::new(ail_bin())
|
||||
.args(["parse", tmp_ail.to_str().unwrap()])
|
||||
.output()
|
||||
.map_err(|e| format!("spawn ail parse: {e}"))?;
|
||||
if !parse_out.status.success() {
|
||||
return Err(format!(
|
||||
"ail parse exit={:?}\nstderr: {}",
|
||||
parse_out.status.code(),
|
||||
String::from_utf8_lossy(&parse_out.stderr),
|
||||
));
|
||||
}
|
||||
let bytes_round = strip_trailing_newlines(parse_out.stdout);
|
||||
let h_round = blake3::hash(&bytes_round);
|
||||
|
||||
if h_orig != h_round {
|
||||
let s_orig = String::from_utf8_lossy(&bytes_orig).into_owned();
|
||||
let s_round = String::from_utf8_lossy(&bytes_round).into_owned();
|
||||
return Err(format!(
|
||||
"BLAKE3 mismatch:\n orig: {}\n round: {}\noriginal bytes: {s_orig}\nround bytes: {s_round}",
|
||||
h_orig.to_hex(),
|
||||
h_round.to_hex(),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_render_then_parse_preserves_canonical_bytes_on_every_fixture() {
|
||||
let fixtures = list_json_fixtures();
|
||||
assert!(
|
||||
!fixtures.is_empty(),
|
||||
"no .ail.json fixtures found under {}",
|
||||
examples_dir().display()
|
||||
);
|
||||
|
||||
let tmpdir = tempfile::TempDir::new().expect("create tempdir");
|
||||
let mut failures = Vec::<String>::new();
|
||||
let mut passed = 0usize;
|
||||
|
||||
for fixture in &fixtures {
|
||||
match roundtrip_one(fixture, tmpdir.path()) {
|
||||
Ok(()) => passed += 1,
|
||||
Err(msg) => failures.push(format!("{}: {msg}", fixture.display())),
|
||||
}
|
||||
}
|
||||
|
||||
if !failures.is_empty() {
|
||||
panic!(
|
||||
"CLI roundtrip failed for {} of {} fixtures (passed: {}):\n{}",
|
||||
failures.len(),
|
||||
fixtures.len(),
|
||||
passed,
|
||||
failures.join("\n\n")
|
||||
);
|
||||
}
|
||||
eprintln!("CLI roundtrip ok for {passed} fixtures");
|
||||
}
|
||||
|
||||
/// CLI-pipeline idempotency (post-form-a-default-authoring §C3): for
|
||||
/// every `.ail` fixture, the user-facing pipeline
|
||||
/// `ail parse <ail> | ail render | ail parse` is byte-identical
|
||||
|
||||
@@ -741,7 +741,7 @@ fn ail_run(fixture_name: &str) -> (std::process::Output, String) {
|
||||
/// failure — all observable at stdout. Defends mono-pass invariant 3.
|
||||
#[test]
|
||||
fn coherence_two_instances_pick_correct_body_at_runtime() {
|
||||
let (output, stdout) = ail_run("test_22b3_coherence_two_instances.ail.json");
|
||||
let (output, stdout) = ail_run("test_22b3_coherence_two_instances.ail");
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"ail run failed: stdout={}, stderr={}",
|
||||
@@ -767,7 +767,7 @@ fn coherence_two_instances_pick_correct_body_at_runtime() {
|
||||
/// constant 99 must reach stdout. Defends mono-pass invariant 4.
|
||||
#[test]
|
||||
fn class_default_method_runs_and_prints_default_value() {
|
||||
let (output, stdout) = ail_run("test_22b3_default_e2e.ail.json");
|
||||
let (output, stdout) = ail_run("test_22b3_default_e2e.ail");
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"ail run failed: stdout={}, stderr={}",
|
||||
@@ -795,7 +795,7 @@ fn class_default_method_runs_and_prints_default_value() {
|
||||
/// Defends mono-pass invariant 6.
|
||||
#[test]
|
||||
fn cross_module_class_method_runs_and_prints_correct_value() {
|
||||
let (output, stdout) = ail_run("test_22b3_xmod_e2e_main.ail.json");
|
||||
let (output, stdout) = ail_run("test_22b3_xmod_e2e_main.ail");
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"ail run failed: stdout={}, stderr={}",
|
||||
|
||||
@@ -31,7 +31,6 @@ fn examples_dir() -> std::path::PathBuf {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "GREEN-ratified by Task 8 (.ail.json deletion); RED until then"]
|
||||
fn examples_ail_json_inventory_matches_carve_outs() {
|
||||
let expected: BTreeSet<&str> = EXPECTED.iter().copied().collect();
|
||||
let mut actual: BTreeSet<String> = BTreeSet::new();
|
||||
|
||||
@@ -326,7 +326,7 @@ fn examples_dir() -> PathBuf {
|
||||
crate_dir.parent().unwrap().parent().unwrap().join("examples")
|
||||
}
|
||||
|
||||
fn list_json_fixtures() -> Vec<PathBuf> {
|
||||
fn list_ail_fixtures() -> Vec<PathBuf> {
|
||||
let dir = examples_dir();
|
||||
let mut paths: Vec<PathBuf> = std::fs::read_dir(&dir)
|
||||
.unwrap_or_else(|e| panic!("read_dir({}): {e}", dir.display()))
|
||||
@@ -335,7 +335,7 @@ fn list_json_fixtures() -> Vec<PathBuf> {
|
||||
.filter(|p| {
|
||||
p.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.map(|n| n.ends_with(".ail.json"))
|
||||
.map(|n| n.ends_with(".ail"))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect();
|
||||
@@ -345,10 +345,10 @@ fn list_json_fixtures() -> Vec<PathBuf> {
|
||||
|
||||
#[test]
|
||||
fn every_ast_variant_is_observed_in_the_fixture_corpus() {
|
||||
let fixtures = list_json_fixtures();
|
||||
let fixtures = list_ail_fixtures();
|
||||
assert!(
|
||||
!fixtures.is_empty(),
|
||||
"no .ail.json fixtures found under {}",
|
||||
"no .ail fixtures found under {}",
|
||||
examples_dir().display()
|
||||
);
|
||||
|
||||
@@ -356,7 +356,7 @@ fn every_ast_variant_is_observed_in_the_fixture_corpus() {
|
||||
let mut load_failures = Vec::<String>::new();
|
||||
|
||||
for path in &fixtures {
|
||||
match ailang_core::load_module(path) {
|
||||
match ailang_surface::load_module(path) {
|
||||
Ok(m) => visit_module(&m, &mut observed),
|
||||
Err(e) => load_failures.push(format!("{}: {e}", path.display())),
|
||||
}
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
//! Round-trip gate for the form-(A) projection.
|
||||
//!
|
||||
//! Three complementary checks over `examples/`, each gathering
|
||||
//! Two complementary checks over `examples/*.ail`, each gathering
|
||||
//! fixtures dynamically via `read_dir` (no hardcoded lists). The
|
||||
//! tests are pure readers — they do not write into the working
|
||||
//! tree.
|
||||
//!
|
||||
//! 1. `print_then_parse_round_trips_every_fixture`: Direction 1 of
|
||||
//! the Roundtrip Invariant (DESIGN.md §"Roundtrip Invariant").
|
||||
//! For every `examples/*.ail.json` fixture, load → `print` →
|
||||
//! `parse` → canonical bytes; assert byte-equal to original.
|
||||
//! 1. `parse_is_deterministic_over_every_ail_fixture`: for every
|
||||
//! well-formed `.ail` text `t`, `parse(t)` produces the same
|
||||
//! canonical bytes every invocation. The parser is a pure
|
||||
//! function of input — no randomness, no time dependence, no
|
||||
//! environment leak. Hashing `canonical::to_bytes(parse(t))` is
|
||||
//! therefore well-defined for any `.ail` source.
|
||||
//!
|
||||
//! 2. `every_ail_fixture_matches_its_json_counterpart`: hand-
|
||||
//! authored ground-truth check. For every `examples/*.ail`
|
||||
//! fixture, parse → canonical bytes; if a same-stem `.ail.json`
|
||||
//! counterpart exists, assert canonical-byte equality against
|
||||
//! it. Pins the `.ail` corpus against semantic drift between
|
||||
//! the two forms at the fixture level.
|
||||
//! 2. `parse_then_print_then_parse_is_idempotent_on_every_ail_fixture`:
|
||||
//! Direction 2 of the Roundtrip Invariant (DESIGN.md §"Roundtrip
|
||||
//! Invariant"). For every well-formed `.ail` text `t`, asserts
|
||||
//! `canonical_bytes(parse(t))` equals
|
||||
//! `canonical_bytes(parse(print(parse(t))))`. The printer is a
|
||||
//! left-inverse of the parser modulo canonical form.
|
||||
//!
|
||||
//! 3. `parse_then_print_then_parse_is_idempotent_on_every_ail_fixture`:
|
||||
//! Direction 2 of the Roundtrip Invariant. For every well-formed
|
||||
//! `.ail` text `t`, asserts `canonical_bytes(parse(t))` equals
|
||||
//! `canonical_bytes(parse(print(parse(t))))`. Robust against
|
||||
//! future `.ail` fixtures without a JSON counterpart.
|
||||
//! Retired iter form-a.1 T9: `print_then_parse_round_trips_every_fixture`
|
||||
//! (corpus shrunk to 8 carve-outs post-iter) and
|
||||
//! `every_ail_fixture_matches_its_json_counterpart` (no longer
|
||||
//! expressible: only one form is hand-authored post-iter).
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn examples_dir() -> PathBuf {
|
||||
// `CARGO_MANIFEST_DIR` is the surface crate root; examples live two
|
||||
@@ -32,73 +33,15 @@ fn examples_dir() -> PathBuf {
|
||||
crate_dir.parent().unwrap().parent().unwrap().join("examples")
|
||||
}
|
||||
|
||||
fn list_json_fixtures() -> Vec<PathBuf> {
|
||||
let dir = examples_dir();
|
||||
let mut paths: Vec<PathBuf> = std::fs::read_dir(&dir)
|
||||
.unwrap_or_else(|e| panic!("read_dir({}): {e}", dir.display()))
|
||||
.filter_map(|entry| entry.ok())
|
||||
.map(|e| e.path())
|
||||
.filter(|p| {
|
||||
p.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.map(|n| {
|
||||
// Round-trip every fixture. The 22b.1/22b.2/22b.3 filter
|
||||
// was retired in 22b.4a once the Form-A parser+printer
|
||||
// arms for ClassDef / InstanceDef landed.
|
||||
n.ends_with(".ail.json")
|
||||
})
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect();
|
||||
paths.sort();
|
||||
paths
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_then_parse_round_trips_every_fixture() {
|
||||
let fixtures = list_json_fixtures();
|
||||
assert!(
|
||||
!fixtures.is_empty(),
|
||||
"no .ail.json fixtures found under {}",
|
||||
examples_dir().display()
|
||||
);
|
||||
|
||||
let mut failures = Vec::<String>::new();
|
||||
let mut passed = 0usize;
|
||||
for path in &fixtures {
|
||||
match round_trip_one(path) {
|
||||
Ok(()) => passed += 1,
|
||||
Err(msg) => failures.push(format!("{}: {msg}", path.display())),
|
||||
}
|
||||
}
|
||||
if !failures.is_empty() {
|
||||
panic!(
|
||||
"round-trip failed for {} of {} fixtures (passed: {}):\n{}",
|
||||
failures.len(),
|
||||
fixtures.len(),
|
||||
passed,
|
||||
failures.join("\n")
|
||||
);
|
||||
}
|
||||
eprintln!("round-trip ok for {passed} fixtures");
|
||||
}
|
||||
|
||||
fn round_trip_one(path: &Path) -> Result<(), String> {
|
||||
let original = ailang_core::load_module(path).map_err(|e| format!("load: {e}"))?;
|
||||
let text = ailang_surface::print(&original);
|
||||
let parsed = ailang_surface::parse(&text)
|
||||
.map_err(|e| format!("re-parse failed: {e}\n--- printed text ---\n{text}"))?;
|
||||
let bytes_orig = ailang_core::canonical::to_bytes(&original);
|
||||
let bytes_round = ailang_core::canonical::to_bytes(&parsed);
|
||||
if bytes_orig != bytes_round {
|
||||
let s_orig = String::from_utf8_lossy(&bytes_orig).into_owned();
|
||||
let s_round = String::from_utf8_lossy(&bytes_round).into_owned();
|
||||
return Err(format!(
|
||||
"canonical bytes differ.\noriginal: {s_orig}\nround: {s_round}"
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
// Retired iter form-a.1 T9:
|
||||
// - `list_json_fixtures` helper (walked `.ail.json` for the two retired tests below).
|
||||
// - `print_then_parse_round_trips_every_fixture`: corpus shrunk to 8 carve-outs
|
||||
// post-iter; property subsumed by `parse_is_deterministic_over_every_ail_fixture`
|
||||
// plus the surviving `parse_then_print_then_parse_is_idempotent_on_every_ail_fixture`.
|
||||
// - `round_trip_one` helper (only consumer was the retired test above).
|
||||
// - `every_ail_fixture_matches_its_json_counterpart`: no longer expressible —
|
||||
// only one form is hand-authored post-iter; counterparts are derived in-process
|
||||
// via `ail parse`.
|
||||
|
||||
fn list_ail_fixtures() -> Vec<PathBuf> {
|
||||
let dir = examples_dir();
|
||||
@@ -117,92 +60,6 @@ fn list_ail_fixtures() -> Vec<PathBuf> {
|
||||
paths
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_ail_fixture_matches_its_json_counterpart() {
|
||||
let fixtures = list_ail_fixtures();
|
||||
assert!(
|
||||
!fixtures.is_empty(),
|
||||
"no .ail fixtures found under {}",
|
||||
examples_dir().display()
|
||||
);
|
||||
|
||||
let mut failures = Vec::<String>::new();
|
||||
let mut paired = 0usize;
|
||||
let mut parse_only = 0usize;
|
||||
|
||||
for ail_path in &fixtures {
|
||||
let text = match std::fs::read_to_string(ail_path) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
failures.push(format!("{}: read failed: {e}", ail_path.display()));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let parsed = match ailang_surface::parse(&text) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
failures.push(format!("{}: parse failed: {e}", ail_path.display()));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Same-stem counterpart lookup. `<stem>.ail` → `<stem>.ail.json`.
|
||||
let stem = ail_path
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.and_then(|n| n.strip_suffix(".ail"))
|
||||
.unwrap_or("");
|
||||
let json_path = ail_path.with_file_name(format!("{stem}.ail.json"));
|
||||
|
||||
if !json_path.exists() {
|
||||
// Spec: parse success alone is sufficient for `.ail` files
|
||||
// without a JSON counterpart. (Today: none expected.)
|
||||
parse_only += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let original = match ailang_core::load_module(&json_path) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
failures.push(format!(
|
||||
"{}: load_module({}) failed: {e}",
|
||||
ail_path.display(),
|
||||
json_path.display()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let bytes_orig = ailang_core::canonical::to_bytes(&original);
|
||||
let bytes_parsed = ailang_core::canonical::to_bytes(&parsed);
|
||||
if bytes_orig != bytes_parsed {
|
||||
let s_orig = String::from_utf8_lossy(&bytes_orig).into_owned();
|
||||
let s_round = String::from_utf8_lossy(&bytes_parsed).into_owned();
|
||||
failures.push(format!(
|
||||
"{} vs {}: canonical bytes differ.\noriginal: {s_orig}\nparsed: {s_round}",
|
||||
ail_path.display(),
|
||||
json_path.display()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
paired += 1;
|
||||
}
|
||||
|
||||
if !failures.is_empty() {
|
||||
panic!(
|
||||
"{} of {} .ail fixture(s) failed cross-check (paired ok: {}, parse-only: {}):\n{}",
|
||||
failures.len(),
|
||||
fixtures.len(),
|
||||
paired,
|
||||
parse_only,
|
||||
failures.join("\n\n")
|
||||
);
|
||||
}
|
||||
eprintln!(
|
||||
".ail cross-check ok ({} paired, {} parse-only)",
|
||||
paired, parse_only
|
||||
);
|
||||
}
|
||||
|
||||
/// Direction 2 of the Roundtrip Invariant (DESIGN.md §"Roundtrip
|
||||
/// Invariant"): for every well-formed `.ail` text `t`, the
|
||||
/// composition `parse → print → parse` is idempotent on the AST.
|
||||
|
||||
+55
-37
@@ -462,8 +462,14 @@ on the shelf for a future iter only if both fail.
|
||||
|
||||
### What this Decision deliberately does not do
|
||||
|
||||
- It does not promote form (A) to the source of truth. Form (A) is
|
||||
one projection; the JSON-AST stays canonical.
|
||||
- It does not change which form is canonical: the JSON-AST remains
|
||||
the hashable, content-addressed representation, and all hashing,
|
||||
content-addressing, and cross-module references flow through it
|
||||
unchanged. What did change in 2026-05-13 (this milestone) is
|
||||
which form is authored: authors now write Form A; the JSON-AST
|
||||
is materialised in-process by callers that need it. The two
|
||||
forms are byte-isomorphic by the round-trip invariant. Form (A)
|
||||
is one projection; the JSON-AST stays canonical.
|
||||
- It does not foreclose visual or graphical front-ends. The crate
|
||||
layout (`core` owns AST; `surface`/`visual`/... are siblings)
|
||||
reserves that lane.
|
||||
@@ -2026,26 +2032,41 @@ would invoke literal-defaulting which axis-7 already excluded.
|
||||
|
||||
## Roundtrip Invariant
|
||||
|
||||
Every well-formed AILang module has both a canonical `.ail.json`
|
||||
representation and a textual `.ail` representation, and the two
|
||||
are exact projections of the same AST. Concretely, both directions
|
||||
of the bijection hold:
|
||||
Every well-formed AILang module has a canonical `.ail.json`
|
||||
representation (the hashable, content-addressed JSON-AST) and a
|
||||
hand-authored `.ail` representation (Form A, the authoring
|
||||
projection). The JSON-AST is derived from `.ail` in-process by
|
||||
consumers that need it; the round-trip is now the *property* of
|
||||
that derivation, not the byte-level agreement of two on-disk forms.
|
||||
|
||||
1. **JSON → text → JSON.** For every valid `.ail.json` module `J`,
|
||||
`parse(print(load_module(J)))` is canonical-byte-equal to
|
||||
`canonical::to_bytes(load_module(J))`. The textual surface is
|
||||
the inverse of the loader composed with the printer; no
|
||||
information is lost across the round-trip.
|
||||
2. **text → JSON → text.** For every well-formed `.ail` text `t`,
|
||||
`parse(t)` is a complete AST, and re-printing `print(parse(t))`
|
||||
produces a text that re-parses to the same AST (modulo
|
||||
formatting). The parser is total over the well-formed surface
|
||||
and the printer is deterministic.
|
||||
Concretely:
|
||||
|
||||
1. **Parse-determinism.** For every well-formed `.ail` text `t`,
|
||||
`ailang_surface::parse(t)` produces a unique AST. The parser is
|
||||
a pure function of input — no randomness, no time dependence,
|
||||
no environment leak. Hashing `canonical::to_bytes(parse(t))` is
|
||||
therefore well-defined for any `.ail` source.
|
||||
|
||||
2. **Idempotency under print.** For every well-formed `.ail` text
|
||||
`t`, `canonical(parse(t)) == canonical(parse(print(parse(t))))`.
|
||||
The printer is a left-inverse of the parser modulo canonical
|
||||
form: print-then-parse is a no-op on the canonical bytes.
|
||||
|
||||
3. **CLI-pipeline idempotency.** For every `.ail` fixture, the
|
||||
public CLI pipeline `ail parse | ail render | ail parse` is
|
||||
byte-identical to direct `ail parse` of the source `.ail`.
|
||||
Pins drift that crate-internal tests cannot see.
|
||||
|
||||
4. **Carve-out anchor.** Eight `.ail.json`-only fixtures (seven
|
||||
subject-matter rejection tests + one compile-time-embed for
|
||||
the prelude) survive in the corpus by structural necessity.
|
||||
They participate in their own dedicated rejection-shape or
|
||||
embed-mechanism tests, not in the round-trip gate.
|
||||
|
||||
Hashing is the consequence the language depends on: BLAKE3 of the
|
||||
canonical bytes is identical for the two paths, so content-
|
||||
addressing is form-agnostic. An LLM author can pick either form
|
||||
without changing the identity of the module it produces.
|
||||
canonical bytes is well-defined for any `.ail` source via parse-
|
||||
determinism. An LLM author writes `.ail`; the build derives the
|
||||
canonical hash without ambiguity.
|
||||
|
||||
### Float literals are inside the invariant
|
||||
|
||||
@@ -2065,29 +2086,26 @@ operating on the `examples/` corpus via dynamic `read_dir`
|
||||
collection (no hardcoded fixture list, so newly added fixtures
|
||||
inherit the gate automatically):
|
||||
|
||||
- `crates/ailang-surface/tests/round_trip.rs::print_then_parse_round_trips_every_fixture`
|
||||
— for every `.ail.json`, `print` then `parse` produces canonical-
|
||||
byte-equal output. Direction 1 above.
|
||||
- `crates/ailang-surface/tests/round_trip.rs::parse_is_deterministic_over_every_ail_fixture`
|
||||
— for every `.ail`, parse twice and assert canonical-byte
|
||||
equality between the two ASTs. Direction 1 above.
|
||||
- `crates/ailang-surface/tests/round_trip.rs::parse_then_print_then_parse_is_idempotent_on_every_ail_fixture`
|
||||
— for every `.ail` text `t`, `parse(t)` and `parse(print(parse(t)))`
|
||||
produce canonical-byte-equal AST. Direction 2 above.
|
||||
- `crates/ailang-surface/tests/round_trip.rs::every_ail_fixture_matches_its_json_counterpart`
|
||||
— for every `.ail` with a same-stem `.ail.json` counterpart,
|
||||
`parse` of the text yields canonical bytes equal to the JSON
|
||||
counterpart. Pins the hand-authored `.ail` corpus against
|
||||
drift between the two forms at the fixture level.
|
||||
- `crates/ail/tests/roundtrip_cli.rs::cli_parse_then_render_then_parse_is_idempotent`
|
||||
— for every `.ail`, the public CLI pipeline `ail parse | ail render | ail parse`
|
||||
reproduces canonical bytes byte-identical to direct `ail parse`.
|
||||
Pins drift internal tests cannot see.
|
||||
- `crates/ailang-core/tests/schema_coverage.rs::every_ast_variant_is_observed_in_the_fixture_corpus`
|
||||
— every variant of `Def`, `Term`, `Pattern`, `Literal`, `Type`,
|
||||
and `ParamMode` appears in at least one fixture. The visitor
|
||||
matches each AST enum exhaustively without wildcard arms, so
|
||||
any new AST variant fails to compile until the visitor is
|
||||
extended in lockstep — the coverage table cannot silently fall
|
||||
behind the schema.
|
||||
- `crates/ail/tests/roundtrip_cli.rs::cli_render_then_parse_preserves_canonical_bytes_on_every_fixture`
|
||||
— for every `.ail.json`, the public CLI pipeline `ail render` →
|
||||
tempfile → `ail parse` reproduces BLAKE3-identical canonical
|
||||
bytes. Pins the user-facing CLI against drift that crate-
|
||||
internal tests cannot see.
|
||||
and `ParamMode` appears in at least one `.ail` fixture (corpus
|
||||
flipped from `.ail.json` to `.ail` at iter form-a.1). New AST
|
||||
variants fail compile until the visitor and corpus are extended
|
||||
in lockstep.
|
||||
- `crates/ailang-core/tests/carve_out_inventory.rs::examples_ail_json_inventory_matches_carve_outs`
|
||||
— exactly the eight named carve-out files exist under
|
||||
`examples/*.ail.json` at any commit. A new `.ail.json` or a
|
||||
missing carve-out fails the test.
|
||||
|
||||
A new fixture or a new AST variant that violates the invariant
|
||||
fails one of these tests; the fix is in render or parse code,
|
||||
|
||||
@@ -118,3 +118,9 @@ The per-type `io/print_int`, `io/print_bool`, `io/print_float` operators stay fo
|
||||
Bench continues on the same noise envelope observed across the last ten audits — baseline pristine.
|
||||
|
||||
Queue back to user-direction: the next roadmap item is that corpus migration, which retires the per-type print operators.
|
||||
|
||||
## 2026-05-13 — Form A is now the authoring surface
|
||||
|
||||
`.ail` is now the form you read, edit, and check in. The JSON-AST counterpart is still the canonical hashable representation, but it is no longer something you look at or maintain by hand — the tools derive it from `.ail` whenever they need it. About a hundred example programs that previously existed as JSON-AST were converted to `.ail` and the JSON files were deleted; only eight stay as `.ail.json` (seven negative-test fixtures whose subject matter cannot be expressed in `.ail`, plus the prelude, which is loaded at compile time and depends on internal plumbing that lands in a later milestone).
|
||||
|
||||
If you were used to opening a `.ail.json` file to see what a program looks like, you now open the `.ail` sibling instead.
|
||||
|
||||
@@ -185,3 +185,247 @@ fixtures = 150 paths. Detail:
|
||||
## Stats
|
||||
|
||||
bench/orchestrator-stats/2026-05-13-iter-form-a.1.json
|
||||
|
||||
---
|
||||
|
||||
# iter form-a.1 — Big-bang migration (Tasks 6-12: bench drivers, e2e rewrites, deletion, doctrine, milestone close)
|
||||
|
||||
**Date:** 2026-05-13
|
||||
**Started from:** 9332d1e (post-T1-5 commit 77b28ad + plan-amendment 9332d1e)
|
||||
**Status:** DONE (Tasks 6-12; iter form-a.1 fully closed)
|
||||
**Tasks completed:** 7 of 7 (this dispatch); 12 of 12 (iter total)
|
||||
|
||||
## Summary
|
||||
|
||||
Second half of the form-a-default-authoring milestone-close iter: T6
|
||||
flips the bench-driver fixture suffix from `.ail.json` to `.ail` (4
|
||||
Python scripts + run.sh). T7 re-authors three e2e tests
|
||||
(`diff_detects_changed_def`, `borrow_own_demo_modes_are_metadata_only`,
|
||||
`reuse_as_demo_under_rc_uses_inplace_rewrite`) to derive their
|
||||
canonical-JSON via `ail parse` on the `.ail` source rather than
|
||||
raw-reading the soon-to-be-deleted `.ail.json` file, retires the
|
||||
redundant `render_parse_round_trip_canonical` (subsumed by T1's
|
||||
`cli_parse_then_render_then_parse_is_idempotent`), and re-authors
|
||||
`ail_run_accepts_ail_source_with_same_stdout_as_ail_json` to derive
|
||||
a tempdir-based `hello.ail.json` from `hello.ail` via `ail parse`
|
||||
rather than reading a deleted `.ail.json` sibling. T8 deletes the
|
||||
156 non-carve-out `.ail.json` files (count drops 164 → 8), removes
|
||||
the `#[ignore]` on the carve-out inventory test, and pulls forward
|
||||
20 stale-`.ail.json`-reference repairs that the T1-5 dispatch missed
|
||||
(12 `let example = "X.ail.json"` Group-B sites + 5
|
||||
`ailang_core::load_workspace` Group-A sites in e2e.rs + 3 `ail_run`
|
||||
Group-B sites in typeclass_22b3.rs); to keep T8's green-gate, T9
|
||||
Step 5 (schema_coverage corpus flip from `.ail.json` to `.ail`) is
|
||||
also pulled forward into T8. T9 retires the 3 obsolete roundtrip
|
||||
tests (`print_then_parse_round_trips_every_fixture`,
|
||||
`every_ail_fixture_matches_its_json_counterpart`,
|
||||
`cli_render_then_parse_preserves_canonical_bytes_on_every_fixture`)
|
||||
plus the dead helpers `list_json_fixtures` (×2),
|
||||
`round_trip_one`, and `strip_trailing_newlines`. T10 restates the
|
||||
DESIGN.md §Roundtrip Invariant with parse-determinism + idempotency
|
||||
+ CLI-pipeline-idempotency + carve-out-anchor framing, replacing
|
||||
the old Direction-1/Direction-2 framing and the five enforcement
|
||||
bullets with the five surviving test names. T11 replaces the
|
||||
CLAUDE.md and DESIGN.md doctrine sentences per spec §A4. T12
|
||||
appends the WhatsNew milestone-close entry, strikes the roadmap
|
||||
entry (`- [x]` + `(Closed 2026-05-13 by iter form-a.1.)`), and
|
||||
verifies final inventory (8 `.ail.json` carve-outs + 157 `.ail`).
|
||||
Final test count: 557 green + 3 ignored (3 pre-existing doctests).
|
||||
The `cargo test --workspace` baseline holds green at every per-task
|
||||
boundary; both `python3 bench/compile_check.py` and
|
||||
`python3 bench/cross_lang.py` exit 0. The milestone
|
||||
`[Form-A as the default authoring surface]` is fully closed.
|
||||
|
||||
## Per-task notes
|
||||
|
||||
- **iter form-a.1.6** — Bench-driver suffix flips in
|
||||
`bench/compile_check.py:43,101`, `bench/cross_lang.py:48,80`,
|
||||
`bench/mono_dispatch.py:10,112`, `bench/run.sh:68,182,183`.
|
||||
Mechanical edit; comment text and path string updated at each
|
||||
site. `python3 bench/compile_check.py` exit 0; `python3
|
||||
bench/cross_lang.py` exit 0. (First compile_check run reported
|
||||
exit-1 due to sub-millisecond `check_ms` noise on `hello` and
|
||||
`borrow_own_demo`; second run clean. The noise is unrelated to
|
||||
the migration — the bench measures `ail check` runtime, and the
|
||||
Python edits did not touch the binary path.)
|
||||
- **iter form-a.1.7** — Re-authored 3 raw-JSON-inspect tests +
|
||||
retired 1 + re-authored the dual-form smoke. Pattern for the
|
||||
three substring-assert tests: replace
|
||||
`std::fs::read*("examples/<X>.ail.json")` with a `Command::new(ail_bin()).args(["parse", "examples/<X>.ail", "-o", tmpfile])`
|
||||
+ `read_to_string(tmpfile)`. `reuse_as_demo_under_rc_uses_inplace_rewrite`
|
||||
additionally switches its `ailang_core::load_workspace(&json_path)`
|
||||
call to `ailang_surface::load_workspace(&ail_path)` (the
|
||||
IR-lowering path no longer needs the JSON file). The dual-form
|
||||
smoke (`ail_run_accepts_ail_source_with_same_stdout_as_ail_json`)
|
||||
uses a per-process tempdir with `hello.ail.json` as the file
|
||||
basename — necessary because the loader name-checks the module
|
||||
name against the file stem, and the first attempt at a
|
||||
tempfile-with-PID-suffix path tripped that check. Net test
|
||||
count: −1 (retirement of `render_parse_round_trip_canonical`).
|
||||
559 green at task close.
|
||||
- **iter form-a.1.8** — CRITICAL task. Before the deletion command,
|
||||
20 stale-`.ail.json`-reference repairs were pulled forward
|
||||
(T1-5 dispatch missed these despite the plan's Group-A/B scope):
|
||||
(a) 12 `let example = "X.ail.json"` patterns in `e2e.rs` flipped
|
||||
to `"X.ail"` via sed; (b) 5 `ailang_core::load_workspace(&json_path)`
|
||||
sites in `e2e.rs` switched to `ailang_surface::load_workspace`
|
||||
(the `let example = "X.ail"` from (a) feeds into `workspace.join("examples").join(example)`,
|
||||
which is `.ail` post-flip — needs the extension-dispatching loader);
|
||||
(c) 3 `ail_run("X.ail.json")` sites in `typeclass_22b3.rs` flipped
|
||||
via sed. Cargo-test green pre-deletion at 559. The plan's deletion
|
||||
bash loop ran clean (exit 0); `ls examples/*.ail.json | wc -l` →
|
||||
8, `ls examples/*.ail | wc -l` → 157. The `#[ignore]` attribute
|
||||
on `examples_ail_json_inventory_matches_carve_outs` was removed;
|
||||
the test passes (8 files match `EXPECTED`). Post-deletion
|
||||
cargo-test surfaced 1 failure
|
||||
(`every_ast_variant_is_observed_in_the_fixture_corpus` in
|
||||
`schema_coverage.rs`) because its corpus walker still looked at
|
||||
`.ail.json` (now down to 8 carve-outs, insufficient to cover all
|
||||
AST variants). The plan-T8 vs. T9 ordering implicitly assumed T9
|
||||
Step 5 (schema_coverage corpus flip) would land before T8 — but
|
||||
T9 is plan-ordered after T8. To satisfy T8's green-gate, T9
|
||||
Step 5 was pulled forward inline (helper rename
|
||||
`list_json_fixtures` → `list_ail_fixtures`, filter `.ail.json`
|
||||
→ `.ail`, loader `ailang_core::load_module` →
|
||||
`ailang_surface::load_module`). Post-fix: 560 green + 3 ignored
|
||||
(was 559 pre-T8 with 4 ignored including carve_out_inventory;
|
||||
un-ignore + correct schema_coverage flip = +1 net = 560).
|
||||
- **iter form-a.1.9** — Retired 3 obsolete roundtrip tests +
|
||||
cleanups. `round_trip.rs`: retired
|
||||
`print_then_parse_round_trips_every_fixture` (lines 57-101 in
|
||||
pre-iter numbering) and `every_ail_fixture_matches_its_json_counterpart`
|
||||
(lines 120-204); retired the `list_json_fixtures` helper and
|
||||
the `round_trip_one` helper (only consumers were the two retired
|
||||
tests); updated the file's doc-comment to describe the two
|
||||
surviving tests (`parse_is_deterministic_*` and
|
||||
`parse_then_print_then_parse_*`); removed the unused `Path`
|
||||
import (only `PathBuf` remains). `roundtrip_cli.rs`: retired
|
||||
`cli_render_then_parse_preserves_canonical_bytes_on_every_fixture`
|
||||
(lines 116-146 pre-iter) and the `list_json_fixtures` +
|
||||
`roundtrip_one` + `strip_trailing_newlines` helpers; updated the
|
||||
doc-comment. T9 Step 5 (schema_coverage corpus flip) was already
|
||||
done in T8; nothing to do here. 557 green + 3 ignored at task
|
||||
close (560 pre-T9 − 3 retired = 557).
|
||||
- **iter form-a.1.10** — DESIGN.md §Roundtrip Invariant restatement.
|
||||
Lines 2029-2048 (Direction 1/Direction 2 framing) replaced with
|
||||
the new 4-property framing (parse-determinism +
|
||||
idempotency-under-print + CLI-pipeline-idempotency +
|
||||
carve-out-anchor) verbatim from the plan. Lines 2061-2094
|
||||
(Enforcement bullets, five tests) replaced with the five
|
||||
surviving tests verbatim. Float-literals subsection (lines
|
||||
2050-2059 pre-edit, 2065-2074 post-edit) preserved. Why-anchored-at-top-level
|
||||
subsection (lines 2096-2108 pre-edit, 2108-2120 post-edit)
|
||||
preserved. The numbered prose (4 properties) and the bulleted
|
||||
enforcement (5 tests) are internally consistent; the carve-out
|
||||
inventory is the 5th enforcement bullet, covering property 4
|
||||
("carve-out anchor") as a meta-property.
|
||||
- **iter form-a.1.11** — Doctrine edits. CLAUDE.md:5-6 sentence
|
||||
replaced verbatim with spec §A4 wording. DESIGN.md:465-466 first
|
||||
sentence replaced verbatim with spec §A4 wording; second
|
||||
sentence ("Form (A) is one projection; the JSON-AST stays
|
||||
canonical.") preserved as the trailing sentence of the new
|
||||
replacement block. Doc-only; tests unaffected.
|
||||
- **iter form-a.1.12** — Milestone close. WhatsNew.md entry
|
||||
appended ("Form A is now the authoring surface", per-boss
|
||||
editorial rules: no crate names, no iter codes, lead with the
|
||||
change, factual). docs/roadmap.md entry at line 97 changed from
|
||||
`- [ ]` to `- [x]` with `(Closed 2026-05-13 by iter form-a.1.)`
|
||||
prepended. Final cargo-test: 557 green + 3 ignored. Final bench:
|
||||
both compile_check and cross_lang exit 0. Final inventory:
|
||||
exactly 8 `.ail.json` (carve-outs alphabetically: broken_unbound,
|
||||
prelude, test_22b2_invalid_superclass_param,
|
||||
test_22b2_kind_mismatch, test_22b2_unbound_constraint_var,
|
||||
test_ct1_bad_qualifier, test_ct1_bare_xmod_rejected,
|
||||
test_ct1_qualified_class_rejected) + 157 `.ail`.
|
||||
|
||||
## Concerns
|
||||
|
||||
- **Forward-pull of T9 Step 5 into T8.** The plan ordered T8
|
||||
(deletion) before T9 (test retirement + schema_coverage flip),
|
||||
but T8's green-gate required schema_coverage to be flipped
|
||||
*first* — otherwise the schema_coverage corpus walker shrinks
|
||||
from 164 `.ail.json` to 8 carve-outs and the AST-variant
|
||||
coverage assertion fails. Pulled T9 Step 5 inline into T8;
|
||||
T9 then had no schema_coverage work left to do. Recorded so a
|
||||
future planner-skill recon pass can detect this ordering
|
||||
defect class (a Task K green-gate depending on an edit
|
||||
scripted for Task K+N).
|
||||
- **T1-5 Group-A/B classification gaps.** The T1-5 dispatch's
|
||||
Concerns flagged 4 raw-JSON-inspect e2e.rs tests but missed
|
||||
20 additional sites of the same kind in two patterns: 12
|
||||
`let example = "X.ail.json"` Group-B-pattern sites in e2e.rs
|
||||
(feeds `build_and_run_with_alloc`) + 5
|
||||
`ailang_core::load_workspace` Group-A-pattern sites in e2e.rs
|
||||
+ 3 `ail_run` Group-B sites in typeclass_22b3.rs. All repaired
|
||||
inline in T8 before the deletion command ran. The pattern that
|
||||
T1-5 missed is "binding pulled out of the call expression" —
|
||||
the `let example = "X.ail.json"` introduces a local that the
|
||||
Group-B sed for `build_and_run("X.ail.json")` doesn't match.
|
||||
Worth noting for a future planner-recon tightening pass.
|
||||
- **bench/compile_check.py first-run flakiness.** The first run
|
||||
after T6 reported exit-1 because two `check_ms` metrics on
|
||||
sub-millisecond timings (`hello`, `borrow_own_demo`) drifted
|
||||
past the 25% tolerance; the second run was exit-0. The drift is
|
||||
measurement noise (system load + ms-scale latency), not a
|
||||
migration-induced regression. Final T12 bench run was exit-0
|
||||
on both scripts.
|
||||
|
||||
## Known debt
|
||||
|
||||
- **None known.** The iter closes the milestone cleanly. Two
|
||||
follow-up roadmap items already exist:
|
||||
- `[milestone] Prelude embed: Form-A as compile-time source`
|
||||
(queued; retires carve-out (b) `prelude.ail.json`).
|
||||
- The Show/print fieldtest example-corpus migration (separately
|
||||
queued; orthogonal to this milestone).
|
||||
- Cosmetic: the `mod tests {}` placeholder in
|
||||
`ailang-core/src/hash.rs` from T5 is still in-tree; could be
|
||||
deleted entirely in a doctrinal cleanup pass. Functionally
|
||||
harmless.
|
||||
|
||||
## Files touched (Tasks 6-12)
|
||||
|
||||
### Modified bench (4)
|
||||
|
||||
- `bench/compile_check.py`
|
||||
- `bench/cross_lang.py`
|
||||
- `bench/mono_dispatch.py`
|
||||
- `bench/run.sh`
|
||||
|
||||
### Modified test source (5)
|
||||
|
||||
- `crates/ail/tests/e2e.rs` — T7 re-authoring of 5 tests; T8
|
||||
forward-pull of 12 Group-B + 5 Group-A sites
|
||||
- `crates/ail/tests/typeclass_22b3.rs` — T8 forward-pull of 3
|
||||
Group-B sites
|
||||
- `crates/ail/tests/roundtrip_cli.rs` — T9 retirement +
|
||||
helpers cleanup + doc-comment update
|
||||
- `crates/ailang-surface/tests/round_trip.rs` — T9 retirement +
|
||||
helpers cleanup + doc-comment update + import cleanup
|
||||
- `crates/ailang-core/tests/schema_coverage.rs` — T8 corpus flip
|
||||
to `.ail` (pulled forward from T9 Step 5)
|
||||
|
||||
### Modified test discipline (1)
|
||||
|
||||
- `crates/ailang-core/tests/carve_out_inventory.rs` — T8 un-ignored
|
||||
|
||||
### Modified doc (4)
|
||||
|
||||
- `CLAUDE.md` — T11 doctrine sentence (lines 5-6)
|
||||
- `docs/DESIGN.md` — T10 §Roundtrip Invariant restatement; T11
|
||||
§"What this Decision deliberately does not do" first sentence
|
||||
- `docs/WhatsNew.md` — T12 milestone-close entry
|
||||
- `docs/roadmap.md` — T12 strike of the Form-A milestone entry
|
||||
|
||||
### Deleted (T8) — 156 files
|
||||
|
||||
`examples/*.ail.json` — every non-carve-out fixture (the eight
|
||||
carve-outs `broken_unbound`, `prelude`,
|
||||
`test_22b2_invalid_superclass_param`, `test_22b2_kind_mismatch`,
|
||||
`test_22b2_unbound_constraint_var`, `test_ct1_bad_qualifier`,
|
||||
`test_ct1_bare_xmod_rejected`, `test_ct1_qualified_class_rejected`
|
||||
preserved).
|
||||
|
||||
## Stats
|
||||
|
||||
bench/orchestrator-stats/2026-05-13-iter-form-a.1.json
|
||||
|
||||
@@ -52,3 +52,4 @@
|
||||
- 2026-05-13 — audit-24: milestone close (Show + print rewire) — architect drift report surfaces 5 actionable items routing to `24.tidy` (3× [high]: DESIGN.md §"Monomorphisation" doc-anchor missing for three iter-24.3 strengthenings — MonoTarget::FreeFn::type_args canonical-form normalisation, post-mono synthesised-body cross-module-ref import_map-bypass invariant, FreeFnCall constraint-residual push; codegen import_map-fallback path has no unit-level pin — only E2E catches regression; FreeFnCall constraint-residual push covers only dot-qualified branch, bare-name poly-fn refs uncovered; 2× [medium]: unwrap_or_default in method-name lookup masks class-index drift, normalize_type_for_lookup duplicated across two mono.rs sites with manual-lockstep invariant), plus 1× [medium] deferred to roadmap P3 (negative-test coverage single-shape — only f:Int→Int, broader shapes wait for downstream corpus-migration milestone), plus 1× [low] carry-on (bench/architect_sweeps.sh noise on pre-milestone-24 DESIGN.md lines, not new drift). Bench: cross_lang.py exit 0 (25/25 stable); check.py + compile_check.py exit 1 with metric-identity-migrating noise envelope per audit-cma → audit-ms → audit-eob → audit-ct-tidy → audit-mq → audit-mq.tidy → iter-24.2 → iter-24.3 lineage — 9th consecutive observation; conservative-call convention holds baseline pristine across all 9, the metric-migration-between-runs is itself attribution evidence variance not signal; right ratification path is the queued P3 latency-methodology-histogram rework, not --update-baseline → 2026-05-13-audit-24.md
|
||||
- 2026-05-13 — iter 24.tidy: close 5 actionable drift items from audit-24 — T1 DESIGN.md new subsection §Cross-module references in synthesised bodies (3 invariants installed iter 24.3: canonical-form MonoTarget::FreeFn::type_args via normalize_type_for_lookup, post-mono synthesised body import_map-bypass + module_user_fns fallback, FreeFnCall constraint-residual push per declared forall-constraint); T2 codegen_import_map_fallback_pin (integration test asserts prelude.print__<UserType> body references user_module.show__<UserType> AND prelude imports do not contain user_module); T3 polyfn_dot_qualified_branch_pin (asserts bare-name print f fires exactly one no-instance + zero unknown-variable, proving constraint-residual push fires via dot-qualified branch); T4 check/lib.rs:2858 unwrap_or_default → expect(class_methods registry coherence) — surfaces class-index drift on regression; T5 mono.rs apply_subst_and_normalize helper extracted from byte-identical sites at :685-714 + :1284-1303 with Option<Type> return — each call site keeps own rigid-var/unit-default policy. Tests 558/558 (was 556+2 pins). Bench cross_lang exit 0 stable, compile_check + check both exit 0 this run (10th consecutive lineage observation unobserved-firing). audit-24 medium-3 negative-test breadth defers to roadmap P3; low-1 sweep noise carry-on → 2026-05-13-iter-24.tidy.md
|
||||
- 2026-05-13 — iter form-a.0: prelude pilot for Form-A-as-default-authoring milestone — examples/prelude.ail rendered (116 lines / 6386 bytes) via `ail render`; two auto-discovering roundtrip tests (every_ail_fixture_matches_its_json_counterpart + parse_then_print_then_parse_is_idempotent_on_every_ail_fixture) green on the new fixture without test-code changes; prelude.ail.json retained per spec §A2 (singular dual-form iter, deletion lands iter 1 with bulk test-infra refactor); cargo test --workspace green at 558 tests → 2026-05-13-iter-form-a.0.md
|
||||
- 2026-05-13 — iter form-a.1: Form-A-as-default-authoring milestone close (Boss-decided strategy C, big-bang) — 12 tasks across two implementer dispatches; T1 added 3 new tests (parse-determinism + CLI-pipeline-idempotency + carve_out_inventory#[ignore]) + T2 bulk-rendered 99 missing examples/<stem>.ail (corpus 58→157 .ail) + T3-4 migrated 26 fixture-loading test files (Group A load_workspace→ailang_surface::load_workspace + Group B subprocess suffix flip) + T5 relocated 23 #[cfg(test)] mod tests blocks from ailang-core/-codegen production source to integration test crates with ailang-surface dev-dep (hash_pin.rs + workspace_pin.rs + eq_primitives_pin.rs + prose snapshot migration) + T6 bench-driver suffix flips (4 Python + run.sh, both compile_check.py + cross_lang.py exit 0) + T7 re-authored 4 raw-JSON-inspect e2e tests via `ail parse`-derived tempfiles + retired 1 (render_parse_round_trip_canonical subsumed by T1) + T8 deleted 156 non-carve-out .ail.json (inventory 8 carve-outs + 157 .ail post-T8, alphabetical: broken_unbound + prelude + 3× test_22b2_* + 3× test_ct1_*) + 20 forward-pulled stale-.ail.json-ref repairs missed by T1-5 recon + T9 retired 3 obsolete roundtrip tests (print_then_parse_round_trips_every_fixture + every_ail_fixture_matches_its_json_counterpart + cli_render_then_parse_preserves_canonical_bytes_on_every_fixture) + dead helpers (list_json_fixtures ×2, round_trip_one, strip_trailing_newlines) + flipped schema_coverage corpus to .ail (forward-pulled into T8 for green-gate) + T10 §C3 DESIGN.md §Roundtrip Invariant restated with parse-determinism + idempotency + CLI-pipeline-idempotency + carve-out-anchor framing (5 surviving enforcement tests named) + T11 §A4 CLAUDE.md + DESIGN.md doctrine sentences replaced (canonical form is JSON-AST; authoring form is .ail) + T12 WhatsNew milestone-close entry + roadmap [milestone] form-a struck [x] (Closed 2026-05-13 by iter form-a.1). 4 carve-outs added beyond the original 7 §C4(a): only 1 — prelude.ail.json — landed as §C4(b) compile-time-embed (rationale: include_str! at workspace.rs:417 + main.rs:474; resolution queued as separate milestone Prelude embed: Form-A as compile-time source). Spec amendment + grounding-recheck PASS at 9fcda8b. Final tests: 557 green + 3 ignored (561 from T1 − 4 retired = 557); bench compile_check.py + cross_lang.py exit 0; check.py noise envelope continues 11th consecutive audit, baseline pristine. Milestone structurally closed → 2026-05-13-iter-form-a.1.md
|
||||
|
||||
+2
-2
@@ -94,8 +94,8 @@ context. Pick the next milestone from P1.)_
|
||||
form-a.0 — `examples/prelude.ail` rendered via `ail render`,
|
||||
116 lines / 6386 bytes, round-trip-CI green.)
|
||||
|
||||
- [ ] **\[milestone\]** Form-A as the default authoring surface for
|
||||
examples and docs. Render every `examples/*.ail.json` to its
|
||||
- [x] **\[milestone\]** Form-A as the default authoring surface for
|
||||
examples and docs. (Closed 2026-05-13 by iter form-a.1.) Render every `examples/*.ail.json` to its
|
||||
`.ail` sibling via `ail render`, **delete the now-redundant
|
||||
`.ail.json`**, and regenerate the JSON-AST per `ail parse` at
|
||||
build / test time. Same for inline JSON-AST blocks in `docs/`
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"args":[{"args":[{"args":[{"name":"seed","t":"var"}],"fn":{"name":"f","t":"var"},"t":"app"}],"fn":{"name":"f","t":"var"},"t":"app"}],"fn":{"name":"f","t":"var"},"t":"app"},"doc":"Higher-order: apply f three times to seed.","kind":"fn","name":"apply_thrice","params":["f","seed"],"type":{"effects":[],"k":"fn","params":[{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"cond":{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"<","t":"var"},"t":"app"},"else":{"body":{"name":"i","t":"var"},"in":{"body":{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"acc","t":"var"},{"name":"r","t":"var"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"run_loop","t":"var"},"t":"app","tail":true},"name":"r","t":"let","value":{"args":[{"name":"helper","t":"var"},{"name":"i","t":"var"}],"fn":{"name":"apply_thrice","t":"var"},"t":"app"}},"name":"helper","params":["x"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"t":"if","then":{"name":"acc","t":"var"}},"doc":"For each i in [n-1, n-2, ..., 0], build a closure capturing i, pass to apply_thrice, accumulate. Tail-recursive on i and acc.","kind":"fn","name":"run_loop","params":["i","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"run_loop","t":"var"},"t":"app"},"doc":"Drive run_loop from i=n-1 down to 0.","kind":"fn","name":"run","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":10000},"t":"lit"}],"fn":{"name":"run","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":100000},"t":"lit"}],"fn":{"name":"run","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":500000},"t":"lit"}],"fn":{"name":"run","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_closure_chain","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"cond":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":2},"t":"lit"}],"fn":{"name":"%","t":"var"},"t":"app"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":3},"t":"lit"}],"fn":{"name":"*","t":"var"},"t":"app"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"},{"args":[{"name":"acc","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"collatz_steps","t":"var"},"t":"app","tail":true},"t":"if","then":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":2},"t":"lit"}],"fn":{"name":"/","t":"var"},"t":"app"},{"args":[{"name":"acc","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"collatz_steps","t":"var"},"t":"app","tail":true}},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Tail-recursive: count Collatz steps from n to 1, accumulating in acc.","kind":"fn","name":"collatz_steps","params":["n","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"cond":{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"total","t":"var"},{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"collatz_steps","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"sum_steps_loop","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"total","t":"var"}},"doc":"Tail-recursive: sum collatz_steps(i) for i in [n, n-1, ..., 1].","kind":"fn","name":"sum_steps_loop","params":["i","total"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"sum_steps_loop","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"kind":"fn","name":"run_one","params":["n"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":10000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"lhs":{"args":[{"lit":{"kind":"int","value":100000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"args":[{"lit":{"kind":"int","value":500000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_compute_collatz","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"cond":{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"acc","t":"var"},{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":7},"t":"lit"}],"fn":{"name":"*","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"intsum_loop","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Tail-recursive: acc += i*7 for i in [n, n-1, ..., 1]. Returns final acc.","kind":"fn","name":"intsum_loop","params":["i","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"intsum_loop","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"kind":"fn","name":"run_one","params":["n"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":1000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"lhs":{"args":[{"lit":{"kind":"int","value":10000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"args":[{"lit":{"kind":"int","value":50000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_compute_intsum","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"Nil"},{"fields":[{"k":"var","name":"a"},{"args":[{"k":"var","name":"a"}],"k":"con","name":"List"}],"name":"Cons"}],"doc":"Polymorphic singly-linked list. Same shape as list_map_poly's List, replicated here so the bench fixture is self-contained.","kind":"type","name":"List","vars":["a"]},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"acc","t":"var"}],"ctor":"Cons","t":"ctor","type":"List"}],"fn":{"name":"build_n","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Build [0, 1, ..., n-1] :: List Int. Tail-recursive accumulator form.","kind":"fn","name":"build_n","params":["n","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"args":[{"k":"con","name":"Int"}],"k":"con","name":"List"}],"ret":{"args":[{"k":"con","name":"Int"}],"k":"con","name":"List"}}},{"body":{"args":[{"name":"x","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"},"doc":"Add 1 to an Int. Used as the HOF argument to fold_with_fn.","kind":"fn","name":"inc","params":["x"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"arms":[{"body":{"name":"acc","t":"var"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"f","t":"var"},{"name":"t","t":"var"},{"args":[{"name":"acc","t":"var"},{"args":[{"name":"h","t":"var"}],"fn":{"name":"f","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"fold_with_fn","t":"var"},"t":"app","tail":true},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Polymorphic foldl-with-mapping. Apply f:(a)->Int to every element of xs, sum into acc. Tail-recursive on (xs, acc); the f arg is forwarded unchanged.","kind":"fn","name":"fold_with_fn","params":["f","xs","acc"],"type":{"body":{"effects":[],"k":"fn","params":[{"effects":[],"k":"fn","params":[{"k":"var","name":"a"}],"ret":{"k":"con","name":"Int"}},{"args":[{"k":"var","name":"a"}],"k":"con","name":"List"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}},"k":"forall","vars":["a"]}},{"body":{"args":[{"args":[{"name":"inc","t":"var"},{"args":[{"name":"n","t":"var"},{"args":[],"ctor":"Nil","t":"ctor","type":"List"}],"fn":{"name":"build_n","t":"var"},"t":"app"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"fold_with_fn","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"doc":"Build [0..n-1], fold with inc, print sum of (inc x).","kind":"fn","name":"run_one","params":["n"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":100000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"lhs":{"args":[{"lit":{"kind":"int","value":1000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"args":[{"lit":{"kind":"int","value":3000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_hof_pipeline","schema":"ailang/v0"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"INil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"ICons"}],"kind":"type","name":"IntList"},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"acc","t":"var"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Tail-recursive list builder. Result = accumulator-prepended list.","kind":"fn","name":"cons_n_acc","params":["n","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"IntList"}}},{"body":{"args":[{"name":"n","t":"var"},{"args":[],"ctor":"INil","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app"},"doc":"Build [0, 1, ..., n-1] :: IntList. Order doesn't matter for sum.","kind":"fn","name":"cons_n","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"IntList"}}},{"body":{"arms":[{"body":{"name":"acc","t":"var"},"pat":{"ctor":"INil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"t","t":"var"},{"args":[{"name":"acc","t":"var"},{"name":"h","t":"var"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"sum_acc","t":"var"},"t":"app","tail":true},"pat":{"ctor":"ICons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Tail-recursive sum.","kind":"fn","name":"sum_acc","params":["xs","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"IntList"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"name":"xs","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"sum_acc","t":"var"},"t":"app"},"doc":"Sum every element. Calls sum_acc with seed 0.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"name":"n","t":"var"}],"fn":{"name":"cons_n","t":"var"},"t":"app"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"doc":"Build a list of length n, sum it, print the sum.","kind":"fn","name":"run_one","params":["n"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":100000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"lhs":{"args":[{"lit":{"kind":"int","value":1000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"args":[{"lit":{"kind":"int","value":3000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_list_sum","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"INil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"ICons"}],"doc":"Singly-linked Int list. drop-iterative so Own-param drops are O(1) stack.","drop-iterative":true,"kind":"type","name":"IntList"},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"acc","t":"var"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Tail-recursive: prepend (n-1, n-2, ..., 0) onto acc. Returns owned chain.","kind":"fn","name":"cons_n_acc","params":["n","acc"],"type":{"effects":[],"k":"fn","param_modes":["implicit","own"],"params":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"IntList"},"ret_mode":"own"}},{"body":{"args":[{"name":"n","t":"var"},{"args":[],"ctor":"INil","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app"},"doc":"Build [0..n-1] :: IntList. Returns owned chain; caller owns and consumes.","kind":"fn","name":"cons_n","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"IntList"},"ret_mode":"own"}},{"body":{"arms":[{"body":{"name":"acc","t":"var"},"pat":{"ctor":"INil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"t","t":"var"},{"args":[{"name":"acc","t":"var"},{"name":"h","t":"var"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"sum_acc","t":"var"},"t":"app","tail":true},"pat":{"ctor":"ICons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Tail-recursive sum. Owns xs; consumes via LCons-arm move-into-tail-call.","kind":"fn","name":"sum_acc","params":["xs","acc"],"type":{"effects":[],"k":"fn","param_modes":["own","implicit"],"params":[{"k":"con","name":"IntList"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"name":"xs","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"sum_acc","t":"var"},"t":"app"},"doc":"Sum every element. Owns xs, hands it to sum_acc which consumes it.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","param_modes":["own"],"params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"name":"n","t":"var"}],"fn":{"name":"cons_n","t":"var"},"t":"app"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"doc":"Build, sum, print. The owned list flows from cons_n into sum_list and is fully consumed.","kind":"fn","name":"run_one","params":["n"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":100000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"lhs":{"args":[{"lit":{"kind":"int","value":1000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"args":[{"lit":{"kind":"int","value":3000000},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_list_sum_explicit","schema":"ailang/v0"}
|
||||
@@ -1,139 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "bench_mono_dispatch",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "class", "name": "Foo", "param": "a",
|
||||
"methods": [{
|
||||
"name": "foo",
|
||||
"type": {
|
||||
"k": "fn", "params": [{ "k": "var", "name": "a" }],
|
||||
"ret": { "k": "con", "name": "Int" }, "effects": []
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Foo",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"methods": [{
|
||||
"name": "foo",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x"],
|
||||
"paramTypes": [{ "k": "var", "name": "a" }],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "*" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "x" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1103515245 } }
|
||||
]
|
||||
},
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 12345 } }
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"kind": "class", "name": "Looper", "param": "a",
|
||||
"methods": [{
|
||||
"name": "loop_call",
|
||||
"type": {
|
||||
"k": "fn", "params": [{ "k": "var", "name": "a" }, { "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" }, "effects": []
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Looper",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"methods": [{
|
||||
"name": "loop_call",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["i", "acc"],
|
||||
"paramTypes": [{ "k": "var", "name": "a" }, { "k": "con", "name": "Int" }],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"body": {
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "==" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "i" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "var", "name": "acc" },
|
||||
"else": {
|
||||
"t": "app",
|
||||
"tail": true,
|
||||
"fn": { "t": "var", "name": "loop_call" },
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "-" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "i" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "acc" },
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "foo" },
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "acc" },
|
||||
{ "t": "var", "name": "i" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "loop_call" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 100000000 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"Leaf"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"Tree"},{"k":"con","name":"Tree"}],"name":"Node"}],"kind":"type","name":"Tree"},{"body":{"cond":{"args":[{"name":"depth","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"depth","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build_tree","t":"var"},"t":"app"},{"args":[{"args":[{"name":"depth","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build_tree","t":"var"},"t":"app"}],"ctor":"Node","t":"ctor","type":"Tree"},"t":"if","then":{"args":[],"ctor":"Leaf","t":"ctor","type":"Tree"}},"doc":"Balanced binary tree of given depth, every value = 1.","kind":"fn","name":"build_tree","params":["depth"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Tree"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Leaf","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"v","t":"var"},{"args":[{"args":[{"name":"l","t":"var"}],"fn":{"name":"sum_tree","t":"var"},"t":"app"},{"args":[{"name":"r","t":"var"}],"fn":{"name":"sum_tree","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Node","fields":[{"name":"v","p":"var"},{"name":"l","p":"var"},{"name":"r","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"t","t":"var"},"t":"match"},"doc":"Sum every Node value via match recursion. Constructor-blocked: not tail-recursive, but recursion depth = tree depth so fits.","kind":"fn","name":"sum_tree","params":["t"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"name":"depth","t":"var"}],"fn":{"name":"build_tree","t":"var"},"t":"app"}],"fn":{"name":"sum_tree","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"doc":"Build a tree of given depth, sum it, print the sum.","kind":"fn","name":"run_one","params":["depth"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":16},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"lhs":{"args":[{"lit":{"kind":"int","value":18},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"rhs":{"args":[{"lit":{"kind":"int","value":20},"t":"lit"}],"fn":{"name":"run_one","t":"var"},"t":"app"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_tree_walk","schema":"ailang/v0"}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "bool_to_str_drop_rc",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter 24.1: pin that `bool_to_str` participates in RC discipline. Bind the heap-Str result to `s`, consume `s` once in `io/print_str`, let the binder drop at scope close. Under --alloc=rc with AILANG_RC_STATS=1 the atexit summary must report allocs == 1 && frees == 1 && live == 0 — the heap-Str slab allocated by str_alloc inside ailang_bool_to_str rides the same rc_header + ailang_rc_dec path as int_to_str.",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "s",
|
||||
"value": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "bool_to_str" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "bool", "value": true } }]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [{ "t": "var", "name": "s" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "bool_to_str_smoke_false",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter 24.1: stdout-smoke for the false branch of bool_to_str. Stdout must be `false\\n` (puts adds the newline). Companion of bool_to_str_drop_rc.ail.json (which covers the true branch and the RC-stats invariant).",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "s",
|
||||
"value": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "bool_to_str" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "bool", "value": false } }]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [{ "t": "var", "name": "s" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"Nil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"List"}],"name":"Cons"}],"doc":"Monomorphic singly-linked Int list — boxed, recursive.","kind":"type","name":"List"},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"list_length","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Borrow xs, count its elements. Iter 18a: `(borrow (con List))`.","kind":"fn","name":"list_length","params":["xs"],"type":{"effects":[],"k":"fn","param_modes":["borrow"],"params":[{"k":"con","name":"List"}],"ret":{"k":"con","name":"Int"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"h","t":"var"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Consume xs, sum its elements. Iter 18a: `(own (con List))`.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","param_modes":["own"],"params":[{"k":"con","name":"List"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"lhs":{"args":[{"args":[{"name":"xs","t":"var"}],"fn":{"name":"list_length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"name":"xs","t":"var"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"name":"xs","t":"let","value":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"lit":{"kind":"int","value":2},"t":"lit"},{"args":[{"lit":{"kind":"int","value":3},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"List"}],"ctor":"Cons","t":"ctor","type":"List"}],"ctor":"Cons","t":"ctor","type":"List"}],"ctor":"Cons","t":"ctor","type":"List"}},"doc":"Build [1,2,3]; print list_length (3) then sum_list (6).","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"borrow_own_demo","schema":"ailang/v0"}
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "box",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "Box",
|
||||
"vars": ["a"],
|
||||
"doc": "A unary box around a polymorphic value.",
|
||||
"ctors": [
|
||||
{
|
||||
"name": "MkBox",
|
||||
"fields": [{ "k": "var", "name": "a" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "unbox",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a"],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "con",
|
||||
"name": "Box",
|
||||
"args": [{ "k": "var", "name": "a" }]
|
||||
}
|
||||
],
|
||||
"ret": { "k": "var", "name": "a" },
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["b"],
|
||||
"doc": "Polymorphic projection out of a Box.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "b" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "MkBox",
|
||||
"fields": [{ "p": "var", "name": "x" }]
|
||||
},
|
||||
"body": { "t": "var", "name": "x" }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Round-trip 42 through MkBox + unbox.",
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "unbox" },
|
||||
"args": [
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "Box",
|
||||
"ctor": "MkBox",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 42 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"body":{"args":[{"t":"clone","value":{"name":"x","t":"var"}}],"op":"io/print_int","t":"do"},"name":"x","t":"let","value":{"lit":{"kind":"int","value":42},"t":"lit"}},"doc":"Use `(clone x)` on a let-bound Int; print it.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"clone_demo","schema":"ailang/v0"}
|
||||
@@ -1,77 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "closure",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "apply",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["f", "x"],
|
||||
"doc": "apply a fn-of-Int to an Int",
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "f" },
|
||||
"args": [{ "t": "var", "name": "x" }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "captures `n` from the enclosing let, returns 42",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "n",
|
||||
"value": { "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "apply" },
|
||||
"args": [
|
||||
{
|
||||
"t": "lam",
|
||||
"params": ["x"],
|
||||
"paramTypes": [{ "k": "con", "name": "Int" }],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"effects": [],
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "x" },
|
||||
{ "t": "var", "name": "n" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 39 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "cmp_max_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "cmp_max",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a"],
|
||||
"constraints": [{ "class": "prelude.Ord", "type": { "k": "var", "name": "a" } }],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }, { "k": "var", "name": "a" }],
|
||||
"ret": { "k": "var", "name": "a" },
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["x", "y"],
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [{ "t": "var", "name": "x" }, { "t": "var", "name": "y" }]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "type": "prelude.Ordering", "ctor": "LT", "fields": [] }, "body": { "t": "var", "name": "y" } },
|
||||
{ "pat": { "p": "wild" }, "body": { "t": "var", "name": "x" } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "cmp_max" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 7 } }
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "compare_primitives_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "b" } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "b" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } }
|
||||
]
|
||||
},
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "ctor": "LT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "EQ", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } } },
|
||||
{ "pat": { "p": "ctor", "ctor": "GT", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 3 } } }
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"INil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"ICons"}],"doc":"Local Int-list ADT; nothing fancy.","kind":"type","name":"IntList"},{"body":{"arms":[{"body":{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},"pat":{"ctor":"LT","fields":[],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"EQ","fields":[],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":1},"t":"lit"},"pat":{"ctor":"GT","fields":[],"p":"ctor"}}],"scrutinee":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"compare","t":"var"},"t":"app"},"t":"match"},"doc":"Map an Int to -1/0/+1 via prelude.compare. Returns the sign as an Int.","kind":"fn","name":"signum","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"arms":[{"body":{"lit":{"kind":"unit"},"t":"lit"},"pat":{"ctor":"INil","fields":[],"p":"ctor"}},{"body":{"lhs":{"args":[{"args":[{"name":"h","t":"var"}],"fn":{"name":"signum","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"name":"t","t":"var"}],"fn":{"name":"drain","t":"var"},"t":"app","tail":true},"t":"seq"},"pat":{"ctor":"ICons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Print signum of every element of xs, in list order.","kind":"fn","name":"drain","params":["xs"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"lit":{"kind":"int","value":3},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"args":[{"lit":{"kind":"int","value":7},"t":"lit"},{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"lit":{"kind":"int","value":2},"t":"lit"},{"args":[],"ctor":"INil","t":"ctor","type":"IntList"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"fn":{"name":"drain","t":"var"},"t":"app"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"ct_1_ordering_signum","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"name":"m","t":"var"},"doc":"Identity over Maybe<Int>; signature uses bare `Maybe` instead of `std_maybe.Maybe`.","kind":"fn","name":"classify","params":["m"],"type":{"effects":[],"k":"fn","params":[{"args":[{"k":"con","name":"Int"}],"k":"con","name":"Maybe"}],"ret":{"args":[{"k":"con","name":"Int"}],"k":"con","name":"Maybe"}}},{"body":{"args":[{"args":[{"lit":{"kind":"int","value":99},"t":"lit"},{"args":[{"args":[{"lit":{"kind":"int","value":7},"t":"lit"}],"ctor":"Just","t":"ctor","type":"std_maybe.Maybe"}],"fn":{"name":"classify","t":"var"},"t":"app"}],"fn":{"name":"std_maybe.from_maybe","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[{"module":"std_maybe"}],"name":"ct_2_bare_cross_module","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"name":"w","t":"var"},"doc":"Identity at mystery.Widget — but `mystery` is not a workspace module.","kind":"fn","name":"passthrough","params":["w"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"mystery.Widget"}],"ret":{"k":"con","name":"mystery.Widget"}}},{"body":{"args":[{"lit":{"kind":"str","value":"unreachable"},"t":"lit"}],"op":"io/print_str","t":"do"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"ct_3_bad_qualified","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"name":"w","t":"var"},"doc":"Identity at std_maybe.Widget — `std_maybe` is real, but `Widget` is not in it.","kind":"fn","name":"passthrough","params":["w"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"std_maybe.Widget"}],"ret":{"k":"con","name":"std_maybe.Widget"}}},{"body":{"args":[{"lit":{"kind":"str","value":"unreachable"},"t":"lit"}],"op":"io/print_str","t":"do"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[{"module":"std_maybe"}],"name":"ct_3b_bad_qualified_known_module","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[{"k":"con","name":"Int"}],"name":"MkBox"}],"doc":"A trivial Int wrapper.","kind":"type","name":"Box"},{"class":"prelude.Eq","kind":"instance","methods":[{"body":{"body":{"arms":[{"body":{"arms":[{"body":{"args":[{"name":"a","t":"var"},{"name":"b","t":"var"}],"fn":{"name":"==","t":"var"},"t":"app"},"pat":{"ctor":"MkBox","fields":[{"name":"b","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"y","t":"var"},"t":"match"},"pat":{"ctor":"MkBox","fields":[{"name":"a","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"x","t":"var"},"t":"match"},"effects":[],"paramTypes":[{"k":"con","name":"Box"},{"k":"con","name":"Box"}],"params":["x","y"],"retType":{"k":"con","name":"Bool"},"t":"lam"},"name":"eq"}],"type":{"k":"con","name":"Box"}}],"imports":[],"name":"ct_4_qualified_class","schema":"ailang/v0"}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "ctt2_collision_cls",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "MyC",
|
||||
"param": "a",
|
||||
"methods": [
|
||||
{
|
||||
"name": "op",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "ctt2_collision_lib",
|
||||
"imports": [{ "module": "ctt2_collision_cls" }],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "Foo",
|
||||
"ctors": [{ "name": "MkLib", "fields": [] }]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "ctt2_collision_cls.MyC",
|
||||
"type": { "k": "con", "name": "Foo" },
|
||||
"methods": [
|
||||
{
|
||||
"name": "op",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["_x"],
|
||||
"paramTypes": [{ "k": "con", "name": "Foo" }],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 2 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "ctt2_collision_main",
|
||||
"imports": [
|
||||
{ "module": "ctt2_collision_cls" },
|
||||
{ "module": "ctt2_collision_lib" }
|
||||
],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "Foo",
|
||||
"ctors": [{ "name": "MkMain", "fields": [] }]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "ctt2_collision_cls.MyC",
|
||||
"type": { "k": "con", "name": "Foo" },
|
||||
"methods": [
|
||||
{
|
||||
"name": "op",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["_x"],
|
||||
"paramTypes": [{ "k": "con", "name": "Foo" }],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"arms":[{"body":{"lit":{"kind":"int","value":1},"t":"lit"},"pat":{"lit":{"kind":"str","value":"hi"},"p":"lit"}},{"body":{"lit":{"kind":"int","value":2},"t":"lit"},"pat":{"lit":{"kind":"str","value":"ho"},"p":"lit"}},{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"p":"wild"}}],"scrutinee":{"name":"s","t":"var"},"t":"match"},"doc":"Lit-pattern over Str; exercises 16c's build_eq for non-Int.","kind":"fn","name":"classify_str","params":["s"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Str"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"},{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"},{"lit":{"kind":"int","value":6},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"bool","value":true},"t":"lit"},{"lit":{"kind":"bool","value":false},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"bool","value":true},"t":"lit"},{"lit":{"kind":"bool","value":true},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"str","value":"hi"},"t":"lit"},{"lit":{"kind":"str","value":"hi"},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"str","value":"hi"},"t":"lit"},{"lit":{"kind":"str","value":"ho"},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"unit"},"t":"lit"},{"lit":{"kind":"unit"},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"str","value":"hi"},"t":"lit"}],"fn":{"name":"classify_str","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"str","value":"ho"},"t":"lit"}],"fn":{"name":"classify_str","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"str","value":"??"},"t":"lit"}],"fn":{"name":"classify_str","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"doc":"Drive == at Int/Bool/Str/Unit; then drive classify_str.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"eq_demo","schema":"ailang/v0"}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "eq_float_noinstance",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "float", "bits": "3ff0000000000000" } },
|
||||
{ "t": "lit", "lit": { "kind": "float", "bits": "4000000000000000" } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "eq_ord_polymorphic",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "at_most",
|
||||
"doc": "Composition of prelude `gt` with `not` — semantically equivalent to `le`. Used to exercise polymorphic-helper-over-prelude-fns composition through the unified mono pass.",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a"],
|
||||
"constraints": [{ "class": "prelude.Ord", "type": { "k": "var", "name": "a" } }],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"param_modes": ["borrow", "borrow"],
|
||||
"ret": { "k": "con", "name": "Bool" },
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["x", "y"],
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "not" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "gt" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "x" },
|
||||
{ "t": "var", "name": "y" }
|
||||
]
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "at_most" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 5 } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "at_most" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "at_most" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "abc" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "abd" } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "eq_ord_user_adt",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "IntBox",
|
||||
"vars": [],
|
||||
"doc": "A one-field box around an Int, used to demonstrate that the unified mono pass synthesises eq__IntBox from a user-written instance, not from the primitive == operator.",
|
||||
"ctors": [
|
||||
{ "name": "MkIntBox", "fields": [{ "k": "con", "name": "Int" }] }
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "prelude.Eq",
|
||||
"type": { "k": "con", "name": "IntBox" },
|
||||
"doc": "Eq IntBox by structural unwrap of the inner Int.",
|
||||
"methods": [
|
||||
{
|
||||
"name": "eq",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["a", "b"],
|
||||
"paramTypes": [
|
||||
{ "k": "con", "name": "IntBox" },
|
||||
{ "k": "con", "name": "IntBox" }
|
||||
],
|
||||
"retType": { "k": "con", "name": "Bool" },
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "a" },
|
||||
"arms": [{
|
||||
"pat": { "p": "ctor", "ctor": "MkIntBox", "fields": [{ "p": "var", "name": "ai" }] },
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "b" },
|
||||
"arms": [{
|
||||
"pat": { "p": "ctor", "ctor": "MkIntBox", "fields": [{ "p": "var", "name": "bi" }] },
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "==" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "ai" },
|
||||
{ "t": "var", "name": "bi" }
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "prelude.Ord",
|
||||
"type": { "k": "con", "name": "IntBox" },
|
||||
"doc": "Ord IntBox by delegating to Int's compare on the inner field.",
|
||||
"methods": [
|
||||
{
|
||||
"name": "compare",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["a", "b"],
|
||||
"paramTypes": [
|
||||
{ "k": "con", "name": "IntBox" },
|
||||
{ "k": "con", "name": "IntBox" }
|
||||
],
|
||||
"retType": { "k": "con", "name": "prelude.Ordering" },
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "a" },
|
||||
"arms": [{
|
||||
"pat": { "p": "ctor", "ctor": "MkIntBox", "fields": [{ "p": "var", "name": "ai" }] },
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "b" },
|
||||
"arms": [{
|
||||
"pat": { "p": "ctor", "ctor": "MkIntBox", "fields": [{ "p": "var", "name": "bi" }] },
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "ai" },
|
||||
{ "t": "var", "name": "bi" }
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{
|
||||
"t": "ctor", "type": "IntBox", "ctor": "MkIntBox",
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 3 } }]
|
||||
},
|
||||
{
|
||||
"t": "ctor", "type": "IntBox", "ctor": "MkIntBox",
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 3 } }]
|
||||
}
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{
|
||||
"t": "ctor", "type": "IntBox", "ctor": "MkIntBox",
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 3 } }]
|
||||
},
|
||||
{
|
||||
"t": "ctor", "type": "IntBox", "ctor": "MkIntBox",
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 5 } }]
|
||||
}
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "eq_primitives_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "to_int",
|
||||
"doc": "1 if the bool is true, 0 otherwise. Used to render Eq results as printable Ints.",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Bool" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["b"],
|
||||
"body": {
|
||||
"t": "if",
|
||||
"cond": { "t": "var", "name": "b" },
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "to_int" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 7 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 7 } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "to_int" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 7 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 8 } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "to_int" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "to_int" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "to_int" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "hello" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "hello" } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "to_int" },
|
||||
"args": [{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "hello" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "world" } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[{"k":"var","name":"a"}],"name":"MkBox"}],"kind":"type","name":"Box","vars":["a"]},{"body":{"body":{"arms":[{"body":{"lit":{"kind":"int","value":42},"t":"lit"},"pat":{"ctor":"MkBox","fields":[{"p":"wild"}],"p":"ctor"}}],"scrutinee":{"name":"b","t":"var"},"t":"match"},"name":"b","t":"let","value":{"args":[{"name":"n","t":"var"}],"ctor":"MkBox","t":"ctor","type":"Box"}},"doc":"Build a Box(n), discard the payload, return 42. The Box is non-escaping.","kind":"fn","name":"peek","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"<=","t":"var"},"t":"app"},"else":{"body":{"arms":[{"body":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"count","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"MkBox","fields":[{"p":"wild"}],"p":"ctor"}}],"scrutinee":{"name":"b","t":"var"},"t":"match"},"name":"b","t":"let","value":{"args":[{"name":"n","t":"var"}],"ctor":"MkBox","t":"ctor","type":"Box"}},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"doc":"Recurse n times; each call builds a temporary Box, discards its payload via _, and returns 0 if n<=0, else 1 + count(n-1).","kind":"fn","name":"count","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"peek","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":123},"t":"lit"}],"fn":{"name":"peek","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"count","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"count","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"t":"seq"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"escape_local_demo","schema":"ailang/v0"}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "float_to_str_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter hs.4: smoke pin for the float_to_str heap-Str builtin. `do io/print_str(float_to_str(3.5))` builds through the whole pipeline (checker resolves float_to_str:(Float)->Str, codegen lowers to call ptr @ailang_float_to_str(double 3.5), runtime/str.c's ailang_float_to_str snprintfs into a heap-Str slab via libc %g, io/print_str's @puts prints from the bytes pointer at offset 8). The exact rendering of 3.5 is libc-target-dependent; on the dev target's clang+glibc with default C locale it is the three bytes `3.5`. Single-value smoke; NaN / +Inf / -Inf edge cases are deferred per the hs.4 plan.",
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "float_to_str" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "float", "bits": "400c000000000000" } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "floats",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_float",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "float", "bits": "3ff8000000000000" } },
|
||||
{ "t": "lit", "lit": { "kind": "float", "bits": "4004000000000000" } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_float",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "int_to_float" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 42 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_float",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "neg" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "float", "bits": "3ff8000000000000" } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"Nil"},{"fields":[{"k":"var","name":"a"},{"args":[{"k":"var","name":"a"}],"k":"con","name":"List"}],"name":"Cons"}],"doc":"Polymorphic singly-linked list (re-declared locally).","kind":"type","name":"List","vars":["a"]},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"name":"n","t":"var"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build","t":"var"},"t":"app"}],"ctor":"Cons","t":"ctor","type":"List"},"t":"if","then":{"args":[],"ctor":"Nil","t":"ctor","type":"List"}},"doc":"Build [n, n-1, ..., 1] :: List Int via Cons recursion.","kind":"fn","name":"build","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"args":[{"k":"con","name":"Int"}],"k":"con","name":"List"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"h","t":"var"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Recursively sum a List Int.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","params":[{"args":[{"k":"con","name":"Int"}],"k":"con","name":"List"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":50},"t":"lit"}],"fn":{"name":"build","t":"var"},"t":"app"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"doc":"Build [50..1], sum, print 1275.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"gc_stress","schema":"ailang/v0"}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "ge_at_int_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "ge" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 5 } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "gt_at_bool_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "gt" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "heap_str_repeated_print_borrow",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter eob.1: heap-Str passed to io/print_str twice in sequence. Under the new rule (Term::Do args = Borrow), the second call no longer triggers use-after-consume; the linearity check accepts the program. Under --alloc=rc + AILANG_RC_STATS=1 the slab allocates once and is freed once at scope close (allocs == 1, frees == 1, live == 0).",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "s",
|
||||
"value": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "int_to_str" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
|
||||
},
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [{ "t": "var", "name": "s" }]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [{ "t": "var", "name": "s" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "hello",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "Hello, AILang." } }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "hof",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "inc",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["x"],
|
||||
"doc": "increment by one",
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "x" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "apply",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["f", "x"],
|
||||
"doc": "apply a fn-of-Int to an Int",
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "f" },
|
||||
"args": [{ "t": "var", "name": "x" }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "apply" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "inc" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 41 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "int_to_print_int_borrow",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter eob.1: primitive Int passed to io/print_int. The rule that Term::Do args are Borrow has no observable RC effect here because Int is unboxed; the test pins that no spurious bookkeeping appears (allocs == 0, frees == 0, live == 0).",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "n",
|
||||
"value": { "t": "lit", "lit": { "kind": "int", "value": 7 } },
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{ "t": "var", "name": "n" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "int_to_str_drop_rc",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter hs.4: pin that `int_to_str` participates in RC discipline. Bind the heap-Str result to `s`, consume `s` once in `io/print_str`, let the binder drop at scope close. Under --alloc=rc with AILANG_RC_STATS=1 the atexit summary must report allocs == frees && live == 0 — the heap-Str slab allocated by str_alloc inside ailang_int_to_str rides the same rc_header + ailang_rc_dec path as any other RC value.",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "s",
|
||||
"value": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "int_to_str" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [{ "t": "var", "name": "s" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "int_to_str_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Iter hs.4: smoke pin for the int_to_str heap-Str builtin. `do io/print_str(int_to_str(42))` builds through the whole pipeline (checker resolves int_to_str:(Int)->Str, codegen lowers to call ptr @ailang_int_to_str(i64 42), runtime/str.c's ailang_int_to_str snprintfs into a heap-Str slab, io/print_str's @puts prints from the bytes pointer at offset 8). Single-value smoke; the spec's broader edge-case sweep (0, -1, i64::MAX, i64::MIN) is deferred to a follow-up tidy iter per the hs.4 plan.",
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "int_to_str" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "le_at_str_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "le" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "abc" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "abd" } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "list",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "IntList",
|
||||
"doc": "Einfach verkettete Int-Liste, boxed.",
|
||||
"ctors": [
|
||||
{ "name": "Nil", "fields": [] },
|
||||
{
|
||||
"name": "Cons",
|
||||
"fields": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "IntList" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "sum_list",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "IntList" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["xs"],
|
||||
"doc": "Summiert die Elemente einer Int-Liste rekursiv.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "h" },
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "sum_list" },
|
||||
"args": [{ "t": "var", "name": "t" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Baut [10, 20, 12] und druckt die Summe (42).",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "xs",
|
||||
"value": {
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 10 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 20 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 12 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "sum_list" },
|
||||
"args": [{ "t": "var", "name": "xs" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "list_map",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "IntList",
|
||||
"doc": "Singly-linked list of Int, boxed.",
|
||||
"ctors": [
|
||||
{ "name": "Nil", "fields": [] },
|
||||
{
|
||||
"name": "Cons",
|
||||
"fields": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "IntList" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "map_int",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
{ "k": "con", "name": "IntList" }
|
||||
],
|
||||
"ret": { "k": "con", "name": "IntList" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["f", "xs"],
|
||||
"doc": "Apply f to every element. Recursive on the tail.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "f" },
|
||||
"args": [{ "t": "var", "name": "h" }]
|
||||
},
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "map_int" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "f" },
|
||||
{ "t": "var", "name": "t" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "print_list",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "IntList" }],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": ["xs"],
|
||||
"doc": "Print each Int on its own line.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "unit" } }
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{ "t": "var", "name": "h" }]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "print_list" },
|
||||
"args": [{ "t": "var", "name": "t" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Build [1,2,3], double each, print result.",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "xs",
|
||||
"value": {
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "print_list" },
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "map_int" },
|
||||
"args": [
|
||||
{
|
||||
"t": "lam",
|
||||
"params": ["x"],
|
||||
"paramTypes": [{ "k": "con", "name": "Int" }],
|
||||
"retType": { "k": "con", "name": "Int" },
|
||||
"effects": [],
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "*" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "x" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "t": "var", "name": "xs" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "list_map_poly",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "List",
|
||||
"vars": ["a"],
|
||||
"doc": "Polymorphic singly-linked list.",
|
||||
"ctors": [
|
||||
{ "name": "Nil", "fields": [] },
|
||||
{
|
||||
"name": "Cons",
|
||||
"fields": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{
|
||||
"k": "con",
|
||||
"name": "List",
|
||||
"args": [{ "k": "var", "name": "a" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "inc",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["x"],
|
||||
"doc": "Add 1 to an Int.",
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "x" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "map",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a", "b"],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"ret": { "k": "var", "name": "b" },
|
||||
"effects": []
|
||||
},
|
||||
{
|
||||
"k": "con",
|
||||
"name": "List",
|
||||
"args": [{ "k": "var", "name": "a" }]
|
||||
}
|
||||
],
|
||||
"ret": {
|
||||
"k": "con",
|
||||
"name": "List",
|
||||
"args": [{ "k": "var", "name": "b" }]
|
||||
},
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["f", "xs"],
|
||||
"doc": "Polymorphic map: apply f to every element, recursing on the tail.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "List",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "List",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "f" },
|
||||
"args": [{ "t": "var", "name": "h" }]
|
||||
},
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "map" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "f" },
|
||||
{ "t": "var", "name": "t" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "print_list",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "con",
|
||||
"name": "List",
|
||||
"args": [{ "k": "con", "name": "Int" }]
|
||||
}
|
||||
],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": ["xs"],
|
||||
"doc": "Print each Int on its own line.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "unit" } }
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{ "t": "var", "name": "h" }]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "print_list" },
|
||||
"args": [{ "t": "var", "name": "t" }],
|
||||
"tail": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Map inc over [1,2,3] via polymorphic List, then print: 2,3,4.",
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "print_list" },
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "map" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "inc" },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "List",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "List",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "List",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "List",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"Nil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"Cons"}],"kind":"type","name":"IntList"},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":100},"t":"lit"},"pat":{"lit":{"kind":"int","value":0},"p":"lit"}},{"body":{"lit":{"kind":"int","value":200},"t":"lit"},"pat":{"lit":{"kind":"int","value":1},"p":"lit"}},{"body":{"lit":{"kind":"int","value":999},"t":"lit"},"pat":{"p":"wild"}}],"scrutinee":{"name":"n","t":"var"},"t":"match"},"doc":"Map 0->100, 1->200, anything else->999.","kind":"fn","name":"classify","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":-1},"t":"lit"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Cons","fields":[{"lit":{"kind":"int","value":0},"p":"lit"},{"p":"wild"}],"p":"ctor"}},{"body":{"name":"h","t":"var"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"p":"wild"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Empty -> -1; first element 0 -> 0; otherwise return the head.","kind":"fn","name":"categorize_first","params":["xs"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"classify","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"classify","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":17},"t":"lit"}],"fn":{"name":"classify","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[],"ctor":"Nil","t":"ctor","type":"IntList"}],"fn":{"name":"categorize_first","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"fn":{"name":"categorize_first","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":7},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"fn":{"name":"categorize_first","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"doc":"Drive both fns. Expected (per line): 100, 200, 999, -1, 0, 7.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"lit_pat","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"f","t":"var"},"t":"app"},"doc":"Higher-order: applies its fn argument to 5.","kind":"fn","name":"apply5","params":["f"],"type":{"effects":[],"k":"fn","params":[{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"<=","t":"var"},"t":"app"},"else":{"args":[{"name":"n","t":"var"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"factorial","t":"var"},"t":"app"}],"fn":{"name":"*","t":"var"},"t":"app"},"t":"if","then":{"lit":{"kind":"int","value":1},"t":"lit"}},"in":{"args":[{"args":[{"name":"factorial","t":"var"}],"fn":{"name":"apply5","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"name":"factorial","params":["n"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"doc":"Iter 16b.5: pass a let-rec'd factorial as a value to apply5. Expected stdout: 120.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"local_rec_as_value","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"f","t":"var"},"t":"app"},"doc":"Higher-order: applies its fn argument to 5.","kind":"fn","name":"apply5","params":["f"],"type":{"effects":[],"k":"fn","params":[{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"<=","t":"var"},"t":"app"},"else":{"args":[{"name":"n","t":"var"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"factorial_plus","t":"var"},"t":"app"}],"fn":{"name":"*","t":"var"},"t":"app"},"t":"if","then":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"name":"base","t":"var"}],"fn":{"name":"+","t":"var"},"t":"app"}},"in":{"args":[{"name":"factorial_plus","t":"var"}],"fn":{"name":"apply5","t":"var"},"t":"app"},"name":"factorial_plus","params":["n"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"doc":"Build a recursive helper that captures `base` and pass it as a value to apply5.","kind":"fn","name":"run_with_base","params":["base"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"}],"fn":{"name":"run_with_base","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":100},"t":"lit"}],"fn":{"name":"run_with_base","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"doc":"Iter 16b.5: pass a capturing let-rec helper as a value. Expected stdout: 1320, 12120.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"local_rec_as_value_capture","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"body":{"cond":{"args":[{"name":"i","t":"var"},{"name":"n","t":"var"}],"fn":{"name":">=","t":"var"},"t":"app"},"else":{"args":[{"name":"i","t":"var"},{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"loop","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"in":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"loop","t":"var"},"t":"app"},"name":"loop","params":["i"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"doc":"Sum 1 + 2 + ... + (n-1). Helper captures n from the enclosing scope.","kind":"fn","name":"sum_below","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"sum_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"sum_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"}],"fn":{"name":"sum_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"doc":"Drive sum_below at 1, 5, 10. Expected (per line): 0, 10, 45.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"local_rec_capture","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"<=","t":"var"},"t":"app"},"else":{"args":[{"name":"n","t":"var"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"fact","t":"var"},"t":"app"}],"fn":{"name":"*","t":"var"},"t":"app"},"t":"if","then":{"lit":{"kind":"int","value":1},"t":"lit"}},"in":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"fact","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":3},"t":"lit"}],"fn":{"name":"fact","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"fact","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"name":"fact","params":["n"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"doc":"Iter 16b.1: drive a let-rec'd factorial helper at three inputs. Expected stdout (per line): 1, 6, 120.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"local_rec_demo","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"body":{"body":{"cond":{"args":[{"name":"i","t":"var"},{"name":"n","t":"var"}],"fn":{"name":">","t":"var"},"t":"app"},"else":{"cond":{"args":[{"name":"i","t":"var"},{"name":"threshold","t":"var"}],"fn":{"name":"<","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"loop","t":"var"},"t":"app"},"t":"if","then":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"loop","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"in":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"loop","t":"var"},"t":"app"},"name":"loop","params":["i"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"name":"threshold","t":"let","value":{"args":[{"lit":{"kind":"int","value":5},"t":"lit"},{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}},"doc":"Count i in 1..=n with i < threshold, where threshold = 5+5.","kind":"fn","name":"count_below","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"count_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"count_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":15},"t":"lit"}],"fn":{"name":"count_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"doc":"Drive count_below at 0, 5, 15. Expected (per line): 0, 5, 9.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"local_rec_let_capture","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[{"k":"var","name":"a"},{"k":"var","name":"b"}],"name":"MkPair"}],"kind":"type","name":"Pair","vars":["a","b"]},{"body":{"arms":[{"body":{"body":{"cond":{"args":[{"name":"i","t":"var"},{"name":"n","t":"var"}],"fn":{"name":">","t":"var"},"t":"app"},"else":{"cond":{"args":[{"name":"i","t":"var"},{"name":"threshold","t":"var"}],"fn":{"name":"<","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"loop","t":"var"},"t":"app"},"t":"if","then":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"loop","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"in":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"loop","t":"var"},"t":"app"},"name":"loop","params":["i"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"pat":{"ctor":"MkPair","fields":[{"name":"threshold","p":"var"},{"name":"n","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"p","t":"var"},"t":"match"},"doc":"Match-arm captures `threshold` and `n`; inner LetRec captures both.","kind":"fn","name":"count_below","params":["p"],"type":{"effects":[],"k":"fn","params":[{"args":[{"k":"con","name":"Int"},{"k":"con","name":"Int"}],"k":"con","name":"Pair"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"},{"lit":{"kind":"int","value":0},"t":"lit"}],"ctor":"MkPair","t":"ctor","type":"Pair"}],"fn":{"name":"count_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"},{"lit":{"kind":"int","value":5},"t":"lit"}],"ctor":"MkPair","t":"ctor","type":"Pair"}],"fn":{"name":"count_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"},{"lit":{"kind":"int","value":15},"t":"lit"}],"ctor":"MkPair","t":"ctor","type":"Pair"}],"fn":{"name":"count_below","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"doc":"Drive count_below at MkPair 10 {0,5,15}. Expected: 0, 5, 9.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"local_rec_match_capture","schema":"ailang/v0"}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "lt_at_int_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "lt" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 5 } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "max3",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "max",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["a", "b"],
|
||||
"body": {
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": ">" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "a" },
|
||||
{ "t": "var", "name": "b" }
|
||||
]
|
||||
},
|
||||
"then": { "t": "var", "name": "a" },
|
||||
"else": { "t": "var", "name": "b" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "max3",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["a", "b", "c"],
|
||||
"doc": "Demonstriert verschachteltes if (statt max-call) zum Test des Block-Trackings.",
|
||||
"body": {
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": ">" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "a" },
|
||||
{ "t": "var", "name": "b" }
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": ">" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "a" },
|
||||
{ "t": "var", "name": "c" }
|
||||
]
|
||||
},
|
||||
"then": { "t": "var", "name": "a" },
|
||||
"else": { "t": "var", "name": "c" }
|
||||
},
|
||||
"else": {
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": ">" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "b" },
|
||||
{ "t": "var", "name": "c" }
|
||||
]
|
||||
},
|
||||
"then": { "t": "var", "name": "b" },
|
||||
"else": { "t": "var", "name": "c" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "max3" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 17 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 9 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "maybe_int",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "Maybe",
|
||||
"vars": ["a"],
|
||||
"doc": "Optional value with a polymorphic payload.",
|
||||
"ctors": [
|
||||
{ "name": "None", "fields": [] },
|
||||
{
|
||||
"name": "Some",
|
||||
"fields": [{ "k": "var", "name": "a" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "or_else",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "con",
|
||||
"name": "Maybe",
|
||||
"args": [{ "k": "con", "name": "Int" }]
|
||||
},
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["m", "d"],
|
||||
"doc": "Returns the wrapped Int for Some(x) and the default d for None.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "m" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "None", "fields": [] },
|
||||
"body": { "t": "var", "name": "d" }
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Some",
|
||||
"fields": [{ "p": "var", "name": "x" }]
|
||||
},
|
||||
"body": { "t": "var", "name": "x" }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Print or_else for both arms; expected 7 then 99.",
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "or_else" },
|
||||
"args": [
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "Maybe",
|
||||
"ctor": "Some",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 7 } }
|
||||
]
|
||||
},
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 99 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "or_else" },
|
||||
"args": [
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "Maybe",
|
||||
"ctor": "None",
|
||||
"args": []
|
||||
},
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 99 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mono_hash_pin_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "ord_to_int",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "prelude.Ordering" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["o"],
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "o" },
|
||||
"arms": [
|
||||
{ "pat": { "p": "ctor", "type": "prelude.Ordering", "ctor": "LT", "fields": [] }, "body": { "t": "lit", "lit": { "kind": "int", "value": -1 } } },
|
||||
{ "pat": { "p": "ctor", "type": "prelude.Ordering", "ctor": "EQ", "fields": [] }, "body": { "t": "lit", "lit": { "kind": "int", "value": 0 } } },
|
||||
{ "pat": { "p": "ctor", "type": "prelude.Ordering", "ctor": "GT", "fields": [] }, "body": { "t": "lit", "lit": { "kind": "int", "value": 1 } } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_bool",
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_bool",
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_bool",
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "eq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } }
|
||||
]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "ord_to_int" },
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "ord_to_int" },
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": false } },
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "ord_to_int" },
|
||||
"args": [{
|
||||
"t": "app", "fn": { "t": "var", "name": "compare" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "a" } },
|
||||
{ "t": "lit", "lit": { "kind": "str", "value": "b" } }
|
||||
]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq1_xmod_constraint_class",
|
||||
"imports": [{ "module": "mq1_xmod_constraint_class_dep" }],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "useShow",
|
||||
"doc": "Positive mq.1 fixture: a polymorphic fn that takes a single value and a Show constraint, ignores the value, and returns Unit. Exercises the qualified `Constraint.class` shape end-to-end (loader + validator + check_workspace).",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a"],
|
||||
"constraints": [
|
||||
{ "class": "mq1_xmod_constraint_class_dep.Show",
|
||||
"type": { "k": "var", "name": "a" } }
|
||||
],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"param_modes": ["borrow"],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["_x"],
|
||||
"body": { "t": "lit", "lit": { "kind": "unit" } }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq1_xmod_constraint_class_dep",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "Show",
|
||||
"param": "a",
|
||||
"methods": [
|
||||
{
|
||||
"name": "show",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"ret": { "k": "con", "name": "Str" },
|
||||
"effects": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_class_eq_vs_fn_eq",
|
||||
"imports": [
|
||||
{ "module": "mq3_class_eq_vs_fn_eq_classmod" },
|
||||
{ "module": "mq3_class_eq_vs_fn_eq_fnmod" }
|
||||
],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"doc": "mq.3.6 fixture (c): bare `myeq 1 2` in a workspace with `class MyEq` (in classmod) and `fn myeq` (in fnmod) both imported. Fn wins per lookup precedence; the typechecker emits `class-method-shadowed-by-fn` warning so the LLM-author sees the shadow.",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_bool",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "myeq" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_class_eq_vs_fn_eq_classmod",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "MyEq",
|
||||
"param": "a",
|
||||
"methods": [
|
||||
{
|
||||
"name": "myeq",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"param_modes": ["borrow", "borrow"],
|
||||
"ret": { "k": "con", "name": "Bool" },
|
||||
"effects": []
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "MyEq",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"methods": [
|
||||
{
|
||||
"name": "myeq",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x", "y"],
|
||||
"paramTypes": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"retType": { "k": "con", "name": "Bool" },
|
||||
"body": { "t": "lit", "lit": { "kind": "bool", "value": true } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_class_eq_vs_fn_eq_fnmod",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "myeq",
|
||||
"doc": "mq.3.6 fixture (c) helper: free fn `myeq` that shadows the class method `myeq` declared in `mq3_class_eq_vs_fn_eq_classmod`. Always returns false so the fn-wins precedence is observable at runtime if the e2e test ever runs the binary.",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "Int" }
|
||||
],
|
||||
"param_modes": ["borrow", "borrow"],
|
||||
"ret": { "k": "con", "name": "Bool" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["x", "y"],
|
||||
"body": { "t": "lit", "lit": { "kind": "bool", "value": false } }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_two_show_ambiguous",
|
||||
"imports": [
|
||||
{ "module": "mq3_two_show_ambiguous_a" },
|
||||
{ "module": "mq3_two_show_ambiguous_b" }
|
||||
],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"doc": "mq.3.6 fixture (a): bare `show 42` in a workspace where two Show classes (in modA and modB) each ship Show Int. Without an explicit qualifier the dispatch is genuinely ambiguous; the typechecker must fire `ambiguous-method-resolution` naming both candidate classes.",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "show" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_two_show_ambiguous_a",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "Show",
|
||||
"param": "a",
|
||||
"methods": [
|
||||
{
|
||||
"name": "show",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"param_modes": ["borrow"],
|
||||
"ret": { "k": "con", "name": "Str" },
|
||||
"effects": []
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Show",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"methods": [
|
||||
{
|
||||
"name": "show",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x"],
|
||||
"paramTypes": [{ "k": "con", "name": "Int" }],
|
||||
"retType": { "k": "con", "name": "Str" },
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "int_to_str" },
|
||||
"args": [{ "t": "var", "name": "x" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_two_show_ambiguous_b",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "Show",
|
||||
"param": "a",
|
||||
"methods": [
|
||||
{
|
||||
"name": "show",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"param_modes": ["borrow"],
|
||||
"ret": { "k": "con", "name": "Str" },
|
||||
"effects": []
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Show",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"methods": [
|
||||
{
|
||||
"name": "show",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x"],
|
||||
"paramTypes": [{ "k": "con", "name": "Int" }],
|
||||
"retType": { "k": "con", "name": "Str" },
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "int_to_str" },
|
||||
"args": [{ "t": "var", "name": "x" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "mq3_two_show_qualified",
|
||||
"imports": [
|
||||
{ "module": "mq3_two_show_ambiguous_a" },
|
||||
{ "module": "mq3_two_show_ambiguous_b" }
|
||||
],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"doc": "mq.3.6 fixture (b): explicit qualifier `mq3_two_show_ambiguous_a.Show.show 42` disambiguates the same workspace as fixture (a). Resolves cleanly to modA's class; typecheck passes.",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_str",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "mq3_two_show_ambiguous_a.Show.show" },
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "ne_at_int_smoke",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn", "params": [], "ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do", "op": "io/print_int",
|
||||
"args": [{
|
||||
"t": "if",
|
||||
"cond": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "ne" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 5 } }
|
||||
]
|
||||
},
|
||||
"then": { "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
"else": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"body":{"cond":{"args":[{"name":"i","t":"var"},{"name":"n","t":"var"}],"fn":{"name":">","t":"var"},"t":"app"},"else":{"args":[{"body":{"cond":{"args":[{"name":"j","t":"var"},{"name":"i","t":"var"}],"fn":{"name":">","t":"var"},"t":"app"},"else":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"j","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"inner","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"in":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"inner","t":"var"},"t":"app"},"name":"inner","params":["j"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"args":[{"args":[{"name":"i","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"outer","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"in":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"outer","t":"var"},"t":"app"},"name":"outer","params":["i"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},"doc":"Sum 1 + 2 + ... + n by nested LetRec helpers; inner captures outer's param i.","kind":"fn","name":"nested_sum","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"nested_sum","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":3},"t":"lit"}],"fn":{"name":"nested_sum","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"}],"fn":{"name":"nested_sum","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"doc":"Drive nested_sum at 1, 3, 5. Expected (per line): 1, 6, 15.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"nested_let_rec","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"arms":[{"body":{"args":[{"name":"a","t":"var"},{"name":"b","t":"var"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"name":"a","p":"var"},{"ctor":"Cons","fields":[{"name":"b","p":"var"},{"p":"wild"}],"p":"ctor"}],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"p":"wild"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Sum of the first two elements of an Int list, or 0 if shorter than two.","kind":"fn","name":"first_two_sum","params":["xs"],"type":{"effects":[],"k":"fn","params":[{"args":[{"k":"con","name":"Int"}],"k":"con","name":"std_list.List"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"},{"args":[{"lit":{"kind":"int","value":20},"t":"lit"},{"args":[{"lit":{"kind":"int","value":30},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"fn":{"name":"first_two_sum","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[{"module":"std_list"}],"name":"nested_pat","schema":"ailang/v0"}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "ordering_match",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": {
|
||||
"k": "con",
|
||||
"name": "Unit"
|
||||
},
|
||||
"effects": [
|
||||
"IO"
|
||||
]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "match",
|
||||
"scrutinee": {
|
||||
"t": "ctor",
|
||||
"type": "prelude.Ordering",
|
||||
"ctor": "LT",
|
||||
"args": []
|
||||
},
|
||||
"arms": [
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "LT",
|
||||
"fields": []
|
||||
},
|
||||
"body": {
|
||||
"t": "lit",
|
||||
"lit": {
|
||||
"kind": "int",
|
||||
"value": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "EQ",
|
||||
"fields": []
|
||||
},
|
||||
"body": {
|
||||
"t": "lit",
|
||||
"lit": {
|
||||
"kind": "int",
|
||||
"value": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "GT",
|
||||
"fields": []
|
||||
},
|
||||
"body": {
|
||||
"t": "lit",
|
||||
"lit": {
|
||||
"kind": "int",
|
||||
"value": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"doc": "Iter 23.1 fixture: pattern-match on prelude Ordering ctor without explicit prelude import."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"Nil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"Cons"}],"doc":"Recursive Int list — boxed.","kind":"type","name":"IntList"},{"ctors":[{"fields":[{"k":"con","name":"IntList"},{"k":"con","name":"IntList"}],"name":"Pair"}],"doc":"Two IntLists side by side. Both fields are pointer-typed; the test exercises move-tracking against EACH slot independently.","kind":"type","name":"Pair"},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"h","t":"var"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Consume xs, sum its elements.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"arms":[{"body":{"args":[{"args":[{"name":"a","t":"var"}],"fn":{"name":"sum_list","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"pat":{"ctor":"Pair","fields":[{"name":"a","p":"var"},{"p":"wild"}],"p":"ctor"}}],"scrutinee":{"name":"p","t":"var"},"t":"match"},"name":"p","t":"let","value":{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"lit":{"kind":"int","value":2},"t":"lit"},{"args":[{"lit":{"kind":"int","value":3},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"},{"args":[{"lit":{"kind":"int","value":4},"t":"lit"},{"args":[{"lit":{"kind":"int","value":5},"t":"lit"},{"args":[{"lit":{"kind":"int","value":6},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"ctor":"Cons","t":"ctor","type":"IntList"}],"ctor":"Pair","t":"ctor","type":"Pair"}},"doc":"Build Pair([1,2,3], [4,5,6]); pattern-bind first slot only; sum first list. The wildcarded second slot's IntList lives only inside the Pair box; closing the Pair's let scope must dec it (non-moved) while skipping the moved first slot.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"pat_extract_partial_drop","schema":"ailang/v0"}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "poly_apply",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "apply",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a", "b"],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"ret": { "k": "var", "name": "b" },
|
||||
"effects": []
|
||||
},
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"ret": { "k": "var", "name": "b" },
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["f", "x"],
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "f" },
|
||||
"args": [{ "t": "var", "name": "x" }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "succ",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "Int" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["n"],
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "n" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "apply" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "succ" },
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 41 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "poly_id",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "id",
|
||||
"type": {
|
||||
"k": "forall",
|
||||
"vars": ["a"],
|
||||
"body": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "var", "name": "a" }],
|
||||
"ret": { "k": "var", "name": "a" },
|
||||
"effects": []
|
||||
}
|
||||
},
|
||||
"params": ["x"],
|
||||
"body": { "t": "var", "name": "x" }
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"body": {
|
||||
"t": "seq",
|
||||
"lhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "id" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 42 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rhs": {
|
||||
"t": "do",
|
||||
"op": "io/print_bool",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "id" },
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "bool", "value": true } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"body":{"args":[{"name":"x","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"+","t":"var"},"t":"app"},"doc":"Helper: increment Int. Used as the Fn(Int) -> Int instance.","kind":"fn","name":"succ","params":["x"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"name":"b","t":"var"}],"fn":{"name":"not","t":"var"},"t":"app"},"doc":"Helper: boolean negation as a top-level fn (so it has an adapter for value-position).","kind":"fn","name":"flip","params":["b"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Bool"}],"ret":{"k":"con","name":"Bool"}}},{"body":{"body":{"cond":{"args":[{"name":"k","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"k","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"acc","t":"var"}],"fn":{"name":"f","t":"var"},"t":"app"}],"fn":{"name":"loop","t":"var"},"t":"app"},"t":"if","then":{"name":"acc","t":"var"}},"in":{"args":[{"name":"n","t":"var"},{"name":"x","t":"var"}],"fn":{"name":"loop","t":"var"},"t":"app"},"name":"loop","params":["k","acc"],"t":"letrec","type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"var","name":"a"}],"ret":{"k":"var","name":"a"}}},"doc":"Apply f to x exactly n times. Polymorphic in a.","kind":"fn","name":"apply_n_times","params":["n","x","f"],"type":{"body":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"var","name":"a"},{"effects":[],"k":"fn","params":[{"k":"var","name":"a"}],"ret":{"k":"var","name":"a"}}],"ret":{"k":"var","name":"a"}},"k":"forall","vars":["a"]}},{"body":{"lhs":{"args":[{"args":[{"lit":{"kind":"int","value":5},"t":"lit"},{"lit":{"kind":"int","value":0},"t":"lit"},{"name":"succ","t":"var"}],"fn":{"name":"apply_n_times","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"lit":{"kind":"int","value":4},"t":"lit"},{"lit":{"kind":"bool","value":false},"t":"lit"},{"name":"flip","t":"var"}],"fn":{"name":"apply_n_times","t":"var"},"t":"app"}],"op":"io/print_bool","t":"do"},"t":"seq"},"doc":"Drive apply_n_times at Int (succ 5 times from 0) and Bool (not 4 times from false).","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"poly_rec_capture","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[{"k":"con","name":"Int"}],"name":"MkWrap"}],"kind":"type","name":"Wrap"},{"ctors":[{"fields":[{"k":"con","name":"Wrap"},{"k":"con","name":"Wrap"}],"name":"MkCell"}],"kind":"type","name":"Cell"},{"ctors":[{"fields":[{"k":"con","name":"Cell"},{"k":"con","name":"Cell"}],"name":"MkPair"}],"kind":"type","name":"Pair"},{"body":{"args":[{"args":[{"args":[{"name":"n","t":"var"}],"ctor":"MkWrap","t":"ctor","type":"Wrap"},{"args":[{"lit":{"kind":"int","value":2},"t":"lit"}],"ctor":"MkWrap","t":"ctor","type":"Wrap"}],"ctor":"MkCell","t":"ctor","type":"Cell"},{"args":[{"args":[{"lit":{"kind":"int","value":3},"t":"lit"}],"ctor":"MkWrap","t":"ctor","type":"Wrap"},{"args":[{"lit":{"kind":"int","value":4},"t":"lit"}],"ctor":"MkWrap","t":"ctor","type":"Wrap"}],"ctor":"MkCell","t":"ctor","type":"Cell"}],"ctor":"MkPair","t":"ctor","type":"Pair"},"kind":"fn","name":"build_pair","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Pair"},"ret_mode":"own"}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":1},"t":"lit"},"pat":{"ctor":"MkCell","fields":[{"name":"w1","p":"var"},{"name":"w2","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"c","t":"var"},"t":"match"},"kind":"fn","name":"use_cell","params":["c"],"suppress":[{"because":"RC codegen test: shape used to feed App-bound let-close partial-drop into use_cell","code":"over-strict-mode"}],"type":{"effects":[],"k":"fn","param_modes":["own"],"params":[{"k":"con","name":"Cell"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"args":[{"arms":[{"body":{"args":[{"name":"a","t":"var"}],"fn":{"name":"use_cell","t":"var"},"t":"app"},"pat":{"ctor":"MkPair","fields":[{"name":"a","p":"var"},{"p":"wild"}],"p":"ctor"}}],"scrutinee":{"name":"p","t":"var"},"t":"match"}],"op":"io/print_int","t":"do"},"name":"p","t":"let","value":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"build_pair","t":"var"},"t":"app"}},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"rc_app_let_partial_drop_leak","schema":"ailang/v0"}
|
||||
@@ -1,59 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "rc_box_drop",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "Box",
|
||||
"vars": [],
|
||||
"doc": "Single-cell ADT around an Int. Iter 18c.3 RC fixture: shallow free is sufficient because Box has no boxed children.",
|
||||
"ctors": [
|
||||
{
|
||||
"name": "MkBox",
|
||||
"fields": [{ "k": "con", "name": "Int" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Bind a heap-allocated MkBox to `b`, read its Int via match, print it. Under --alloc=rc, codegen emits `ailang_rc_dec(b)` at the let scope close: `b` is unique, has zero consume uses (only the match scrutinee, a borrow), and the body's tail value is the printed Unit, not `b` itself. The Box has no boxed children so shallow `free()` is correct.",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "b",
|
||||
"value": {
|
||||
"t": "ctor",
|
||||
"type": "Box",
|
||||
"ctor": "MkBox",
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
|
||||
},
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "b" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "MkBox",
|
||||
"fields": [{ "p": "var", "name": "x" }]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{ "t": "var", "name": "x" }]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"INil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"ICons"}],"drop-iterative":true,"kind":"type","name":"IntList"},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"n","t":"var"},{"name":"acc","t":"var"}],"ctor":"ICons","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Tail-recursive list builder. acc-prepended.","kind":"fn","name":"cons_n_acc","params":["n","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"IntList"}}},{"body":{"args":[{"name":"n","t":"var"},{"args":[],"ctor":"INil","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app"},"doc":"Build [1, 2, ..., n] :: IntList. Order is reverse of build but immaterial for head/sum.","kind":"fn","name":"cons_n","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"IntList"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"INil","fields":[],"p":"ctor"}},{"body":{"name":"h","t":"var"},"pat":{"ctor":"ICons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Take ownership of an IntList; return its head if ICons, else 0. The (own ...) signature signals 18d.4 to emit an Own-param drop at fn return — which under the (drop-iterative) annotation is the iterative-worklist body, freeing the entire chain via the heap-allocated worklist instead of recursive cascade.","kind":"fn","name":"head_or_zero","params":["xs"],"suppress":[{"because":"Iter 18e test: forces (drop-iterative) cascade via Own-param drop at fn return","code":"over-strict-mode"}],"type":{"effects":[],"k":"fn","param_modes":["own"],"params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":1000000},"t":"lit"}],"fn":{"name":"cons_n","t":"var"},"t":"app"}],"fn":{"name":"head_or_zero","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"rc_drop_iterative_long_list","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"TLeaf"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"Tree"},{"k":"con","name":"Tree"}],"name":"TNode"}],"kind":"type","name":"Tree"},{"body":{"cond":{"args":[{"name":"d","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"d","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build","t":"var"},"t":"app"},{"args":[{"args":[{"name":"d","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build","t":"var"},"t":"app"}],"ctor":"TNode","t":"ctor","type":"Tree"},"t":"if","then":{"args":[],"ctor":"TLeaf","t":"ctor","type":"Tree"}},"kind":"fn","name":"build","params":["d"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Tree"},"ret_mode":"own"}},{"body":{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"TLeaf","fields":[],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":1},"t":"lit"},"pat":{"ctor":"TNode","fields":[{"name":"v","p":"var"},{"name":"l","p":"var"},{"name":"r","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"a","t":"var"},"t":"match"},"name":"a","t":"let","value":{"name":"t","t":"var"}},"kind":"fn","name":"pin_aliased","params":["t"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"body":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"t","t":"var"}],"fn":{"name":"loop","t":"var"},"t":"app"},"name":"_v","t":"let","value":{"args":[{"name":"t","t":"var"}],"fn":{"name":"pin_aliased","t":"var"},"t":"app"}},"t":"if","then":{"lit":{"kind":"int","value":0},"t":"lit"}},"kind":"fn","name":"loop","params":["n","t"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"args":[{"args":[{"lit":{"kind":"int","value":3},"t":"lit"},{"name":"t","t":"var"}],"fn":{"name":"loop","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"name":"t","t":"let","value":{"args":[{"lit":{"kind":"int","value":2},"t":"lit"}],"fn":{"name":"build","t":"var"},"t":"app"}},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"rc_let_alias_implicit_param","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[{"k":"con","name":"Int"}],"name":"MkT"}],"kind":"type","name":"T"},{"body":{"args":[{"name":"n","t":"var"}],"ctor":"MkT","t":"ctor","type":"T"},"kind":"fn","name":"alloc","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"T"}}},{"body":{"arms":[{"body":{"name":"v","t":"var"},"pat":{"ctor":"MkT","fields":[{"name":"v","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"x","t":"var"},"t":"match"},"kind":"fn","name":"unbox","params":["x"],"type":{"effects":[],"k":"fn","param_modes":["borrow"],"params":[{"k":"con","name":"T"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"args":[{"args":[{"name":"x","t":"var"}],"fn":{"name":"unbox","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"name":"x","t":"let","value":{"args":[{"lit":{"kind":"int","value":7},"t":"lit"}],"fn":{"name":"alloc","t":"var"},"t":"app"}},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"rc_let_implicit_returning_app","schema":"ailang/v0"}
|
||||
@@ -1 +0,0 @@
|
||||
{"defs":[{"ctors":[{"fields":[],"name":"TLeaf"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"Tree"},{"k":"con","name":"Tree"}],"name":"TNode"}],"kind":"type","name":"Tree"},{"body":{"cond":{"args":[{"name":"d","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"d","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build","t":"var"},"t":"app"},{"args":[{"args":[{"name":"d","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build","t":"var"},"t":"app"}],"ctor":"TNode","t":"ctor","type":"Tree"},"t":"if","then":{"args":[],"ctor":"TLeaf","t":"ctor","type":"Tree"}},"kind":"fn","name":"build","params":["d"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Tree"},"ret_mode":"own"}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"TLeaf","fields":[],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":1},"t":"lit"},"pat":{"ctor":"TNode","fields":[{"name":"v","p":"var"},{"name":"l","p":"var"},{"name":"r","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"t","t":"var"},"t":"match"},"kind":"fn","name":"pin","params":["t"],"type":{"effects":[],"k":"fn","param_modes":["borrow"],"params":[{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"body":{"args":[{"args":[{"name":"t","t":"var"}],"fn":{"name":"pin","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"name":"t","t":"let","value":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"build","t":"var"},"t":"app"}},"kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"rc_let_owned_app_leak","schema":"ailang/v0"}
|
||||
@@ -1,139 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "rc_list_drop",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "IntList",
|
||||
"doc": "Recursive Int list. Iter 18c.4 RC fixture: codegen emits `drop_rc_list_drop_IntList` whose `Cons` arm recursively calls itself on the tail field.",
|
||||
"ctors": [
|
||||
{ "name": "Nil", "fields": [] },
|
||||
{
|
||||
"name": "Cons",
|
||||
"fields": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "IntList" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "sum_list",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [{ "k": "con", "name": "IntList" }],
|
||||
"ret": { "k": "con", "name": "Int" },
|
||||
"effects": []
|
||||
},
|
||||
"params": ["xs"],
|
||||
"doc": "Recursive fold over IntList.",
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "+" },
|
||||
"args": [
|
||||
{ "t": "var", "name": "h" },
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "sum_list" },
|
||||
"args": [{ "t": "var", "name": "t" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Build a 5-element IntList [1,2,3,4,5] and print its sum (15). Under --alloc=rc the recursive drop_rc_list_drop_IntList fn cascades through the tail at process exit when sum_list returns ownership-implicit (the consume_count of `xs` is 1 so no dec at the outer let; the test's correctness invariant is the byte-identical stdout — leak quantification is 18f's bench).",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "xs",
|
||||
"value": {
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 2 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 4 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 5 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [
|
||||
{
|
||||
"t": "app",
|
||||
"fn": { "t": "var", "name": "sum_list" },
|
||||
"args": [{ "t": "var", "name": "xs" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
{
|
||||
"schema": "ailang/v0",
|
||||
"name": "rc_list_drop_borrow",
|
||||
"imports": [],
|
||||
"defs": [
|
||||
{
|
||||
"kind": "type",
|
||||
"name": "IntList",
|
||||
"doc": "Recursive Int list. Iter 18c.4 RC fixture: codegen emits a recursive drop fn; this fixture keeps the binder consume_count at 0 so the drop call actually fires at scope close, exercising the recursive cascade at runtime over a 5-element list.",
|
||||
"ctors": [
|
||||
{ "name": "Nil", "fields": [] },
|
||||
{
|
||||
"name": "Cons",
|
||||
"fields": [
|
||||
{ "k": "con", "name": "Int" },
|
||||
{ "k": "con", "name": "IntList" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "fn",
|
||||
"name": "main",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [],
|
||||
"ret": { "k": "con", "name": "Unit" },
|
||||
"effects": ["IO"]
|
||||
},
|
||||
"params": [],
|
||||
"doc": "Build a 5-element IntList and print only its head via match. xs has consume_count == 0 (only the match scrutinee, a borrow), so under --alloc=rc the let scope close emits `drop_rc_list_drop_borrow_IntList(xs)` which recursively dec-cascades over the whole 5-cell chain.",
|
||||
"body": {
|
||||
"t": "let",
|
||||
"name": "xs",
|
||||
"value": {
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 11 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 22 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 33 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 44 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Cons",
|
||||
"args": [
|
||||
{ "t": "lit", "lit": { "kind": "int", "value": 55 } },
|
||||
{
|
||||
"t": "ctor",
|
||||
"type": "IntList",
|
||||
"ctor": "Nil",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "match",
|
||||
"scrutinee": { "t": "var", "name": "xs" },
|
||||
"arms": [
|
||||
{
|
||||
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 0 } }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"pat": {
|
||||
"p": "ctor",
|
||||
"ctor": "Cons",
|
||||
"fields": [
|
||||
{ "p": "var", "name": "h" },
|
||||
{ "p": "var", "name": "t" }
|
||||
]
|
||||
},
|
||||
"body": {
|
||||
"t": "do",
|
||||
"op": "io/print_int",
|
||||
"args": [{ "t": "var", "name": "h" }]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user