aboutsummaryrefslogtreecommitdiff
path: root/src/fold.cff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-17 22:47:36 +0200
committerlemon <lsof@mailbox.org>2022-08-17 22:47:36 +0200
commit1c25c197d860ad49bb6a84e077a54e5aaf441bbd (patch)
tree8f7b963d1c891cfaa2d490a2f651ac0b8fa83c42 /src/fold.cff
parent86242b6cc1f53a86fcce1312211d3232661bf454 (diff)
parse defmacro
Diffstat (limited to 'src/fold.cff')
-rw-r--r--src/fold.cff66
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;
+ }
+
+}