]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/misc.c
541900329a362b2a42e200dc9479c15f9bf63e54
[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 = naObj(type, naGC_get(&(c->pools[type])));
53     naVec_append(c->temps, result);
54     return result;
55 }
56
57 naRef naNewString(struct Context* c)
58 {
59     naRef s = naNew(c, T_STR);
60     s.ref.ptr.str->len = 0;
61     s.ref.ptr.str->data = 0;
62     return s;
63 }
64
65 naRef naNewVector(struct Context* c)
66 {
67     naRef r = naNew(c, T_VEC);
68     naVec_init(r);
69     return r;
70 }
71
72 naRef naNewHash(struct Context* c)
73 {
74     naRef r = naNew(c, T_HASH);
75     naHash_init(r);
76     return r;
77 }
78
79 naRef naNewCode(struct Context* c)
80 {
81     return naNew(c, T_CODE);
82 }
83
84 naRef naNewCCode(struct Context* c, naCFunction fptr)
85 {
86     naRef r = naNew(c, T_CCODE);
87     r.ref.ptr.ccode->fptr = fptr;
88     return r;
89 }
90
91 naRef naNewFunc(struct Context* c, naRef code)
92 {
93     naRef func = naNew(c, T_FUNC);
94     func.ref.ptr.func->code = code;
95     func.ref.ptr.func->closure = naNil();
96     return func;
97 }
98
99 naRef naNewClosure(struct Context* c, naRef namespace, naRef next)
100 {
101     naRef closure = naNew(c, T_CLOSURE);
102     closure.ref.ptr.closure->namespace = namespace;
103     closure.ref.ptr.closure->next = next;
104     return closure;
105 }
106
107 naRef naNil()
108 {
109     naRef r;
110     r.ref.reftag = NASAL_REFTAG;
111     r.ref.ptr.obj = 0;
112     return r;
113 }
114
115 naRef naNum(double num)
116 {
117     naRef r;
118     r.num = num;
119     return r;
120 }
121
122 int naEqual(naRef a, naRef b)
123 {
124     double na=0, nb=0;
125     if(IS_REF(a) && IS_REF(b) && a.ref.ptr.obj == b.ref.ptr.obj)
126         return 1; // Object identity (and nil == nil)
127     if(IS_NIL(a) || IS_NIL(b))
128         return 0;
129     if(IS_NUM(a) && IS_NUM(b) && a.num == b.num)
130         return 1; // Numeric equality
131     if(IS_STR(a) && IS_STR(b) && naStr_equal(a, b))
132         return 1; // String equality
133
134     // Numeric equality after conversion
135     if(IS_NUM(a)) { na = a.num; }
136     else if(!(IS_STR(a) && naStr_tonum(a, &na))) { return 0; }
137
138     if(IS_NUM(b)) { nb = b.num; }
139     else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
140
141     return na == nb ? 1 : 0;
142 }
143
144 int naTypeSize(int type)
145 {
146     switch(type) {
147     case T_STR: return sizeof(struct naStr);
148     case T_VEC: return sizeof(struct naVec);
149     case T_HASH: return sizeof(struct naHash);
150     case T_CODE: return sizeof(struct naCode);
151     case T_FUNC: return sizeof(struct naFunc);
152     case T_CLOSURE: return sizeof(struct naClosure);
153     case T_CCODE: return sizeof(struct naCCode);
154     };
155     return 0x7fffffff; // Make sure the answer is nonsense :)
156 }
157
158 int naIsNil(naRef r)
159 {
160     return IS_NIL(r);
161 }
162
163 int naIsNum(naRef r)
164 {
165     return IS_NUM(r);
166 }
167
168 int naIsString(naRef r)
169 {
170     return (!IS_NIL(r))&&IS_STR(r);
171 }
172
173 int naIsScalar(naRef r)
174 {
175     return IS_SCALAR(r);
176 }
177
178 int naIsVector(naRef r)
179 {
180     return (!IS_NIL(r))&&IS_VEC(r);
181 }
182
183 int naIsHash(naRef r)
184 {
185     return (!IS_NIL(r))&&IS_HASH(r);
186 }
187
188 int naIsFunc(naRef r)
189 {
190     return (!IS_NIL(r))&&IS_FUNC(r);
191 }
192
193 int naIsCode(naRef r)
194 {
195     return IS_CODE(r);
196 }
197
198 int naIsCCode(naRef r)
199 {
200     return IS_CCODE(r);
201 }
202