2009-09-01 21:00:44 +00:00
|
|
|
|
2009-08-29 21:30:25 +00:00
|
|
|
#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
|
|
|
|
|