commit 92c7b581389a40b5ba868477da057b72f7578267
parent 7b3dafb8d828d47f183c4d38045c3fbb8b926bfb
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Tue, 25 Nov 2025 12:15:02 +0000
made brackets work!!
Diffstat:
| M | Makefile | | | 4 | ++-- |
| M | lexer.h | | | 2 | +- |
| M | spl.c | | | 60 | +++++++++++++++++++++++++++++++++++------------------------- |
3 files changed, 38 insertions(+), 28 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
-CFLAGS = -fsanitize=address -ggdb -pedantic
+CFLAGS = -ggdb -pedantic
CPPFLAGS = -D_POSIX_C_SOURCE
-LDFLAGS = -fsanitize=address
+LDFLAGS =
SRC = spl.c lexer.c util.c
OBJ = ${SRC:.c=.o}
diff --git a/lexer.h b/lexer.h
@@ -14,7 +14,7 @@ enum ops {
};
typedef struct tok {
- short op;
+ enum ops op;
int n;
} tok;
diff --git a/spl.c b/spl.c
@@ -8,9 +8,8 @@
typedef struct rexpr {
char op;
union {
- struct { /* for bracketed exprs */
- tok *ts;
- int *tc;
+ struct { /* bin ops */
+ struct rexpr *e;
};
struct { /* operators */
struct rexpr *expr[2];
@@ -46,9 +45,9 @@ getpres(tok t) {
return 2;
case INT:
- case OBRACE:
- case CBRACE:
return 3;
+ case OBRACE:
+ return 4;
}
parserErr("Not an op");
}
@@ -58,34 +57,42 @@ isop(tok t) {
return (t.op == ADD || t.op == SUB || t.op == MUL || t.op == DIV);
}
-rexpr *
-parseBrace(tok *lowest, mctx *ctx) {
- tok *endbrace;
+tok *
+findend(tok *start, tok *end) { /* this doesnt quite work yet */
int d = 1;
- for (int i = 1; d != 0; i++) {
- if (lowest[i].op == '(') d++;
- else if (lowest[i].op == ')') d--;
- endbrace = &lowest[i];
+ tok *t;
+
+ if (start->op != OBRACE)
+ parserErr("Expected a '('");
+
+ for (t = &start[1]; d != 0; t = &t[1]) {
+ if (end->op != CBRACE && t == end)
+ parserErr("unclosed brace");
+ if (t->op == OBRACE)
+ d++;
+ else if (t->op == CBRACE)
+ d--;
}
- return pivotParse(&lowest[1], &endbrace[-1], ctx);
+ return &t[-1];
}
rexpr *
pivotParse(tok *start, tok *end, mctx *ctx) {
rexpr *e = alloczctx(ctx, sizeof(rexpr));
tok *lowest = start;
- int i = 0;
- for (tok *t = lowest; t != end; i++, t = &start[i]) {
+
+ for (tok *t = lowest ; t != end; t = &t[1]) {
+ if (t->op == CBRACE)
+ continue;
if (getpres(*t) < getpres(*lowest))
lowest = t;
- if (t->op == '(') {
- while (t->op != ')') {
- i++;
- t = &start[i];
- }
- i--;
- }
+ if (t->op == OBRACE)
+ t = findend(t, end);
+
+ if (t == end)
+ break;
}
+
if (lowest == start) {
switch (lowest->op) {
case INT:
@@ -95,7 +102,8 @@ pivotParse(tok *start, tok *end, mctx *ctx) {
e->n = lowest->n;
break;
case OBRACE:
- e = parseBrace(lowest, ctx);
+ e->op = OBRACE;
+ e->e = pivotParse(&lowest[1], &findend(lowest, end)[-1], ctx);
break;
default:
parserErr("Unexpected token type");
@@ -117,6 +125,8 @@ eval(rexpr *e) {
switch (e->op) {
case INT:
return e->n;
+ case OBRACE:
+ return eval(e->e);
case ADD:
return eval(e->expr[0]) + eval(e->expr[1]);
case SUB:
@@ -130,7 +140,7 @@ eval(rexpr *e) {
int
main() {
- lex l = mklexer("(2 + 4) * 9 / 3");
+ lex l = mklexer("1 - (5 + 5)");
tok list[32] = {0}, t = next(&l);
int i;
for (i = 0; i < 32 && t.op != LEOF; i++, t = next(&l)) {
@@ -138,7 +148,7 @@ main() {
}
mctx *ctx = newctx();
- rexpr *e = pivotParse(list, &list[i - 1], ctx);
+ rexpr *e = pivotParse(list, &list[i-1], ctx);
printf("%d\n", eval(e));
freectx(ctx);
}