diff options
-rw-r--r-- | parse.c | 15 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | toc.c | 2 | ||||
-rw-r--r-- | types.c | 19 | ||||
-rw-r--r-- | util/err.c | 7 | ||||
-rw-r--r-- | util/location.c | 6 |
6 files changed, 39 insertions, 24 deletions
@@ -649,6 +649,8 @@ static bool parse_args(Parser *p, Array *args) { return true; } +static void fprint_expr(FILE *out, Expression *e); + static bool parse_expr(Parser *p, Expression *e, Token *end) { Tokenizer *t = p->tokr; e->flags = 0; @@ -813,14 +815,15 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (token->kind == TOKEN_KW) { switch (token->kw) { case KW_LPAREN: - if (square_level == 0 && paren_level == 0 && token != t->tokens.data + if (square_level == 0 && paren_level == 0 && brace_level == 0 + && token != t->tokens.data && token[-1].kind != TOKEN_DIRECT /* don't include directives */) opening_bracket = token; /* maybe this left parenthesis opens the function call */ paren_level++; break; case KW_LSQUARE: - if (square_level == 0 && paren_level == 0) - opening_bracket = token; /* ^^ (array access) */ + if (square_level == 0 && paren_level == 0 && brace_level == 0) + opening_bracket = token; /* (array access) */ square_level++; break; case KW_RPAREN: @@ -829,6 +832,12 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { case KW_RSQUARE: square_level--; break; + case KW_LBRACE: + brace_level++; + break; + case KW_RBRACE: + brace_level--; + break; default: break; } @@ -1,8 +1,12 @@ main @= fn() { - y := { - x := 5; - z := y; - z - }; +/* + f := main; + f(); + main(); +*/ + N @= { + foo : [N]int; + foo[0] + }; }; @@ -16,13 +16,13 @@ typedef long double Floating; /* OPTIM: Switch to double */ #define UINTEGER_FMT "%llu" #define INTEGER_FMT "%lld" +#include "util/location.c" #include "util/err.c" #include "util/arr.c" #include "util/blockarr.c" #include "util/str.c" #include "identifiers.c" #include "tokenizer.c" -#include "util/location.c" #include "parse.c" #include "eval.c" #include "types.c" @@ -167,15 +167,18 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t, bool typedef Declaration *DeclarationPtr; arr_foreach(&tr->in_decls, DeclarationPtr, in_decl) { if (d == *in_decl) { - /* if we've complained about it before when we were figuring out the type, don't complain again */ - if (!(d->flags & DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE)) { - char *s = ident_to_str(i); - err_print(where, "Use of identifier %s within its own declaration.", s); - free(s); - info_print(d->where, "Declaration was here."); - d->flags |= DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE; + assert(d->flags & DECL_FLAG_HAS_EXPR); /* we can only be in decls with an expr */ + if (d->expr.kind != EXPR_FN) { /* it's okay if a function references itself */ + /* if we've complained about it before when we were figuring out the type, don't complain again */ + if (!(d->flags & DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE)) { + char *s = ident_to_str(i); + err_print(where, "Use of identifier %s within its own declaration.", s); + free(s); + info_print(d->where, "Declaration was here."); + d->flags |= DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE; + } + return false; } - return false; } } if (!allow_use_before_decl) { @@ -21,13 +21,6 @@ static inline const char *ordinals(size_t x) { } } -typedef uint32_t LineNo; - -typedef struct { - LineNo line; - char *code; -} Location; - /* file name of file being processed */ /* TODO: remove this */ static const char *err_filename; diff --git a/util/location.c b/util/location.c index f588146..9a8beb8 100644 --- a/util/location.c +++ b/util/location.c @@ -1,3 +1,9 @@ +typedef uint32_t LineNo; +typedef struct { + LineNo line; + char *code; +} Location; + bool location_after(Location a, Location b) { /* a is after b? */ return a.code > b.code; } |