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 }