diff options
| author | 2022-08-15 15:39:34 +0200 | |
|---|---|---|
| committer | 2022-08-15 15:39:34 +0200 | |
| commit | 9a81784d8331fb59465cb9eed6207ebd3ceb25ff (patch) | |
| tree | 6c83dbbe37bc10bee09741e07ea35cca228dfd61 | |
| parent | feeb86d046d55d197040c7061e39198c80373ecb (diff) | |
self hosted hello world parses
| -rw-r--r-- | bootstrap/parse.c | 2 | ||||
| -rw-r--r-- | examples/hello-world.cff | 11 | ||||
| -rw-r--r-- | src/cffc.hff | 2 | ||||
| -rw-r--r-- | src/env.cff | 1 | ||||
| -rw-r--r-- | src/parse.cff | 41 |
5 files changed, 47 insertions, 10 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 1848caf..aeb8124 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -1690,6 +1690,8 @@ pexcmp(struct parser *P) { if (matchcmpop(P, &tok)) { P->targty = ex.ty; struct expr rhs = pexbitarith(P); + P->used_targty = 0; + P->targty = NULL; if (!typeof2(ex.ty, rhs.ty)) fatal(P, tok.span, "incompatible operands %t and %t to binary operator %T", ex.ty, rhs.ty, tok); diff --git a/examples/hello-world.cff b/examples/hello-world.cff index 6266246..9764ac2 100644 --- a/examples/hello-world.cff +++ b/examples/hello-world.cff @@ -1,13 +1,6 @@ extern fn printf(fmt *const u8, ...) int; -#when sizeof *void == 8 { -def str = "hello 64-bit"; -} -#when sizeof *void == 4 { -def str = "hello 32-bit"; -} - -extern fn main(argc int, argv *const *const u8) int { - printf(str ## "\n"); +extern fn main(argc int, argc *const *const u8) int { + printf("hello world\n"); } diff --git a/src/cffc.hff b/src/cffc.hff index 6910179..2b6faaf 100644 --- a/src/cffc.hff +++ b/src/cffc.hff @@ -99,6 +99,8 @@ struct Expr { StrLit [#]const u8, BoolLit bool, NullLit, + Symbol *Decl, + Call struct { lhs *Expr, args [#]Expr } } } diff --git a/src/env.cff b/src/env.cff index 0ae465a..60b485b 100644 --- a/src/env.cff +++ b/src/env.cff @@ -43,4 +43,5 @@ extern fn envfind(env *Env, name *const u8) *Decl { extern fn envfree(env *Env) void { env.decls->clear(); + free(env); } 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 { |