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;
{ "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 },
};
///////////////////////////////////////////////////////////////////////////////
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;
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);
}
}
///////////////// 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) {
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);
-
- 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("+", add);
+ ADD_LITERAL_WORD("-", sub);
+ ADD_LITERAL_WORD("*", mul);
+ ADD_LITERAL_WORD("/", div);
+ ADD_LITERAL_WORD("MOD", mod);
+ ADD_LITERAL_WORD("/MOD", divmod);
+
+ 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);