2
#include "ForthParser.h"
5
#define BEGIN_WORD(name) \
6
class name##_ForthWord : public ForthWord { \
8
virtual void exec(ForthEngine* fe)
12
///////////////////////////////////////////////////////////////////////////////
19
fe->push(fe->peek(1));
27
intptr_t a = fe->pop();
28
intptr_t b = fe->top();
34
intptr_t c = fe->pop();
35
intptr_t b = fe->pop();
36
intptr_t a = fe->pop();
43
intptr_t c = fe->pop();
44
intptr_t b = fe->pop();
45
intptr_t a = fe->pop();
52
intptr_t d = fe->pop();
53
intptr_t c = fe->pop();
54
intptr_t b = fe->pop();
55
intptr_t a = fe->pop();
63
fe->push(fe->peek(1));
64
fe->push(fe->peek(1));
68
fe->push(fe->peek(3));
69
fe->push(fe->peek(3));
77
///////////////// logicals
79
BEGIN_WORD(logical_and) {
80
intptr_t tmp = fe->pop();
81
fe->setTop(-(tmp && fe->top()));
84
BEGIN_WORD(logical_or) {
85
intptr_t tmp = fe->pop();
86
fe->setTop(-(tmp || fe->top()));
89
BEGIN_WORD(logical_not) {
90
fe->setTop(-(!fe->top()));
94
intptr_t tmp = fe->top();
100
///////////////// ints
102
class add_ForthWord : public ForthWord { public:
103
virtual void exec(ForthEngine* fe) {
104
intptr_t tmp = fe->pop();
105
fe->setTop(fe->top() + tmp);
108
class sub_ForthWord : public ForthWord { public:
109
virtual void exec(ForthEngine* fe) {
110
intptr_t tmp = fe->pop();
111
fe->setTop(fe->top() - tmp);
114
class mul_ForthWord : public ForthWord { public:
115
virtual void exec(ForthEngine* fe) {
116
intptr_t tmp = fe->pop();
117
fe->setTop(fe->top() * tmp);
120
class div_ForthWord : public ForthWord { public:
121
virtual void exec(ForthEngine* fe) {
122
intptr_t tmp = fe->pop();
123
fe->setTop(fe->top() / tmp);
126
class mod_ForthWord : public ForthWord { public:
127
virtual void exec(ForthEngine* fe) {
128
intptr_t tmp = fe->pop();
129
fe->setTop(fe->top() % tmp);
132
class divmod_ForthWord : public ForthWord { public:
133
virtual void exec(ForthEngine* fe) {
134
intptr_t denom = fe->pop();
135
intptr_t numer = fe->pop();
136
fe->push(numer % denom);
137
fe->push(numer / denom);
140
class dot_ForthWord : public ForthWord { public:
141
virtual void exec(ForthEngine* fe) {
143
str.printf("%d ", fe->pop());
144
fe->sendOutput(str.c_str());
147
class abs_ForthWord : public ForthWord { public:
148
virtual void exec(ForthEngine* fe) {
149
int32_t value = fe->top();
155
class negate_ForthWord : public ForthWord { public:
156
virtual void exec(ForthEngine* fe) {
157
fe->setTop(-fe->top());
160
class min_ForthWord : public ForthWord { public:
161
virtual void exec(ForthEngine* fe) {
162
int32_t value = fe->pop();
163
if (value < fe->top()) {
168
class max_ForthWord : public ForthWord {
170
virtual void exec(ForthEngine* fe) {
171
int32_t value = fe->pop();
172
if (value > fe->top()) {
178
///////////////// floats
180
class fadd_ForthWord : public ForthWord {
182
virtual void exec(ForthEngine* fe) {
183
float tmp = fe->fpop();
184
fe->fsetTop(fe->ftop() + tmp);
188
class fsub_ForthWord : public ForthWord {
190
virtual void exec(ForthEngine* fe) {
191
float tmp = fe->fpop();
192
fe->fsetTop(fe->ftop() - tmp);
196
class fmul_ForthWord : public ForthWord {
198
virtual void exec(ForthEngine* fe) {
199
float tmp = fe->fpop();
200
fe->fsetTop(fe->ftop() * tmp);
204
class fdiv_ForthWord : public ForthWord {
206
virtual void exec(ForthEngine* fe) {
207
float tmp = fe->fpop();
208
fe->fsetTop(fe->ftop() / tmp);
212
class fdot_ForthWord : public ForthWord {
214
virtual void exec(ForthEngine* fe) {
216
str.printf("%g ", fe->fpop());
217
fe->sendOutput(str.c_str());
221
class fabs_ForthWord : public ForthWord {
223
virtual void exec(ForthEngine* fe) {
224
float value = fe->ftop();
231
class fmin_ForthWord : public ForthWord {
233
virtual void exec(ForthEngine* fe) {
234
float value = fe->fpop();
235
if (value < fe->ftop()) {
241
class fmax_ForthWord : public ForthWord {
243
virtual void exec(ForthEngine* fe) {
244
float value = fe->fpop();
245
if (value > fe->ftop()) {
251
class floor_ForthWord : public ForthWord {
253
virtual void exec(ForthEngine* fe) {
254
fe->fsetTop(floorf(fe->ftop()));
258
class ceil_ForthWord : public ForthWord {
260
virtual void exec(ForthEngine* fe) {
261
fe->fsetTop(ceilf(fe->ftop()));
265
class round_ForthWord : public ForthWord {
267
virtual void exec(ForthEngine* fe) {
268
fe->fsetTop(floorf(fe->ftop() + 0.5f));
272
class f2i_ForthWord : public ForthWord {
274
virtual void exec(ForthEngine* fe) {
275
fe->setTop((int)fe->ftop());
279
class i2f_ForthWord : public ForthWord {
281
virtual void exec(ForthEngine* fe) {
282
fe->fsetTop((float)fe->top());
286
////////////////////////////// int compares
288
class eq_ForthWord : public ForthWord { public:
289
virtual void exec(ForthEngine* fe) {
290
fe->push(-(fe->pop() == fe->pop()));
294
class neq_ForthWord : public ForthWord { public:
295
virtual void exec(ForthEngine* fe) {
296
fe->push(-(fe->pop() != fe->pop()));
300
class lt_ForthWord : public ForthWord { public:
301
virtual void exec(ForthEngine* fe) {
302
intptr_t tmp = fe->pop();
303
fe->setTop(-(fe->top() < tmp));
307
class le_ForthWord : public ForthWord { public:
308
virtual void exec(ForthEngine* fe) {
309
intptr_t tmp = fe->pop();
310
fe->setTop(-(fe->top() <= tmp));
314
class gt_ForthWord : public ForthWord { public:
315
virtual void exec(ForthEngine* fe) {
316
intptr_t tmp = fe->pop();
317
fe->setTop(-(fe->top() > tmp));
321
class ge_ForthWord : public ForthWord { public:
322
virtual void exec(ForthEngine* fe) {
323
intptr_t tmp = fe->pop();
324
fe->setTop(-(fe->top() >= tmp));
329
fe->setTop(fe->top() >> 31);
333
fe->setTop(~(fe->top() >> 31));
337
fe->setTop(-(fe->top() > 0));
341
fe->setTop(-(fe->top() <= 0));
344
/////////////////////////////// float compares
346
/* negative zero is our nemesis, otherwise we could use = and <> from ints */
348
class feq_ForthWord : public ForthWord { public:
349
virtual void exec(ForthEngine* fe) {
350
fe->push(-(fe->fpop() == fe->fpop()));
354
class fneq_ForthWord : public ForthWord { public:
355
virtual void exec(ForthEngine* fe) {
356
fe->push(-(fe->fpop() != fe->fpop()));
360
class flt_ForthWord : public ForthWord { public:
361
virtual void exec(ForthEngine* fe) {
362
float tmp = fe->fpop();
363
fe->setTop(-(fe->ftop() < tmp));
367
class fle_ForthWord : public ForthWord { public:
368
virtual void exec(ForthEngine* fe) {
369
float tmp = fe->fpop();
370
fe->setTop(-(fe->ftop() <= tmp));
374
class fgt_ForthWord : public ForthWord { public:
375
virtual void exec(ForthEngine* fe) {
376
float tmp = fe->fpop();
377
fe->setTop(-(fe->ftop() > tmp));
381
class fge_ForthWord : public ForthWord { public:
382
virtual void exec(ForthEngine* fe) {
383
float tmp = fe->fpop();
384
fe->setTop(-(fe->ftop() >= tmp));
388
///////////////////////////////////////////////////////////////////////////////
390
#define ADD_LITERAL_WORD(sym, name) \
391
this->add(sym, sizeof(sym)-1, new name##_ForthWord)
393
void ForthParser::addStdWords() {
394
ADD_LITERAL_WORD("DROP", drop);
395
ADD_LITERAL_WORD("DUP", dup);
396
ADD_LITERAL_WORD("SWAP", swap);
397
ADD_LITERAL_WORD("OVER", over);
398
ADD_LITERAL_WORD("ROT", rot);
399
ADD_LITERAL_WORD("-ROT", rrot);
400
ADD_LITERAL_WORD("2SWAP", swap2);
401
ADD_LITERAL_WORD("2DUP", dup2);
402
ADD_LITERAL_WORD("2OVER", over2);
403
ADD_LITERAL_WORD("2DROP", drop2);
405
ADD_LITERAL_WORD("+", add);
406
ADD_LITERAL_WORD("-", sub);
407
ADD_LITERAL_WORD("*", mul);
408
ADD_LITERAL_WORD("/", div);
409
ADD_LITERAL_WORD("MOD", mod);
410
ADD_LITERAL_WORD("/MOD", divmod);
412
ADD_LITERAL_WORD(".", dot);
413
ADD_LITERAL_WORD("ABS", abs);
414
ADD_LITERAL_WORD("NEGATE", negate);
415
ADD_LITERAL_WORD("MIN", min);
416
ADD_LITERAL_WORD("MAX", max);
418
ADD_LITERAL_WORD("AND", logical_and);
419
ADD_LITERAL_WORD("OR", logical_or);
420
ADD_LITERAL_WORD("0=", logical_not);
421
ADD_LITERAL_WORD("?DUP", if_dup);
423
this->add("f+", 2, new fadd_ForthWord);
424
this->add("f-", 2, new fsub_ForthWord);
425
this->add("f*", 2, new fmul_ForthWord);
426
this->add("f/", 2, new fdiv_ForthWord);
427
this->add("f.", 2, new fdot_ForthWord);
428
this->add("fabs", 4, new fabs_ForthWord);
429
this->add("fmin", 4, new fmin_ForthWord);
430
this->add("fmax", 4, new fmax_ForthWord);
431
this->add("fmax", 4, new fmax_ForthWord);
432
this->add("floor", 5, new floor_ForthWord);
433
this->add("ceil", 4, new ceil_ForthWord);
434
this->add("round", 5, new round_ForthWord);
435
this->add("f>i", 3, new f2i_ForthWord);
436
this->add("i>f", 3, new i2f_ForthWord);
438
this->add("=", 1, new eq_ForthWord);
439
this->add("<>", 2, new neq_ForthWord);
440
this->add("<", 1, new lt_ForthWord);
441
this->add("<=", 2, new le_ForthWord);
442
this->add(">", 1, new gt_ForthWord);
443
this->add(">=", 2, new ge_ForthWord);
444
ADD_LITERAL_WORD("0<", lt0);
445
ADD_LITERAL_WORD("0>", gt0);
446
ADD_LITERAL_WORD("0<=", le0);
447
ADD_LITERAL_WORD("0>=", ge0);
449
this->add("f=", 2, new feq_ForthWord);
450
this->add("f<>", 3, new fneq_ForthWord);
451
this->add("f<", 2, new flt_ForthWord);
452
this->add("f<=", 3, new fle_ForthWord);
453
this->add("f>", 2, new fgt_ForthWord);
454
this->add("f>=", 3, new fge_ForthWord);