summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-09-21 18:48:41 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-09-21 18:48:41 -0400
commit098499d4ca6cc5157f71e9d199f4eb14b91c90e1 (patch)
tree79f9201de819c458c22326ceb1456d76f4cf063e
parenta1099999e02fb87e3f5f209dfbba3f93692953db (diff)
fixed a bit of parsing
-rw-r--r--parse.c15
-rw-r--r--test.toc14
-rw-r--r--toc.c2
-rw-r--r--types.c19
-rw-r--r--util/err.c7
-rw-r--r--util/location.c6
6 files changed, 39 insertions, 24 deletions
diff --git a/parse.c b/parse.c
index 2f5cd2e..e8b7376 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
}
diff --git a/test.toc b/test.toc
index df1a8fe..de8ee0e 100644
--- a/test.toc
+++ b/test.toc
@@ -1,8 +1,12 @@
main @= fn() {
- y := {
- x := 5;
- z := y;
- z
- };
+/*
+ f := main;
+ f();
+ main();
+*/
+ N @= {
+ foo : [N]int;
+ foo[0]
+ };
};
diff --git a/toc.c b/toc.c
index 3965e18..d20868d 100644
--- a/toc.c
+++ b/toc.c
@@ -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"
diff --git a/types.c b/types.c
index fb570b0..511614c 100644
--- a/types.c
+++ b/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) {
diff --git a/util/err.c b/util/err.c
index c5d32b2..cc642d4 100644
--- a/util/err.c
+++ b/util/err.c
@@ -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;
}