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:
reed@android.com 2009-09-02 02:07:32 +00:00
parent e50025a656
commit de2e7fb96d
4 changed files with 235 additions and 20 deletions

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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);