]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/misc.c
6e0e92398d7e4fcb2e3561667df700dc8418f4f5
[simgear.git] / simgear / nasal / misc.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include "nasal.h"
6 #include "code.h"
7
8 static void* chkptr(void* p)
9 {
10     naRef foo;
11     SETPTR(foo, p);
12     if(PTR(foo).obj != p) *(int*)0=0;
13     return p;
14 }
15
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); }
20
21 void naTempSave(naContext c, naRef r)
22 {
23     int i;
24     if(!IS_OBJ(r)) return;
25     if(c->ntemps >= c->tempsz) {
26         struct naObj** newtemps;
27         c->tempsz *= 2;
28         newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
29         for(i=0; i<c->ntemps; i++)
30             newtemps[i] = c->temps[i];
31         naFree(c->temps);
32         c->temps = newtemps;
33     }
34     c->temps[c->ntemps++] = PTR(r).obj;
35 }
36
37 naRef naObj(int type, struct naObj* o)
38 {
39     naRef r;
40     SETPTR(r, o);
41     o->type = type;
42     return r;
43 }
44
45 int naTrue(naRef r)
46 {
47     if(IS_NIL(r)) return 0;
48     if(IS_NUM(r)) return r.num != 0;
49     if(IS_STR(r)) return 1;
50     return 0;
51 }
52
53 naRef naNumValue(naRef n)
54 {
55     double d;
56     if(IS_NUM(n)) return n;
57     if(IS_NIL(n)) return naNil();
58     if(IS_STR(n) && naStr_tonum(n, &d))
59         return naNum(d);
60     return naNil();
61 }
62
63 naRef naStringValue(naContext c, naRef r)
64 {
65     if(IS_NIL(r) || IS_STR(r)) return r;
66     if(IS_NUM(r)) {
67         naRef s = naNewString(c);
68         naStr_fromnum(s, r.num);
69         return s;
70     }
71     return naNil();
72 }
73
74 naRef naNew(struct Context* c, int type)
75 {
76     naRef result;
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);
82     return result;
83 }
84
85 naRef naNewString(struct Context* c)
86 {
87     naRef s = naNew(c, T_STR);
88     PTR(s).str->len = 0;
89     PTR(s).str->data = 0;
90     PTR(s).str->hashcode = 0;
91     return s;
92 }
93
94 naRef naNewVector(struct Context* c)
95 {
96     naRef r = naNew(c, T_VEC);
97     PTR(r).vec->rec = 0;
98     return r;
99 }
100
101 naRef naNewHash(struct Context* c)
102 {
103     naRef r = naNew(c, T_HASH);
104     PTR(r).hash->rec = 0;
105     return r;
106 }
107
108 naRef naNewCode(struct Context* c)
109 {
110     return naNew(c, T_CODE);
111 }
112
113 naRef naNewCCode(struct Context* c, naCFunction fptr)
114 {
115     naRef r = naNew(c, T_CCODE);
116     PTR(r).ccode->fptr = fptr;
117     return r;
118 }
119
120 naRef naNewFunc(struct Context* c, naRef code)
121 {
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();
126     return func;
127 }
128
129 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
130 {
131     naRef ghost = naNew(c, T_GHOST);
132     PTR(ghost).ghost->gtype = type;
133     PTR(ghost).ghost->ptr = ptr;
134     return ghost;
135 }
136
137 naGhostType* naGhost_type(naRef ghost)
138 {
139     if(!IS_GHOST(ghost)) return 0;
140     return PTR(ghost).ghost->gtype;
141 }
142
143 void* naGhost_ptr(naRef ghost)
144 {
145     if(!IS_GHOST(ghost)) return 0;
146     return PTR(ghost).ghost->ptr;
147 }
148
149 naRef naNil()
150 {
151     naRef r; 
152     SETPTR(r, 0);
153     return r;
154 }
155
156 naRef naNum(double num)
157 {
158     naRef r;
159     SETNUM(r, num);
160     return r;
161 }
162
163 int naEqual(naRef a, naRef b)
164 {
165     double na=0, nb=0;
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))
169         return 0;
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
174
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; }
178
179     if(IS_NUM(b)) { nb = b.num; }
180     else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
181
182     return na == nb ? 1 : 0;
183 }
184
185 int naStrEqual(naRef a, naRef b)
186 {
187     int i;
188     if(!(IS_STR(a) && IS_STR(b)))
189         return 0;
190     if(PTR(a).str->len != PTR(b).str->len)
191         return 0;
192     for(i=0; i<PTR(a).str->len; i++)
193         if(PTR(a).str->data[i] != PTR(b).str->data[i])
194             return 0;
195     return 1;
196 }
197
198 int naTypeSize(int type)
199 {
200     switch(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);
208     };
209     return 0x7fffffff; // Make sure the answer is nonsense :)
210 }
211
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); }
222
223 void naSetUserData(naContext c, void* p) { c->userData = p; }
224 void* naGetUserData(naContext c)
225 {
226     if(c->userData) return c->userData;
227     return c->callParent ? naGetUserData(c->callParent) : 0;
228 }
229
230 void naAddSym(naContext c, naRef ns, char *sym, naRef val)
231 {
232     naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
233     naHash_set(ns, naInternSymbol(name), val);
234 }
235
236 naRef naGenLib(naContext c, naCFuncItem *fns)
237 {
238     naRef ns = naNewHash(c);
239     for(/**/; fns->name; fns++)
240         naAddSym(c, ns, fns->name, naNewFunc(c, naNewCCode(c, fns->func)));
241     return ns;
242 }