Fix the fixes. Note that "." had the same problem as "+" and "-", and

that we can still match non-identical constants if they are both
strings with the same numerical value.
This commit is contained in:
andy 2005-03-11 20:39:07 +00:00
parent d2cbed151b
commit d314164fed
2 changed files with 25 additions and 10 deletions

View File

@ -55,15 +55,25 @@ static naRef getConstant(struct Parser* p, int idx)
// Interns a scalar (!) constant and returns its index // Interns a scalar (!) constant and returns its index
static int internConstant(struct Parser* p, naRef c) static int internConstant(struct Parser* p, naRef c)
{ {
int i, n = naVec_size(p->cg->consts); int i, j, n = naVec_size(p->cg->consts);
for(i=0; i<n; i++) { for(i=0; i<n; i++) {
naRef b = naVec_get(p->cg->consts, i); naRef b = naVec_get(p->cg->consts, i);
if(IS_NUM(b) && IS_NUM(c) && b.num == c.num) if(IS_NUM(b) && IS_NUM(c) && b.num == c.num)
return i; return i;
if(IS_REF(b) && IS_REF(c) && b.ref.ptr.obj->type != c.ref.ptr.obj->type) if(IS_STR(b) && IS_STR(c)) {
continue; int len = naStr_len(c);
if(naEqual(b, c)) char* cs = naStr_data(c);
return i; char* bs = naStr_data(b);
if(naStr_len(b) != len)
continue;
for(j=0; j<len; j++)
if(cs[j] != bs[j])
continue;
}
if(IS_REF(b) && IS_REF(c))
if(b.ref.ptr.obj->type == c.ref.ptr.obj->type)
if(naEqual(b, c))
return i;
} }
return newConstant(p, c); return newConstant(p, c);
} }

View File

@ -147,8 +147,7 @@ static int readdec(unsigned char* s, int len, int i, double* v)
// Reads a signed integer out of the string starting at i, stores it // Reads a signed integer out of the string starting at i, stores it
// in v, and returns the next index to start at. Zero-length // in v, and returns the next index to start at. Zero-length
// decimal numbers (and length-1 strings like '+') are allowed, and // decimal numbers are allowed, and are returned as zero.
// are returned as zero.
static int readsigned(unsigned char* s, int len, int i, double* v) static int readsigned(unsigned char* s, int len, int i, double* v)
{ {
int i0 = i, i2; int i0 = i, i2;
@ -157,10 +156,12 @@ static int readsigned(unsigned char* s, int len, int i, double* v)
if(s[i] == '+') { i++; } if(s[i] == '+') { i++; }
else if(s[i] == '-') { i++; sgn = -1; } else if(s[i] == '-') { i++; sgn = -1; }
i2 = readdec(s, len, i, &val); i2 = readdec(s, len, i, &val);
if(i2 == i) if(i0 == i && i2 == i) {
return i0; // don't parse "+" or "-" as zero. *v = 0;
return i0; // don't successfully parse bare "+" or "-"
}
*v = sgn*val; *v = sgn*val;
return i; return i2;
} }
@ -183,6 +184,10 @@ static int tonum(unsigned char* s, int len, double* result)
int i=0, fraclen=0; int i=0, fraclen=0;
double sgn=1, val, frac=0, exp=0; double sgn=1, val, frac=0, exp=0;
// Special case, "." is not a number, even though "1." and ".0" are.
if(len == 1 && s[0] == '.')
return 0;
// Read the integer part // Read the integer part
i = readsigned(s, len, i, &val); i = readsigned(s, len, i, &val);
if(val < 0) { sgn = -1; val = -val; } if(val < 0) { sgn = -1; val = -val; }