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
14class ForthOutput {
15public:
16    virtual void show(const char output[]) = 0;
17};
18
19union FloatIntDual {
20    int32_t fInt;
21    float   fFloat;
22};
23
24static inline int32_t f2i_bits(float x) {
25    FloatIntDual d;
26    d.fFloat = x;
27    return d.fInt;
28}
29
30static inline float i2f_bits(int32_t x) {
31    FloatIntDual d;
32    d.fInt = x;
33    return d.fFloat;
34}
35
36class ForthEngine {
37public:
38    ForthEngine(ForthOutput*);
39    ~ForthEngine();
40
41    int         depth() const { return fStackStop - fStackCurr; }
42    void        clearStack() { fStackCurr = fStackStop; }
43
44    void        push(intptr_t value);
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
50    void        fpush(float value) { this->push(f2i_bits(value)); }
51    float       fpeek(size_t i) const { return i2f_bits(this->fpeek(i)); }
52    float       ftop() const { return i2f_bits(this->top()); }
53    void        fsetTop(float value) { this->setTop(f2i_bits(value)); }
54    float       fpop() { return i2f_bits(this->pop()); }
55
56    void sendOutput(const char text[]);
57
58private:
59    ForthOutput* fOutput;
60    intptr_t*   fStackBase;
61    intptr_t*   fStackCurr;
62    intptr_t*   fStackStop;
63
64    void signal_error(const char msg[]) const {
65        SkDebugf("ForthEngine error: %s\n", msg);
66    }
67};
68
69struct 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
77class ForthWord {
78public:
79    virtual ~ForthWord() {}
80    virtual void exec(ForthEngine*) = 0;
81
82    // todo: return error state of the engine
83    void call(ForthCallBlock*);
84};
85
86class ForthEnv {
87public:
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
100private:
101    class Impl;
102    Impl* fImpl;
103};
104
105#endif
106