aboutsummaryrefslogtreecommitdiff
path: root/src/parse.cff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-15 15:39:34 +0200
committerlemon <lsof@mailbox.org>2022-08-15 15:39:34 +0200
commit9a81784d8331fb59465cb9eed6207ebd3ceb25ff (patch)
tree6c83dbbe37bc10bee09741e07ea35cca228dfd61 /src/parse.cff
parentfeeb86d046d55d197040c7061e39198c80373ecb (diff)
self hosted hello world parses
Diffstat (limited to 'src/parse.cff')
-rw-r--r--src/parse.cff41
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 {