aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-25 06:23:01 +0200
committerlemon <lsof@mailbox.org>2022-08-25 06:23:01 +0200
commita004d0f4033dab74a237d598c493228a7d107014 (patch)
treea6f130b57992ea09bd4207e77af080ea6b2eb5a1 /src
parent033e0fc64415dcaebf15ec26f743e8916fc0aa03 (diff)
check casts
Diffstat (limited to 'src')
-rw-r--r--src/parse.cff22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/parse.cff b/src/parse.cff
index 752165b..d0c3da7 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -1780,11 +1780,27 @@ fn pexprefix(P *Parser) Expr {
case lexmatch(P, &tok, :kw_as);
let loc = tok.loc;
lexexpect(P, '(');
- let ty = parsetype(P);
+ let to = parsetype(P);
lexexpect(P, ')');
let ex = pexprefix(P);
- // TODO check valid cast
- return { loc, ty, :Cast(exprdup(P.alloc, ex)) };
+ let from = ex.ty;
+ switch {
+ case to->is(:Arr) and to.u.Arr.length < 0 and ex.u.#tag == :ArrIni;
+ ex.ty = (to = mkarrtype(ex.u.ArrIni.maxn + 1, #f, to.u.Arr.child));
+ case typeof2(to, from);
+ case to->is(:Int) and from->is(:Ptr) and to.size == from.size;
+ case to->is(:Ptr) and from->is(:Int) and to.size == from.size;
+ case to->is(:Ptr) and from->is(:Ptr);
+ case to->is(:Flo) and from->is(:Int);
+ case to->is(:Int) and from->is(:Flo);
+ case to->is(:Int) and from->is(:Bool);
+ case to->is(:Bool) and from->is(:Int);
+ case to->is(:Int) and from->is(:Enum);
+ case to->is(:Enum) and from->is(:Int);
+ case else
+ err(P, loc, "invalid cast from %t to %t", from, to);
+ }
+ return { loc, to, :Cast(exprdup(P.alloc, ex)) };
}
return pexpostfix(P);
}