summaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-08-19 21:04:51 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-08-19 21:04:51 -0400
commitc4b9c987ce33c3511a1ac1b20c85c0c0e9bde960 (patch)
tree9b69b122015dd09332477596f71bbb1962d1380e /parse.c
parentf7c157079964bf42076db700776346204a894a53 (diff)
Added parentheses to expressions
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/parse.c b/parse.c
index 483d1d6..55c2c6f 100644
--- a/parse.c
+++ b/parse.c
@@ -225,6 +225,8 @@ static bool expr_parse(Expression *e, Parser *p, Token *end) {
/* Find the lowest-precedence operator not in parentheses */
int paren_level = 0;
int lowest_precedence = NOT_AN_OP;
+ /* e.g. (5+3) */
+ bool entirely_within_parentheses = token_is_kw(t->token, KW_LPAREN);
Token *lowest_precedence_op;
for (Token *token = t->token; token < end; token++) {
if (token->kind == TOKEN_KW) {
@@ -234,25 +236,46 @@ static bool expr_parse(Expression *e, Parser *p, Token *end) {
break;
case KW_RPAREN:
paren_level--;
+ if (paren_level == 0 && token != end - 1)
+ entirely_within_parentheses = false;
if (paren_level < 0) {
t->token = token;
tokr_err(t, "Excessive closing parenthesis.");
+ return false;
}
break;
default: { /* OPTIM: use individual cases for each op */
- int precedence = op_precedence(token->kw);
- if (precedence == NOT_AN_OP) break; /* nvm it's not an operator */
- if (lowest_precedence == NOT_AN_OP || precedence <= lowest_precedence) {
- lowest_precedence = precedence;
- lowest_precedence_op = token;
+ if (paren_level == 0) {
+ int precedence = op_precedence(token->kw);
+ if (precedence == NOT_AN_OP) break; /* nvm it's not an operator */
+ if (lowest_precedence == NOT_AN_OP || precedence <= lowest_precedence) {
+ lowest_precedence = precedence;
+ lowest_precedence_op = token;
+ }
}
} break;
}
}
}
+ if (paren_level > 0) {
+ tokr_err(t, "Too many opening parentheses.");
+ return false;
+ }
+ if (paren_level < 0) {
+ tokr_err(t, "Too many closing parentheses.");
+ return false;
+ }
+
+ if (entirely_within_parentheses) {
+ t->token++; /* move past opening ( */
+ Token *new_end = end - 1; /* parse to ending ) */
+ if (!expr_parse(e, p, new_end))
+ return false;
+ t->token++; /* move past closing ) */
+ return true;
+ }
if (lowest_precedence == NOT_AN_OP) {
- /* function calls, array accesses, etc. OR
- something like (5+3)*/
+ /* function calls, array accesses, etc. */
tokr_err(t, "Not implemented yet.");
return false;
}