int i;
if(!IS_OBJ(r)) return;
if(c->ntemps >= c->tempsz) {
+ struct naObj** newtemps;
c->tempsz *= 2;
- struct naObj** newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
+ newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
for(i=0; i<c->ntemps; i++)
newtemps[i] = c->temps[i];
naFree(c->temps);
c->temps = newtemps;
}
- c->temps[c->ntemps++] = r.ref.ptr.obj;
+ c->temps[c->ntemps++] = PTR(r).obj;
}
naRef naObj(int type, struct naObj* o)
{
naRef r;
- r.ref.reftag = NASAL_REFTAG;
- r.ref.ptr.obj = o;
+ SETPTR(r, o);
o->type = type;
return r;
}
naRef naNewString(struct Context* c)
{
naRef s = naNew(c, T_STR);
- s.ref.ptr.str->len = 0;
- s.ref.ptr.str->data = 0;
- s.ref.ptr.str->hashcode = 0;
+ PTR(s).str->emblen = 0;
+ PTR(s).str->data.ref.len = 0;
+ PTR(s).str->data.ref.ptr = 0;
+ PTR(s).str->hashcode = 0;
return s;
}
naRef naNewVector(struct Context* c)
{
naRef r = naNew(c, T_VEC);
- r.ref.ptr.vec->rec = 0;
+ PTR(r).vec->rec = 0;
return r;
}
naRef naNewHash(struct Context* c)
{
naRef r = naNew(c, T_HASH);
- r.ref.ptr.hash->rec = 0;
+ PTR(r).hash->rec = 0;
return r;
}
naRef naNewCCode(struct Context* c, naCFunction fptr)
{
naRef r = naNew(c, T_CCODE);
- r.ref.ptr.ccode->fptr = fptr;
+ PTR(r).ccode->fptr = fptr;
return r;
}
naRef naNewFunc(struct Context* c, naRef code)
{
naRef func = naNew(c, T_FUNC);
- func.ref.ptr.func->code = code;
- func.ref.ptr.func->namespace = naNil();
- func.ref.ptr.func->next = naNil();
+ PTR(func).func->code = code;
+ PTR(func).func->namespace = naNil();
+ PTR(func).func->next = naNil();
return func;
}
naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
+{
+ naRef ghost;
+ // ensure 'simple' ghost users don't see garbage for these fields
+ type->get_member = 0;
+ type->set_member = 0;
+
+ ghost = naNew(c, T_GHOST);
+ PTR(ghost).ghost->gtype = type;
+ PTR(ghost).ghost->ptr = ptr;
+ return ghost;
+}
+
+naRef naNewGhost2(naContext c, naGhostType* t, void* ptr)
{
naRef ghost = naNew(c, T_GHOST);
- ghost.ref.ptr.ghost->gtype = type;
- ghost.ref.ptr.ghost->ptr = ptr;
+ PTR(ghost).ghost->gtype = t;
+ PTR(ghost).ghost->ptr = ptr;
return ghost;
}
naGhostType* naGhost_type(naRef ghost)
{
if(!IS_GHOST(ghost)) return 0;
- return ghost.ref.ptr.ghost->gtype;
+ return PTR(ghost).ghost->gtype;
}
void* naGhost_ptr(naRef ghost)
{
if(!IS_GHOST(ghost)) return 0;
- return ghost.ref.ptr.ghost->ptr;
+ return PTR(ghost).ghost->ptr;
}
naRef naNil()
{
- naRef r;
- r.ref.reftag = NASAL_REFTAG;
- r.ref.ptr.obj = 0;
+ naRef r;
+ SETPTR(r, 0);
return r;
}
naRef naNum(double num)
{
naRef r;
- r.ref.reftag = ~NASAL_REFTAG;
- r.num = num;
+ SETNUM(r, num);
return r;
}
int naEqual(naRef a, naRef b)
{
double na=0, nb=0;
- if(IS_REF(a) && IS_REF(b) && a.ref.ptr.obj == b.ref.ptr.obj)
+ if(IS_REF(a) && IS_REF(b) && PTR(a).obj == PTR(b).obj)
return 1; // Object identity (and nil == nil)
if(IS_NIL(a) || IS_NIL(b))
return 0;
int naStrEqual(naRef a, naRef b)
{
int i;
- if(!(IS_STR(a) && IS_STR(b)))
- return 0;
- if(a.ref.ptr.str->len != b.ref.ptr.str->len)
+ char *ap, *bp;
+ if(!IS_STR(a) || !IS_STR(b) || naStr_len(a) != naStr_len(b))
return 0;
- for(i=0; i<a.ref.ptr.str->len; i++)
- if(a.ref.ptr.str->data[i] != b.ref.ptr.str->data[i])
+ ap = naStr_data(a);
+ bp = naStr_data(b);
+ for(i=0; i<naStr_len(a); i++)
+ if(ap[i] != bp[i])
return 0;
return 1;
}
int naIsCode(naRef r) { return IS_CODE(r); }
int naIsCCode(naRef r) { return IS_CCODE(r); }
int naIsGhost(naRef r) { return IS_GHOST(r); }
+
+void naSetUserData(naContext c, void* p) { c->userData = p; }
+void* naGetUserData(naContext c)
+{
+ if(c->userData) return c->userData;
+ return c->callParent ? naGetUserData(c->callParent) : 0;
+}
+
+void naAddSym(naContext c, naRef ns, char *sym, naRef val)
+{
+ naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
+ naHash_set(ns, naInternSymbol(name), val);
+}
+
+naRef naGenLib(naContext c, naCFuncItem *fns)
+{
+ naRef ns = naNewHash(c);
+ for(/**/; fns->name; fns++)
+ naAddSym(c, ns, fns->name, naNewFunc(c, naNewCCode(c, fns->func)));
+ return ns;
+}