aboutsummaryrefslogtreecommitdiffhomepage
path: root/forth/Forth.h
blob: f6df06e1ebeb32fd6ad456c22a3ca48d9057a60d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#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