diff options
| author | 2022-08-25 06:23:01 +0200 | |
|---|---|---|
| committer | 2022-08-25 06:23:01 +0200 | |
| commit | a004d0f4033dab74a237d598c493228a7d107014 (patch) | |
| tree | a6f130b57992ea09bd4207e77af080ea6b2eb5a1 | |
| parent | 033e0fc64415dcaebf15ec26f743e8916fc0aa03 (diff) | |
check casts
| -rw-r--r-- | src/parse.cff | 22 |
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); } |