]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/lib.c
1ed3837bd6549fbd400d361c87f7177e48218576
[simgear.git] / simgear / nasal / lib.c
1 #include "nasal.h"
2
3 #ifndef _MSC_VER
4 // No need to include <string.h> just for this:
5 static int strlen(char* s)
6 {
7     char* s0 = s;
8     while(*s) s++;
9     return s - s0;
10 }
11 #endif
12
13 static naRef size(naContext c, naRef args)
14 {
15     naRef r;
16     if(naVec_size(args) == 0) return naNil();
17     r = naVec_get(args, 0);
18     if(naIsString(r)) return naNum(naStr_len(r));
19     if(naIsVector(r)) return naNum(naVec_size(r));
20     if(naIsHash(r)) return naNum(naHash_size(r));
21     return naNil();
22 }
23
24 static naRef keys(naContext c, naRef args)
25 {
26     naRef v, h = naVec_get(args, 0);
27     if(!naIsHash(h)) return naNil();
28     v = naNewVector(c);
29     naHash_keys(v, h);
30     return v;
31 }
32
33 static naRef append(naContext c, naRef args)
34 {
35     naRef v = naVec_get(args, 0);
36     naRef e = naVec_get(args, 1);
37     if(!naIsVector(v)) return naNil();
38     naVec_append(v, e);
39     return v;
40 }
41
42 static naRef pop(naContext c, naRef args)
43 {
44     naRef v = naVec_get(args, 0);
45     if(!naIsVector(v)) return naNil();
46     return naVec_removelast(v);
47 }
48
49 static naRef delete(naContext c, naRef args)
50 {
51     naRef h = naVec_get(args, 0);
52     naRef k = naVec_get(args, 1);
53     if(naIsHash(h)) naHash_delete(h, k);
54     return naNil();
55 }
56
57 static naRef intf(naContext c, naRef args)
58 {
59     naRef n = naNumValue(naVec_get(args, 0));
60     if(!naIsNil(n)) n.num = (int)n.num;
61     return n;
62 }
63
64 static naRef num(naContext c, naRef args)
65 {
66     return naNumValue(naVec_get(args, 0));
67 }
68
69 static naRef streq(naContext c, naRef args)
70 {
71     int i;
72     naRef a = naVec_get(args, 0);
73     naRef b = naVec_get(args, 1);
74     if(!naIsString(a) || !naIsString(b)) return naNil();
75     if(naStr_len(a) != naStr_len(b)) return naNum(0);
76     for(i=0; i<naStr_len(a); i++)
77         if(naStr_data(a)[i] != naStr_data(b)[i])
78             return naNum(0);
79     return naNum(1);
80 }
81
82 static naRef substr(naContext c, naRef args)
83 {
84     naRef src = naVec_get(args, 0);
85     naRef startR = naVec_get(args, 1);
86     naRef lenR = naVec_get(args, 2);
87     int start, len;
88     if(!naIsString(src)) return naNil();
89     startR = naNumValue(startR);
90     if(naIsNil(startR)) return naNil();
91     start = (int)startR.num;
92     if(naIsNil(lenR)) {
93         len = naStr_len(src) - start;
94     } else {
95         lenR = naNumValue(lenR);
96         if(naIsNil(lenR)) return naNil();
97         len = (int)lenR.num;
98     }
99     return naStr_substr(naNewString(c), src, start, len);
100 }
101
102 static naRef contains(naContext c, naRef args)
103 {
104     naRef hash = naVec_get(args, 0);
105     naRef key = naVec_get(args, 1);
106     if(naIsNil(hash) || naIsNil(key)) return naNil();
107     if(!naIsHash(hash)) return naNil();
108     return naHash_get(hash, key, &key) ? naNum(1) : naNum(0);
109 }
110
111 static naRef typeOf(naContext c, naRef args)
112 {
113     naRef r = naVec_get(args, 0);
114     char* t = "unknown";
115     if(naIsNil(r)) t = "nil";
116     else if(naIsNum(r)) t = "scalar";
117     else if(naIsString(r)) t = "scalar";
118     else if(naIsVector(r)) t = "vector";
119     else if(naIsHash(r)) t = "hash";
120     else if(naIsFunc(r)) t = "func";
121     r = naStr_fromdata(naNewString(c), t, strlen(t));
122     return r;
123 }
124
125 struct func { char* name; naCFunction func; };
126 static struct func funcs[] = {
127     { "size", size },
128     { "keys", keys }, 
129     { "append", append }, 
130     { "pop", pop }, 
131     { "delete", delete }, 
132     { "int", intf },
133     { "num", num },
134     { "streq", streq },
135     { "substr", substr },
136     { "contains", contains },
137     { "typeof", typeOf },
138 };
139
140 naRef naStdLib(naContext c)
141 {
142     naRef namespace = naNewHash(c);
143     int i, n = sizeof(funcs)/sizeof(struct func);
144     for(i=0; i<n; i++) {
145         naRef code = naNewCCode(c, funcs[i].func);
146         naRef name = naStr_fromdata(naNewString(c),
147                                     funcs[i].name, strlen(funcs[i].name));
148         naHash_set(namespace, name, naNewFunc(c, code));
149     }
150     return namespace;
151 }