WIP: expression parser
authorLukas Krickl <lukas@krickl.dev>
Sat, 18 Nov 2023 07:42:17 +0000 (08:42 +0100)
committerLukas Krickl <lukas@krickl.dev>
Sat, 18 Nov 2023 07:42:17 +0000 (08:42 +0100)
include/ulas.h
makefile
src/test.c
src/ulas.c

index 0ef18029a8adc5523b3ef05ea5b531b1862fedcb..f026f2e4a3ff89466005ed074076507da806cee1 100644 (file)
@@ -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;
 };
 
 /**
index e2755f7fce6f9f66f973ebb3ed76ce2196841db0..a99435343d56d8649652f6278c3e2a775898bf57 100644 (file)
--- 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:
index c8b18d53ec284b2bd7f5920051235c1b2f71a4bc..e70d3a0ff8710dca56d1a117c4e0a02ce4217926 100644 (file)
@@ -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();
 
index b61fe4ef01db1efc062519d70ccac1b68d15c83c..c75190fb93096c82e41b8ed3836376a92288a9fb 100644 (file)
@@ -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;
 }