more unittests (already found/fixed some bugs)
authorreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 2 Sep 2009 02:07:32 +0000 (02:07 +0000)
committerreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 2 Sep 2009 02:07:32 +0000 (02:07 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@348 2bbb7eff-a529-9590-31e7-b0007b416f81

forth/ForthParser.h
forth/ForthTests.cpp
forth/SampleForth.cpp
forth/StdWords.cpp

index 9c939f83dbf2eecc86d0144018a2b4eb453de4c5..65a39a1a0fa25a1b1eef1c23296a51e2a95ddc75 100644 (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);
     }
 
index e9183290c6a54332fd253ae4b04869630579656b..91ffaece4a46e2972c559e8bf7823e19a514a652 100644 (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);
         }
     }
index 2877fb66d487feea14e3c8454f139a737de568b4..cfd1172d67457243b2453cb1cf8e67a2aa697926 100644 (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:
index 98e39c028d6d9a095016a6dfbe9cf97a7e3ecbc3..177dabd5b811332577345ea2ba1ab3c2d7e8482f 100644 (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);
-
-    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);