From c4b9c987ce33c3511a1ac1b20c85c0c0e9bde960 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Mon, 19 Aug 2019 21:04:51 -0400 Subject: Added parentheses to expressions --- main.c | 16 +--------------- parse.c | 37 ++++++++++++++++++++++++++++++------- test.toc | 13 +------------ toc.c | 17 +++++++++++++++++ tokenizer.c | 4 +++- 5 files changed, 52 insertions(+), 35 deletions(-) create mode 100644 toc.c diff --git a/main.c b/main.c index 6aa66a3..9946625 100644 --- a/main.c +++ b/main.c @@ -1,18 +1,4 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util/err.c" -#include "util/arr.c" -#include "util/blockarr.c" -#include "identifiers.c" -#include "tokenizer.c" -#include "parse.c" +#include "toc.c" int main(int argc, char **argv) { if (argc < 2) { 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; } diff --git a/test.toc b/test.toc index 52d7a52..901d938 100644 --- a/test.toc +++ b/test.toc @@ -1,12 +1 @@ -foo:i8=3; -foo:i8=3-+++-a--+b++c---3; -a:float-4; - -baskjfm := bar; - -X :- 4 ; y :- 5; -x, y, z : float = 3; - -foo, bar, baz := 0; - - +x :- 3 + 4 - (3 + ((-3--b-5)+6++8)---+a+-4); diff --git a/toc.c b/toc.c new file mode 100644 index 0000000..ee05b2a --- /dev/null +++ b/toc.c @@ -0,0 +1,17 @@ +/* Includes all of toc's files */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util/err.c" +#include "util/arr.c" +#include "util/blockarr.c" +#include "identifiers.c" +#include "tokenizer.c" +#include "parse.c" diff --git a/tokenizer.c b/tokenizer.c index 587d080..5dbd9f4 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -269,11 +269,13 @@ static bool tokenize_string(Tokenizer *tokr, char *str) { if (is_comment) continue; } { + char *start_s = t.s; Keyword kw = tokenize_keyword(&t.s); if (kw != KW_COUNT) { /* it's a keyword */ Token *token = tokr_add(&t); - tokr_put_location(&t, token); + token->where.line = t.line; + token->where.code = start_s; token->kind = TOKEN_KW; token->kw = kw; continue; -- cgit v1.2.3