summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/parser.c b/parser.c
index a45bf0da..2cd7f1d0 100644
--- a/parser.c
+++ b/parser.c
@@ -21,7 +21,6 @@
#include "names.c"
-
static long reg_flags[] = { /* sizes and special flags */
0, REG8, REG_AL, REG_AX, REG8, REG8, REG16, REG16, REG8, REG_CL,
REG_CREG, REG_CREG, REG_CREG, REG_CR4, REG_CS, REG_CX, REG8,
@@ -164,7 +163,7 @@ insn *parse_line (long segment, long offset, lfunc lookup_label, int pass,
}
result->nprefix = 0;
- result->times = 1;
+ result->times = 1L;
while (i == TOKEN_PREFIX ||
(i==TOKEN_REG && !(REG_SREG & ~reg_flags[tokval.t_integer]))) {
@@ -184,9 +183,13 @@ insn *parse_line (long segment, long offset, lfunc lookup_label, int pass,
if (!is_simple (value)) {
error (ERR_NONFATAL,
"non-constant argument supplied to TIMES");
- result->times = 1;
- } else
+ result->times = 1L;
+ } else {
result->times = value->value;
+ if (value->value < 0)
+ error(ERR_WARNING, "TIMES value %d is negative",
+ value->value);
+ }
} else {
if (result->nprefix == MAXPREFIX)
error (ERR_NONFATAL,
@@ -231,7 +234,8 @@ insn *parse_line (long segment, long offset, lfunc lookup_label, int pass,
result->opcode == I_DW ||
result->opcode == I_DD ||
result->opcode == I_DQ ||
- result->opcode == I_DT) {
+ result->opcode == I_DT ||
+ result->opcode == I_INCBIN) {
extop *eop, **tail = &result->eops;
int oper_num = 0;
@@ -315,6 +319,36 @@ insn *parse_line (long segment, long offset, lfunc lookup_label, int pass,
}
}
}
+
+ if (result->opcode == I_INCBIN) {
+ /*
+ * Correct syntax for INCBIN is that there should be
+ * one string operand, followed by one or two numeric
+ * operands.
+ */
+ if (!result->eops || result->eops->type != EOT_DB_STRING)
+ error (ERR_NONFATAL, "`incbin' expects a file name");
+ else if (result->eops->next &&
+ result->eops->next->type != EOT_DB_NUMBER)
+ error (ERR_NONFATAL, "`incbin': second parameter is",
+ " non-numeric");
+ else if (result->eops->next && result->eops->next->next &&
+ result->eops->next->next->type != EOT_DB_NUMBER)
+ error (ERR_NONFATAL, "`incbin': third parameter is",
+ " non-numeric");
+ else if (result->eops->next && result->eops->next->next &&
+ result->eops->next->next->next)
+ error (ERR_NONFATAL, "`incbin': more than three parameters");
+ else
+ return result;
+ /*
+ * If we reach here, one of the above errors happened.
+ * Throw the instruction away.
+ */
+ result->opcode = -1;
+ return result;
+ }
+
return result;
}
@@ -595,25 +629,6 @@ static int is_comma_next (void) {
return (*p == ',' || *p == ';' || !*p);
}
-/* isidstart matches any character that may start an identifier, and isidchar
- * matches any character that may appear at places other than the start of an
- * identifier. E.g. a period may only appear at the start of an identifier
- * (for local labels), whereas a number may appear anywhere *but* at the
- * start. */
-
-#define isidstart(c) ( isalpha(c) || (c)=='_' || (c)=='.' || (c)=='?' )
-#define isidchar(c) ( isidstart(c) || isdigit(c) || (c)=='$' || (c)=='#' \
- || (c)=='@' || (c)=='~' )
-
-/* Ditto for numeric constants. */
-
-#define isnumstart(c) ( isdigit(c) || (c)=='$' )
-#define isnumchar(c) ( isalnum(c) )
-
-/* This returns the numeric value of a given 'digit'. */
-
-#define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
-
/*
* This tokeniser routine has only one side effect, that of
* updating `bufptr'. Hence by saving `bufptr', lookahead may be