Mercurial > repo
comparison interps/glass/builtins.cc @ 996:859f9b4339e6
<Gregor> tar xf egobot.tar.xz
author | HackBot |
---|---|
date | Sun, 09 Dec 2012 19:30:08 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
995:6883f5911eb7 | 996:859f9b4339e6 |
---|---|
1 /* | |
2 * Copyright (c) 2005 Gregor Richards | |
3 * | |
4 * This file is part of Glass. | |
5 * | |
6 * Glass is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * Glass is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with Glass; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 #include <cstdio> | |
22 #include <iostream> | |
23 #include <sstream> | |
24 using namespace std; | |
25 | |
26 #include "builtins.h" | |
27 #include "func.h" | |
28 #include "glass.h" | |
29 #include "klass.h" | |
30 #include "klassi.h" | |
31 #include "parseq.h" | |
32 #include "variable.h" | |
33 | |
34 #define POP \ | |
35 { \ | |
36 if (mainStack.size() != 0) { \ | |
37 delete mainStack[0]; \ | |
38 mainStack.pop_front(); \ | |
39 } \ | |
40 } | |
41 | |
42 char builtinDefinitions[] = "{A \ | |
43 [a~A.a~] \ | |
44 [s~A.s~] \ | |
45 [m~A.m~] \ | |
46 [d~A.d~] \ | |
47 [(mod)~A.mod~] \ | |
48 [f~A.f~] \ | |
49 [e~A.e~] \ | |
50 [(ne)~A.ne~] \ | |
51 [(lt)~A.lt~] \ | |
52 [(le)~A.le~] \ | |
53 [(gt)~A.gt~] \ | |
54 [(ge)~A.ge~] \ | |
55 } \ | |
56 {S \ | |
57 [l~S.l~] \ | |
58 [i~S.i~] \ | |
59 [(si)~S.si~] \ | |
60 [a~S.a~] \ | |
61 [d~S.d~] \ | |
62 [e~S.e~] \ | |
63 [(ns)~S.ns~] \ | |
64 [(sn)~S.sn~] \ | |
65 } \ | |
66 {V \ | |
67 [n~V.n~] \ | |
68 [d~V.d~] \ | |
69 } \ | |
70 {O \ | |
71 [o~O.o~] \ | |
72 [(on)~O.on~] \ | |
73 } \ | |
74 {I \ | |
75 [l~I.l~] \ | |
76 [c~I.c~] \ | |
77 [e~I.e~] \ | |
78 [n~I.n~] \ | |
79 } \ | |
80 {(Debug) \ | |
81 [(cl)~Debug.cl~] \ | |
82 [(fl)~Debug.fl~] \ | |
83 [(fc)~Debug.fc~] \ | |
84 [s~Debug.s~] \ | |
85 }"; | |
86 | |
87 | |
88 #define BUILTIN(A, B) else if (which == A && mainStack.size() >= B) | |
89 void doBuiltin(string which) | |
90 { | |
91 if (0) { | |
92 } BUILTIN("A.a", 2) { | |
93 mainStack[1]->nval = mainStack[1]->nval + mainStack[0]->nval; | |
94 POP; | |
95 } BUILTIN("A.s", 2) { | |
96 mainStack[1]->nval = mainStack[1]->nval - mainStack[0]->nval; | |
97 POP; | |
98 } BUILTIN("A.m", 2) { | |
99 mainStack[1]->nval = mainStack[1]->nval * mainStack[0]->nval; | |
100 POP; | |
101 } BUILTIN("A.d", 2) { | |
102 if (mainStack[0]->nval != 0) | |
103 mainStack[1]->nval = mainStack[1]->nval / mainStack[0]->nval; | |
104 POP; | |
105 } BUILTIN("A.mod", 2) { | |
106 long long a = (long long) mainStack[1]->nval; | |
107 long long b = (long long) mainStack[0]->nval; | |
108 if (b != 0) | |
109 mainStack[1]->nval = a % b; | |
110 POP; | |
111 } BUILTIN("A.f", 1) { | |
112 mainStack[0]->nval = (long long) mainStack[0]->nval; | |
113 } BUILTIN("A.e", 2) { | |
114 mainStack[1]->nval = mainStack[1]->nval == mainStack[0]->nval; | |
115 POP; | |
116 } BUILTIN("A.ne", 2) { | |
117 mainStack[1]->nval = mainStack[1]->nval != mainStack[0]->nval; | |
118 POP; | |
119 } BUILTIN("A.lt", 2) { | |
120 mainStack[1]->nval = mainStack[1]->nval < mainStack[0]->nval; | |
121 POP; | |
122 } BUILTIN("A.le", 2) { | |
123 mainStack[1]->nval = mainStack[1]->nval <= mainStack[0]->nval; | |
124 POP; | |
125 } BUILTIN("A.gt", 2) { | |
126 mainStack[1]->nval = mainStack[1]->nval > mainStack[0]->nval; | |
127 POP; | |
128 } BUILTIN("A.ge", 2) { | |
129 mainStack[1]->nval = mainStack[1]->nval >= mainStack[0]->nval; | |
130 POP; | |
131 } BUILTIN("S.l", 1) { | |
132 mainStack[0]->nval = mainStack[0]->sval.length(); | |
133 mainStack[0]->type = VAR_NUMBER; | |
134 mainStack[0]->sval = ""; | |
135 } BUILTIN("S.i", 2) { | |
136 if (mainStack[0]->nval >= 0 && | |
137 mainStack[0]->nval < mainStack[1]->sval.length()) { | |
138 mainStack[1]->sval = mainStack[1]->sval[(int) mainStack[0]->nval]; | |
139 } else { | |
140 mainStack[1]->sval = ""; | |
141 } | |
142 POP; | |
143 } BUILTIN("S.si", 3) { | |
144 if (mainStack[1]->nval >= 0 && | |
145 mainStack[1]->nval < mainStack[2]->sval.length() && | |
146 mainStack[0]->sval.length() > 0) { | |
147 mainStack[2]->sval[(int) mainStack[1]->nval] = mainStack[0]->sval[0]; | |
148 } | |
149 POP; POP; | |
150 } BUILTIN("S.a", 2) { | |
151 mainStack[1]->sval += mainStack[0]->sval; | |
152 POP; | |
153 } BUILTIN("S.d", 2) { | |
154 mainStack[0]->sval = mainStack[1]->sval.substr((int) mainStack[0]->nval); | |
155 mainStack[0]->type = VAR_STRING; | |
156 mainStack[1]->sval = mainStack[1]->sval.substr(0, (int) mainStack[0]->nval); | |
157 } BUILTIN("S.e", 2) { | |
158 mainStack[1]->nval = (mainStack[1]->sval == mainStack[0]->sval); | |
159 mainStack[1]->type = VAR_NUMBER; | |
160 mainStack[1]->sval = ""; | |
161 POP; | |
162 } BUILTIN("S.ns", 1) { | |
163 mainStack[0]->sval = (char) mainStack[0]->nval; | |
164 mainStack[0]->type = VAR_STRING; | |
165 } BUILTIN("S.sn", 1) { | |
166 if (mainStack[0]->sval.length() > 0) { | |
167 mainStack[0]->nval = mainStack[0]->sval[0]; | |
168 } else { | |
169 mainStack[0]->nval = 0; | |
170 } | |
171 mainStack[0]->type = VAR_NUMBER; | |
172 mainStack[0]->sval = ""; | |
173 } BUILTIN("V.n", 0) { | |
174 // find one | |
175 unsigned int i; | |
176 stringstream nm; | |
177 for (i = 1; i != 0; i++) { | |
178 // check this name ... | |
179 nm.str(""); | |
180 nm << "Anonymous" << i; | |
181 if (globalVars.find(nm.str()) == globalVars.end()) { | |
182 // it's free | |
183 globalVars[nm.str()] = new Variable(); | |
184 mainStack.push_front(new Variable(VAR_VARIABLEP, nm.str())); | |
185 return; | |
186 } | |
187 } | |
188 // uh oh! | |
189 mainStack.push_front(new Variable()); | |
190 } BUILTIN("V.d", 1) { | |
191 // TODO | |
192 #ifndef IRC | |
193 } BUILTIN("O.o", 1) { | |
194 cout << mainStack[0]->sval; | |
195 fflush(stdout); | |
196 POP; | |
197 } BUILTIN("O.on", 1) { | |
198 cout << mainStack[0]->nval; | |
199 fflush(stdout); | |
200 POP; | |
201 #else | |
202 } BUILTIN("O.o", 1) { | |
203 IRC_o += mainStack[0]->sval; | |
204 POP; | |
205 } BUILTIN("O.on", 1) { | |
206 stringstream IRC_os; | |
207 IRC_os << mainStack[0]->nval; | |
208 IRC_o += IRC_os.str(); | |
209 POP; | |
210 #endif | |
211 #ifndef IRC | |
212 } BUILTIN("I.l", 0) { | |
213 char line[1025]; | |
214 string sline; | |
215 | |
216 line[1024] = '\0'; | |
217 line[0] = '\0'; | |
218 fgets(line, 1024, stdin); // ignore errors purposely | |
219 sline = line; | |
220 | |
221 mainStack.push_front(new Variable(VAR_STRING, sline)); | |
222 | |
223 } BUILTIN("I.c", 0) { | |
224 int ic = getchar(); | |
225 string ics; | |
226 | |
227 if (ic == EOF) ic = 0; | |
228 ics = ic; | |
229 | |
230 mainStack.push_front(new Variable(VAR_STRING, ics)); | |
231 | |
232 } BUILTIN ("I.n", 0) { | |
233 int in; | |
234 int inn; | |
235 scanf ("%d",&in); | |
236 inn = in; | |
237 mainStack.push_front(new Variable(VAR_NUMBER, inn)); | |
238 | |
239 } BUILTIN("I.e", 0) { | |
240 if (feof(stdin) || ferror(stdin)) { | |
241 mainStack.push_front(new Variable(VAR_NUMBER, 1.0)); | |
242 } else { | |
243 mainStack.push_front(new Variable(VAR_NUMBER, 0.0)); | |
244 } | |
245 #else | |
246 } BUILTIN("I.l", 0) { | |
247 mainStack.push_front(new Variable(VAR_STRING, "")); | |
248 } BUILTIN("I.c", 0) { | |
249 mainStack.push_front(new Variable(VAR_STRING, "")); | |
250 } BUILTIN("I.e", 0) { | |
251 mainStack.push_front(new Variable(VAR_NUMBER, 1.0)); | |
252 #endif | |
253 } BUILTIN("Debug.cl", 0) { | |
254 map<string,Variable *>::iterator svari; | |
255 for (svari = globalVars.begin(); svari != globalVars.end(); svari++) { | |
256 if (svari->second->type == VAR_KLASS) { | |
257 #ifndef IRC | |
258 cout << svari->first << " "; | |
259 #else | |
260 IRC_o += svari->first + " "; | |
261 #endif | |
262 } | |
263 } | |
264 } BUILTIN("Debug.fl", 1) { | |
265 if (mainStack[0]->type != VAR_STRING) { POP; return; } | |
266 if (globalVars.find(mainStack[0]->sval) != globalVars.end()) { | |
267 Klass *tolist = globalVars[mainStack[0]->sval]->kval; | |
268 map<string,Func *>::iterator sfuni; | |
269 for (sfuni = tolist->functions.begin(); sfuni != tolist->functions.end(); sfuni++) { | |
270 #ifndef IRC | |
271 cout << sfuni->first << " "; | |
272 #else | |
273 IRC_o += sfuni->first + " "; | |
274 #endif | |
275 } | |
276 } | |
277 POP; | |
278 } BUILTIN("Debug.fc", 2) { | |
279 if (mainStack[0]->type != VAR_STRING || | |
280 mainStack[1]->type != VAR_STRING) { POP; POP; return; } | |
281 | |
282 if (globalVars.find(mainStack[1]->sval) != globalVars.end()) { | |
283 Klass *tolist = globalVars[mainStack[1]->sval]->kval; | |
284 if (tolist->functions.find(mainStack[0]->sval) != tolist->functions.end()) { | |
285 Func *ftolist = tolist->functions[mainStack[0]->sval]; | |
286 | |
287 // now output it all | |
288 string cont = ftolist->contents->dump(); | |
289 #ifndef IRC | |
290 cout << cont; | |
291 #else | |
292 IRC_o += cont; | |
293 #endif | |
294 } | |
295 } | |
296 POP; POP; | |
297 } BUILTIN("Debug.s", 0) { | |
298 unsigned int ui; | |
299 stringstream dso; | |
300 for (ui = 0; ui < mainStack.size(); ui++) { | |
301 switch (mainStack[ui]->type) { | |
302 case VAR_VARIABLEP: | |
303 dso << "(" << mainStack[ui]->sval << ")"; | |
304 break; | |
305 | |
306 case VAR_NUMBER: | |
307 dso << "<" << mainStack[ui]->nval << ">"; | |
308 break; | |
309 | |
310 case VAR_STRING: | |
311 dso << "\"" << mainStack[ui]->sval << "\""; | |
312 break; | |
313 | |
314 case VAR_KLASS: | |
315 dso << "(" << mainStack[ui]->kval->name << "*:c)"; | |
316 break; | |
317 | |
318 case VAR_KLASSI: | |
319 dso << "(" << mainStack[ui]->kival->of->name << "*:ci)"; | |
320 break; | |
321 | |
322 case VAR_FUNC: | |
323 dso << "(" << mainStack[ui]->fval->name << "*:f)"; | |
324 break; | |
325 | |
326 case VAR_FUNCI: | |
327 dso << "(" << mainStack[ui]->kival->of->name << "." << | |
328 mainStack[ui]->fval->name << "*:f)"; | |
329 break; | |
330 } | |
331 } | |
332 #ifndef IRC | |
333 cout << dso.str(); | |
334 #else | |
335 IRC_o += dso.str(); | |
336 #endif | |
337 } | |
338 } |