more unittests (already found/fixed some bugs)
git-svn-id: http://skia.googlecode.com/svn/trunk@348 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/forth/ForthParser.h b/forth/ForthParser.h
index 9c939f8..65a39a1 100644
--- a/forth/ForthParser.h
+++ b/forth/ForthParser.h
@@ -2,6 +2,7 @@
#define ForthParser_DEFINED
#include "SkTDict.h"
+//#include "SkString.h"
class ForthWord;
class FCode;
@@ -18,6 +19,8 @@
}
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);
}
diff --git a/forth/ForthTests.cpp b/forth/ForthTests.cpp
index e918329..91ffaec 100644
--- a/forth/ForthTests.cpp
+++ b/forth/ForthTests.cpp
@@ -132,6 +132,198 @@
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 @@
{ "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 @@
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 @@
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);
}
}
diff --git a/forth/SampleForth.cpp b/forth/SampleForth.cpp
index 2877fb6..cfd1172 100644
--- a/forth/SampleForth.cpp
+++ b/forth/SampleForth.cpp
@@ -150,7 +150,7 @@
///////////////////////////////////////////////////////////////////////////////
-void Forth_test_stdwords();
+void Forth_test_stdwords(bool verbose);
class ForthView : public SkView {
ForthEnv fEnv;
@@ -160,7 +160,7 @@
SkForthCtx fContext;
public:
ForthView() {
- Forth_test_stdwords();
+ Forth_test_stdwords(false);
load_words(&fEnv, &fContext);
@@ -186,9 +186,6 @@
"draw1 "
);
#endif
- ForthEnv env;
- env.parse("3 5 = IF 42 . ELSE -42 . THEN 99 .");
- env.run();
}
protected:
diff --git a/forth/StdWords.cpp b/forth/StdWords.cpp
index 98e39c0..177dabd 100644
--- a/forth/StdWords.cpp
+++ b/forth/StdWords.cpp
@@ -77,11 +77,13 @@
///////////////// 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 @@
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);