From 7f15c97521f48dc0df13f69b3312ef68443b8ad9 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 30 Oct 2019 19:47:31 -0400 Subject: fixed type expressions --- parse.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- test.toc | 19 +++++---- types.c | 5 +++ 3 files changed, 150 insertions(+), 11 deletions(-) diff --git a/parse.c b/parse.c index 1b9667e..97368e5 100644 --- a/parse.c +++ b/parse.c @@ -501,6 +501,141 @@ static bool parse_type(Parser *p, Type *type) { } +/* +is the thing we're looking at definitely a type, as opposed to an expression? +if end is not NULL, it is set to the token one past the last one in the type, +assuming it's successful +*/ +static bool parser_is_definitely_type(Parser *p, Token **end) { + Tokenizer *t = p->tokr; + Token *start = t->token; + bool ret = false; + do { + continu: + switch (t->token->kind) { + case TOKEN_KW: + switch (t->token->kw) { + case KW_STRUCT: + ret = true; + if (end) { + int level = 1; + t->token += 2; /* skip struct { */ + while (t->token->kind != TOKEN_EOF) { + if (t->token->kind == TOKEN_KW) switch (t->token->kw) { + case KW_LBRACE: + level++; + break; + case KW_RBRACE: + level--; + if (level == 0) goto end; + break; + default: break; + } + t->token++; + } + } + break; + case KW_LSQUARE: + ret = true; + if (end) { + int level = 1; + t->token++; + while (t->token->kind != TOKEN_EOF) { + if (t->token->kind == TOKEN_KW) switch (t->token->kw) { + case KW_LSQUARE: + level++; + break; + case KW_RSQUARE: + level--; + if (level == 0) { + if (end) { + t->token++; + parser_is_definitely_type(p, &t->token); /* move to end of type */ + } + goto end; + } + break; + default: break; + } + t->token++; + } + } + break; + case KW_LPAREN: { + Token *child_end; + t->token++; + ret = false; + while (parser_is_definitely_type(p, &child_end)) { + t->token = child_end; + if (t->token->kind == TOKEN_KW) { + if (t->token->kw == KW_COMMA) { + t->token++; + continue; + } else if (t->token->kw == KW_RPAREN) { + /* it *is* a tuple! */ + ret = true; + t->token++; + goto end; + } + } else break; + } + } break; + case KW_FN: + t->token++; + if (!token_is_kw(t->token, KW_LPAREN)) { + ret = false; + break; + } + t->token++; + int paren_level = 1; + while (t->token->kind != TOKEN_EOF) { + if (t->token->kind == TOKEN_KW) switch (t->token->kw) { + case KW_LPAREN: + paren_level++; + break; + case KW_RPAREN: + 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; + } + } + break; + default: break; + } + t->token++; + } + ret = false; + break; + case KW_AMPERSAND: + t->token++; /* continue; see if next thing is definitely a type */ + goto continu; + default: { + int x = kw_to_builtin_type(t->token->kw); + if ((ret = x != -1)) { + t->token++; + } + break; + } + } break; + case TOKEN_DIRECT: + case TOKEN_NUM_LITERAL: + case TOKEN_CHAR_LITERAL: + case TOKEN_STR_LITERAL: + case TOKEN_EOF: + case TOKEN_IDENT: + ret = false; + break; + } + } while (0); + end: + if (ret && end) *end = t->token; + t->token = start; + return ret; +} static bool parse_block(Parser *p, Block *b) { b->flags = 0; @@ -719,7 +854,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { return false; } Token *before = t->token; - if (parser_is_type(p)) { + if (parser_is_definitely_type(p, NULL)) { /* it's a type! */ e->kind = EXPR_TYPE; return parse_type(p, &e->typeval); diff --git a/test.toc b/test.toc index 15ab6d6..dacfbda 100644 --- a/test.toc +++ b/test.toc @@ -1,13 +1,12 @@ -puti @= fn(x: int) { - #C("printf(\"%ld\\n\", (long)x); -"); -}; +// puti @= fn(x: int) { + // #C("printf(\"%ld\\n\", (long)x); +// "); +// }; -Point @= struct { - x, y: int; - something: float; -}; +F @= fn(int,int); -main @= fn() { -}; +foo @ F = fn(x,y:int) {} as F; + +// main @= fn() { +// }; diff --git a/types.c b/types.c index 5f60845..eb5b0df 100644 --- a/types.c +++ b/types.c @@ -1183,6 +1183,11 @@ static bool types_decl(Typer *tr, Declaration *d) { success = false; goto ret; } + if (val->type->kind == TYPE_TUPLE) { + err_print(d->where, "You can't declare a new type to be a tuple."); + success = false; + goto ret; + } } } -- cgit v1.2.3