// Interns a scalar (!) constant and returns its index
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++) {
naRef b = naVec_get(p->cg->consts, i);
if(IS_NUM(b) && IS_NUM(c) && b.num == c.num)
return i;
- if(IS_REF(b) && IS_REF(c) && b.ref.ptr.obj->type != c.ref.ptr.obj->type)
- continue;
- if(naEqual(b, c))
- return i;
+ if(IS_STR(b) && IS_STR(c)) {
+ int len = naStr_len(c);
+ char* cs = naStr_data(c);
+ 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);
}
// 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
-// decimal numbers (and length-1 strings like '+') are allowed, and
-// are returned as zero.
+// decimal numbers are allowed, and are returned as zero.
static int readsigned(unsigned char* s, int len, int i, double* v)
{
int i0 = i, i2;
if(s[i] == '+') { i++; }
else if(s[i] == '-') { i++; sgn = -1; }
i2 = readdec(s, len, i, &val);
- if(i2 == i)
- return i0; // don't parse "+" or "-" as zero.
+ if(i0 == i && i2 == i) {
+ *v = 0;
+ return i0; // don't successfully parse bare "+" or "-"
+ }
*v = sgn*val;
- return i;
+ return i2;
}
int i=0, fraclen=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
i = readsigned(s, len, i, &val);
if(val < 0) { sgn = -1; val = -val; }