Don't parse the strings "+" and "-" as numerical zeros. Also fix the
code generation of constant objects to use real identity and not Nasal equality, so (e.g.) the constants 1 (number) and "1.0" (string) do not get turned into the same object in the generated code.
This commit is contained in:
+16
-17
@@ -40,31 +40,32 @@ static void genBinOp(int op, struct Parser* p, struct Token* t)
|
|||||||
|
|
||||||
static int newConstant(struct Parser* p, naRef c)
|
static int newConstant(struct Parser* p, naRef c)
|
||||||
{
|
{
|
||||||
int i = p->cg->nConsts++;
|
int i;
|
||||||
|
naVec_append(p->cg->consts, c);
|
||||||
|
i = naVec_size(p->cg->consts) - 1;
|
||||||
if(i > 0xffff) naParseError(p, "too many constants in code block", 0);
|
if(i > 0xffff) naParseError(p, "too many constants in code block", 0);
|
||||||
naHash_set(p->cg->consts, naNum(i), c);
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static naRef getConstant(struct Parser* p, int idx)
|
static naRef getConstant(struct Parser* p, int idx)
|
||||||
{
|
{
|
||||||
naRef c;
|
return naVec_get(p->cg->consts, idx);
|
||||||
naHash_get(p->cg->consts, naNum(idx), &c);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
naRef r;
|
int i, n = naVec_size(p->cg->consts);
|
||||||
naHash_get(p->cg->interned, c, &r);
|
for(i=0; i<n; i++) {
|
||||||
if(!IS_NIL(r)) {
|
naRef b = naVec_get(p->cg->consts, i);
|
||||||
return (int)r.num;
|
if(IS_NUM(b) && IS_NUM(c) && b.num == c.num)
|
||||||
} else {
|
return i;
|
||||||
int idx = newConstant(p, c);
|
if(IS_REF(b) && IS_REF(c) && b.ref.ptr.obj->type != c.ref.ptr.obj->type)
|
||||||
naHash_set(p->cg->interned, c, naNum(idx));
|
continue;
|
||||||
return idx;
|
if(naEqual(b, c))
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
return newConstant(p, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void genScalarConstant(struct Parser* p, struct Token* t)
|
static void genScalarConstant(struct Parser* p, struct Token* t)
|
||||||
@@ -515,9 +516,7 @@ naRef naCodeGen(struct Parser* p, struct Token* t)
|
|||||||
cg.codeAlloced = 1024; // Start fairly big, this is a cheap allocation
|
cg.codeAlloced = 1024; // Start fairly big, this is a cheap allocation
|
||||||
cg.byteCode = naParseAlloc(p, cg.codeAlloced);
|
cg.byteCode = naParseAlloc(p, cg.codeAlloced);
|
||||||
cg.nBytes = 0;
|
cg.nBytes = 0;
|
||||||
cg.consts = naNewHash(p->context);
|
cg.consts = naNewVector(p->context);
|
||||||
cg.interned = naNewHash(p->context);
|
|
||||||
cg.nConsts = 0;
|
|
||||||
cg.loopTop = 0;
|
cg.loopTop = 0;
|
||||||
p->cg = &cg;
|
p->cg = &cg;
|
||||||
|
|
||||||
@@ -530,7 +529,7 @@ naRef naCodeGen(struct Parser* p, struct Token* t)
|
|||||||
code->byteCode = naAlloc(cg.nBytes);
|
code->byteCode = naAlloc(cg.nBytes);
|
||||||
for(i=0; i < cg.nBytes; i++)
|
for(i=0; i < cg.nBytes; i++)
|
||||||
code->byteCode[i] = cg.byteCode[i];
|
code->byteCode[i] = cg.byteCode[i];
|
||||||
code->nConstants = cg.nConsts;
|
code->nConstants = naVec_size(cg.consts);
|
||||||
code->constants = naAlloc(code->nConstants * sizeof(naRef));
|
code->constants = naAlloc(code->nConstants * sizeof(naRef));
|
||||||
code->srcFile = p->srcFile;
|
code->srcFile = p->srcFile;
|
||||||
for(i=0; i<code->nConstants; i++)
|
for(i=0; i<code->nConstants; i++)
|
||||||
|
|||||||
@@ -79,9 +79,7 @@ struct CodeGenerator {
|
|||||||
int loopTop;
|
int loopTop;
|
||||||
|
|
||||||
// Dynamic storage for constants, to be compiled into a static table
|
// Dynamic storage for constants, to be compiled into a static table
|
||||||
naRef consts; // index -> naRef
|
naRef consts;
|
||||||
naRef interned; // naRef -> index (scalars only!)
|
|
||||||
int nConsts;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void naParseError(struct Parser* p, char* msg, int line);
|
void naParseError(struct Parser* p, char* msg, int line);
|
||||||
|
|||||||
@@ -151,11 +151,14 @@ static int readdec(unsigned char* s, int len, int i, double* v)
|
|||||||
// 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;
|
||||||
double sgn=1, val;
|
double sgn=1, val;
|
||||||
if(i >= len) { *v = 0; return len; }
|
if(i >= len) { *v = 0; return len; }
|
||||||
if(s[i] == '+') { i++; }
|
if(s[i] == '+') { i++; }
|
||||||
else if(s[i] == '-') { i++; sgn = -1; }
|
else if(s[i] == '-') { i++; sgn = -1; }
|
||||||
i = readdec(s, len, i, &val);
|
i2 = readdec(s, len, i, &val);
|
||||||
|
if(i2 == i)
|
||||||
|
return i0; // don't parse "+" or "-" as zero.
|
||||||
*v = sgn*val;
|
*v = sgn*val;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user