8 void naFree(void* m) { free(m); }
9 void* naAlloc(int n) { return malloc(n); }
10 void* naRealloc(void* b, int n) { return realloc(b, n); }
11 void naBZero(void* m, int n) { memset(m, 0, n); }
13 void naTempSave(naContext c, naRef r)
16 if(!IS_OBJ(r)) return;
17 if(c->ntemps >= c->tempsz) {
18 struct naObj** newtemps;
20 newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
21 for(i=0; i<c->ntemps; i++)
22 newtemps[i] = c->temps[i];
26 c->temps[c->ntemps++] = r.ref.ptr.obj;
29 naRef naObj(int type, struct naObj* o)
32 r.ref.reftag = NASAL_REFTAG;
40 if(IS_NIL(r)) return 0;
41 if(IS_NUM(r)) return r.num != 0;
42 if(IS_STR(r)) return 1;
46 naRef naNumValue(naRef n)
49 if(IS_NUM(n)) return n;
50 if(IS_NIL(n)) return naNil();
51 if(IS_STR(n) && naStr_tonum(n, &d))
56 naRef naStringValue(naContext c, naRef r)
58 if(IS_NIL(r) || IS_STR(r)) return r;
60 naRef s = naNewString(c);
61 naStr_fromnum(s, r.num);
67 naRef naNew(struct Context* c, int type)
70 if(c->nfree[type] == 0)
71 c->free[type] = naGC_get(&globals->pools[type],
72 OBJ_CACHE_SZ, &c->nfree[type]);
73 result = naObj(type, c->free[type][--c->nfree[type]]);
74 naTempSave(c, result);
78 naRef naNewString(struct Context* c)
80 naRef s = naNew(c, T_STR);
81 s.ref.ptr.str->len = 0;
82 s.ref.ptr.str->data = 0;
83 s.ref.ptr.str->hashcode = 0;
87 naRef naNewVector(struct Context* c)
89 naRef r = naNew(c, T_VEC);
90 r.ref.ptr.vec->rec = 0;
94 naRef naNewHash(struct Context* c)
96 naRef r = naNew(c, T_HASH);
97 r.ref.ptr.hash->rec = 0;
101 naRef naNewCode(struct Context* c)
103 return naNew(c, T_CODE);
106 naRef naNewCCode(struct Context* c, naCFunction fptr)
108 naRef r = naNew(c, T_CCODE);
109 r.ref.ptr.ccode->fptr = fptr;
113 naRef naNewFunc(struct Context* c, naRef code)
115 naRef func = naNew(c, T_FUNC);
116 func.ref.ptr.func->code = code;
117 func.ref.ptr.func->namespace = naNil();
118 func.ref.ptr.func->next = naNil();
122 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
124 naRef ghost = naNew(c, T_GHOST);
125 ghost.ref.ptr.ghost->gtype = type;
126 ghost.ref.ptr.ghost->ptr = ptr;
130 naGhostType* naGhost_type(naRef ghost)
132 if(!IS_GHOST(ghost)) return 0;
133 return ghost.ref.ptr.ghost->gtype;
136 void* naGhost_ptr(naRef ghost)
138 if(!IS_GHOST(ghost)) return 0;
139 return ghost.ref.ptr.ghost->ptr;
145 r.ref.reftag = NASAL_REFTAG;
150 naRef naNum(double num)
153 r.ref.reftag = ~NASAL_REFTAG;
158 int naEqual(naRef a, naRef b)
161 if(IS_REF(a) && IS_REF(b) && a.ref.ptr.obj == b.ref.ptr.obj)
162 return 1; // Object identity (and nil == nil)
163 if(IS_NIL(a) || IS_NIL(b))
165 if(IS_NUM(a) && IS_NUM(b) && a.num == b.num)
166 return 1; // Numeric equality
167 if(IS_STR(a) && IS_STR(b) && naStr_equal(a, b))
168 return 1; // String equality
170 // Numeric equality after conversion
171 if(IS_NUM(a)) { na = a.num; }
172 else if(!(IS_STR(a) && naStr_tonum(a, &na))) { return 0; }
174 if(IS_NUM(b)) { nb = b.num; }
175 else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
177 return na == nb ? 1 : 0;
180 int naStrEqual(naRef a, naRef b)
183 if(!(IS_STR(a) && IS_STR(b)))
185 if(a.ref.ptr.str->len != b.ref.ptr.str->len)
187 for(i=0; i<a.ref.ptr.str->len; i++)
188 if(a.ref.ptr.str->data[i] != b.ref.ptr.str->data[i])
193 int naTypeSize(int type)
196 case T_STR: return sizeof(struct naStr);
197 case T_VEC: return sizeof(struct naVec);
198 case T_HASH: return sizeof(struct naHash);
199 case T_CODE: return sizeof(struct naCode);
200 case T_FUNC: return sizeof(struct naFunc);
201 case T_CCODE: return sizeof(struct naCCode);
202 case T_GHOST: return sizeof(struct naGhost);
204 return 0x7fffffff; // Make sure the answer is nonsense :)
207 int naIsNil(naRef r) { return IS_NIL(r); }
208 int naIsNum(naRef r) { return IS_NUM(r); }
209 int naIsString(naRef r) { return IS_STR(r); }
210 int naIsScalar(naRef r) { return IS_SCALAR(r); }
211 int naIsVector(naRef r) { return IS_VEC(r); }
212 int naIsHash(naRef r) { return IS_HASH(r); }
213 int naIsFunc(naRef r) { return IS_FUNC(r); }
214 int naIsCode(naRef r) { return IS_CODE(r); }
215 int naIsCCode(naRef r) { return IS_CCODE(r); }
216 int naIsGhost(naRef r) { return IS_GHOST(r); }