summaryrefslogtreecommitdiff
path: root/usr.bin/oasm/lex.c
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-07-23 18:38:09 -0400
committerIan Moffett <ian@osmora.org>2025-07-23 18:47:57 -0400
commit729a19a6b7e636a8af3a15f7fe5204cc0d59dbf7 (patch)
tree9dc5dbacd0576f1aa369e9442f442e6a117865bc /usr.bin/oasm/lex.c
parentf9a78caefd6f254e854fd6cdf64a8642ccddc34e (diff)
oasm: Add initial support for labels
A label is like a pin on a map with a number attached to it. OASM keeps track of a number referred to as the psuedo instruction pointer (PIP). This value is initially zero by default and is incremented every instruction. The purpose of this value is to pin a location in the code and mark it to be at a specific address so that further references to that label would be translated to the previous PIP value at the time of encountering the label. Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'usr.bin/oasm/lex.c')
-rw-r--r--usr.bin/oasm/lex.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/usr.bin/oasm/lex.c b/usr.bin/oasm/lex.c
index a33a570..87ac464 100644
--- a/usr.bin/oasm/lex.c
+++ b/usr.bin/oasm/lex.c
@@ -50,6 +50,20 @@ static char putback = '\0';
#define S_IMN_HLT "hlt"
#define S_IMN_BR "br"
+/* Instruction length */
+#define OSMX64_INST_LEN 4
+
+/*
+ * Update the state when the caller encounters
+ * a newline.
+ */
+static inline void
+lex_newline(struct oasm_state *state)
+{
+ ++state->line;
+ state->pip += OSMX64_INST_LEN;
+}
+
/*
* Returns 0 if a char is counted as a
* skippable token. Otherwise, -1
@@ -63,7 +77,7 @@ lex_skippable(struct oasm_state *state, char c)
case '\t': return 0;
case '\r': return 0;
case '\n':
- ++state->line;
+ lex_newline(state);
return 0;
}
@@ -154,6 +168,10 @@ lex_nomstr(struct oasm_state *state, char **res)
retval = tmp;
break;
}
+ if (tmp == ':') {
+ retval = tmp;
+ break;
+ }
if (tmp == '\n') {
++state->line;
retval = tmp;
@@ -295,7 +313,7 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp)
switch (c) {
case '\n':
- ++state->line;
+ lex_newline(state);
return 0;
case '\0':
return -1;
@@ -306,7 +324,14 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp)
ttp->raw = NULL;
lex_putback(c);
- lex_nomstr(state, &p);
+ c = lex_nomstr(state, &p);
+
+ while (c == ':') {
+ ttp->type = TT_LABEL;
+ ttp->raw = p;
+ state->label_ip = state->pip;
+ return 0;
+ }
/* Arithmetic operation? */
if ((tok = token_arith(p)) != TT_UNKNOWN) {
@@ -340,6 +365,7 @@ lex_tok(struct oasm_state *state, struct oasm_token *ttp)
ttp->raw = p;
return 0;
}
+
oasm_err("bad token \"%s\"\n", p);
lex_try_free(p);
return -1;