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