extern FILE *ulasout;
extern FILE *ulaserr;
+// NULL for int based lookup
+#define INULL (-1)
+
+// expression index in the expression list
+typedef int iexpr;
+
+// token index in the token list
+typedef int itok;
+
+// string index in the string list
+typedef int istr;
+
+struct ulas_expr;
+struct ulas_tok;
+
struct ulas_config {
// argv represents file names
char **argv;
bool verbose;
};
+/**
+ * Assembly context
+ */
+
+struct ulas {
+ char **strs;
+ size_t strslen;
+};
+
/**
* Tokens
*/
};
struct ulas_tokliteral {
- const char *literal;
+ istr literal;
};
union ulas_tokdat {
*/
struct ulas_sym {
- const char *name;
+ istr name;
};
/**
* Expressions
+ *
+ * Expressions use an index based lookup instead of
+ * actual pointers to allow easy dumping of the structure to a file
+ * as well as realloc calls. As an index the integer based iexpr and itok
+ * denote which data type is supposed to be looked up. An iexpr or itok value of
+ * -1 denotes a NULL value
*/
-struct ulas_expr;
-
enum ulas_exprs { ULAS_EXPUNARY, ULAS_EXPBINARY, ULAS_EXPLITERAL };
struct ulas_expunary {
- struct ulas_expr *left;
- struct ulas_tok *op;
+ iexpr left;
+ itok op;
};
struct ulas_expbinary {
- struct ulas_expr *left;
- struct ulas_expr *right;
- struct ulas_tok *op;
+ iexpr left;
+ iexpr right;
+ itok op;
};
struct ulas_expliteral {
- struct ulas_tok *tok;
+ itok tok;
};
union ulas_expdat {
assert(strcmp(buf, expected_tok) == 0); \
}
-#define assert_tokline(expected_toks, expected_n, line, rule) \
- {}
+#define assert_tokline(expected_n, line, rule, ...) \
+ { \
+ char *expect[] = __VA_ARGS__; \
+ size_t n = 0; \
+ char **toks = ulas_tokline(line, &n, rule); \
+ assert(toks); \
+ assert(n == expected_n); \
+ for (size_t i = 0; i < n; i++) { \
+ assert(strcmp(toks[i], expect[i]) == 0); \
+ } \
+ ulas_toklinefree(toks, n); \
+ }
void test_tok(void) {
TESTBEGIN("tok");
assert_tok("", 0, "", ulas_tokrulespace);
assert_tok("", -1, NULL, ulas_tokrulespace);
- assert_tokline(({"test", "tokens", "with", "line"}), 4,
- " test tokens with line", ulas_tokrulespace);
+ assert_tokline(4, " test tokens with line", ulas_tokrulespace,
+ {"test", "tokens", "with", "line"});
TESTEND("tok");
}
}
#undef weld_tokcond
- dst[write + 1] = '\0';
+ dst[write] = '\0';
return i;
}
}
dst = newdst;
- dst[*n - 1] = strndup(buf, ULAS_TOKMAX);
+ dst[(*n) - 1] = strndup(buf, ULAS_TOKMAX);
}
return dst;
fail:
ulas_toklinefree(dst, *n);
+ *n = 0;
return NULL;
}
return;
}
for (size_t i = 0; i < n; i++) {
- free(data[n]);
+ free(data[i]);
}
free(data);