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++] = PTR(r).obj;
29 naRef naObj(int type, struct naObj* o)
39 if(IS_NIL(r)) return 0;
40 if(IS_NUM(r)) return r.num != 0;
41 if(IS_STR(r)) return 1;
45 naRef naNumValue(naRef n)
48 if(IS_NUM(n)) return n;
49 if(IS_NIL(n)) return naNil();
50 if(IS_STR(n) && naStr_tonum(n, &d))
55 naRef naStringValue(naContext c, naRef r)
57 if(IS_NIL(r) || IS_STR(r)) return r;
59 naRef s = naNewString(c);
60 naStr_fromnum(s, r.num);
66 naRef naNew(struct Context* c, int type)
69 if(c->nfree[type] == 0)
70 c->free[type] = naGC_get(&globals->pools[type],
71 OBJ_CACHE_SZ, &c->nfree[type]);
72 result = naObj(type, c->free[type][--c->nfree[type]]);
73 naTempSave(c, result);
77 naRef naNewString(struct Context* c)
79 naRef s = naNew(c, T_STR);
80 PTR(s).str->emblen = 0;
81 PTR(s).str->data.ref.len = 0;
82 PTR(s).str->data.ref.ptr = 0;
83 PTR(s).str->hashcode = 0;
87 naRef naNewVector(struct Context* c)
89 naRef r = naNew(c, T_VEC);
94 naRef naNewHash(struct Context* c)
96 naRef r = naNew(c, T_HASH);
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 PTR(r).ccode->fptr = fptr;
110 PTR(r).ccode->fptru = 0;
114 naRef naNewCCodeU(struct Context* c, naCFunctionU fptr, void* user_data)
116 return naNewCCodeUD(c, fptr, user_data, 0);
119 naRef naNewCCodeUD( struct Context* c,
122 void (*destroy)(void*) )
124 naRef r = naNew(c, T_CCODE);
125 PTR(r).ccode->fptru = fptr;
126 PTR(r).ccode->user_data = user_data;
127 PTR(r).ccode->destroy = destroy;
131 naRef naNewFunc(struct Context* c, naRef code)
133 naRef func = naNew(c, T_FUNC);
134 PTR(func).func->code = code;
135 PTR(func).func->namespace = naNil();
136 PTR(func).func->next = naNil();
140 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
143 // ensure 'simple' ghost users don't see garbage for these fields
144 type->get_member = 0;
145 type->set_member = 0;
147 ghost = naNew(c, T_GHOST);
148 PTR(ghost).ghost->gtype = type;
149 PTR(ghost).ghost->ptr = ptr;
150 PTR(ghost).ghost->data = naNil();
154 naRef naNewGhost2(naContext c, naGhostType* t, void* ptr)
156 naRef ghost = naNew(c, T_GHOST);
157 PTR(ghost).ghost->gtype = t;
158 PTR(ghost).ghost->ptr = ptr;
159 PTR(ghost).ghost->data = naNil();
163 naGhostType* naGhost_type(naRef ghost)
165 if(!IS_GHOST(ghost)) return 0;
166 return PTR(ghost).ghost->gtype;
169 void* naGhost_ptr(naRef ghost)
171 if(!IS_GHOST(ghost)) return 0;
172 return PTR(ghost).ghost->ptr;
175 void naGhost_setData(naRef ghost, naRef data)
178 PTR(ghost).ghost->data = data;
181 naRef naGhost_data(naRef ghost)
183 if(!IS_GHOST(ghost)) return naNil();
184 return PTR(ghost).ghost->data;
194 naRef naNum(double num)
201 int naEqual(naRef a, naRef b)
204 if(IS_REF(a) && IS_REF(b) && PTR(a).obj == PTR(b).obj)
205 return 1; // Object identity (and nil == nil)
206 if(IS_NIL(a) || IS_NIL(b))
208 if(IS_NUM(a) && IS_NUM(b) && a.num == b.num)
209 return 1; // Numeric equality
210 if(IS_STR(a) && IS_STR(b) && naStr_equal(a, b))
211 return 1; // String equality
213 // Numeric equality after conversion
214 if(IS_NUM(a)) { na = a.num; }
215 else if(!(IS_STR(a) && naStr_tonum(a, &na))) { return 0; }
217 if(IS_NUM(b)) { nb = b.num; }
218 else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
220 return na == nb ? 1 : 0;
223 int naStrEqual(naRef a, naRef b)
227 if(!IS_STR(a) || !IS_STR(b) || naStr_len(a) != naStr_len(b))
231 for(i=0; i<naStr_len(a); i++)
237 int naTypeSize(int type)
240 case T_STR: return sizeof(struct naStr);
241 case T_VEC: return sizeof(struct naVec);
242 case T_HASH: return sizeof(struct naHash);
243 case T_CODE: return sizeof(struct naCode);
244 case T_FUNC: return sizeof(struct naFunc);
245 case T_CCODE: return sizeof(struct naCCode);
246 case T_GHOST: return sizeof(struct naGhost);
248 return 0x7fffffff; // Make sure the answer is nonsense :)
251 int naIsNil(naRef r) { return IS_NIL(r); }
252 int naIsNum(naRef r) { return IS_NUM(r); }
253 int naIsString(naRef r) { return IS_STR(r); }
254 int naIsScalar(naRef r) { return IS_SCALAR(r); }
255 int naIsVector(naRef r) { return IS_VEC(r); }
256 int naIsHash(naRef r) { return IS_HASH(r); }
257 int naIsFunc(naRef r) { return IS_FUNC(r); }
258 int naIsCode(naRef r) { return IS_CODE(r); }
259 int naIsCCode(naRef r) { return IS_CCODE(r); }
260 int naIsGhost(naRef r) { return IS_GHOST(r); }
261 int naIsIdentical(naRef l, naRef r) { return IDENTICAL(l, r); }
263 void naSetUserData(naContext c, void* p) { c->userData = p; }
264 void* naGetUserData(naContext c)
266 if(c->userData) return c->userData;
267 return c->callParent ? naGetUserData(c->callParent) : 0;
270 void naAddSym(naContext c, naRef ns, char *sym, naRef val)
272 naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
273 naHash_set(ns, naInternSymbol(name), val);
276 naRef naGenLib(naContext c, naCFuncItem *fns)
278 naRef ns = naNewHash(c);
279 for(/**/; fns->name; fns++)
280 naAddSym(c, ns, fns->name, naNewFunc(c, naNewCCode(c, fns->func)));