996
|
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 }
|