summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-30 20:01:01 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-30 20:01:01 -0400
commitfdc1946407222c340609d6c993138690a508a641 (patch)
treed1ce104aec6f67fb2178643d1c8d336d61dd9eb2
parent7f15c97521f48dc0df13f69b3312ef68443b8ad9 (diff)
fixed more problems with type expressions
-rw-r--r--cgen.c2
-rw-r--r--parse.c21
-rw-r--r--test.toc19
3 files changed, 28 insertions, 14 deletions
diff --git a/cgen.c b/cgen.c
index f214878..57282af 100644
--- a/cgen.c
+++ b/cgen.c
@@ -277,6 +277,8 @@ static inline void cgen_fn_name(CGenerator *g, FnExpr *f) {
static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) {
bool out_param = cgen_uses_ptr(&f->ret_type);
bool any_params = false;
+ if (!f->c.name) /* anonymous fn */
+ cgen_write(g, "static ");
if (out_param) {
cgen_write(g, "void ");
} else {
diff --git a/parse.c b/parse.c
index 97368e5..747c68b 100644
--- a/parse.c
+++ b/parse.c
@@ -581,9 +581,9 @@ static bool parser_is_definitely_type(Parser *p, Token **end) {
}
} break;
case KW_FN:
+ ret = false;
t->token++;
if (!token_is_kw(t->token, KW_LPAREN)) {
- ret = false;
break;
}
t->token++;
@@ -597,18 +597,25 @@ static bool parser_is_definitely_type(Parser *p, Token **end) {
paren_level--;
if (paren_level == 0) {
t->token++;
- if (!token_is_kw(t->token, KW_LBRACE)) {
- /* it's a function type! */
- ret = true;
- goto end;
+ if (token_is_kw(t->token, KW_LBRACE)) goto end; /* void fn expr */
+ Token *child_end;
+ if (parser_is_definitely_type(p, &child_end)) { /* try return type */
+ if (token_is_kw(t->token, KW_LBRACE)) {
+ /* non-void fn expr */
+ goto end;
+ }
}
+ /* it's a function type! */
+ ret = true;
+ goto end;
+
+
}
break;
default: break;
}
t->token++;
}
- ret = false;
break;
case KW_AMPERSAND:
t->token++; /* continue; see if next thing is definitely a type */
@@ -914,7 +921,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
Token *start = t->token;
-
+ /* TODO: consider moving this after ops, so that "if true { 5 } else { 3 } as f32" is possible */
if (t->token->kind == TOKEN_KW) switch (t->token->kw) {
case KW_FN: {
/* this is a function */
diff --git a/test.toc b/test.toc
index dacfbda..d56dc78 100644
--- a/test.toc
+++ b/test.toc
@@ -1,12 +1,17 @@
-// puti @= fn(x: int) {
- // #C("printf(\"%ld\\n\", (long)x);
-// ");
-// };
+puti @= fn(x: int) {
+ #C("printf(\"%ld\\n\", (long)x);
+");
+};
F @= fn(int,int);
-foo @ F = fn(x,y:int) {} as F;
+main @= fn() {
-// main @= fn() {
-// };
+ foo := (fn(x,y:int) {}) as F;
+
+ bar := foo as fn(int, int);
+ baz := bar as &char;
+ quux := baz as int;
+ puti(quux);
+};