1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #ifndef Forth_DEFINED
10 #define Forth_DEFINED
11 
12 #include "SkTypes.h"
13 
14 class ForthOutput {
15 public:
16     virtual void show(const char output[]) = 0;
17 };
18 
19 union FloatIntDual {
20     int32_t fInt;
21     float   fFloat;
22 };
23 
f2i_bits(float x)24 static inline int32_t f2i_bits(float x) {
25     FloatIntDual d;
26     d.fFloat = x;
27     return d.fInt;
28 }
29 
i2f_bits(int32_t x)30 static inline float i2f_bits(int32_t x) {
31     FloatIntDual d;
32     d.fInt = x;
33     return d.fFloat;
34 }
35 
36 class ForthEngine {
37 public:
38     ForthEngine(ForthOutput*);
39     ~ForthEngine();
40 
depth()41     int         depth() const { return fStackStop - fStackCurr; }
clearStack()42     void        clearStack() { fStackCurr = fStackStop; }
43 
44     void        push(intptr_t value);
top()45     intptr_t    top() const { return this->peek(0); }
46     intptr_t    peek(size_t index) const;
47     void        setTop(intptr_t value);
48     intptr_t    pop();
49 
fpush(float value)50     void        fpush(float value) { this->push(f2i_bits(value)); }
fpeek(size_t i)51     float       fpeek(size_t i) const { return i2f_bits(this->fpeek(i)); }
ftop()52     float       ftop() const { return i2f_bits(this->top()); }
fsetTop(float value)53     void        fsetTop(float value) { this->setTop(f2i_bits(value)); }
fpop()54     float       fpop() { return i2f_bits(this->pop()); }
55 
56     void sendOutput(const char text[]);
57 
58 private:
59     ForthOutput* fOutput;
60     intptr_t*   fStackBase;
61     intptr_t*   fStackCurr;
62     intptr_t*   fStackStop;
63 
signal_error(const char msg[])64     void signal_error(const char msg[]) const {
65         SkDebugf("ForthEngine error: %s\n", msg);
66     }
67 };
68 
69 struct ForthCallBlock {
70     const intptr_t* in_data;
71     size_t          in_count;
72     intptr_t*       out_data;
73     size_t          out_count;
74     size_t          out_depth;
75 };
76 
77 class ForthWord {
78 public:
~ForthWord()79     virtual ~ForthWord() {}
80     virtual void exec(ForthEngine*) = 0;
81 
82     // todo: return error state of the engine
83     void call(ForthCallBlock*);
84 };
85 
86 class ForthEnv {
87 public:
88     ForthEnv();
89     ~ForthEnv();
90 
91 
92     void addWord(const char name[], ForthWord*);
93 
94     void parse(const char code[]);
95 
96     ForthWord* findWord(const char name[]);
97 
98     void run(ForthOutput* = NULL);
99 
100 private:
101     class Impl;
102     Impl* fImpl;
103 };
104 
105 #endif
106