// 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
// 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
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; \
test_preproc();
test_totok();
test_intexpr();
+ test_strexpr();
test_asminstr();
test_symscope();
i++;
}
tokdone:
-
+
dst->buf[write] = '\0';
*out_line += i;
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: