summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-31 16:36:23 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-31 16:36:23 -0400
commit4322b5897449db33bb8c22bae13726c285708009 (patch)
treeca971d4eb21e8ff9b9a4c7111a66f1354306ace0
parenta328c2cb8dac42b87d30bf64963cebc4922fbaa1 (diff)
fixed order of operations problem with .
-rw-r--r--parse.c29
-rw-r--r--test.toc5
2 files changed, 28 insertions, 6 deletions
diff --git a/parse.c b/parse.c
index 3676ad9..4e43eef 100644
--- a/parse.c
+++ b/parse.c
@@ -870,7 +870,6 @@ static int op_precedence(Keyword op) {
case KW_ASTERISK: return 30;
case KW_SLASH: return 40;
case KW_EXCLAMATION: return 50;
- case KW_DOT: return 60;
case KW_DEL: return 1000;
default: return NOT_AN_OP;
}
@@ -1045,6 +1044,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
}
default: break;
}
+
+
+ /* NOTE: the . operator is not handled here, but further down, in order to allow some_struct.fn_member() */
+ Token *dot = NULL; /* this keeps track of it for later */
/* Find the lowest-precedence operator not in parentheses/braces/square brackets */
int paren_level = 0;
@@ -1092,6 +1095,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
return false;
}
break;
+ case KW_DOT:
+ if (paren_level == 0 && brace_level == 0 && square_level == 0)
+ dot = token;
+ break;
default: { /* OPTIM: use individual cases for each op */
if (paren_level == 0 && brace_level == 0 && square_level == 0) {
int precedence;
@@ -1297,9 +1304,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
case KW_SLASH:
op = BINARY_DIV;
break;
- case KW_DOT:
- op = BINARY_DOT;
- break;
case KW_AMPERSAND:
case KW_EXCLAMATION:
case KW_DEL:
@@ -1345,7 +1349,8 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
case KW_LPAREN:
if (square_level == 0 && paren_level == 0 && brace_level == 0
&& token != t->tokens
- && token[-1].kind != TOKEN_DIRECT /* don't include directives */)
+ && token[-1].kind != TOKEN_DIRECT /* don't include directives */
+ && !token_is_kw(&token[-1], KW_DOT)) /* or some_struct.("property") */
opening_bracket = token; /* maybe this left parenthesis opens the function call */
paren_level++;
break;
@@ -1499,6 +1504,20 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
}
return true;
}
+
+ if (dot) {
+ e->kind = EXPR_BINARY_OP;
+ e->binary.lhs = parser_new_expr(p);
+ e->binary.rhs = parser_new_expr(p);
+ e->binary.op = BINARY_DOT;
+ if (!parse_expr(p, e->binary.lhs, dot))
+ return false;
+ t->token = dot + 1;
+ if (!parse_expr(p, e->binary.rhs, end))
+ return false;
+ return true;
+ }
+
tokr_err(t, "Unrecognized expression.");
return false;
}
diff --git a/test.toc b/test.toc
index bf0fc19..4fdc819 100644
--- a/test.toc
+++ b/test.toc
@@ -5,6 +5,7 @@ puti @= fn(x: int) {
Point @= struct {
x_coordinate, y_coordinate : int;
+ f : fn();
};
somefn @= fn() int {
@@ -21,8 +22,10 @@ somefn @= fn() int {
x
};
-main @= fn() {
+main @= fn() {
+ p: Point;
X @= somefn();
puti(X);
puti(somefn());
+ puti(p.x_coordinate);
};