aboutsummaryrefslogtreecommitdiff
path: root/tr8as.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-05 12:59:21 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-05 12:59:21 +0100
commitf10e1ea20cbadd151b20175f48ac902eac4ee0d7 (patch)
tree2e9eb228469f36b2a474dd46d5b2b4d4f252f02c /tr8as.c
parentdca7a781545c1b16af76bbbcbd45f6d735c02587 (diff)
downloadtr8vm-f10e1ea20cbadd151b20175f48ac902eac4ee0d7.tar.gz
tr8vm-f10e1ea20cbadd151b20175f48ac902eac4ee0d7.zip
Fixes parsin and improves error reporting
The assembler supports: label: instr ; comment Being any of those three optional. This change makes it happen and also settles on the "retrun error code" pattern for the parse functions.
Diffstat (limited to 'tr8as.c')
-rw-r--r--tr8as.c343
1 files changed, 202 insertions, 141 deletions
diff --git a/tr8as.c b/tr8as.c
index a02f696..1a83b97 100644
--- a/tr8as.c
+++ b/tr8as.c
@@ -87,7 +87,7 @@ typedef struct
typedef struct
{
char id[9];
- uint8_t (*parse)(As *, char *);
+ uint8_t (*parse)(As *, char **);
} InstParse;
/* used to map RGB values to palette index when including a PNG image */
@@ -133,27 +133,32 @@ static char * skip_whitespace(char *c)
return c;
}
-static char * next_string(char *c, char *word, uint8_t *wlen)
+static uint8_t next_string(As *as, char **c, char *word, uint8_t *wlen)
{
- c = skip_whitespace(c);
+ *c = skip_whitespace(*c);
*wlen = 0;
- if (*c != '"')
- return c;
- c++;
+ if (**c != '"')
+ return 0;
+ (*c)++;
- while (*c && *c != '"')
+ while (**c && **c != '"')
{
- word[(*wlen)++] = *c++;
+ word[(*wlen)++] = **c;
+ (*c)++;
if (*wlen == MAX_ID)
{
+ word[*wlen - 1] = 0;
*wlen = 0;
- break;
+ return error_l("String is too long", &as->loc, word);
}
}
word[*wlen] = 0;
- return c + 1;
+ /* the closing quote */
+ (*c)++;
+
+ return 1;
}
static uint8_t isspecial(char c)
@@ -161,23 +166,25 @@ static uint8_t isspecial(char c)
return c == '$' || c == '_' || c == '.' || c == '#' || c == '<' || c == '>';
}
-static char * next_word(char *c, char *word, uint8_t *wlen)
+static uint8_t next_word(As *as, char **c, char *word, uint8_t *wlen)
{
- c = skip_whitespace(c);
+ *c = skip_whitespace(*c);
*wlen = 0;
- while (*c && (isalnum(*c) || isspecial(*c)))
+ while (**c && (isalnum(**c) || isspecial(**c)))
{
- word[(*wlen)++] = *c++;
+ word[(*wlen)++] = **c;
+ (*c)++;
if (*wlen == MAX_ID)
{
- /* XXX: should be an error? */
- break;
+ word[*wlen - 1] = 0;
+ *wlen = 0;
+ return error_l("Invalid input (too long)", &as->loc, word);
}
}
word[*wlen] = 0;
- return c;
+ return 1;
}
static uint8_t next_imm(char *word, uint16_t *n)
@@ -385,14 +392,16 @@ static uint8_t emit_imm(As *as, uint16_t imm)
return 1;
}
-static uint8_t parse_org(As *as, char *c)
+static uint8_t parse_org(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
/* .org imm */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
@@ -407,7 +416,7 @@ static uint8_t parse_org(As *as, char *c)
static uint8_t parse(As *as, char *c);
-static uint8_t parse_include(As *as, char *c)
+static uint8_t parse_include(As *as, char **c)
{
/* XXX: may be support longer filenames */
char word[MAX_ID + 1];
@@ -419,7 +428,9 @@ static uint8_t parse_include(As *as, char *c)
/* .include "filename" */
- next_string(c, word, &wlen);
+ if (!next_string(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected string");
@@ -454,7 +465,7 @@ static uint8_t parse_include(As *as, char *c)
return 1;
}
-static uint8_t parse_incpng(As *as, char *c)
+static uint8_t parse_incpng(As *as, char **c)
{
/* XXX: may be support longer filenames */
char word[MAX_ID + 1];
@@ -462,7 +473,9 @@ static uint8_t parse_incpng(As *as, char *c)
/* .incpng "filename" */
- next_string(c, word, &wlen);
+ if (!next_string(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected string");
@@ -512,7 +525,7 @@ exit_parseinc:
return rc;
}
-static uint8_t parse_incbin(As *as, char *c)
+static uint8_t parse_incbin(As *as, char **c)
{
/* XXX: may be support longer filenames */
char word[MAX_ID + 1];
@@ -522,7 +535,9 @@ static uint8_t parse_incbin(As *as, char *c)
/* .incbin "filename" */
- next_string(c, word, &wlen);
+ if (!next_string(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected string");
@@ -557,21 +572,24 @@ static uint8_t parse_incbin(As *as, char *c)
return 1;
}
-static uint8_t parse_equ(As *as, char *c)
+static uint8_t parse_equ(As *as, char **c)
{
char label[MAX_ID + 1];
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint16_t imm;
/* .equ label imm */
- pt = next_word(c, label, &wlen);
+ if (!next_word(as, c, label, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected label");
- next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
@@ -581,19 +599,19 @@ static uint8_t parse_equ(As *as, char *c)
return new_label_imm(as, label, imm);
}
-static uint8_t parse_db(As *as, char *c)
+static uint8_t parse_db(As *as, char **c)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint16_t imm = 0xff;
/* .db imm [, imm] */
- pt = c;
while (1)
{
- pt = next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
@@ -612,9 +630,9 @@ static uint8_t parse_db(As *as, char *c)
if (as->addr > as->size)
as->size = as->addr;
- if (*pt == ',')
+ if (**c == ',')
{
- pt++;
+ (*c)++;
continue;
}
break;
@@ -623,19 +641,19 @@ static uint8_t parse_db(As *as, char *c)
return 1;
}
-static uint8_t parse_dw(As *as, char *c)
+static uint8_t parse_dw(As *as, char **c)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint16_t imm;
/* .dw imm [, imm] */
- pt = c;
while (1)
{
- pt = next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
@@ -652,9 +670,9 @@ static uint8_t parse_dw(As *as, char *c)
if (as->addr > as->size)
as->size = as->addr;
- if (*pt == ',')
+ if (**c == ',')
{
- pt++;
+ (*c)++;
continue;
}
break;
@@ -663,74 +681,75 @@ static uint8_t parse_dw(As *as, char *c)
return 1;
}
-static uint8_t parse_nop(As *as, char *c)
+static uint8_t parse_nop(As *as, char **c)
{
/* NOP */
return emit(as, 0, 0, 0, 0);
}
-static uint8_t parse_sif(As *as, char *c)
+static uint8_t parse_sif(As *as, char **c)
{
/* SIF */
return emit(as, 11, 0, FHL, 0);
}
-static uint8_t parse_cif(As *as, char *c)
+static uint8_t parse_cif(As *as, char **c)
{
/* CIF */
return emit(as, 11, 0, 0, 0);
}
-static uint8_t parse_ccf(As *as, char *c)
+static uint8_t parse_ccf(As *as, char **c)
{
/* CCF */
return emit(as, 13, 0, FHH | FHL, 0);
}
-static uint8_t parse_scf(As *as, char *c)
+static uint8_t parse_scf(As *as, char **c)
{
/* SCF */
return emit(as, 13, 0, FHH, 0);
}
-static uint8_t parse_sof(As *as, char *c)
+static uint8_t parse_sof(As *as, char **c)
{
/* SOF */
return emit(as, 13, 0, FHL, 0);
}
-static uint8_t parse_cof(As *as, char *c)
+static uint8_t parse_cof(As *as, char **c)
{
/* COF */
return emit(as, 13, 0, 0, 0);
}
-static uint8_t parse_halt(As *as, char *c)
+static uint8_t parse_halt(As *as, char **c)
{
/* HALT */
return emit(as, 0, 0, FHH | FHL, 0);
}
-static uint8_t parse_iret(As *as, char *c)
+static uint8_t parse_iret(As *as, char **c)
{
/* IRET */
return emit(as, 0, 0, FHL, 0);
}
-static uint8_t parse_ret(As *as, char *c)
+static uint8_t parse_ret(As *as, char **c)
{
/* RET */
return emit(as, 0, 0, 0, FL);
}
-static uint8_t parse_r1_r2_or_imm(As *as, char *c, uint8_t *r1, uint8_t *r2, uint16_t *imm)
+static uint8_t parse_r1_r2_or_imm(As *as, char **c, uint8_t *r1, uint8_t *r2, uint16_t *imm)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
/* ? r1, ? */
- pt = next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -738,12 +757,14 @@ static uint8_t parse_r1_r2_or_imm(As *as, char *c, uint8_t *r1, uint8_t *r2, uin
if (*r1 == 0xff)
return error_l("Syntax error", &as->loc, word);
- pt = skip_whitespace(pt);
- if (*pt != ',')
+ *c = skip_whitespace(*c);
+ if (**c != ',')
return error_l("Syntax error", &as->loc, "expected ,");
- pt++;
+ (*c)++;
+
+ if (!next_word(as, c, word, &wlen))
+ return 0;
- pt = next_word(pt, word, &wlen);
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register or immediate");
@@ -768,14 +789,15 @@ static uint8_t parse_r1_r2_or_imm(As *as, char *c, uint8_t *r1, uint8_t *r2, uin
return 1;
}
-static uint8_t parse_r1_imm(As *as, char *c, uint8_t *r1, uint16_t *imm)
+static uint8_t parse_r1_imm(As *as, char **c, uint8_t *r1, uint16_t *imm)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
/* ? r1, imm */
- pt = next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -783,12 +805,14 @@ static uint8_t parse_r1_imm(As *as, char *c, uint8_t *r1, uint16_t *imm)
if (*r1 == 0xff)
return error_l("Syntax error", &as->loc, word);
- pt = skip_whitespace(pt);
- if (*pt != ',')
+ *c = skip_whitespace(*c);
+ if (**c != ',')
return error_l("Syntax error", &as->loc, "expected ,");
- pt++;
+ (*c)++;
+
+ if (!next_word(as, c, word, &wlen))
+ return 0;
- pt = next_word(pt, word, &wlen);
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
@@ -801,7 +825,7 @@ static uint8_t parse_r1_imm(As *as, char *c, uint8_t *r1, uint16_t *imm)
return 1;
}
-static uint8_t parse_and(As *as, char *c)
+static uint8_t parse_and(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1, r2;
@@ -817,7 +841,7 @@ static uint8_t parse_and(As *as, char *c)
return emit(as, 4, r1, FHH, imm);
}
-static uint8_t parse_or(As *as, char *c)
+static uint8_t parse_or(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1, r2;
@@ -833,7 +857,7 @@ static uint8_t parse_or(As *as, char *c)
return emit(as, 4, r1, 0, imm);
}
-static uint8_t parse_xor(As *as, char *c)
+static uint8_t parse_xor(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1, r2;
@@ -849,7 +873,7 @@ static uint8_t parse_xor(As *as, char *c)
return emit(as, 5, r1, FHH, imm);
}
-static uint8_t parse_cmp(As *as, char *c)
+static uint8_t parse_cmp(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1, r2;
@@ -865,7 +889,7 @@ static uint8_t parse_cmp(As *as, char *c)
return emit(as, 5, r1, 0, imm);
}
-static uint8_t parse_add(As *as, char *c)
+static uint8_t parse_add(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1, r2;
@@ -881,7 +905,7 @@ static uint8_t parse_add(As *as, char *c)
return emit(as, 6, r1, FHH, imm);
}
-static uint8_t parse_sub(As *as, char *c)
+static uint8_t parse_sub(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1, r2;
@@ -897,7 +921,7 @@ static uint8_t parse_sub(As *as, char *c)
return emit(as, 6, r1, 0, imm);
}
-static uint8_t parse_bit(As *as, char *c)
+static uint8_t parse_bit(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1;
@@ -912,7 +936,7 @@ static uint8_t parse_bit(As *as, char *c)
return emit(as, 7, r1, FHH, imm);
}
-static uint8_t parse_shl(As *as, char *c)
+static uint8_t parse_shl(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1;
@@ -927,7 +951,7 @@ static uint8_t parse_shl(As *as, char *c)
return emit(as, 7, r1, FHL, imm);
}
-static uint8_t parse_shr(As *as, char *c)
+static uint8_t parse_shr(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1;
@@ -942,7 +966,7 @@ static uint8_t parse_shr(As *as, char *c)
return emit(as, 7, r1, 0, imm);
}
-static uint8_t parse_ror(As *as, char *c)
+static uint8_t parse_ror(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1;
@@ -957,7 +981,7 @@ static uint8_t parse_ror(As *as, char *c)
return emit(as, 8, r1, 0, imm);
}
-static uint8_t parse_rol(As *as, char *c)
+static uint8_t parse_rol(As *as, char **c)
{
uint16_t imm = 0xff;
uint8_t r1;
@@ -972,14 +996,16 @@ static uint8_t parse_rol(As *as, char *c)
return emit(as, 8, r1, FHH, imm);
}
-static uint8_t parse_push(As *as, char *c)
+static uint8_t parse_push(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
uint8_t r1;
/* PUSH r1 */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -995,14 +1021,16 @@ static uint8_t parse_push(As *as, char *c)
return emit(as, 3, r1, FHL, 0);
}
-static uint8_t parse_port(As *as, char *c)
+static uint8_t parse_port(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
uint8_t r1, r2;
/* PORT r1, r2 */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1010,7 +1038,9 @@ static uint8_t parse_port(As *as, char *c)
if (r1 == 0xff)
return error_l("Syntax error", &as->loc, word);
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1021,14 +1051,16 @@ static uint8_t parse_port(As *as, char *c)
return emit(as, 0, r1, FHH, r2);
}
-static uint8_t parse_pop(As *as, char *c)
+static uint8_t parse_pop(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
uint8_t r1;
/* POP r1 */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1044,14 +1076,16 @@ static uint8_t parse_pop(As *as, char *c)
return emit(as, 3, r1, 0, 0);
}
-static uint8_t parse_xsp(As *as, char *c)
+static uint8_t parse_xsp(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
uint8_t r1;
/* XSP r1 */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1062,14 +1096,16 @@ static uint8_t parse_xsp(As *as, char *c)
return emit(as, 3, r1, 0, FL);
}
-static uint8_t parse_inc(As *as, char *c)
+static uint8_t parse_inc(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
uint8_t r1;
/* INC r1 */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1080,14 +1116,16 @@ static uint8_t parse_inc(As *as, char *c)
return emit(as, 11, r1, FHH | FHL, 0);
}
-static uint8_t parse_dec(As *as, char *c)
+static uint8_t parse_dec(As *as, char **c)
{
char word[MAX_ID + 1];
uint8_t wlen;
uint8_t r1;
/* INC r1 */
- next_word(c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1098,61 +1136,61 @@ static uint8_t parse_dec(As *as, char *c)
return emit(as, 11, r1, FHH, 0);
}
-static uint8_t parse_bz(As *as, char *c)
+static uint8_t parse_bz(As *as, char **c)
{
/* BZ */
return emit(as, 10, 0, 0, 0);
}
-static uint8_t parse_bnz(As *as, char *c)
+static uint8_t parse_bnz(As *as, char **c)
{
/* BNZ */
return emit(as, 10, 0, FHH, 0);
}
-static uint8_t parse_bc(As *as, char *c)
+static uint8_t parse_bc(As *as, char **c)
{
/* BC */
return emit(as, 10, 0, 0, 1);
}
-static uint8_t parse_bnc(As *as, char *c)
+static uint8_t parse_bnc(As *as, char **c)
{
/* BNC */
return emit(as, 10, 0, FHH, 1);
}
-static uint8_t parse_bo(As *as, char *c)
+static uint8_t parse_bo(As *as, char **c)
{
/* BO */
return emit(as, 10, 0, 0, 2);
}
-static uint8_t parse_bno(As *as, char *c)
+static uint8_t parse_bno(As *as, char **c)
{
/* BNO */
return emit(as, 10, 0, FHH, 2);
}
-static uint8_t parse_bs(As *as, char *c)
+static uint8_t parse_bs(As *as, char **c)
{
/* BS */
return emit(as, 10, 0, 0, 3);
}
-static uint8_t parse_bns(As *as, char *c)
+static uint8_t parse_bns(As *as, char **c)
{
/* BNS */
return emit(as, 10, 0, FHH, 3);
}
-static uint8_t parse_bi(As *as, char *c)
+static uint8_t parse_bi(As *as, char **c)
{
/* BI */
return emit(as, 10, 0, 0, 4);
}
-static uint8_t parse_bni(As *as, char *c)
+static uint8_t parse_bni(As *as, char **c)
{
/* BNI */
return emit(as, 10, 0, FHH, 4);
@@ -1164,7 +1202,9 @@ static uint8_t parse_indirect(As *as, char **c, uint8_t *r1, uint8_t *r2, uint16
uint8_t wlen;
/* [r1:r2] */
- *c = next_word(*c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1182,7 +1222,9 @@ static uint8_t parse_indirect(As *as, char **c, uint8_t *r1, uint8_t *r2, uint16
return error_l("Syntax error", &as->loc, "expected +");
(*c)++;
- *c = next_word(*c, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
@@ -1210,7 +1252,10 @@ static uint8_t parse_indirect(As *as, char **c, uint8_t *r1, uint8_t *r2, uint16
if (**c != ':')
return error_l("Syntax error", &as->loc, "expected :");
- *c = next_word(*c + 1, word, &wlen);
+ (*c)++;
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1226,27 +1271,28 @@ static uint8_t parse_indirect(As *as, char **c, uint8_t *r1, uint8_t *r2, uint16
return 1;
}
-static uint8_t parse_jmp(As *as, char *c)
+static uint8_t parse_jmp(As *as, char **c)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint16_t imm = 0xffff;
uint8_t r1, r2;
- pt = skip_whitespace(c);
+ *c = skip_whitespace(*c);
/* JMP [r1:r2] */
- if (*pt == '[')
+ if (**c == '[')
{
- pt++;
- if (!parse_indirect(as, &pt, &r1, &r2, NULL))
+ (*c)++;
+ if (!parse_indirect(as, c, &r1, &r2, NULL))
return 0;
return emit(as, 9, r1, 0, (r2 << 6) | FL);
}
- next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected label or immediate");
@@ -1263,27 +1309,28 @@ static uint8_t parse_jmp(As *as, char *c)
return (emit(as, 9, 0, FHH, FL) && emit_imm(as, imm));
}
-static uint8_t parse_call(As *as, char *c)
+static uint8_t parse_call(As *as, char **c)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint16_t imm = 0xffff;
uint8_t r1, r2;
- pt = skip_whitespace(c);
+ *c = skip_whitespace(*c);
/* CALL [r1:r2] */
- if (*pt == '[')
+ if (**c == '[')
{
- pt++;
- if (!parse_indirect(as, &pt, &r1, &r2, NULL))
+ (*c)++;
+ if (!parse_indirect(as, c, &r1, &r2, NULL))
return 0;
return emit(as, 9, r1, 0, (r2 << 6));
}
- next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected label or immediate");
@@ -1300,30 +1347,32 @@ static uint8_t parse_call(As *as, char *c)
return (emit(as, 9, 0, FHH, 0) && emit_imm(as, imm));
}
-static uint8_t parse_ld(As *as, char *c)
+static uint8_t parse_ld(As *as, char **c)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint16_t imm = 0xff;
uint8_t r1, r2, r3;
- pt = skip_whitespace(c);
+ *c = skip_whitespace(*c);
/* LD [r1:r2], r3 */
/* LD [sp + imm], r2 */
- if (*pt == '[')
+ if (**c == '[')
{
- pt++;
- if (!parse_indirect(as, &pt, &r1, &r2, &imm))
+ (*c)++;
+ if (!parse_indirect(as, c, &r1, &r2, &imm))
return 0;
/* expected , */
- pt = skip_whitespace(pt);
- if (*pt != ',')
+ *c = skip_whitespace(*c);
+ if (**c != ',')
return error_l("Syntax error", &as->loc, "expected ,");
- pt = next_word(pt + 1, word, &wlen);
+ (*c)++;
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1338,7 +1387,9 @@ static uint8_t parse_ld(As *as, char *c)
}
/* LD r1, ? */
- pt = next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register");
@@ -1346,18 +1397,18 @@ static uint8_t parse_ld(As *as, char *c)
if (r1 == 0xff)
return error_l("Syntax error", &as->loc, word);
- pt = skip_whitespace(pt);
- if (*pt != ',')
+ *c = skip_whitespace(*c);
+ if (**c != ',')
return error_l("Syntax error", &as->loc, "expected ,");
- pt++;
+ (*c)++;
- pt = skip_whitespace(pt);
+ *c = skip_whitespace(*c);
/* LD r1, [r2:r3] */
/* LD r1, [sp + imm] */
- if (*pt == '[')
+ if (**c == '[')
{
- pt++;
- if (!parse_indirect(as, &pt, &r2, &r3, &imm))
+ (*c)++;
+ if (!parse_indirect(as, c, &r2, &r3, &imm))
return 0;
if (r2 == 0xff)
@@ -1366,7 +1417,9 @@ static uint8_t parse_ld(As *as, char *c)
return emit(as, 2, r2, r3, r1 << 6);
}
- pt = next_word(pt, word, &wlen);
+ if (!next_word(as, c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected register or immediate");
@@ -1445,11 +1498,12 @@ static InstParse insts[] = {
static uint8_t parse(As *as, char *c)
{
char word[MAX_ID + 1];
- char *pt;
uint8_t wlen;
uint8_t i;
- pt = next_word(c, word, &wlen);
+ if (!next_word(as, &c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return 1;
@@ -1458,9 +1512,9 @@ static uint8_t parse(As *as, char *c)
return 1;
/* new label */
- if (*pt == ':')
+ if (*c == ':')
{
- pt++;
+ c++;
if (!new_label(as, word))
return 0;
@@ -1470,13 +1524,20 @@ static uint8_t parse(As *as, char *c)
/* instructions */
for (i = 0; insts[i].parse; i++)
if (!strcasecmp(insts[i].id, word))
- return insts[i].parse(as, pt);
+ {
+ if (!insts[i].parse(as, &c))
+ return 0;
+ break;
+ }
- return error_l("Parse error", &as->loc, word);
+ if (!insts[i].parse)
+ return error_l("Parse error", &as->loc, word);
}
/* EOL */
- pt = next_word(pt, word, &wlen);
+ if (!next_word(as, &c, word, &wlen))
+ return 0;
+
if (wlen == 0)
return 1;