spl

a Simple Programming Language
Log | Files | Refs

commit 92c7b581389a40b5ba868477da057b72f7578267
parent 7b3dafb8d828d47f183c4d38045c3fbb8b926bfb
Author: thing1 <thing1@seacrossedlovers.xyz>
Date:   Tue, 25 Nov 2025 12:15:02 +0000

made brackets work!!

Diffstat:
MMakefile | 4++--
Mlexer.h | 2+-
Mspl.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); }