From: Lukas Krickl Date: Tue, 5 Dec 2023 09:04:51 +0000 (+0100) Subject: WIP: string expressions X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=4c1a397e124fc23076cf7cbf20df559c1d9b3df0;p=ulas%2F.git WIP: string expressions --- diff --git a/include/ulas.h b/include/ulas.h index 7364b39..ba27aee 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -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 diff --git a/src/test.c b/src/test.c index fbf6ecb..6e4aff3 100644 --- a/src/test.c +++ b/src/test.c @@ -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(); diff --git a/src/ulas.c b/src/ulas.c index e46f43c..eabccfa 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -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: