summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nasm.h6
-rw-r--r--parser.c2
-rw-r--r--stdscan.c110
-rwxr-xr-xtokhash.pl1
4 files changed, 54 insertions, 65 deletions
diff --git a/nasm.h b/nasm.h
index cb786f8..87e82d2 100644
--- a/nasm.h
+++ b/nasm.h
@@ -65,6 +65,7 @@
#endif
#define IDLEN_MAX 4096
+#define DECOLEN_MAX 32
/*
* Name pollution problems: <time.h> on Digital UNIX pulls in some
@@ -421,6 +422,8 @@ extern struct preproc_ops preproc_nop;
* 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.
+ * isbrcchar matches any character that may placed inside curly braces as a
+ * decorator. E.g. {rn-sae}, {1to8}, {k1}{z}
*/
#define isidstart(c) (nasm_isalpha(c) || \
@@ -435,6 +438,9 @@ extern struct preproc_ops preproc_nop;
(c) == '#' || \
(c) == '~')
+#define isbrcchar(c) (isidchar(c) || \
+ (c) == '-')
+
/* Ditto for numeric constants. */
#define isnumstart(c) (nasm_isdigit(c) || (c) == '$')
diff --git a/parser.c b/parser.c
index 343f35e..f73c7b5 100644
--- a/parser.c
+++ b/parser.c
@@ -200,7 +200,7 @@ static void process_size_override(insn *result, operand *op)
* when two or more decorators follow a register operand,
* consecutive decorators are parsed here.
* opmask and zeroing decorators can be placed in any order.
- * e.g. zmm1 {k2}{z} or zmm2 {z,k3}
+ * e.g. zmm1 {k2}{z} or zmm2 {z}{k3}
* decorator(s) are placed at the end of an operand.
*/
static bool parse_braces(decoflags_t *decoflags)
diff --git a/stdscan.c b/stdscan.c
index b5e389d..ea7537d 100644
--- a/stdscan.c
+++ b/stdscan.c
@@ -53,8 +53,6 @@
static char *stdscan_bufptr = NULL;
static char **stdscan_tempstorage = NULL;
static int stdscan_tempsize = 0, stdscan_templen = 0;
-static int brace = 0; /* nested brace counter */
-static bool brace_opened = false; /* if brace is just opened */
#define STDSCAN_TEMP_DELTA 256
void stdscan_set(char *str)
@@ -110,7 +108,6 @@ static char *stdscan_copy(char *p, int len)
/*
* a token is enclosed with braces. proper token type will be assigned
* accordingly with the token flag.
- * a closing brace is treated as an ending character of corresponding token.
*/
static int stdscan_handle_brace(struct tokenval *tv)
{
@@ -126,18 +123,6 @@ static int stdscan_handle_brace(struct tokenval *tv)
}
}
- stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr);
-
- if (stdscan_bufptr[0] == '}') {
- stdscan_bufptr ++; /* skip the closing brace */
- brace --;
- } else if (stdscan_bufptr[0] != ',') {
- /* treat {foo,bar} as {foo}{bar}
- * by regarding ',' as a mere separator between decorators
- */
- nasm_error(ERR_NONFATAL, "closing brace expected");
- tv->t_type = TOKEN_INVALID;
- }
return tv->t_type;
}
@@ -148,23 +133,16 @@ int stdscan(void *private_data, struct tokenval *tv)
(void)private_data; /* Don't warn that this parameter is unused */
stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr);
- if (!*stdscan_bufptr) {
- /* nested brace shouldn't affect following lines */
- brace = 0;
+ if (!*stdscan_bufptr)
return tv->t_type = TOKEN_EOS;
- }
/* we have a token; either an id, a number or a char */
if (isidstart(*stdscan_bufptr) ||
- (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1])) ||
- (brace && isidchar(*stdscan_bufptr))) { /* because of {1to8} */
+ (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) {
/* now we've got an identifier */
bool is_sym = false;
int token_type;
- /* opening brace is followed by any letter */
- brace_opened = false;
-
if (*stdscan_bufptr == '$') {
is_sym = true;
stdscan_bufptr++;
@@ -172,8 +150,7 @@ int stdscan(void *private_data, struct tokenval *tv)
r = stdscan_bufptr++;
/* read the entire buffer to advance the buffer pointer but... */
- /* {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. */
- while (isidchar(*stdscan_bufptr) || (brace && *stdscan_bufptr == '-'))
+ while (isidchar(*stdscan_bufptr))
stdscan_bufptr++;
/* ... copy only up to IDLEN_MAX-1 characters */
@@ -190,16 +167,11 @@ int stdscan(void *private_data, struct tokenval *tv)
* is it actually a register or instruction name, or what? */
token_type = nasm_token_hash(ourcopy, tv);
- if (likely(!brace)) {
- if (likely(!(tv->t_flag & TFLAG_BRC))) {
- /* most of the tokens fall into this case */
- return token_type;
- } else {
- return tv->t_type = TOKEN_ID;
- }
+ if (likely(!(tv->t_flag & TFLAG_BRC))) {
+ /* most of the tokens fall into this case */
+ return token_type;
} else {
- /* handle tokens inside braces */
- return stdscan_handle_brace(tv);
+ return tv->t_type = TOKEN_ID;
}
} else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {
/*
@@ -285,6 +257,45 @@ int stdscan(void *private_data, struct tokenval *tv)
return tv->t_type = TOKEN_ERRSTR;
stdscan_bufptr++; /* Skip final quote */
return tv->t_type = TOKEN_STR;
+ } else if (*stdscan_bufptr == '{') {
+ /* now we've got a decorator */
+ int token_len;
+
+ stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr);
+
+ r = ++stdscan_bufptr;
+ /*
+ * read the entire buffer to advance the buffer pointer
+ * {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens.
+ */
+ while (isbrcchar(*stdscan_bufptr))
+ stdscan_bufptr++;
+
+ token_len = stdscan_bufptr - r;
+
+ /* ... copy only up to DECOLEN_MAX-1 characters */
+ tv->t_charptr = stdscan_copy(r, token_len < DECOLEN_MAX ?
+ token_len : DECOLEN_MAX - 1);
+
+ stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr);
+ /* if brace is not closed properly or token is too long */
+ if ((*stdscan_bufptr != '}') || (token_len > MAX_KEYWORD)) {
+ nasm_error(ERR_NONFATAL,
+ "invalid decorator token inside braces");
+ return tv->t_type = TOKEN_INVALID;
+ }
+
+ stdscan_bufptr++; /* skip closing brace */
+
+ for (s = tv->t_charptr, r = ourcopy; *s; s++)
+ *r++ = nasm_tolower(*s);
+ *r = '\0';
+
+ /* right, so we have a decorator sitting in temp storage. */
+ nasm_token_hash(ourcopy, tv);
+
+ /* handle tokens inside braces */
+ return stdscan_handle_brace(tv);
} else if (*stdscan_bufptr == ';') {
/* a comment has happened - stay */
return tv->t_type = TOKEN_EOS;
@@ -324,35 +335,6 @@ int stdscan(void *private_data, struct tokenval *tv)
} else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') {
stdscan_bufptr += 2;
return tv->t_type = TOKEN_DBL_OR;
- } else if (stdscan_bufptr[0] == '{') {
- stdscan_bufptr ++; /* skip the opening brace */
- brace ++; /* in case of nested braces */
- brace_opened = true; /* brace is just opened */
- return stdscan(private_data, tv);
- } else if (stdscan_bufptr[0] == ',' && brace) {
- /*
- * a comma inside braces should be treated just as a separator.
- * this is almost same as an opening brace except increasing counter.
- */
- stdscan_bufptr ++;
- brace_opened = true; /* brace is just opened */
- return stdscan(private_data, tv);
- } else if (stdscan_bufptr[0] == '}') {
- stdscan_bufptr ++; /* skip the closing brace */
- if (brace) {
- /* unhandled nested closing brace */
- brace --;
- /* if brace is closed without any content in it */
- if (brace_opened) {
- brace_opened = false;
- nasm_error(ERR_NONFATAL, "nothing inside braces");
- }
- return stdscan(private_data, tv);
- } else {
- /* redundant closing brace */
- return tv->t_type = TOKEN_INVALID;
- }
- return stdscan(private_data, tv);
} else /* just an ordinary char */
return tv->t_type = (uint8_t)(*stdscan_bufptr++);
}
diff --git a/tokhash.pl b/tokhash.pl
index 4ea387d..60bd258 100755
--- a/tokhash.pl
+++ b/tokhash.pl
@@ -260,6 +260,7 @@ if ($output eq 'h') {
print " uint16_t ix;\n";
print " const struct tokendata *data;\n";
print "\n";
+ printf " tv->t_flag = 0;\n";
printf " crc = crc64(UINT64_C(0x%08x%08x), token);\n",
$$sv[0], $$sv[1];
print " k1 = (uint32_t)crc;\n";