From 9a81784d8331fb59465cb9eed6207ebd3ceb25ff Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 15 Aug 2022 15:39:34 +0200 Subject: self hosted hello world parses --- src/parse.cff | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'src/parse.cff') 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 = {}; + 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 { -- cgit v1.2.3