aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}