floats iter 4.1: codegen primitive registration + Float literal hex-double lowering
This commit is contained in:
@@ -925,7 +925,7 @@ impl<'a> Emitter<'a> {
|
||||
let g = self.intern_string("str", value);
|
||||
("ptr".to_string(), format!("@{g}"))
|
||||
}
|
||||
Literal::Float { .. } => unimplemented!("Floats milestone iter 4: codegen"),
|
||||
Literal::Float { bits } => ("double".to_string(), format!("0x{:016X}", bits)),
|
||||
};
|
||||
if val_ty != lty {
|
||||
return Err(CodegenError::Internal(format!(
|
||||
@@ -1225,7 +1225,7 @@ impl<'a> Emitter<'a> {
|
||||
(format!("@{g}"), "ptr".into())
|
||||
}
|
||||
Literal::Unit => ("0".into(), "i8".into()),
|
||||
Literal::Float { .. } => unimplemented!("Floats milestone iter 4: codegen"),
|
||||
Literal::Float { bits } => (format!("0x{:016X}", bits), "double".into()),
|
||||
}),
|
||||
Term::Var { name } => {
|
||||
// Iter 16d: `__unreachable__` is a polymorphic bottom
|
||||
@@ -2877,4 +2877,45 @@ mod tests {
|
||||
"gc IR should not declare/define any per-type drop fn. IR was:\n{ir_gc}"
|
||||
);
|
||||
}
|
||||
|
||||
/// Floats iter 4.1 RED: a `Literal::Float { bits: 0x3ff8_0000_0000_0000 }`
|
||||
/// (= `1.5_f64`) lowers in a `Const` definition as an LLVM hex-float
|
||||
/// `double` SSA constant. The exact IR snippet pinned: `@ail_t_k =
|
||||
/// constant double 0x3FF8000000000000`.
|
||||
#[test]
|
||||
fn lowers_float_const_to_hex_double() {
|
||||
use ailang_core::ast::*;
|
||||
let m = Module {
|
||||
schema: ailang_core::SCHEMA.to_string(),
|
||||
name: "t".into(),
|
||||
imports: vec![],
|
||||
defs: vec![
|
||||
Def::Const(ConstDef {
|
||||
name: "k".into(),
|
||||
ty: Type::float(),
|
||||
value: Term::Lit { lit: Literal::Float { bits: 0x3ff8_0000_0000_0000u64 } },
|
||||
doc: None,
|
||||
}),
|
||||
Def::Fn(FnDef {
|
||||
name: "main".into(),
|
||||
ty: Type::Fn {
|
||||
params: vec![],
|
||||
ret: Box::new(Type::unit()),
|
||||
effects: vec![],
|
||||
param_modes: vec![],
|
||||
ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
params: vec![],
|
||||
body: Term::Lit { lit: Literal::Unit },
|
||||
suppress: vec![],
|
||||
doc: None,
|
||||
}),
|
||||
],
|
||||
};
|
||||
let ir = emit_ir(&m).unwrap();
|
||||
assert!(
|
||||
ir.contains("@ail_t_k = constant double 0x3FF8000000000000"),
|
||||
"ir missing the Float literal lowering: {ir}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ pub(crate) fn llvm_type(t: &Type) -> Result<String> {
|
||||
"Bool" => Ok("i1".into()),
|
||||
"Unit" => Ok("i8".into()),
|
||||
"Str" => Ok("ptr".into()),
|
||||
"Float" => Ok("double".into()),
|
||||
// All other type names are treated as ADT (boxed).
|
||||
// If the typechecker didn't reject this earlier, it's
|
||||
// intentional — otherwise `ptr` would mask a wrong value.
|
||||
@@ -207,6 +208,7 @@ pub(crate) fn type_descriptor(t: &Type) -> String {
|
||||
"Bool" => "B".into(),
|
||||
"Unit" => "U".into(),
|
||||
"Str" => "S".into(),
|
||||
"Float" => "Fl".into(),
|
||||
other => format!("F{other}"),
|
||||
};
|
||||
if args.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user