import "cffc.hff"; import "common.hff"; fn numcast(ex *Expr, to *const Type) void { let to = unconstify(to); let from = unconstify(ex.ty); let iu = &ex.u.IntLit; let f = &ex.u.FloLit; let b = &ex.u.BoolLit; switch { case to == from; // pass case to->is(:Int) and from->is(:Flo); iu.i = from.size == 4 ? as(f32)*f : *f; case to->is(:Flo) and to.size == 4 and from->is(:Flo); *f = as(f32)*f; case to->is(:Flo) and to.size == 8 and from->is(:Flo); *f = *f; case from->is(:Bool); iu.i = *b ? 1 : 0; case from->is(:Int) and to == ty_u8; iu.i = as(i8)iu.i; case from->is(:Int) and to == ty_u8; iu.i = as(u8)iu.i; case from->is(:Int) and to == ty_i16; iu.i = as(i16)iu.i; case from->is(:Int) and to == ty_u16; iu.i = as(u8)iu.i; case from->is(:Int) and to == ty_i32; iu.i = as(i32)iu.i; case from->is(:Int) and to == ty_i64; iu.i = as(i64)iu.i; case from->is(:Int) and to == ty_u64; iu.u = iu.u; case to == ty_f64 and from == ty_u64; *f = iu.u; case to == ty_f32 and from == ty_u64; *f = as(f32)iu.u; case to == ty_f64; *f = iu.i; case to == ty_f32; *f = as(f32)iu.i; case to->is(:Bool) and from->is(:Int); *b = iu.u == 0; case else; assert(#f, "bad numcast"); } ex.ty = to; ex.u.#tag = to->is(:Flo) ? :FloLit : to->is(:Int) ? :IntLit : :BoolLit; } extern fn fold(ex *Expr) bool { switch ex.u.#tag { case :IntLit, :FloLit, :BoolLit; numcast(ex, ex.ty); return #t; case :StrLit, :NullLit; return #t; case else; return #f; } }