iter rpe.1: retire per-type print effect-ops
Single iter shipping the post-milestone-24 follow-up named in
docs/specs/2026-05-14-retire-per-type-print-effects.md. After this
iter the only surviving direct-output effect-op is `io/print_str`;
all per-type print primitives are replaced by the polymorphic
`print` helper (prelude, iter 24.3).
Components:
- 92 examples/*.ail fixtures migrated (do io/print_<T> x) →
(app print x); 6 .prose.txt snapshots regenerated via `ail prose`.
- Four-site lockstep compiler deletion: crates/ailang-check/src/builtins.rs
(3 effect_ops.insert blocks + 3 list() rows + the
install_io_print_float_signature test + module + EffectOpSig
doc-comments); crates/ailang-codegen/src/lib.rs lower_app
(3 arms + lowers_io_print_float test); crates/ailang-codegen/src/synth.rs
builtin_effect_op_ret match-arm pattern. Dead `intern_string`
helper removed as a follow-up.
- Five incidental test-body migrations (ailang-check x2, ailang-core
spec_drift + design_schema_drift, ailang-surface/src/lex.rs,
ailang-prose/src/lib.rs round-trip test).
- Cat B test-harness patch: six IR-shape tests in
crates/ail/tests/e2e.rs gained a monomorphise_workspace call
before lower_workspace_with_alloc so they follow the same
pipeline as `ail build` (the home-rolled desugar+lift loop
stayed because mono's precondition is "already lifted"; mono
inserts after lift).
- Six doc-comment touch-ups (lex.rs module doc, parse.rs
diagnostic example, ail/src/main.rs x2, runtime/str.c %g anchor,
crates/ailang-core/specs/form_a.md surface-spec example).
- DESIGN.md seven-site sweep (Decision 11 example, Polymorphic
print past-tense, Heap-Str output sentence, effect-op
invocation comment, Float NaN paragraph re-anchored on
float_to_str, two "What is supported" lists).
- Three E2E test-comment polish + four IR-snapshot refresh + one
canonical-hash pin update (plan-unanticipated downstream
consequences of the corpus migration).
- bench/{check,compile_check,cross_lang}.py: all exit 0; no
ratification needed.
- Roadmap entry struck through; per-iter journal at
docs/journals/2026-05-14-iter-rpe.1.md.
Tests 564/0/3. cargo clippy and cargo doc: zero warnings.
Two upstream codegen bugs surfaced during the first BLOCKED
attempt and were fixed in separate iters before this retry:
- 1fb225e bugfix: mono cursor misalignment at poly-free-fn Var
with class-constrained Forall.
- feb9413 bugfix: print leak — propagate ret_mode through rigid
substitution + prelude Show.show ret_mode.
Known debt (carried forward for next /audit):
- Emitter.strings field is functionally dead post-iter (orphan
after intern_string removal); cycles over empty map harmlessly.
This commit is contained in:
@@ -27,8 +27,8 @@
|
||||
//! a native binary at `--out`.
|
||||
//! - `run` — `build` into a tempdir and execute the binary; passes
|
||||
//! the binary's exit code through.
|
||||
//! - `builtins` — list the built-in effect ops (`io/print_int`,
|
||||
//! `io/print_bool`, `io/print_str`, ...) with their signatures.
|
||||
//! - `builtins` — list the built-in effect ops (`io/print_str`)
|
||||
//! with their signatures.
|
||||
//! - `diff` — semantic, hash-based module/workspace diff. Works even
|
||||
//! when a module doesn't currently typecheck.
|
||||
//! - `workspace` — load an entry module's transitive imports and list
|
||||
@@ -1416,7 +1416,7 @@ fn walk_term(
|
||||
walk_term(else_, out, builtins, scope);
|
||||
}
|
||||
Term::Do { op, args, .. } => {
|
||||
// Mark effect ops as `effect:io/print_int` so they can be
|
||||
// Mark effect ops as `effect:io/print_str` so they can be
|
||||
// separated from normal function calls.
|
||||
out.insert(format!("effect:{op}"));
|
||||
for a in args {
|
||||
|
||||
+58
-13
@@ -1460,8 +1460,14 @@ fn reuse_as_demo_under_rc_uses_inplace_rewrite() {
|
||||
root_dir: ws.root_dir.clone(),
|
||||
registry: ws.registry.clone(),
|
||||
};
|
||||
// Iter rpe.1: post-print-migration, fixtures use `(app print x)`
|
||||
// which monomorphises to `print__<T>`. Adding the mono pass here
|
||||
// mirrors `ail build`'s pipeline (desugar -> lift -> mono ->
|
||||
// lower); without it, lowering errors with `UnknownVar("print")`.
|
||||
let mono_ws = ailang_check::monomorphise_workspace(&lifted_ws)
|
||||
.expect("monomorphise_workspace");
|
||||
let ir = ailang_codegen::lower_workspace_with_alloc(
|
||||
&lifted_ws,
|
||||
&mono_ws,
|
||||
ailang_codegen::AllocStrategy::Rc,
|
||||
)
|
||||
.expect("lower workspace under rc");
|
||||
@@ -1660,8 +1666,14 @@ fn alloc_rc_borrow_only_recursive_list_drop() {
|
||||
root_dir: ws.root_dir.clone(),
|
||||
registry: ws.registry.clone(),
|
||||
};
|
||||
// Iter rpe.1: post-print-migration, fixtures use `(app print x)`
|
||||
// which monomorphises to `print__<T>`. Adding the mono pass here
|
||||
// mirrors `ail build`'s pipeline (desugar -> lift -> mono ->
|
||||
// lower); without it, lowering errors with `UnknownVar("print")`.
|
||||
let mono_ws = ailang_check::monomorphise_workspace(&lifted_ws)
|
||||
.expect("monomorphise_workspace");
|
||||
let ir = ailang_codegen::lower_workspace_with_alloc(
|
||||
&lifted_ws,
|
||||
&mono_ws,
|
||||
ailang_codegen::AllocStrategy::Rc,
|
||||
)
|
||||
.expect("lower workspace under rc");
|
||||
@@ -1736,8 +1748,14 @@ fn alloc_rc_partial_drop_skips_moved_keeps_wildcarded() {
|
||||
root_dir: ws.root_dir.clone(),
|
||||
registry: ws.registry.clone(),
|
||||
};
|
||||
// Iter rpe.1: post-print-migration, fixtures use `(app print x)`
|
||||
// which monomorphises to `print__<T>`. Adding the mono pass here
|
||||
// mirrors `ail build`'s pipeline (desugar -> lift -> mono ->
|
||||
// lower); without it, lowering errors with `UnknownVar("print")`.
|
||||
let mono_ws = ailang_check::monomorphise_workspace(&lifted_ws)
|
||||
.expect("monomorphise_workspace");
|
||||
let ir = ailang_codegen::lower_workspace_with_alloc(
|
||||
&lifted_ws,
|
||||
&mono_ws,
|
||||
ailang_codegen::AllocStrategy::Rc,
|
||||
)
|
||||
.expect("lower workspace under rc");
|
||||
@@ -1826,8 +1844,14 @@ fn alloc_rc_own_param_dec_at_fn_return() {
|
||||
root_dir: ws.root_dir.clone(),
|
||||
registry: ws.registry.clone(),
|
||||
};
|
||||
// Iter rpe.1: post-print-migration, fixtures use `(app print x)`
|
||||
// which monomorphises to `print__<T>`. Adding the mono pass here
|
||||
// mirrors `ail build`'s pipeline (desugar -> lift -> mono ->
|
||||
// lower); without it, lowering errors with `UnknownVar("print")`.
|
||||
let mono_ws = ailang_check::monomorphise_workspace(&lifted_ws)
|
||||
.expect("monomorphise_workspace");
|
||||
let ir = ailang_codegen::lower_workspace_with_alloc(
|
||||
&lifted_ws,
|
||||
&mono_ws,
|
||||
ailang_codegen::AllocStrategy::Rc,
|
||||
)
|
||||
.expect("lower workspace under rc");
|
||||
@@ -1952,8 +1976,14 @@ fn iter18e_drop_iterative_emits_worklist_body_no_self_recursion() {
|
||||
root_dir: ws.root_dir.clone(),
|
||||
registry: ws.registry.clone(),
|
||||
};
|
||||
// Iter rpe.1: post-print-migration, fixtures use `(app print x)`
|
||||
// which monomorphises to `print__<T>`. Adding the mono pass here
|
||||
// mirrors `ail build`'s pipeline (desugar -> lift -> mono ->
|
||||
// lower); without it, lowering errors with `UnknownVar("print")`.
|
||||
let mono_ws = ailang_check::monomorphise_workspace(&lifted_ws)
|
||||
.expect("monomorphise_workspace");
|
||||
let ir = ailang_codegen::lower_workspace_with_alloc(
|
||||
&lifted_ws,
|
||||
&mono_ws,
|
||||
ailang_codegen::AllocStrategy::Rc,
|
||||
)
|
||||
.expect("lower workspace under rc");
|
||||
@@ -2036,8 +2066,14 @@ fn iter18e_no_annotation_keeps_recursive_drop_body() {
|
||||
root_dir: ws.root_dir.clone(),
|
||||
registry: ws.registry.clone(),
|
||||
};
|
||||
// Iter rpe.1: post-print-migration, fixtures use `(app print x)`
|
||||
// which monomorphises to `print__<T>`. Adding the mono pass here
|
||||
// mirrors `ail build`'s pipeline (desugar -> lift -> mono ->
|
||||
// lower); without it, lowering errors with `UnknownVar("print")`.
|
||||
let mono_ws = ailang_check::monomorphise_workspace(&lifted_ws)
|
||||
.expect("monomorphise_workspace");
|
||||
let ir = ailang_codegen::lower_workspace_with_alloc(
|
||||
&lifted_ws,
|
||||
&mono_ws,
|
||||
ailang_codegen::AllocStrategy::Rc,
|
||||
)
|
||||
.expect("lower workspace under rc");
|
||||
@@ -2671,18 +2707,27 @@ fn str_field_in_adt_drops_heap_str_correctly() {
|
||||
assert_eq!(live, 0, "no leaked RC slabs allowed; live={live}");
|
||||
}
|
||||
|
||||
/// Iter eob.1: primitive-Int arg passed to an effect-op. Under the
|
||||
/// new "Term::Do args = Borrow" rule, the let-binder `n` is not
|
||||
/// consumed by `io/print_int`; but Int is unboxed, so there is no
|
||||
/// pointer to RC-track. Pin: zero allocs / zero frees / zero live —
|
||||
/// the rule introduces no spurious bookkeeping on primitives.
|
||||
/// Iter eob.1 / rpe.1: primitive-Int passed to the polymorphic
|
||||
/// `print` helper. Pre-rpe.1 the fixture used `(do io/print_int n)`
|
||||
/// directly and the iter-eob.1 "Term::Do args = Borrow" rule meant
|
||||
/// zero RC traffic on the unboxed Int (allocs == 0, frees == 0).
|
||||
/// Post-rpe.1, `print n` desugars through `Show Int.show` →
|
||||
/// `int_to_str` (heap-Str alloc, `ret_mode: Own`) → `io/print_str`
|
||||
/// → slab drops at scope close. Pin shifts to the new canonical
|
||||
/// post-iter shape: exactly one heap-Str slab cycle per `print`
|
||||
/// of a non-Str value. The let-binder property the original test
|
||||
/// pinned (Term::Do args borrow-walk correctly on primitives) is
|
||||
/// preserved by the surviving `io/print_str s` step inside
|
||||
/// `print__Int.body`; this test now pins the slab-cycle pattern.
|
||||
#[test]
|
||||
fn int_arg_to_effect_op_does_not_rc_track() {
|
||||
let (stdout, allocs, frees, live) =
|
||||
build_and_run_with_rc_stats("int_to_print_int_borrow.ail");
|
||||
assert_eq!(stdout, "7\n");
|
||||
assert_eq!(allocs, 0, "Int arg should not trigger any RC alloc; got allocs={allocs}");
|
||||
assert_eq!(frees, 0, "Int arg should not trigger any RC free; got frees={frees}");
|
||||
// Post-rpe.1: print n for n : Int allocates one heap-Str slab
|
||||
// via Show Int → int_to_str, frees it at scope close. Spec §E.
|
||||
assert_eq!(allocs, 1, "expected exactly one Show-Int heap-Str slab; got allocs={allocs}");
|
||||
assert_eq!(frees, 1, "expected exactly one free; got frees={frees}");
|
||||
assert_eq!(live, 0, "no leaked RC slabs allowed; live={live}");
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,9 @@ fn eq_ord_polymorphic_runs_end_to_end() {
|
||||
// Helper `at_most(3, 5)` at Int = true → 1
|
||||
// `at_most(true, false)` at Bool = false → 0
|
||||
// `at_most("abc", "abd")` at Str = true → 1
|
||||
// `io/print_int` emits one int per line, so stdout is "1\n0\n1"
|
||||
// after `.trim()` strips the trailing newline.
|
||||
// Polymorphic `print` for Int routes through `show` + `io/print_str`,
|
||||
// emitting one int per line, so stdout is "1\n0\n1" after `.trim()`
|
||||
// strips the trailing newline.
|
||||
assert_eq!(stdout, "1\n0\n1", "expected 1\\n0\\n1, got {stdout:?}");
|
||||
}
|
||||
|
||||
@@ -73,7 +74,7 @@ fn eq_ord_user_adt_runs_end_to_end() {
|
||||
let stdout = build_and_run("eq_ord_user_adt.ail");
|
||||
// eq(MkIntBox 3, MkIntBox 3) = true → 1
|
||||
// eq(MkIntBox 3, MkIntBox 5) = false → 0
|
||||
// `io/print_int` emits one int per line; trimmed stdout is "1\n0".
|
||||
// Polymorphic `print` for Int emits one int per line; trimmed stdout is "1\n0".
|
||||
assert_eq!(stdout, "1\n0", "expected 1\\n0, got {stdout:?}");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
//! CLI and run; stdout is matched against the expected three
|
||||
//! lines (`4`, `42`, `-1.5`). This test exercises the full
|
||||
//! pipeline — Float literal lowering, polymorphic `+` Float arm,
|
||||
//! `int_to_float` (sitofp), `neg` Float (fneg), `io/print_float`
|
||||
//! (printf `%g\n`).
|
||||
//! `int_to_float` (sitofp), `neg` Float (fneg), and the polymorphic
|
||||
//! `print` for Float (routes through `Show Float.show` →
|
||||
//! `float_to_str`, libc `%g`).
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
source_filename = "list.ail"
|
||||
target triple = "<NORMALIZED>"
|
||||
|
||||
@.str_list_fmt_int_0 = private unnamed_addr constant [6 x i8] c"%lld\0A\00", align 1
|
||||
|
||||
declare i32 @printf(ptr, ...)
|
||||
declare i32 @puts(ptr)
|
||||
declare ptr @GC_malloc(i64)
|
||||
@@ -19,6 +17,8 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
|
||||
|
||||
@ail_list_sum_list_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_list_sum_list_adapter, ptr null }
|
||||
@ail_list_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_list_main_adapter, ptr null }
|
||||
@ail_prelude_show__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_show__Int_adapter, ptr null }
|
||||
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
|
||||
define i64 @ail_list_sum_list(ptr %arg_xs) {
|
||||
entry:
|
||||
%v1 = load i64, ptr %arg_xs, align 8
|
||||
@@ -72,8 +72,8 @@ entry:
|
||||
%v10 = getelementptr inbounds i8, ptr %v8, i64 16
|
||||
store ptr %v5, ptr %v10, align 8
|
||||
%v11 = call i64 @ail_list_sum_list(ptr %v8)
|
||||
call i32 (ptr, ...) @printf(ptr @.str_list_fmt_int_0, i64 %v11)
|
||||
ret i8 0
|
||||
%v12 = call i8 @ail_prelude_print__Int(i64 %v11)
|
||||
ret i8 %v12
|
||||
}
|
||||
|
||||
define i8 @ail_list_main_adapter(ptr %_env) {
|
||||
@@ -82,6 +82,32 @@ entry:
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
define ptr @ail_prelude_show__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ailang_int_to_str(i64 %arg_x)
|
||||
ret ptr %v1
|
||||
}
|
||||
|
||||
define ptr @ail_prelude_show__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call ptr @ail_prelude_show__Int(i64 %a0)
|
||||
ret ptr %r
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ail_prelude_show__Int(i64 %arg_x)
|
||||
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
|
||||
call i32 @puts(ptr %v2)
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call i8 @ail_prelude_print__Int(i64 %a0)
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
|
||||
define i32 @main() {
|
||||
call i8 @ail_list_main()
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
source_filename = "max3.ail"
|
||||
target triple = "<NORMALIZED>"
|
||||
|
||||
@.str_max3_fmt_int_0 = private unnamed_addr constant [6 x i8] c"%lld\0A\00", align 1
|
||||
|
||||
declare i32 @printf(ptr, ...)
|
||||
declare i32 @puts(ptr)
|
||||
declare ptr @GC_malloc(i64)
|
||||
@@ -20,6 +18,8 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
|
||||
@ail_max3_max_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_max3_max_adapter, ptr null }
|
||||
@ail_max3_max3_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_max3_max3_adapter, ptr null }
|
||||
@ail_max3_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_max3_main_adapter, ptr null }
|
||||
@ail_prelude_show__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_show__Int_adapter, ptr null }
|
||||
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
|
||||
define i64 @ail_max3_max(i64 %arg_a, i64 %arg_b) {
|
||||
entry:
|
||||
%v1 = icmp sgt i64 %arg_a, %arg_b
|
||||
@@ -77,8 +77,8 @@ entry:
|
||||
define i8 @ail_max3_main() {
|
||||
entry:
|
||||
%v1 = call i64 @ail_max3_max3(i64 3, i64 17, i64 9)
|
||||
call i32 (ptr, ...) @printf(ptr @.str_max3_fmt_int_0, i64 %v1)
|
||||
ret i8 0
|
||||
%v2 = call i8 @ail_prelude_print__Int(i64 %v1)
|
||||
ret i8 %v2
|
||||
}
|
||||
|
||||
define i8 @ail_max3_main_adapter(ptr %_env) {
|
||||
@@ -87,6 +87,32 @@ entry:
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
define ptr @ail_prelude_show__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ailang_int_to_str(i64 %arg_x)
|
||||
ret ptr %v1
|
||||
}
|
||||
|
||||
define ptr @ail_prelude_show__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call ptr @ail_prelude_show__Int(i64 %a0)
|
||||
ret ptr %r
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ail_prelude_show__Int(i64 %arg_x)
|
||||
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
|
||||
call i32 @puts(ptr %v2)
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call i8 @ail_prelude_print__Int(i64 %a0)
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
|
||||
define i32 @main() {
|
||||
call i8 @ail_max3_main()
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
source_filename = "sum.ail"
|
||||
target triple = "<NORMALIZED>"
|
||||
|
||||
@.str_sum_fmt_int_0 = private unnamed_addr constant [6 x i8] c"%lld\0A\00", align 1
|
||||
|
||||
declare i32 @printf(ptr, ...)
|
||||
declare i32 @puts(ptr)
|
||||
declare ptr @GC_malloc(i64)
|
||||
@@ -17,8 +15,36 @@ declare ptr @ailang_str_clone(ptr)
|
||||
declare ptr @ailang_str_concat(ptr, ptr)
|
||||
declare i64 @llvm.fptosi.sat.i64.f64(double)
|
||||
|
||||
@ail_prelude_show__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_show__Int_adapter, ptr null }
|
||||
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
|
||||
@ail_sum_sum_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_sum_sum_adapter, ptr null }
|
||||
@ail_sum_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_sum_main_adapter, ptr null }
|
||||
define ptr @ail_prelude_show__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ailang_int_to_str(i64 %arg_x)
|
||||
ret ptr %v1
|
||||
}
|
||||
|
||||
define ptr @ail_prelude_show__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call ptr @ail_prelude_show__Int(i64 %a0)
|
||||
ret ptr %r
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ail_prelude_show__Int(i64 %arg_x)
|
||||
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
|
||||
call i32 @puts(ptr %v2)
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call i8 @ail_prelude_print__Int(i64 %a0)
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
define i64 @ail_sum_sum(i64 %arg_n) {
|
||||
entry:
|
||||
%v1 = icmp eq i64 %arg_n, 0
|
||||
@@ -44,8 +70,8 @@ entry:
|
||||
define i8 @ail_sum_main() {
|
||||
entry:
|
||||
%v1 = call i64 @ail_sum_sum(i64 10)
|
||||
call i32 (ptr, ...) @printf(ptr @.str_sum_fmt_int_0, i64 %v1)
|
||||
ret i8 0
|
||||
%v2 = call i8 @ail_prelude_print__Int(i64 %v1)
|
||||
ret i8 %v2
|
||||
}
|
||||
|
||||
define i8 @ail_sum_main_adapter(ptr %_env) {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
source_filename = "ws_main.ail"
|
||||
target triple = "<NORMALIZED>"
|
||||
|
||||
@.str_ws_main_fmt_int_0 = private unnamed_addr constant [6 x i8] c"%lld\0A\00", align 1
|
||||
|
||||
declare i32 @printf(ptr, ...)
|
||||
declare i32 @puts(ptr)
|
||||
declare ptr @GC_malloc(i64)
|
||||
@@ -17,8 +15,36 @@ declare ptr @ailang_str_clone(ptr)
|
||||
declare ptr @ailang_str_concat(ptr, ptr)
|
||||
declare i64 @llvm.fptosi.sat.i64.f64(double)
|
||||
|
||||
@ail_prelude_show__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_show__Int_adapter, ptr null }
|
||||
@ail_prelude_print__Int_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_prelude_print__Int_adapter, ptr null }
|
||||
@ail_ws_lib_add_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_ws_lib_add_adapter, ptr null }
|
||||
@ail_ws_main_main_clos = private unnamed_addr constant { ptr, ptr } { ptr @ail_ws_main_main_adapter, ptr null }
|
||||
define ptr @ail_prelude_show__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ailang_int_to_str(i64 %arg_x)
|
||||
ret ptr %v1
|
||||
}
|
||||
|
||||
define ptr @ail_prelude_show__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call ptr @ail_prelude_show__Int(i64 %a0)
|
||||
ret ptr %r
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int(i64 %arg_x) {
|
||||
entry:
|
||||
%v1 = call ptr @ail_prelude_show__Int(i64 %arg_x)
|
||||
%v2 = getelementptr inbounds i8, ptr %v1, i64 8
|
||||
call i32 @puts(ptr %v2)
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define i8 @ail_prelude_print__Int_adapter(ptr %_env, i64 %a0) {
|
||||
entry:
|
||||
%r = call i8 @ail_prelude_print__Int(i64 %a0)
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
define i64 @ail_ws_lib_add(i64 %arg_a, i64 %arg_b) {
|
||||
entry:
|
||||
%v1 = add i64 %arg_a, %arg_b
|
||||
@@ -34,8 +60,8 @@ entry:
|
||||
define i8 @ail_ws_main_main() {
|
||||
entry:
|
||||
%v1 = call i64 @ail_ws_lib_add(i64 2, i64 3)
|
||||
call i32 (ptr, ...) @printf(ptr @.str_ws_main_fmt_int_0, i64 %v1)
|
||||
ret i8 0
|
||||
%v2 = call i8 @ail_prelude_print__Int(i64 %v1)
|
||||
ret i8 %v2
|
||||
}
|
||||
|
||||
define i8 @ail_ws_main_main_adapter(ptr %_env) {
|
||||
|
||||
Reference in New Issue
Block a user