diff options
| author | 2022-08-17 13:10:45 +0200 | |
|---|---|---|
| committer | 2022-08-17 13:32:11 +0200 | |
| commit | 86242b6cc1f53a86fcce1312211d3232661bf454 (patch) | |
| tree | a86552654922058fc53c1678878bb5c720bd25f6 /src/parse.cff | |
| parent | 37cd29c0299dc3a726c7f8273cf203a868133f57 (diff) | |
collatz checks
Diffstat (limited to 'src/parse.cff')
| -rw-r--r-- | src/parse.cff | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/parse.cff b/src/parse.cff index 34e7943..c2c1817 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -724,6 +724,8 @@ fn islvalue(ex Expr) bool { return decl.u.#tag == :Let or decl.u.#tag == :Static; case UnOp u; return u.op == :deref; + case Index; + return #t; } return #f; } @@ -735,15 +737,20 @@ fn pexprimary(P *Parser) Expr { switch tok.t { case :int, :chr; return { tok.loc, tok.ty, .u: :IntLit { tok.u.int }}; + case :flo; return { tok.loc, tok.ty, .u: :FloLit(tok.u.flo) }; + case :bool; return { tok.loc, ty_bool, .u: :BoolLit(tok.u.bool) }; + case :null; return { tok.loc, ty_voidptr, .u: :NullLit }; + case :str; let ty = mkarrtype(tok.u.str.#len + 1, #t, ty_u8); return { tok.loc, ty, .u: :StrLit(tok.u.str) }; + case :ident; let ident = tok.u.ident; let decl = finddecl(P, ident); @@ -758,10 +765,19 @@ fn pexprimary(P *Parser) Expr { case Static var; return { tok.loc, var.ty, .u: :Symbol(decl) }; } + case :kw_sizeof; + if lexmatch(P, &tok, '(') { + let ex = parseexpr(P); + lexexpect(P, ')'); + return { ex.loc, ty_usize, :IntLit { ex.ty.size }}; + } + return { tok.loc, ty_usize, :IntLit { parsetype(P).size }}; + case '('; let ex = parseexpr(P); lexexpect(P, ')'); return ex; + case else; fatal(P, tok.loc, "expected expression (near %qT)", tok); } @@ -1177,8 +1193,11 @@ fn pstwhile(P *Parser) Stmt { err(P, test.loc, "while condition must be bool or pointer (%t)", test.ty); } lexexpect(P, '{'); - let t = parseblock(P); - return { loc, :While { test, t }}; + let t [#]Stmt #?; + with_tmpchange(P.curloop, ++P.loopid, + t = parseblock(P); + ) + return { loc, :While { test, t, P.loopid }}; } fn pstfor(P *Parser) Stmt { @@ -1215,7 +1234,11 @@ fn pstfor(P *Parser) Stmt { next = :Some(parseexpr(P)); lexexpect(P, '{'); } - return { loc, :For { ini, test, next, parseblock(P) }}; + let body [#]Stmt #?; + with_tmpchange(P.curloop, ++P.loopid, + body = parseblock(P); + ) + return { loc, :For { ini, test, next, body, P.loopid }}; } fn parsestmts(P *Parser, yield StmtYielder, yarg *void) void { @@ -1241,6 +1264,20 @@ fn parsestmts(P *Parser, yield StmtYielder, yarg *void) void { case lexmatch(P, &tok, :kw_for); return yield(pstfor(P), yarg); + case lexmatch(P, &tok, :kw_break); + if P.curloop == 0 { + err(P, tok.loc, "break outside loop"); + } + lexexpect(P, ';'); + return yield({ tok.loc, :Break(P.curloop) }, yarg); + + case lexmatch(P, &tok, :kw_continue); + if P.curloop == 0 { + err(P, tok.loc, "continue outside loop"); + } + lexexpect(P, ';'); + return yield({ tok.loc, :Continue(P.curloop) }, yarg); + case else; let ex = parseexpr(P); lexexpect(P, ';'); |