more unittests (already found/fixed some bugs)
git-svn-id: http://skia.googlecode.com/svn/trunk@348 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
e50025a656
commit
de2e7fb96d
@ -2,6 +2,7 @@
|
||||
#define ForthParser_DEFINED
|
||||
|
||||
#include "SkTDict.h"
|
||||
//#include "SkString.h"
|
||||
|
||||
class ForthWord;
|
||||
class FCode;
|
||||
@ -18,6 +19,8 @@ public:
|
||||
}
|
||||
|
||||
void add(const char name[], size_t len, ForthWord* word) {
|
||||
// SkString str(name, len);
|
||||
// SkDebugf("add %s %p\n", str.c_str(), word);
|
||||
(void)fDict.set(name, len, word);
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,198 @@ static void drop2_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
FORTH_ASSERT(reporter, 2 == fe->peek(0));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void iadd_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(35);
|
||||
fe->push(99);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 134 == fe->top());
|
||||
fe->push(-135);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, -1 == fe->top());
|
||||
}
|
||||
|
||||
static void isub_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(35);
|
||||
fe->push(99);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 35-99 == fe->top());
|
||||
}
|
||||
|
||||
static void imul_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(15);
|
||||
fe->push(-20);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, -300 == fe->top());
|
||||
fe->push(0);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 0 == fe->top());
|
||||
}
|
||||
|
||||
static void idiv_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(100);
|
||||
fe->push(25);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 4 == fe->top());
|
||||
fe->setTop(10);
|
||||
fe->push(-3);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, -3 == fe->top());
|
||||
fe->setTop(-1);
|
||||
fe->push(-1);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 1 == fe->top());
|
||||
}
|
||||
|
||||
static void imod_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
fe->push(3);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 1 == fe->top());
|
||||
fe->push(5);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 1 == fe->top());
|
||||
}
|
||||
|
||||
static void idivmod_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
fe->push(3);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 2 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 1 == fe->peek(1));
|
||||
FORTH_ASSERT(reporter, 3 == fe->peek(0));
|
||||
}
|
||||
|
||||
static void idot_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(1);
|
||||
fe->push(2);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 1 == fe->top());
|
||||
}
|
||||
|
||||
static void iabs_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 10 == fe->top());
|
||||
fe->setTop(-10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 10 == fe->top());
|
||||
}
|
||||
|
||||
static void inegate_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, -10 == fe->top());
|
||||
fe->setTop(-10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 10 == fe->top());
|
||||
}
|
||||
|
||||
static void imin_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
fe->push(3);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 3 == fe->top());
|
||||
fe->push(-10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, -10 == fe->top());
|
||||
}
|
||||
|
||||
static void imax_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
fe->push(3);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 10 == fe->top());
|
||||
fe->push(-10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 10 == fe->top());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void logical_and_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
const static int data[] = {
|
||||
0, 0, 0,
|
||||
2, 0, 0,
|
||||
0, -1, 0,
|
||||
1, 5, -1
|
||||
};
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(data)/3; i++) {
|
||||
fe->push(data[i*3 + 0]);
|
||||
fe->push(data[i*3 + 1]);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, data[i*3 + 2] == fe->top());
|
||||
fe->pop();
|
||||
}
|
||||
}
|
||||
|
||||
static void logical_or_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
const static int data[] = {
|
||||
0, 0, 0,
|
||||
2, 0, -1,
|
||||
0, -1, -1,
|
||||
1, 5, -1
|
||||
};
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(data)/3; i++) {
|
||||
fe->push(data[i*3 + 0]);
|
||||
fe->push(data[i*3 + 1]);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, data[i*3 + 2] == fe->top());
|
||||
fe->pop();
|
||||
}
|
||||
}
|
||||
|
||||
static void logical_not_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
const static int data[] = {
|
||||
0, -1,
|
||||
5, 0,
|
||||
-1, 0
|
||||
};
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(data)/2; i++) {
|
||||
fe->push(data[i*2 + 0]);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, data[i*2 + 1] == fe->top());
|
||||
fe->pop();
|
||||
}
|
||||
}
|
||||
|
||||
static void if_dup_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
|
||||
fe->push(10);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 2 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 10 == fe->peek(1));
|
||||
FORTH_ASSERT(reporter, 10 == fe->peek(0));
|
||||
fe->pop();
|
||||
fe->pop();
|
||||
fe->push(0);
|
||||
word->exec(fe);
|
||||
FORTH_ASSERT(reporter, 1 == fe->depth());
|
||||
FORTH_ASSERT(reporter, 0 == fe->top());
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char* fName;
|
||||
ForthWordTestProc fProc;
|
||||
@ -146,6 +338,24 @@ static const struct {
|
||||
{ "2DUP", dup2_test },
|
||||
{ "2OVER", over2_test },
|
||||
{ "2DROP", drop2_test },
|
||||
|
||||
{ "+", iadd_test },
|
||||
{ "-", isub_test },
|
||||
{ "*", imul_test },
|
||||
{ "/", idiv_test },
|
||||
{ "MOD", imod_test },
|
||||
{ "/MOD", idivmod_test },
|
||||
|
||||
// { ".", idot_test },
|
||||
{ "ABS", iabs_test },
|
||||
{ "NEGATE", inegate_test },
|
||||
{ "MIN", imin_test },
|
||||
{ "MAX", imax_test },
|
||||
|
||||
{ "AND", logical_and_test },
|
||||
{ "OR", logical_or_test },
|
||||
{ "0=", logical_not_test },
|
||||
{ "?DUP", if_dup_test },
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -161,8 +371,8 @@ void Reporter::reportFailure(const char msg[]) {
|
||||
fFailureCount += 1;
|
||||
}
|
||||
|
||||
void Forth_test_stdwords();
|
||||
void Forth_test_stdwords() {
|
||||
void Forth_test_stdwords(bool verbose);
|
||||
void Forth_test_stdwords(bool verbose) {
|
||||
ForthEnv env;
|
||||
Reporter reporter;
|
||||
|
||||
@ -175,6 +385,9 @@ void Forth_test_stdwords() {
|
||||
str.printf("--- can't find stdword %d", gRecs[i].fName);
|
||||
reporter.reportFailure(str.c_str());
|
||||
} else {
|
||||
if (verbose) {
|
||||
SkDebugf("--- testing %s %p\n", gRecs[i].fName, word);
|
||||
}
|
||||
gRecs[i].fProc(word, &engine, &reporter);
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ static void load_words(ForthEnv* env, SkForthCtx* ctx) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Forth_test_stdwords();
|
||||
void Forth_test_stdwords(bool verbose);
|
||||
|
||||
class ForthView : public SkView {
|
||||
ForthEnv fEnv;
|
||||
@ -160,7 +160,7 @@ class ForthView : public SkView {
|
||||
SkForthCtx fContext;
|
||||
public:
|
||||
ForthView() {
|
||||
Forth_test_stdwords();
|
||||
Forth_test_stdwords(false);
|
||||
|
||||
load_words(&fEnv, &fContext);
|
||||
|
||||
@ -186,9 +186,6 @@ public:
|
||||
"draw1 "
|
||||
);
|
||||
#endif
|
||||
ForthEnv env;
|
||||
env.parse("3 5 = IF 42 . ELSE -42 . THEN 99 .");
|
||||
env.run();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -77,11 +77,13 @@ BEGIN_WORD(drop2) {
|
||||
///////////////// logicals
|
||||
|
||||
BEGIN_WORD(logical_and) {
|
||||
fe->push(-(fe->pop() && fe->pop()));
|
||||
intptr_t tmp = fe->pop();
|
||||
fe->setTop(-(tmp && fe->top()));
|
||||
} END_WORD
|
||||
|
||||
BEGIN_WORD(logical_or) {
|
||||
fe->push(-(fe->pop() || fe->pop()));
|
||||
intptr_t tmp = fe->pop();
|
||||
fe->setTop(-(tmp || fe->top()));
|
||||
} END_WORD
|
||||
|
||||
BEGIN_WORD(logical_not) {
|
||||
@ -400,18 +402,18 @@ void ForthParser::addStdWords() {
|
||||
ADD_LITERAL_WORD("2OVER", over2);
|
||||
ADD_LITERAL_WORD("2DROP", drop2);
|
||||
|
||||
this->add("+", 1, new add_ForthWord);
|
||||
this->add("-", 1, new sub_ForthWord);
|
||||
this->add("*", 1, new mul_ForthWord);
|
||||
this->add("/", 1, new div_ForthWord);
|
||||
this->add("MOD", 1, new mod_ForthWord);
|
||||
this->add("/MOD", 1, new divmod_ForthWord);
|
||||
ADD_LITERAL_WORD("+", add);
|
||||
ADD_LITERAL_WORD("-", sub);
|
||||
ADD_LITERAL_WORD("*", mul);
|
||||
ADD_LITERAL_WORD("/", div);
|
||||
ADD_LITERAL_WORD("MOD", mod);
|
||||
ADD_LITERAL_WORD("/MOD", divmod);
|
||||
|
||||
this->add(".", 1, new dot_ForthWord);
|
||||
this->add("ABS", 3, new abs_ForthWord);
|
||||
this->add("NEGATE", 3, new negate_ForthWord);
|
||||
this->add("MIN", 3, new min_ForthWord);
|
||||
this->add("MAX", 3, new max_ForthWord);
|
||||
ADD_LITERAL_WORD(".", dot);
|
||||
ADD_LITERAL_WORD("ABS", abs);
|
||||
ADD_LITERAL_WORD("NEGATE", negate);
|
||||
ADD_LITERAL_WORD("MIN", min);
|
||||
ADD_LITERAL_WORD("MAX", max);
|
||||
|
||||
ADD_LITERAL_WORD("AND", logical_and);
|
||||
ADD_LITERAL_WORD("OR", logical_or);
|
||||
|
Loading…
Reference in New Issue
Block a user