]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/misc.c
25302e4bf08baffa9c2026e4028b175c26ee8fd5
[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 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); }
11
12 naRef naObj(int type, struct naObj* o)
13 {
14     naRef r;
15     r.ref.reftag = NASAL_REFTAG;
16     r.ref.ptr.obj = o;
17     o->type = type;
18     return r;
19 }
20
21 int naTrue(naRef r)
22 {
23     if(IS_NIL(r)) return 0;
24     if(IS_NUM(r)) return r.num != 0;
25     if(IS_STR(r)) return 1;
26     return 0;
27 }
28
29 naRef naNumValue(naRef n)
30 {
31     double d;
32     if(IS_NUM(n)) return n;
33     if(IS_NIL(n)) return naNil();
34     if(IS_STR(n) && naStr_tonum(n, &d))
35         return naNum(d);
36     return naNil();
37 }
38
39 naRef naStringValue(naContext c, naRef r)
40 {
41     if(IS_NIL(r) || IS_STR(r)) return r;
42     if(IS_NUM(r)) {
43         naRef s = naNewString(c);
44         naStr_fromnum(s, r.num);
45         return s;
46     }
47     return naNil();
48 }
49
50 naRef naNew(struct Context* c, int type)
51 {
52     naRef result;
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);
58     return result;
59 }
60
61 naRef naNewString(struct Context* c)
62 {
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;
67     return s;
68 }
69
70 naRef naNewVector(struct Context* c)
71 {
72     naRef r = naNew(c, T_VEC);
73     r.ref.ptr.vec->rec = 0;
74     return r;
75 }
76
77 naRef naNewHash(struct Context* c)
78 {
79     naRef r = naNew(c, T_HASH);
80     r.ref.ptr.hash->rec = 0;
81     return r;
82 }
83
84 naRef naNewCode(struct Context* c)
85 {
86     return naNew(c, T_CODE);
87 }
88
89 naRef naNewCCode(struct Context* c, naCFunction fptr)
90 {
91     naRef r = naNew(c, T_CCODE);
92     r.ref.ptr.ccode->fptr = fptr;
93     return r;
94 }
95
96 naRef naNewFunc(struct Context* c, naRef code)
97 {
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();
102     return func;
103 }
104
105 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
106 {
107     naRef ghost = naNew(c, T_GHOST);
108     ghost.ref.ptr.ghost->gtype = type;
109     ghost.ref.ptr.ghost->ptr = ptr;
110     return ghost;
111 }
112
113 naGhostType* naGhost_type(naRef ghost)
114 {
115     if(!IS_GHOST(ghost)) return 0;
116     return ghost.ref.ptr.ghost->gtype;
117 }
118
119 void* naGhost_ptr(naRef ghost)
120 {
121     if(!IS_GHOST(ghost)) return 0;
122     return ghost.ref.ptr.ghost->ptr;
123 }
124
125 naRef naNil()
126 {
127     naRef r;
128     r.ref.reftag = NASAL_REFTAG;
129     r.ref.ptr.obj = 0;
130     return r;
131 }
132
133 naRef naNum(double num)
134 {
135     naRef r;
136     r.ref.reftag = ~NASAL_REFTAG;
137     r.num = num;
138     return r;
139 }
140
141 int naEqual(naRef a, naRef b)
142 {
143     double na=0, nb=0;
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))
147         return 0;
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
152
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; }
156
157     if(IS_NUM(b)) { nb = b.num; }
158     else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
159
160     return na == nb ? 1 : 0;
161 }
162
163 int naStrEqual(naRef a, naRef b)
164 {
165     int i;
166     if(!(IS_STR(a) && IS_STR(b)))
167         return 0;
168     if(a.ref.ptr.str->len != b.ref.ptr.str->len)
169         return 0;
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])
172             return 0;
173     return 1;
174 }
175
176 int naTypeSize(int type)
177 {
178     switch(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);
186     };
187     return 0x7fffffff; // Make sure the answer is nonsense :)
188 }
189
190 int naIsNil(naRef r)
191 {
192     return IS_NIL(r);
193 }
194
195 int naIsNum(naRef r)
196 {
197     return IS_NUM(r);
198 }
199
200 int naIsString(naRef r)
201 {
202     return (!IS_NIL(r))&&IS_STR(r);
203 }
204
205 int naIsScalar(naRef r)
206 {
207     return IS_SCALAR(r);
208 }
209
210 int naIsVector(naRef r)
211 {
212     return (!IS_NIL(r))&&IS_VEC(r);
213 }
214
215 int naIsHash(naRef r)
216 {
217     return (!IS_NIL(r))&&IS_HASH(r);
218 }
219
220 int naIsFunc(naRef r)
221 {
222     return (!IS_NIL(r))&&IS_FUNC(r);
223 }
224
225 int naIsCode(naRef r)
226 {
227     return IS_CODE(r);
228 }
229
230 int naIsCCode(naRef r)
231 {
232     return IS_CCODE(r);
233 }
234
235 int naIsGhost(naRef r)
236 {
237     return IS_GHOST(r);
238 }