8 void naFree(void* m) { free(m); }
9 void* naAlloc(int n) { return malloc(n); }
10 void naBZero(void* m, int n) { memset(m, 0, n); }
12 naRef naObj(int type, struct naObj* o)
15 r.ref.reftag = NASAL_REFTAG;
23 if(IS_NIL(r)) return 0;
24 if(IS_NUM(r)) return r.num != 0;
25 if(IS_STR(r)) return 1;
29 naRef naNumValue(naRef n)
32 if(IS_NUM(n)) return n;
33 if(IS_NIL(n)) return naNil();
34 if(IS_STR(n) && naStr_tonum(n, &d))
39 naRef naStringValue(naContext c, naRef r)
41 if(IS_NIL(r) || IS_STR(r)) return r;
43 naRef s = naNewString(c);
44 naStr_fromnum(s, r.num);
50 naRef naNew(struct Context* c, int type)
53 if(c->nfree[type] == 0)
54 c->free[type] = naGC_get(&globals->pools[type],
55 OBJ_CACHE_SZ, &c->nfree[type]);
56 result = naObj(type, c->free[type][--c->nfree[type]]);
57 naVec_append(c->temps, result);
61 naRef naNewString(struct Context* c)
63 naRef s = naNew(c, T_STR);
64 s.ref.ptr.str->len = 0;
65 s.ref.ptr.str->data = 0;
66 s.ref.ptr.str->hashcode = 0;
70 naRef naNewVector(struct Context* c)
72 naRef r = naNew(c, T_VEC);
73 r.ref.ptr.vec->rec = 0;
77 naRef naNewHash(struct Context* c)
79 naRef r = naNew(c, T_HASH);
80 r.ref.ptr.hash->rec = 0;
84 naRef naNewCode(struct Context* c)
86 return naNew(c, T_CODE);
89 naRef naNewCCode(struct Context* c, naCFunction fptr)
91 naRef r = naNew(c, T_CCODE);
92 r.ref.ptr.ccode->fptr = fptr;
96 naRef naNewFunc(struct Context* c, naRef code)
98 naRef func = naNew(c, T_FUNC);
99 func.ref.ptr.func->code = code;
100 func.ref.ptr.func->namespace = naNil();
101 func.ref.ptr.func->next = naNil();
105 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
107 naRef ghost = naNew(c, T_GHOST);
108 ghost.ref.ptr.ghost->gtype = type;
109 ghost.ref.ptr.ghost->ptr = ptr;
113 naGhostType* naGhost_type(naRef ghost)
115 if(!IS_GHOST(ghost)) return 0;
116 return ghost.ref.ptr.ghost->gtype;
119 void* naGhost_ptr(naRef ghost)
121 if(!IS_GHOST(ghost)) return 0;
122 return ghost.ref.ptr.ghost->ptr;
128 r.ref.reftag = NASAL_REFTAG;
133 naRef naNum(double num)
136 r.ref.reftag = ~NASAL_REFTAG;
141 int naEqual(naRef a, naRef b)
144 if(IS_REF(a) && IS_REF(b) && a.ref.ptr.obj == b.ref.ptr.obj)
145 return 1; // Object identity (and nil == nil)
146 if(IS_NIL(a) || IS_NIL(b))
148 if(IS_NUM(a) && IS_NUM(b) && a.num == b.num)
149 return 1; // Numeric equality
150 if(IS_STR(a) && IS_STR(b) && naStr_equal(a, b))
151 return 1; // String equality
153 // Numeric equality after conversion
154 if(IS_NUM(a)) { na = a.num; }
155 else if(!(IS_STR(a) && naStr_tonum(a, &na))) { return 0; }
157 if(IS_NUM(b)) { nb = b.num; }
158 else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
160 return na == nb ? 1 : 0;
163 int naStrEqual(naRef a, naRef b)
166 if(!(IS_STR(a) && IS_STR(b)))
168 if(a.ref.ptr.str->len != b.ref.ptr.str->len)
170 for(i=0; i<a.ref.ptr.str->len; i++)
171 if(a.ref.ptr.str->data[i] != b.ref.ptr.str->data[i])
176 int naTypeSize(int type)
179 case T_STR: return sizeof(struct naStr);
180 case T_VEC: return sizeof(struct naVec);
181 case T_HASH: return sizeof(struct naHash);
182 case T_CODE: return sizeof(struct naCode);
183 case T_FUNC: return sizeof(struct naFunc);
184 case T_CCODE: return sizeof(struct naCCode);
185 case T_GHOST: return sizeof(struct naGhost);
187 return 0x7fffffff; // Make sure the answer is nonsense :)
200 int naIsString(naRef r)
202 return (!IS_NIL(r))&&IS_STR(r);
205 int naIsScalar(naRef r)
210 int naIsVector(naRef r)
212 return (!IS_NIL(r))&&IS_VEC(r);
215 int naIsHash(naRef r)
217 return (!IS_NIL(r))&&IS_HASH(r);
220 int naIsFunc(naRef r)
222 return (!IS_NIL(r))&&IS_FUNC(r);
225 int naIsCode(naRef r)
230 int naIsCCode(naRef r)
235 int naIsGhost(naRef r)