enum ulas_syms { ULAS_SYM_FORWARD, ULAS_SYM_DECL };
-enum ulas_symres { ULAS_EGLOBALUNRESOLVE = 1, ULAS_ELOCALUNRESOLVE = 2 };
-
struct ulas_sym {
char *name;
struct ulas_tok tok;
* Assembly context
*/
+enum ulas_pass {
+ ULAS_PASS_FINAL = 0,
+ ULAS_PASS_RESOLVE = 1,
+};
+
struct ulas {
char *filename;
unsigned long line;
+ // count how many passes we have completed so far
+ int pass;
+
// holds the current token
struct ulas_str tok;
// returns -1 if any flagged symbol was not found
// if flagged symbols remain unresolved (e.g. global or locals) rc is set to the
// respective flag value
-struct ulas_tok *ulas_symbolresolve(const char *name, enum ulas_symres flags,
- int *rc);
+struct ulas_tok *ulas_symbolresolve(const char *name, int *rc);
// tokenisze according to pre-defined rules
// returns the amount of bytes of line that were
// convert literal to its int value
// retunrs -1 on error, 0 on success and 1 if there is an unresolved symbol
-int ulas_valint(struct ulas_tok *lit, enum ulas_symres flags, int *rc);
+int ulas_valint(struct ulas_tok *lit, int *rc);
// convert literal to its char value
-char *ulas_valstr(struct ulas_tok *lit, enum ulas_symres flags, int *rc);
+char *ulas_valstr(struct ulas_tok *lit, int *rc);
struct ulas_tokbuf ulas_tokbuf(void);
return 1;
}
-struct ulas_tok *ulas_symbolresolve(const char *name, enum ulas_symres flags,
- int *rc) {
+struct ulas_tok *ulas_symbolresolve(const char *name, int *rc) {
// TODO: implement
return NULL;
}
* Literals, tokens and expressions
*/
-int ulas_valint(struct ulas_tok *lit, enum ulas_symres flags, int *rc) {
+int ulas_valint(struct ulas_tok *lit, int *rc) {
if (lit->type == ULAS_SYMBOL) {
- struct ulas_tok *stok = ulas_symbolresolve(lit->val.strv, flags, rc);
+ struct ulas_tok *stok = ulas_symbolresolve(lit->val.strv, rc);
// bail if symbol is not resolvable
if (*rc > 0) {
return 0;
}
- return ulas_valint(stok, flags, rc);
+ return ulas_valint(stok, rc);
}
if (!lit || lit->type != ULAS_INT) {
return lit->val.intv;
}
-char *ulas_valstr(struct ulas_tok *lit, enum ulas_symres flags, int *rc) {
+char *ulas_valstr(struct ulas_tok *lit, int *rc) {
if (!lit || lit->type != ULAS_STR) {
ULASERR("Expected str\n");
*rc = -1;
}
case ULAS_EXPPRIM: {
struct ulas_tok *t = ulas_tokbufget(&ulas.toks, (int)e->val.prim.tok);
- return ulas_valint(t, 0, rc);
+ return ulas_valint(t, rc);
}
}
goto fail;
}
towrite += nextwrite;
-
- // TODO:
- // place marker when a label was unresolved
- // write down byte location in dst as well as the byte offset in lstout so
- // we can fix them later labels can only be unresolved when they are the
- // only node in an expression!
}
// check for trailing
}
}
- ulas_asmout(dst, outbuf, towrite);
- ulas_asmlst(start, outbuf, towrite);
+ // only write to dst on final pass
+ if (ulas.pass == ULAS_PASS_FINAL) {
+ ulas_asmout(dst, outbuf, towrite);
+ ulas_asmlst(start, outbuf, towrite);
+ }
ulas.address += towrite;
fail: