Added group expressions
authorLukas Krickl <lukas@krickl.dev>
Mon, 20 Nov 2023 12:10:49 +0000 (13:10 +0100)
committerLukas Krickl <lukas@krickl.dev>
Mon, 20 Nov 2023 12:10:49 +0000 (13:10 +0100)
include/ulas.h
src/test.c
src/ulas.c

index 32f8f6edfe81d6710208c97ccf165e62d177717c..98bf2195b0d66b7af83e6ec208420bbe06bec516 100644 (file)
@@ -241,9 +241,7 @@ struct ulas_expprim {
 struct ulas_expgrp {
   // points to the first expression
   // in this group
-  long expr;
-  // how many expressions belong to the group
-  long len;
+  long head;
 };
 
 union ulas_expval {
@@ -256,9 +254,6 @@ union ulas_expval {
 struct ulas_expr {
   enum ulas_exprs type;
   union ulas_expval val;
-  // link to the next expression, -1 indicates
-  // there is no next expression
-  long next;
 };
 
 /**
index ecdd3c23e3024fbb5aa7dd2b05b84b2df3814304..dd76cd5b53d5e6eeebd46cacb921ed6ad140008f 100644 (file)
@@ -268,6 +268,10 @@ void test_intexpr(void) {
   ASSERT_INTEXPR(-1, 0, "-1");
   ASSERT_INTEXPR(1, 0, "--1");
   ASSERT_INTEXPR(2, 0, "1 - -1");
+  ASSERT_INTEXPR(17, 0, "2 + 3 * 5");
+
+  ASSERT_INTEXPR(-1, -1, "((2 + 3) * 5");
+  ASSERT_INTEXPR(25, 0, "(2 + 3) * 5");
 
   TESTEND("intexpr");
 }
index 1a1cc3a0023f9986b820b688e368245d233ea78f..a5bb969cdf7f42b81cf3bf84480d09c75d326574 100644 (file)
@@ -1044,19 +1044,38 @@ end:
  * we error out because of trailing tokens!
  */
 
+int ulas_parseexprat(int *i);
+
 int ulas_parseprim(int *i) {
   struct ulas_tok *t = ulas_tokbufget(&ulas.toks, *i);
-  if (!t ||
-      (t->type != ULAS_INT && t->type != ULAS_STR && t->type != ULAS_SYMBOL)) {
+  if (!t || (t->type != ULAS_INT && t->type != ULAS_STR &&
+             t->type != ULAS_SYMBOL && t->type != '(' && t->type != ')')) {
     ULASERR("Primary expression expected\n");
     return -1;
   }
 
-  struct ulas_expprim prim = {*i};
-  union ulas_expval val = {.prim = prim};
-  struct ulas_expr e = {ULAS_EXPPRIM, val, -1};
-  *i += 1;
-  return ulas_exprbufpush(&ulas.exprs, e);
+  if (t->type == '(') {
+    *i += 1;
+    int head = ulas_parseexprat(i);
+
+    struct ulas_expgrp grp = {head};
+    union ulas_expval val = {.grp = grp};
+    struct ulas_expr e = {ULAS_EXPGRP, val};
+
+    struct ulas_tok *closing = ulas_tokbufget(&ulas.toks, *i);
+    if (!closing || closing->type != ')') {
+      ULASERR("Unterminated group expression\n");
+      return -1;
+    }
+    *i += 1;
+    return ulas_exprbufpush(&ulas.exprs, e);
+  } else {
+    struct ulas_expprim prim = {*i};
+    union ulas_expval val = {.prim = prim};
+    struct ulas_expr e = {ULAS_EXPPRIM, val};
+    *i += 1;
+    return ulas_exprbufpush(&ulas.exprs, e);
+  }
 }
 
 int ulas_parsecmp(int *i);
@@ -1071,7 +1090,7 @@ int ulas_parseun(int *i) {
 
     struct ulas_expun un = {right, op};
     union ulas_expval val = {.un = un};
-    struct ulas_expr e = {ULAS_EXPUN, val, -1};
+    struct ulas_expr e = {ULAS_EXPUN, val};
     return ulas_exprbufpush(&ulas.exprs, e);
   }
 
@@ -1090,7 +1109,7 @@ int ulas_parsefact(int *i) {
 
     struct ulas_expbin bin = {expr, right, op};
     union ulas_expval val = {.bin = bin};
-    struct ulas_expr e = {ULAS_EXPBIN, val, -1};
+    struct ulas_expr e = {ULAS_EXPBIN, val};
     expr = ulas_exprbufpush(&ulas.exprs, e);
   }
 
@@ -1109,7 +1128,7 @@ int ulas_parseterm(int *i) {
 
     struct ulas_expbin bin = {expr, right, op};
     union ulas_expval val = {.bin = bin};
-    struct ulas_expr e = {ULAS_EXPBIN, val, -1};
+    struct ulas_expr e = {ULAS_EXPBIN, val};
     expr = ulas_exprbufpush(&ulas.exprs, e);
   }
 
@@ -1129,7 +1148,7 @@ int ulas_parsecmp(int *i) {
 
     struct ulas_expbin bin = {expr, right, op};
     union ulas_expval val = {.bin = bin};
-    struct ulas_expr e = {ULAS_EXPBIN, val, -1};
+    struct ulas_expr e = {ULAS_EXPBIN, val};
     expr = ulas_exprbufpush(&ulas.exprs, e);
   }
 
@@ -1147,13 +1166,15 @@ int ulas_parseeq(int *i) {
 
     struct ulas_expbin bin = {expr, right, op};
     union ulas_expval val = {.bin = bin};
-    struct ulas_expr e = {ULAS_EXPBIN, val, -1};
+    struct ulas_expr e = {ULAS_EXPBIN, val};
     expr = ulas_exprbufpush(&ulas.exprs, e);
   }
 
   return expr;
 }
 
+int ulas_parseexprat(int *i) { return ulas_parseeq(i); }
+
 // parses tokens to expression tree
 // returns head expression index
 int ulas_parseexpr(void) {
@@ -1166,7 +1187,7 @@ int ulas_parseexpr(void) {
   }
 
   int i = 0;
-  int rc = ulas_parseeq(&i);
+  int rc = ulas_parseexprat(&i);
 
   if (i < toks->len) {
     ULASERR("Trailing token at index %d\n", i);
@@ -1248,8 +1269,9 @@ int ulas_intexpreval(int i, int *rc) {
     }
     break;
   }
-  case ULAS_EXPGRP:
-    break;
+  case ULAS_EXPGRP: {
+    return ulas_intexpreval(e->val.grp.head, rc);
+  }
   case ULAS_EXPPRIM: {
     struct ulas_tok *t = ulas_tokbufget(&ulas.toks, e->val.prim.tok);
     return ulas_valint(t, rc);