summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c16
-rw-r--r--parse.c37
-rw-r--r--test.toc13
-rw-r--r--toc.c17
-rw-r--r--tokenizer.c4
5 files changed, 52 insertions, 35 deletions
diff --git a/main.c b/main.c
index 6aa66a3..9946625 100644
--- a/main.c
+++ b/main.c
@@ -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) {
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 <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;