diff options
-rw-r--r-- | main.c | 16 | ||||
-rw-r--r-- | parse.c | 37 | ||||
-rw-r--r-- | test.toc | 13 | ||||
-rw-r--r-- | toc.c | 17 | ||||
-rw-r--r-- | tokenizer.c | 4 |
5 files changed, 52 insertions, 35 deletions
@@ -1,18 +1,4 @@ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> -#include <stdint.h> -#include <stdbool.h> -#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) { @@ -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; } @@ -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); @@ -0,0 +1,17 @@ +/* Includes all of toc's files */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> +#include <stdint.h> +#include <stdbool.h> +#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; |