From 413cfa0327ae94fc899ed24f73dc7e4bf30946e3 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Sat, 18 Nov 2023 08:42:17 +0100 Subject: [PATCH] WIP: expression parser --- include/ulas.h | 34 +++++++++++++++++++--------------- makefile | 4 +++- src/test.c | 12 +++++++++--- src/ulas.c | 40 +++++++++++++++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/include/ulas.h b/include/ulas.h index 0ef1802..f026f2e 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -90,7 +90,11 @@ struct ulas_str { */ // any token before 256 is just the literal char value -enum ulas_toks { ULAS_TOKLITERAL = 256, ULAS_TOKSYMBOL }; +enum ulas_toks { + ULAS_TOKLITERAL = 256, + ULAS_TOKSYMBOL, + +}; // primitive data types enum ulas_type { ULAS_INT, ULAS_STR }; @@ -216,30 +220,30 @@ struct ulas_sym { enum ulas_exprs { ULAS_EXPUNARY, ULAS_EXPBINARY, ULAS_EXPLITERAL }; -struct ulas_expunary { - struct ulas_expr *expr; - struct ulas_tok *op; +struct ulas_expun { + long expr; + long op; }; -struct ulas_expbinary { - struct ulas_expr *left; - struct ulas_expr *right; - struct ulas_tok *op; +struct ulas_expbin { + long left; + long right; + long op; }; -struct ulas_expliteral { - struct ulas_tok *tok; +struct ulas_explit { + long tok; }; -union ulas_expdat { - struct ulas_expunary unary; - struct ulas_expbinary binary; - struct ulas_expliteral literal; +union ulas_expval { + struct ulas_expun un; + struct ulas_expbin bin; + struct ulas_explit lit; }; struct ulas_expr { enum ulas_exprs type; - union ulas_expdat dat; + union ulas_expval val; }; /** diff --git a/makefile b/makefile index e2755f7..a994353 100644 --- a/makefile +++ b/makefile @@ -9,6 +9,8 @@ LIBS= TEST_LIBS= LDFLAGS=$(DBGLDFLAGS) $(LIBS) +TAG_LIBS=/usr/include/unistd.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/assert.h /usr/include/errno.h /usr/include/ctype.h + ODIR=obj TEST_ODIR=obj/test BDIR=bin @@ -53,7 +55,7 @@ install: .PHONY: tags tags: - ctags --recurse=yes --exclude=.git --exclude=bin --exclude=obj --extras=* --fields=* --c-kinds=* --language-force=C + ctags --recurse=yes --exclude=.git --exclude=bin --exclude=obj --extras=* --fields=* --c-kinds=* --language-force=C $(TAG_LIBS) .PHONY: ccmds: diff --git a/src/test.c b/src/test.c index c8b18d5..e70d3a0 100644 --- a/src/test.c +++ b/src/test.c @@ -174,14 +174,13 @@ void test_preproc(void) { free(tok.lit.val.strv); \ } -#define ASSERT_UNEXPECTED_TOTOK(expected_rc, token) \ +#define ASSERT_UNEXPECTED_TOTOK(expected_rc, token) \ { \ int rc = 0; \ - ulas_totok((token), strlen(token), &rc); \ + ulas_totok((token), strlen(token), &rc); \ assert((expected_rc) == rc); \ } - void test_totok(void) { TESTBEGIN("totok"); @@ -217,6 +216,12 @@ void test_totok(void) { TESTEND("totok"); } +void test_intexpr(void) { + TESTBEGIN("intexpr"); + + TESTEND("intexpr"); +} + int main(int arc, char **argv) { ulas_init(ulas_cfg_from_env()); @@ -228,6 +233,7 @@ int main(int arc, char **argv) { test_strbuf(); test_preproc(); test_totok(); + test_intexpr(); ulas_free(); diff --git a/src/ulas.c b/src/ulas.c index b61fe4e..c75190f 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -905,27 +905,57 @@ void ulas_tokbufpush(struct ulas_tokbuf *tb, struct ulas_tok tok) { tb->len++; } -void ulas_tokbufclear(struct ulas_tokbuf *tb) { tb->len = 0; } +void ulas_tokbufclear(struct ulas_tokbuf *tb) { + for (long i = 0; i < tb->len; i++) { + struct ulas_tok *t = &tb->buf[i]; + if ((t->type == ULAS_TOKLITERAL || t->type == ULAS_TOKSYMBOL) && + t->lit.type == ULAS_STR) { + free(t->lit.val.strv); + } + } + tb->len = 0; +} -void ulas_tokbuffree(struct ulas_tokbuf *tb) { free(tb->buf); } +void ulas_tokbuffree(struct ulas_tokbuf *tb) { + ulas_tokbufclear(tb); + free(tb->buf); +} /** * Assembly step */ -int ulas_intexpr(const char **line, unsigned long n, int *rc) { - // read tokens until the next token is end of line, ; or , +int ulas_tokexpr(const char **line, unsigned long n) { + ulas_tokbufclear(&ulas.toks); int tokrc = 0; while ((tokrc = ulas_tok(&ulas.tok, line, n) > 0)) { if (tokrc == -1) { - *rc = -1; goto fail; } // interpret the token + struct ulas_tok tok = ulas_totok( + ulas.tok.buf, strnlen(ulas.tok.buf, ulas.tok.maxlen), &tokrc); + if (tokrc == -1) { + goto fail; + } + + // now we can loop token type, add all tokens to the token buffer + ulas_tokbufpush(&ulas.toks, tok); } fail: + return tokrc; +} + +int ulas_intexpr(const char **line, unsigned long n, int *rc) { + if (ulas_tokexpr(line, n) == -1) { + *rc = -1; + return -1; + } + + // now that we have all tokens in the buffer, create the tree strucute + return -1; } -- 2.30.2