8 static void* chkptr(void* p)
12 if(PTR(foo).obj != p) *(int*)0=0;
16 void naFree(void* m) { free(m); }
17 void* naAlloc(int n) { return chkptr(malloc(n)); }
18 void* naRealloc(void* b, int n) { return chkptr(realloc(b, n)); }
19 void naBZero(void* m, int n) { memset(m, 0, n); }
21 void naTempSave(naContext c, naRef r)
24 if(!IS_OBJ(r)) return;
25 if(c->ntemps >= c->tempsz) {
26 struct naObj** newtemps;
28 newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
29 for(i=0; i<c->ntemps; i++)
30 newtemps[i] = c->temps[i];
34 c->temps[c->ntemps++] = PTR(r).obj;
37 naRef naObj(int type, struct naObj* o)
47 if(IS_NIL(r)) return 0;
48 if(IS_NUM(r)) return r.num != 0;
49 if(IS_STR(r)) return 1;
53 naRef naNumValue(naRef n)
56 if(IS_NUM(n)) return n;
57 if(IS_NIL(n)) return naNil();
58 if(IS_STR(n) && naStr_tonum(n, &d))
63 naRef naStringValue(naContext c, naRef r)
65 if(IS_NIL(r) || IS_STR(r)) return r;
67 naRef s = naNewString(c);
68 naStr_fromnum(s, r.num);
74 naRef naNew(struct Context* c, int type)
77 if(c->nfree[type] == 0)
78 c->free[type] = naGC_get(&globals->pools[type],
79 OBJ_CACHE_SZ, &c->nfree[type]);
80 result = naObj(type, c->free[type][--c->nfree[type]]);
81 naTempSave(c, result);
85 naRef naNewString(struct Context* c)
87 naRef s = naNew(c, T_STR);
90 PTR(s).str->hashcode = 0;
94 naRef naNewVector(struct Context* c)
96 naRef r = naNew(c, T_VEC);
101 naRef naNewHash(struct Context* c)
103 naRef r = naNew(c, T_HASH);
104 PTR(r).hash->rec = 0;
108 naRef naNewCode(struct Context* c)
110 return naNew(c, T_CODE);
113 naRef naNewCCode(struct Context* c, naCFunction fptr)
115 naRef r = naNew(c, T_CCODE);
116 PTR(r).ccode->fptr = fptr;
120 naRef naNewFunc(struct Context* c, naRef code)
122 naRef func = naNew(c, T_FUNC);
123 PTR(func).func->code = code;
124 PTR(func).func->namespace = naNil();
125 PTR(func).func->next = naNil();
129 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
131 naRef ghost = naNew(c, T_GHOST);
132 PTR(ghost).ghost->gtype = type;
133 PTR(ghost).ghost->ptr = ptr;
137 naGhostType* naGhost_type(naRef ghost)
139 if(!IS_GHOST(ghost)) return 0;
140 return PTR(ghost).ghost->gtype;
143 void* naGhost_ptr(naRef ghost)
145 if(!IS_GHOST(ghost)) return 0;
146 return PTR(ghost).ghost->ptr;
156 naRef naNum(double num)
163 int naEqual(naRef a, naRef b)
166 if(IS_REF(a) && IS_REF(b) && PTR(a).obj == PTR(b).obj)
167 return 1; // Object identity (and nil == nil)
168 if(IS_NIL(a) || IS_NIL(b))
170 if(IS_NUM(a) && IS_NUM(b) && a.num == b.num)
171 return 1; // Numeric equality
172 if(IS_STR(a) && IS_STR(b) && naStr_equal(a, b))
173 return 1; // String equality
175 // Numeric equality after conversion
176 if(IS_NUM(a)) { na = a.num; }
177 else if(!(IS_STR(a) && naStr_tonum(a, &na))) { return 0; }
179 if(IS_NUM(b)) { nb = b.num; }
180 else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
182 return na == nb ? 1 : 0;
185 int naStrEqual(naRef a, naRef b)
188 if(!(IS_STR(a) && IS_STR(b)))
190 if(PTR(a).str->len != PTR(b).str->len)
192 for(i=0; i<PTR(a).str->len; i++)
193 if(PTR(a).str->data[i] != PTR(b).str->data[i])
198 int naTypeSize(int type)
201 case T_STR: return sizeof(struct naStr);
202 case T_VEC: return sizeof(struct naVec);
203 case T_HASH: return sizeof(struct naHash);
204 case T_CODE: return sizeof(struct naCode);
205 case T_FUNC: return sizeof(struct naFunc);
206 case T_CCODE: return sizeof(struct naCCode);
207 case T_GHOST: return sizeof(struct naGhost);
209 return 0x7fffffff; // Make sure the answer is nonsense :)
212 int naIsNil(naRef r) { return IS_NIL(r); }
213 int naIsNum(naRef r) { return IS_NUM(r); }
214 int naIsString(naRef r) { return IS_STR(r); }
215 int naIsScalar(naRef r) { return IS_SCALAR(r); }
216 int naIsVector(naRef r) { return IS_VEC(r); }
217 int naIsHash(naRef r) { return IS_HASH(r); }
218 int naIsFunc(naRef r) { return IS_FUNC(r); }
219 int naIsCode(naRef r) { return IS_CODE(r); }
220 int naIsCCode(naRef r) { return IS_CCODE(r); }
221 int naIsGhost(naRef r) { return IS_GHOST(r); }
223 void naSetUserData(naContext c, void* p) { c->userData = p; }
224 void* naGetUserData(naContext c)
226 if(c->userData) return c->userData;
227 return c->callParent ? naGetUserData(c->callParent) : 0;
230 void naAddSym(naContext c, naRef ns, char *sym, naRef val)
232 naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
233 naHash_set(ns, naInternSymbol(name), val);
236 naRef naGenLib(naContext c, naCFuncItem *fns)
238 naRef ns = naNewHash(c);
239 for(/**/; fns->name; fns++)
240 naAddSym(c, ns, fns->name, naNewFunc(c, naNewCCode(c, fns->func)));