floats iter 4.6: codegen io/print_float + examples/floats.ail.json E2E fixture
This commit is contained in:
@@ -2294,6 +2294,28 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
Ok(("0".into(), "i8".into()))
|
||||
}
|
||||
"io/print_float" => {
|
||||
if args.len() != 1 {
|
||||
return Err(CodegenError::Internal(
|
||||
"io/print_float arity".into(),
|
||||
));
|
||||
}
|
||||
let (v, vty) = self.lower_term(&args[0])?;
|
||||
if vty != "double" {
|
||||
return Err(CodegenError::Internal(
|
||||
"io/print_float needs double".into(),
|
||||
));
|
||||
}
|
||||
let fmt = self.intern_string("fmt_float", "%g\n");
|
||||
self.body.push_str(&format!(
|
||||
" {call_kw} i32 (ptr, ...) @printf(ptr @{fmt}, double {v})\n"
|
||||
));
|
||||
if tail {
|
||||
self.body.push_str(" ret i8 0\n");
|
||||
self.block_terminated = true;
|
||||
}
|
||||
Ok(("0".into(), "i8".into()))
|
||||
}
|
||||
"io/print_str" => {
|
||||
if args.len() != 1 {
|
||||
return Err(CodegenError::Internal(
|
||||
@@ -3269,4 +3291,43 @@ mod tests {
|
||||
assert!(ir.contains("0x7FF0000000000000"), "+inf bit pattern missing: {ir}");
|
||||
assert!(ir.contains("0xFFF0000000000000"), "-inf bit pattern missing: {ir}");
|
||||
}
|
||||
|
||||
/// Floats iter 4.6 RED: `(do io/print_float 1.5)` lowers via
|
||||
/// `printf("%g\n", v)`, parallel to `io/print_int` at line 2152.
|
||||
#[test]
|
||||
fn lowers_io_print_float() {
|
||||
use ailang_core::ast::*;
|
||||
let body = Term::Do {
|
||||
op: "io/print_float".into(),
|
||||
args: vec![Term::Lit { lit: Literal::Float { bits: 0x3ff8_0000_0000_0000u64 } }],
|
||||
tail: false,
|
||||
};
|
||||
let m = Module {
|
||||
schema: ailang_core::SCHEMA.to_string(),
|
||||
name: "t".into(),
|
||||
imports: vec![],
|
||||
defs: vec![Def::Fn(FnDef {
|
||||
name: "main".into(),
|
||||
ty: Type::Fn {
|
||||
params: vec![], ret: Box::new(Type::unit()), effects: vec!["IO".into()],
|
||||
param_modes: vec![], ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
params: vec![], body, suppress: vec![], doc: None,
|
||||
})],
|
||||
};
|
||||
let ir = emit_ir(&m).unwrap();
|
||||
assert!(
|
||||
ir.contains("call i32 (ptr, ...) @printf"),
|
||||
"io/print_float not emitting printf: {ir}"
|
||||
);
|
||||
assert!(
|
||||
ir.contains("double 0x3FF8000000000000"),
|
||||
"Float arg not threaded through io/print_float: {ir}"
|
||||
);
|
||||
// Verify the format string `%g\n` is interned.
|
||||
assert!(
|
||||
ir.contains("%g") || ir.contains("\\67"), // `g` ASCII = 67 = 0x47
|
||||
"format string `%g\\n` not interned: {ir}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user