summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-10-19 14:10:35 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-10-19 14:10:35 -0700
commit37d88e4125865eef3544f1ee072436fc12dbe6fb (patch)
tree84ab64d9c5b065e2bed961760b9bdfd49d4e101e
parentf5f3d70d6da2ce876496033a388dd1656c5a59cd (diff)
downloadnasm-37d88e4125865eef3544f1ee072436fc12dbe6fb.tar.gz
Don't confuse suffixed hexadecimal with floating-point
1e30 is a floating-point constant, but 1e30h is not. The scanner won't know that until it sees the "h", so make sure we keep enough state to be able to distinguish "1e30" (a possible hex constant) from "1.e30", "1e+30" or "1.0" (unabiguously floating-point.)
-rw-r--r--stdscan.c23
-rw-r--r--test/uscore.asm4
2 files changed, 24 insertions, 3 deletions
diff --git a/stdscan.c b/stdscan.c
index 3979144e..c2f97e80 100644
--- a/stdscan.c
+++ b/stdscan.c
@@ -118,6 +118,8 @@ int stdscan(void *private_data, struct tokenval *tv)
bool rn_error;
bool is_hex = false;
bool is_float = false;
+ bool has_e = false;
+ bool has_h = false;
char c;
r = stdscan_bufptr++;
@@ -128,8 +130,17 @@ int stdscan(void *private_data, struct tokenval *tv)
for (;;) {
c = *stdscan_bufptr++;
- if ((!is_hex && (c == 'e' || c == 'E')) ||
- (c == 'P' || c == 'p')) {
+ if (!is_hex && (c == 'e' || c == 'E')) {
+ has_e = true;
+ if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-') {
+ /* e can only be followed by +/- if it is either a
+ prefixed hex number or a floating-point number */
+ is_float = true;
+ stdscan_bufptr++;
+ }
+ } else if (c == 'H' || c == 'h') {
+ has_h = true;
+ } else if (c == 'P' || c == 'p') {
is_float = true;
if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-')
stdscan_bufptr++;
@@ -142,6 +153,11 @@ int stdscan(void *private_data, struct tokenval *tv)
}
stdscan_bufptr--; /* Point to first character beyond number */
+ if (has_e && !has_h) {
+ /* 1e13 is floating-point, but 1e13h is not */
+ is_float = true;
+ }
+
if (is_float) {
tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);
return tv->t_type = TOKEN_FLOAT;
@@ -154,7 +170,8 @@ int stdscan(void *private_data, struct tokenval *tv)
tv->t_charptr = NULL;
return tv->t_type = TOKEN_NUM;
}
- } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') { /* a char constant */
+ } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') {
+ /* a char constant */
char quote = *stdscan_bufptr++, *r;
bool rn_warn;
r = tv->t_charptr = stdscan_bufptr;
diff --git a/test/uscore.asm b/test/uscore.asm
index 6cb99ea3..2bc99c25 100644
--- a/test/uscore.asm
+++ b/test/uscore.asm
@@ -1,6 +1,10 @@
dd 0x1234_5678
dd 305_419_896 ; Same number as above it
dd 0x1e16 ; NOT a floating-point number!
+ dd 1e16h ; NOT a floating-point number!
+ dd 1e16_h ; NOT a floating-point number!
+ dd $1e16 ; NOT a floating-point number!
+ dd $1e16 ; NOT a floating-point number!
dd 1e16 ; THIS is a floating-point number!
dd 1e+16
dd 1.e+16