diff options
| author | 2022-08-17 22:47:36 +0200 | |
|---|---|---|
| committer | 2022-08-17 22:47:36 +0200 | |
| commit | 1c25c197d860ad49bb6a84e077a54e5aaf441bbd (patch) | |
| tree | 8f7b963d1c891cfaa2d490a2f651ac0b8fa83c42 /src/fold.cff | |
| parent | 86242b6cc1f53a86fcce1312211d3232661bf454 (diff) | |
parse defmacro
Diffstat (limited to 'src/fold.cff')
| -rw-r--r-- | src/fold.cff | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/fold.cff b/src/fold.cff new file mode 100644 index 0000000..7b393e5 --- /dev/null +++ b/src/fold.cff @@ -0,0 +1,66 @@ +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; + } + +} |