experimental hack to write a forth engine to drive skia



git-svn-id: http://skia.googlecode.com/svn/trunk@343 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/forth/Forth.h b/forth/Forth.h
new file mode 100644
index 0000000..a68b219
--- /dev/null
+++ b/forth/Forth.h
@@ -0,0 +1,98 @@
+#ifndef Forth_DEFINED
+#define Forth_DEFINED
+
+#include "SkTypes.h"
+
+class ForthOutput {
+public:
+    virtual void show(const char output[]) = 0;
+};
+
+union FloatIntDual {
+    int32_t fInt;
+    float   fFloat;
+};
+
+static inline int32_t f2i_bits(float x) {
+    FloatIntDual d;
+    d.fFloat = x;
+    return d.fInt;
+}
+
+static inline float i2f_bits(int32_t x) {
+    FloatIntDual d;
+    d.fInt = x;
+    return d.fFloat;
+}
+
+class ForthEngine {
+public:
+    ForthEngine(ForthOutput*);
+    ~ForthEngine();
+
+    int         depth() const { return fStackStop - fStackCurr; }
+    void        clearStack() { fStackCurr = fStackStop; }
+
+    void        push(intptr_t value);
+    intptr_t    top() const { return this->peek(0); }
+    intptr_t    peek(size_t index) const;
+    void        setTop(intptr_t value);
+    intptr_t    pop();
+
+    void        fpush(float value) { this->push(f2i_bits(value)); }
+    float       fpeek(size_t i) const { return i2f_bits(this->fpeek(i)); }
+    float       ftop() const { return i2f_bits(this->top()); }
+    void        fsetTop(float value) { this->setTop(f2i_bits(value)); }
+    float       fpop() { return i2f_bits(this->pop()); }
+
+    void sendOutput(const char text[]);
+
+private:
+    ForthOutput* fOutput;
+    intptr_t*   fStackBase;
+    intptr_t*   fStackCurr;
+    intptr_t*   fStackStop;
+
+    void signal_error(const char msg[]) const {
+        SkDebugf("ForthEngine error: %s\n", msg);
+    }
+};
+
+struct ForthCallBlock {
+    const intptr_t* in_data;
+    size_t          in_count;
+    intptr_t*       out_data;
+    size_t          out_count;
+    size_t          out_depth;
+};
+
+class ForthWord {
+public:
+    virtual ~ForthWord() {}
+    virtual void exec(ForthEngine*) = 0;
+
+    // todo: return error state of the engine
+    void call(ForthCallBlock*);
+};
+
+class ForthEnv {
+public:
+    ForthEnv();
+    ~ForthEnv();
+
+
+    void addWord(const char name[], ForthWord*);
+
+    void parse(const char code[]);
+
+    ForthWord* findWord(const char name[]);
+
+    void run(ForthOutput* = NULL);
+
+private:
+    class Impl;
+    Impl* fImpl;
+};
+
+#endif
+