WIP: string expressions
authorLukas Krickl <lukas@krickl.dev>
Tue, 5 Dec 2023 09:04:51 +0000 (10:04 +0100)
committerLukas Krickl <lukas@krickl.dev>
Tue, 5 Dec 2023 09:04:51 +0000 (10:04 +0100)
include/ulas.h
src/test.c
src/ulas.c

index 7364b3942954e4f87b8260286255b35fefca11e0..ba27aeea6e43ccb5f81c1541efbb66abc22858fc 100644 (file)
@@ -551,5 +551,6 @@ int ulas_asm(FILE *dst, FILE *src);
 
 // parses and executes a 32 bit signed int math expressions
 int ulas_intexpr(const char **line, unsigned long n, int *rc);
+char *ulas_strexpr(const char **line, unsigned long n, int *rc);
 
 #endif
index fbf6ecb89b19d51b3de6ad7d30b03c9a1a073151..6e4aff338c2130bd3b6105acc616962f0aa39a50 100644 (file)
@@ -210,6 +210,7 @@ void test_totok(void) {
 
   // string token
   ASSERT_STR_TOTOK("test", 0, "\"test\"");
+  ASSERT_STR_TOTOK("test\n", 0, "\"test\\n\"");
   // string with escape
   ASSERT_STR_TOTOK("test\n\"123\"", 0, "\"test\\n\\\"123\\\"\"");
   // unterminated string
@@ -279,6 +280,26 @@ void test_intexpr(void) {
   TESTEND("intexpr");
 }
 
+#define ASSERT_STREXPR(expected_val, expected_rc, expr)                        \
+  {                                                                            \
+    int rc = 0;                                                                \
+    const char *oexpr = expr;                                                  \
+    ulas.pass = ULAS_PASS_FINAL;                                               \
+    const char *val = ulas_strexpr(&oexpr, strlen((expr)), &rc);               \
+    assert(rc == (expected_rc));                                               \
+    assert(val);                                                               \
+    assert(strcmp((expected_val), val) == 0);                                  \
+  }
+
+void test_strexpr(void) {
+  TESTBEGIN("strexpr");
+
+  ASSERT_STREXPR("test", 0, "\"test\"");
+  // ASSERT_STREXPR("test\n", 0, "\"test\\n\"");
+
+  TESTEND("strexpr");
+}
+
 #define ASSERT_ASMINSTR(expect_len, line, ...)                                 \
   {                                                                            \
     const char *l = line;                                                      \
@@ -380,6 +401,7 @@ int main(int arc, char **argv) {
   test_preproc();
   test_totok();
   test_intexpr();
+  test_strexpr();
   test_asminstr();
   test_symscope();
 
index e46f43cbac0c3e662a10d455dcd782a8c0a39a47..eabccfab94d8077a037d7bdc1d7a35ac53b4f1f2 100644 (file)
@@ -350,7 +350,7 @@ int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n) {
     i++;
   }
 tokdone:
-
+  
   dst->buf[write] = '\0';
 
   *out_line += i;
@@ -1532,6 +1532,39 @@ int ulas_intexpr(const char **line, unsigned long n, int *rc) {
   return ulas_intexpreval(expr, rc);
 }
 
+char *ulas_strexpr(const char **line, unsigned long n, int *rc) {
+  if (ulas_tokexpr(line, n) == -1) {
+    *rc = -1;
+    return NULL;
+  }
+
+  int expr = ulas_parseexpr();
+  if (expr == -1) {
+    *rc = -1;
+    return NULL;
+  }
+
+  struct ulas_expr *e = ulas_exprbufget(&ulas.exprs, expr);
+  if (!e) {
+    ULASERR("unable to evaluate expression\n");
+    *rc = -1;
+    return NULL;
+  }
+
+  switch ((int)e->type) {
+  case ULAS_EXPPRIM: {
+    struct ulas_tok *t = ulas_tokbufget(&ulas.toks, (int)e->val.prim.tok);
+    char *s = ulas_valstr(t, rc);
+    return s;
+  }
+  default:
+    ULASERR("Unhandeled string expression\n");
+    *rc = -1;
+    return NULL;
+  }
+  return NULL;
+}
+
 const char *ulas_asmregstr(enum ulas_asmregs reg) {
   switch (reg) {
   case ULAS_REG_A: