~jammy-zhou/+junk/skia

« back to all changes in this revision

Viewing changes to forth/StdWords.cpp

  • Committer: Jammy Zhou
  • Date: 2010-11-05 22:47:35 UTC
  • Revision ID: jammy.zhou@linaro.org-20101105224735-i1miyqbyxwslg7t2
initial version (upstream r622)

http://code.google.com/p/skia/source/list

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Forth.h"
 
2
#include "ForthParser.h"
 
3
#include "SkString.h"
 
4
 
 
5
#define BEGIN_WORD(name)   \
 
6
    class name##_ForthWord : public ForthWord { \
 
7
    public:                                     \
 
8
        virtual void exec(ForthEngine* fe)
 
9
 
 
10
#define END_WORD };
 
11
 
 
12
///////////////////////////////////////////////////////////////////////////////
 
13
 
 
14
BEGIN_WORD(drop) {
 
15
    (void)fe->pop();
 
16
} END_WORD
 
17
 
 
18
BEGIN_WORD(over) {
 
19
    fe->push(fe->peek(1));
 
20
} END_WORD
 
21
 
 
22
BEGIN_WORD(dup) {
 
23
    fe->push(fe->top());
 
24
} END_WORD
 
25
 
 
26
BEGIN_WORD(swap) {
 
27
    intptr_t a = fe->pop();
 
28
    intptr_t b = fe->top();
 
29
    fe->setTop(a);
 
30
    fe->push(b);
 
31
} END_WORD
 
32
 
 
33
BEGIN_WORD(rot) {
 
34
    intptr_t c = fe->pop();
 
35
    intptr_t b = fe->pop();
 
36
    intptr_t a = fe->pop();
 
37
    fe->push(b);
 
38
    fe->push(c);
 
39
    fe->push(a);
 
40
} END_WORD
 
41
 
 
42
BEGIN_WORD(rrot) {
 
43
    intptr_t c = fe->pop();
 
44
    intptr_t b = fe->pop();
 
45
    intptr_t a = fe->pop();
 
46
    fe->push(c);
 
47
    fe->push(a);
 
48
    fe->push(b);
 
49
} END_WORD
 
50
 
 
51
BEGIN_WORD(swap2) {
 
52
    intptr_t d = fe->pop();
 
53
    intptr_t c = fe->pop();
 
54
    intptr_t b = fe->pop();
 
55
    intptr_t a = fe->pop();
 
56
    fe->push(c);
 
57
    fe->push(d);
 
58
    fe->push(a);
 
59
    fe->push(b);
 
60
} END_WORD
 
61
 
 
62
BEGIN_WORD(dup2) {
 
63
    fe->push(fe->peek(1));
 
64
    fe->push(fe->peek(1));
 
65
} END_WORD
 
66
 
 
67
BEGIN_WORD(over2) {
 
68
    fe->push(fe->peek(3));
 
69
    fe->push(fe->peek(3));
 
70
} END_WORD
 
71
 
 
72
BEGIN_WORD(drop2) {
 
73
    (void)fe->pop();
 
74
    (void)fe->pop();
 
75
} END_WORD
 
76
 
 
77
///////////////// logicals
 
78
 
 
79
BEGIN_WORD(logical_and) {
 
80
    intptr_t tmp = fe->pop();
 
81
    fe->setTop(-(tmp && fe->top()));
 
82
} END_WORD
 
83
 
 
84
BEGIN_WORD(logical_or) {
 
85
    intptr_t tmp = fe->pop();
 
86
    fe->setTop(-(tmp || fe->top()));
 
87
} END_WORD
 
88
 
 
89
BEGIN_WORD(logical_not) {
 
90
    fe->setTop(-(!fe->top()));
 
91
} END_WORD
 
92
 
 
93
BEGIN_WORD(if_dup) {
 
94
    intptr_t tmp = fe->top();
 
95
    if (tmp) {
 
96
        fe->push(tmp);
 
97
    }
 
98
} END_WORD
 
99
 
 
100
///////////////// ints
 
101
 
 
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);
 
106
    }};
 
107
 
 
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);
 
112
    }};
 
113
 
 
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);
 
118
    }};
 
119
 
 
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);
 
124
    }};
 
125
 
 
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);
 
130
    }};
 
131
 
 
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);
 
138
    }};
 
139
 
 
140
class dot_ForthWord : public ForthWord { public:
 
141
    virtual void exec(ForthEngine* fe) {
 
142
        SkString str;
 
143
        str.printf("%d ", fe->pop());
 
144
        fe->sendOutput(str.c_str());
 
145
    }};
 
146
 
 
147
class abs_ForthWord : public ForthWord { public:
 
148
    virtual void exec(ForthEngine* fe) {
 
149
        int32_t value = fe->top();
 
150
        if (value < 0) {
 
151
            fe->setTop(-value);
 
152
        }
 
153
    }};
 
154
 
 
155
class negate_ForthWord : public ForthWord { public:
 
156
    virtual void exec(ForthEngine* fe) {
 
157
        fe->setTop(-fe->top());
 
158
    }};
 
159
 
 
160
class min_ForthWord : public ForthWord { public:
 
161
    virtual void exec(ForthEngine* fe) {
 
162
        int32_t value = fe->pop();
 
163
        if (value < fe->top()) {
 
164
            fe->setTop(value);
 
165
        }
 
166
    }};
 
167
 
 
168
class max_ForthWord : public ForthWord {
 
169
public:
 
170
    virtual void exec(ForthEngine* fe) {
 
171
        int32_t value = fe->pop();
 
172
        if (value > fe->top()) {
 
173
            fe->setTop(value);
 
174
        }
 
175
    }
 
176
};
 
177
 
 
178
///////////////// floats
 
179
 
 
180
class fadd_ForthWord : public ForthWord {
 
181
public:
 
182
    virtual void exec(ForthEngine* fe) {
 
183
        float tmp = fe->fpop();
 
184
        fe->fsetTop(fe->ftop() + tmp);
 
185
    }
 
186
};
 
187
 
 
188
class fsub_ForthWord : public ForthWord {
 
189
public:
 
190
    virtual void exec(ForthEngine* fe) {
 
191
        float tmp = fe->fpop();
 
192
        fe->fsetTop(fe->ftop() - tmp);
 
193
    }
 
194
};
 
195
 
 
196
class fmul_ForthWord : public ForthWord {
 
197
public:
 
198
    virtual void exec(ForthEngine* fe) {
 
199
        float tmp = fe->fpop();
 
200
        fe->fsetTop(fe->ftop() * tmp);
 
201
    }
 
202
};
 
203
 
 
204
class fdiv_ForthWord : public ForthWord {
 
205
public:
 
206
    virtual void exec(ForthEngine* fe) {
 
207
        float tmp = fe->fpop();
 
208
        fe->fsetTop(fe->ftop() / tmp);
 
209
    }
 
210
};
 
211
 
 
212
class fdot_ForthWord : public ForthWord {
 
213
public:
 
214
    virtual void exec(ForthEngine* fe) {
 
215
        SkString str;
 
216
        str.printf("%g ", fe->fpop());
 
217
        fe->sendOutput(str.c_str());
 
218
    }
 
219
};
 
220
 
 
221
class fabs_ForthWord : public ForthWord {
 
222
public:
 
223
    virtual void exec(ForthEngine* fe) {
 
224
        float value = fe->ftop();
 
225
        if (value < 0) {
 
226
            fe->fsetTop(-value);
 
227
        }
 
228
    }
 
229
};
 
230
 
 
231
class fmin_ForthWord : public ForthWord {
 
232
public:
 
233
    virtual void exec(ForthEngine* fe) {
 
234
        float value = fe->fpop();
 
235
        if (value < fe->ftop()) {
 
236
            fe->fsetTop(value);
 
237
        }
 
238
    }
 
239
};
 
240
 
 
241
class fmax_ForthWord : public ForthWord {
 
242
public:
 
243
    virtual void exec(ForthEngine* fe) {
 
244
        float value = fe->fpop();
 
245
        if (value > fe->ftop()) {
 
246
            fe->fsetTop(value);
 
247
        }
 
248
    }
 
249
};
 
250
 
 
251
class floor_ForthWord : public ForthWord {
 
252
public:
 
253
    virtual void exec(ForthEngine* fe) {
 
254
        fe->fsetTop(floorf(fe->ftop()));
 
255
    }
 
256
};
 
257
 
 
258
class ceil_ForthWord : public ForthWord {
 
259
public:
 
260
    virtual void exec(ForthEngine* fe) {
 
261
        fe->fsetTop(ceilf(fe->ftop()));
 
262
    }
 
263
};
 
264
 
 
265
class round_ForthWord : public ForthWord {
 
266
public:
 
267
    virtual void exec(ForthEngine* fe) {
 
268
        fe->fsetTop(floorf(fe->ftop() + 0.5f));
 
269
    }
 
270
};
 
271
 
 
272
class f2i_ForthWord : public ForthWord {
 
273
public:
 
274
    virtual void exec(ForthEngine* fe) {
 
275
        fe->setTop((int)fe->ftop());
 
276
    }
 
277
};
 
278
 
 
279
class i2f_ForthWord : public ForthWord {
 
280
public:
 
281
    virtual void exec(ForthEngine* fe) {
 
282
        fe->fsetTop((float)fe->top());
 
283
    }
 
284
};
 
285
 
 
286
////////////////////////////// int compares
 
287
 
 
288
class eq_ForthWord : public ForthWord { public:
 
289
    virtual void exec(ForthEngine* fe) {
 
290
        fe->push(-(fe->pop() == fe->pop()));
 
291
    }
 
292
};
 
293
 
 
294
class neq_ForthWord : public ForthWord { public:
 
295
    virtual void exec(ForthEngine* fe) {
 
296
        fe->push(-(fe->pop() != fe->pop()));
 
297
    }
 
298
};
 
299
 
 
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));
 
304
    }
 
305
};
 
306
 
 
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));
 
311
    }
 
312
};
 
313
 
 
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));
 
318
    }
 
319
};
 
320
 
 
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));
 
325
    }
 
326
};
 
327
 
 
328
BEGIN_WORD(lt0) {
 
329
    fe->setTop(fe->top() >> 31);
 
330
} END_WORD
 
331
 
 
332
BEGIN_WORD(ge0) {
 
333
    fe->setTop(~(fe->top() >> 31));
 
334
} END_WORD
 
335
 
 
336
BEGIN_WORD(gt0) {
 
337
    fe->setTop(-(fe->top() > 0));
 
338
} END_WORD
 
339
 
 
340
BEGIN_WORD(le0) {
 
341
    fe->setTop(-(fe->top() <= 0));
 
342
} END_WORD
 
343
 
 
344
/////////////////////////////// float compares
 
345
 
 
346
/*  negative zero is our nemesis, otherwise we could use = and <> from ints */
 
347
 
 
348
class feq_ForthWord : public ForthWord { public:
 
349
    virtual void exec(ForthEngine* fe) {
 
350
        fe->push(-(fe->fpop() == fe->fpop()));
 
351
    }
 
352
};
 
353
 
 
354
class fneq_ForthWord : public ForthWord { public:
 
355
    virtual void exec(ForthEngine* fe) {
 
356
        fe->push(-(fe->fpop() != fe->fpop()));
 
357
    }
 
358
};
 
359
 
 
360
class flt_ForthWord : public ForthWord { public:
 
361
    virtual void exec(ForthEngine* fe) {
 
362
        float tmp = fe->fpop();
 
363
        fe->setTop(-(fe->ftop() < tmp));
 
364
    }
 
365
};
 
366
 
 
367
class fle_ForthWord : public ForthWord { public:
 
368
    virtual void exec(ForthEngine* fe) {
 
369
        float tmp = fe->fpop();
 
370
        fe->setTop(-(fe->ftop() <= tmp));
 
371
    }
 
372
};
 
373
 
 
374
class fgt_ForthWord : public ForthWord { public:
 
375
    virtual void exec(ForthEngine* fe) {
 
376
        float tmp = fe->fpop();
 
377
        fe->setTop(-(fe->ftop() > tmp));
 
378
    }
 
379
};
 
380
 
 
381
class fge_ForthWord : public ForthWord { public:
 
382
    virtual void exec(ForthEngine* fe) {
 
383
        float tmp = fe->fpop();
 
384
        fe->setTop(-(fe->ftop() >= tmp));
 
385
    }
 
386
};
 
387
 
 
388
///////////////////////////////////////////////////////////////////////////////
 
389
 
 
390
#define ADD_LITERAL_WORD(sym, name) \
 
391
    this->add(sym, sizeof(sym)-1, new name##_ForthWord)
 
392
 
 
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);
 
404
    
 
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);
 
411
 
 
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);
 
417
 
 
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);
 
422
 
 
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);
 
437
 
 
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);
 
448
    
 
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);
 
455
}
 
456