aboutsummaryrefslogtreecommitdiff
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
parentfeeb86d046d55d197040c7061e39198c80373ecb (diff)
self hosted hello world parses
-rw-r--r--bootstrap/parse.c2
-rw-r--r--examples/hello-world.cff11
-rw-r--r--src/cffc.hff2
-rw-r--r--src/env.cff1
-rw-r--r--src/parse.cff41
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 {