diff options
| author | 2022-08-15 15:39:34 +0200 | |
|---|---|---|
| committer | 2022-08-15 15:39:34 +0200 | |
| commit | 9a81784d8331fb59465cb9eed6207ebd3ceb25ff (patch) | |
| tree | 6c83dbbe37bc10bee09741e07ea35cca228dfd61 /src/parse.cff | |
| parent | feeb86d046d55d197040c7061e39198c80373ecb (diff) | |
self hosted hello world parses
Diffstat (limited to 'src/parse.cff')
| -rw-r--r-- | src/parse.cff | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/parse.cff b/src/parse.cff index 0f06259..f77c30f 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -587,6 +587,12 @@ fn parsetype(P *Parser) *const Type { // Expressions Parsing // ///////////////////////// +fn exprdup(alloc *Allocator, ex Expr) *Expr { + return memcpy(alloc->alloc(sizeof(ex)), &ex, sizeof(ex)); +} + +fn parseexpr(P *Parser) Expr; + fn pexprimary(P *Parser) Expr { let tok Tok = lex(P); switch tok.t { @@ -599,14 +605,46 @@ fn pexprimary(P *Parser) Expr { case :null; return { tok.loc, ty_voidptr, .u: :NullLit }; case :str; - return { tok.loc, .u: :StrLit tok.u.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); + if decl == #null { + fatal(P, tok.loc, "%qT is not defined", tok); + } + switch decl.u { + case Fn f; + return { tok.loc, f.ty, .u: :Symbol decl }; + } case else; fatal(P, tok.loc, "expected expression (near %qT)", tok); } } fn pexpostfix(P *Parser) Expr { + let tok Tok = {}; let ex = pexprimary(P); + for ;; { + switch { + case lexmatch(P, &tok, '('); + let lhs = exprdup(P.alloc, ex), + ty = lhs.ty.u.#tag == :Ptr ? lhs.ty.u.Ptr : lhs.ty; + if ty.u.#tag != :Fn { + fatal(P, lhs.loc, "not callable (%t)", lhs.ty); + } + let args Vec<Expr> = {}; + while not lexmatch(P, #null, ')') { + args->push(parseexpr(P)); + if not lexmatch(P, #null, ',') { + lexexpect(P, ')'); + break; + } + } + ex = { tok.loc, .ty: ty.u.Fn.ret, .u: :Call { lhs, args->move(P.alloc) }}; + case else; break; + } + } return ex; } @@ -770,6 +808,7 @@ extern fn parse(P *Parser) [#]Decl { envfree(P.curenv); aralloc->destroy(); + decls->clear(); } extern fn parser_init(P *Parser, path *const u8) void { |