1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8e50025a656005c4000fb55647373475eb5dfda54reed@android.com#include "Forth.h"
9e50025a656005c4000fb55647373475eb5dfda54reed@android.com#include "SkString.h"
10e50025a656005c4000fb55647373475eb5dfda54reed@android.com
11e50025a656005c4000fb55647373475eb5dfda54reed@android.comclass Reporter {
12e50025a656005c4000fb55647373475eb5dfda54reed@android.compublic:
13e50025a656005c4000fb55647373475eb5dfda54reed@android.com    int fFailureCount;
14e50025a656005c4000fb55647373475eb5dfda54reed@android.com
15e50025a656005c4000fb55647373475eb5dfda54reed@android.com    Reporter() : fFailureCount(0) {}
16e50025a656005c4000fb55647373475eb5dfda54reed@android.com    void reportFailure(const char expression[], const char file[], int line);
17e50025a656005c4000fb55647373475eb5dfda54reed@android.com    void reportFailure(const char msg[]);
18e50025a656005c4000fb55647373475eb5dfda54reed@android.com};
19fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
20e50025a656005c4000fb55647373475eb5dfda54reed@android.comtypedef void (*ForthWordTestProc)(ForthWord*, ForthEngine*, Reporter*);
21e50025a656005c4000fb55647373475eb5dfda54reed@android.com
22e50025a656005c4000fb55647373475eb5dfda54reed@android.com#define FORTH_ASSERT(reporter, expression)      \
23e50025a656005c4000fb55647373475eb5dfda54reed@android.com    do {                                        \
24e50025a656005c4000fb55647373475eb5dfda54reed@android.com        if (!(expression)) {                    \
25e50025a656005c4000fb55647373475eb5dfda54reed@android.com            reporter->reportFailure(#expression, __FILE__, __LINE__);   \
26e50025a656005c4000fb55647373475eb5dfda54reed@android.com        }                                       \
27e50025a656005c4000fb55647373475eb5dfda54reed@android.com    } while (0)
28e50025a656005c4000fb55647373475eb5dfda54reed@android.com
29e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void drop_test0(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
30e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(-17);
31e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
32e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 0 == fe->depth());
33e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
34e50025a656005c4000fb55647373475eb5dfda54reed@android.com
35e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void drop_test1(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
36e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(-17);
37e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(93);
38e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
39e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
40e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, -17 == fe->peek(0));
41e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
42e50025a656005c4000fb55647373475eb5dfda54reed@android.com
43e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void dup_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
44e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(-17);
45e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
46e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->depth());
47e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, -17 == fe->peek(0));
48e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, -17 == fe->peek(1));
49e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
50e50025a656005c4000fb55647373475eb5dfda54reed@android.com
51e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void swap_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
52e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(-17);
53e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(42);
54e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
55e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->depth());
56e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, -17 == fe->peek(0));
57e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 42 == fe->peek(1));
58e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
59e50025a656005c4000fb55647373475eb5dfda54reed@android.com
60e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void over_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
61e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
62e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
63e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
64e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->depth());
65e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(0));
66e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(1));
67e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(2));
68e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
69e50025a656005c4000fb55647373475eb5dfda54reed@android.com
70e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void rot_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
71e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
72e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
73e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(3);
74e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
75e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->depth());
76e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(2));
77e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->peek(1));
78e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(0));
79e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
80e50025a656005c4000fb55647373475eb5dfda54reed@android.com
81e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void rrot_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
82e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
83e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
84e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(3);
85e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
86e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->depth());
87e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(0));
88e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(1));
89e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->peek(2));
90e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
91e50025a656005c4000fb55647373475eb5dfda54reed@android.com
92e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void swap2_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
93e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
94e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
95e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(3);
96e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(4);
97e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
98e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 4 == fe->depth());
99e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(0));
100e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(1));
101e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 4 == fe->peek(2));
102e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->peek(3));
103e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
104e50025a656005c4000fb55647373475eb5dfda54reed@android.com
105e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void dup2_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
106e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
107e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
108e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
109e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 4 == fe->depth());
110e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(3));
111e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(2));
112e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(1));
113e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(0));
114e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
115e50025a656005c4000fb55647373475eb5dfda54reed@android.com
116e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void over2_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
117e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
118e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
119e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(3);
120e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(4);
121e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
122e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 6 == fe->depth());
123e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(5));
124e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(4));
125e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 3 == fe->peek(3));
126e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 4 == fe->peek(2));
127e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(1));
128e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(0));
129e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
130e50025a656005c4000fb55647373475eb5dfda54reed@android.com
131e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic void drop2_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
132e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(1);
133e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(2);
134e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(3);
135e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fe->push(4);
136e50025a656005c4000fb55647373475eb5dfda54reed@android.com    word->exec(fe);
137e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->depth());
138e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(1));
139e50025a656005c4000fb55647373475eb5dfda54reed@android.com    FORTH_ASSERT(reporter, 2 == fe->peek(0));
140e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
141e50025a656005c4000fb55647373475eb5dfda54reed@android.com
142de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com//////////////////////////////////////////////////////////////////////////////
143de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
144de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void iadd_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
145de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(35);
146de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(99);
147de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
148de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
149de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 134 == fe->top());
150de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(-135);
151de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
152de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
153de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, -1 == fe->top());
154de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
155de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
156de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void isub_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
157de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(35);
158de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(99);
159de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
160de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
161de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 35-99 == fe->top());
162de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
163de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
164de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void imul_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
165de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(15);
166de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(-20);
167de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
168de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
169de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, -300 == fe->top());
170de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(0);
171de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
172de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
173de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 0 == fe->top());
174de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
175de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
176de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void idiv_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
177de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(100);
178de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(25);
179de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
180de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
181de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 4 == fe->top());
182de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->setTop(10);
183de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(-3);
184de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
185de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
186de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, -3 == fe->top());
187de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->setTop(-1);
188de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(-1);
189de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
190de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
191de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->top());
192de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
193de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
194de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void imod_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
195de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
196de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(3);
197de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
198de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
199de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->top());
200de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(5);
201de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
202de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
203de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->top());
204de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
205de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
206de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void idivmod_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
207de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
208de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(3);
209de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
210de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 2 == fe->depth());
211de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->peek(1));
212de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 3 == fe->peek(0));
213de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
214de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
215de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void idot_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
216de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(1);
217de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(2);
218de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
219de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
220de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->top());
221de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
222de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
223de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void iabs_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
224de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
225de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
226de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
227de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->top());
228de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->setTop(-10);
229de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
230de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
231de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->top());
232de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
233de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
234de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void inegate_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
235de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
236de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
237de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
238de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, -10 == fe->top());
239de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->setTop(-10);
240de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
241de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
242de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->top());
243de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
244de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
245de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void imin_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
246de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
247de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(3);
248de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
249de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
250de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 3 == fe->top());
251de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(-10);
252de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
253de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
254de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, -10 == fe->top());
255de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
256de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
257de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void imax_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
258de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
259de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(3);
260de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
261de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
262de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->top());
263de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(-10);
264de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
265de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
266de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->top());
267de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
268de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
269de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com///////////////////////////////////////////////////////////////////////////////
270de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
271de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void logical_and_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
272de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    const static int data[] = {
273de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        0, 0, 0,
274de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        2, 0, 0,
275de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        0, -1, 0,
276de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        1, 5, -1
277de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    };
278de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(data)/3; i++) {
279de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->push(data[i*3 + 0]);
280de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->push(data[i*3 + 1]);
281de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        word->exec(fe);
282de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        FORTH_ASSERT(reporter, 1 == fe->depth());
283de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        FORTH_ASSERT(reporter, data[i*3 + 2] == fe->top());
284de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->pop();
285de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    }
286de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
287de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
288de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void logical_or_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
289de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    const static int data[] = {
290de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        0, 0, 0,
291de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        2, 0, -1,
292de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        0, -1, -1,
293de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        1, 5, -1
294de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    };
295de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(data)/3; i++) {
296de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->push(data[i*3 + 0]);
297de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->push(data[i*3 + 1]);
298de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        word->exec(fe);
299de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        FORTH_ASSERT(reporter, 1 == fe->depth());
300de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        FORTH_ASSERT(reporter, data[i*3 + 2] == fe->top());
301de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->pop();
302de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    }
303de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
304de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
305de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void logical_not_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
306de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    const static int data[] = {
307de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        0, -1,
308de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        5, 0,
309de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        -1, 0
310de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    };
311de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(data)/2; i++) {
312de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->push(data[i*2 + 0]);
313de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        word->exec(fe);
314de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        FORTH_ASSERT(reporter, 1 == fe->depth());
315de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        FORTH_ASSERT(reporter, data[i*2 + 1] == fe->top());
316de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com        fe->pop();
317de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    }
318de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
319de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
320de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comstatic void if_dup_test(ForthWord* word, ForthEngine* fe, Reporter* reporter) {
321de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(10);
322de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
323de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 2 == fe->depth());
324de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->peek(1));
325de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 10 == fe->peek(0));
326de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->pop();
327de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->pop();
328de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    fe->push(0);
329de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    word->exec(fe);
330de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 1 == fe->depth());
331de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    FORTH_ASSERT(reporter, 0 == fe->top());
332de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com}
333de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
334e50025a656005c4000fb55647373475eb5dfda54reed@android.comstatic const struct {
335e50025a656005c4000fb55647373475eb5dfda54reed@android.com    const char*         fName;
336e50025a656005c4000fb55647373475eb5dfda54reed@android.com    ForthWordTestProc   fProc;
337e50025a656005c4000fb55647373475eb5dfda54reed@android.com} gRecs[] = {
338e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "DROP",   drop_test0 },   { "DROP",   drop_test1 },
339e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "DUP",    dup_test },
340e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "SWAP",   swap_test },
341e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "OVER",   over_test },
342e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "ROT",    rot_test },
343e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "-ROT",   rrot_test },
344e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "2SWAP",  swap2_test },
345e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "2DUP",   dup2_test },
346e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "2OVER",  over2_test },
347e50025a656005c4000fb55647373475eb5dfda54reed@android.com    { "2DROP",  drop2_test },
348de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
349de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "+",      iadd_test },
350de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "-",      isub_test },
351de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "*",      imul_test },
352de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "/",      idiv_test },
353de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "MOD",    imod_test },
354de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "/MOD",   idivmod_test },
355de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
356de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com//    { ".",      idot_test },
357de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "ABS",    iabs_test },
358de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "NEGATE", inegate_test },
359de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "MIN",    imin_test },
360de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "MAX",    imax_test },
361de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com
362de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "AND",    logical_and_test },
363de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "OR",     logical_or_test },
364de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "0=",     logical_not_test },
365de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com    { "?DUP",   if_dup_test },
366e50025a656005c4000fb55647373475eb5dfda54reed@android.com};
367e50025a656005c4000fb55647373475eb5dfda54reed@android.com
368e50025a656005c4000fb55647373475eb5dfda54reed@android.com///////////////////////////////////////////////////////////////////////////////
369e50025a656005c4000fb55647373475eb5dfda54reed@android.com
370e50025a656005c4000fb55647373475eb5dfda54reed@android.comvoid Reporter::reportFailure(const char expression[], const char file[],
371e50025a656005c4000fb55647373475eb5dfda54reed@android.com                             int line) {
372e50025a656005c4000fb55647373475eb5dfda54reed@android.com    SkDebugf("failed %s:%d: %s\n", file, line, expression);
373e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fFailureCount += 1;
374e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
375e50025a656005c4000fb55647373475eb5dfda54reed@android.com
376e50025a656005c4000fb55647373475eb5dfda54reed@android.comvoid Reporter::reportFailure(const char msg[]) {
377e50025a656005c4000fb55647373475eb5dfda54reed@android.com    SkDebugf("%s\n");
378e50025a656005c4000fb55647373475eb5dfda54reed@android.com    fFailureCount += 1;
379e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
380e50025a656005c4000fb55647373475eb5dfda54reed@android.com
381de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comvoid Forth_test_stdwords(bool verbose);
382de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.comvoid Forth_test_stdwords(bool verbose) {
383e50025a656005c4000fb55647373475eb5dfda54reed@android.com    ForthEnv env;
384e50025a656005c4000fb55647373475eb5dfda54reed@android.com    Reporter reporter;
385e50025a656005c4000fb55647373475eb5dfda54reed@android.com
386e50025a656005c4000fb55647373475eb5dfda54reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
387e50025a656005c4000fb55647373475eb5dfda54reed@android.com        ForthEngine engine(NULL);
388fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
389e50025a656005c4000fb55647373475eb5dfda54reed@android.com        ForthWord* word = env.findWord(gRecs[i].fName);
390e50025a656005c4000fb55647373475eb5dfda54reed@android.com        if (NULL == word) {
391e50025a656005c4000fb55647373475eb5dfda54reed@android.com            SkString str;
392e50025a656005c4000fb55647373475eb5dfda54reed@android.com            str.printf("--- can't find stdword %d", gRecs[i].fName);
393e50025a656005c4000fb55647373475eb5dfda54reed@android.com            reporter.reportFailure(str.c_str());
394e50025a656005c4000fb55647373475eb5dfda54reed@android.com        } else {
395de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com            if (verbose) {
396de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com                SkDebugf("--- testing %s %p\n", gRecs[i].fName, word);
397de2e7fb96dd8633df779ab2b634c65717afb5eb3reed@android.com            }
398e50025a656005c4000fb55647373475eb5dfda54reed@android.com            gRecs[i].fProc(word, &engine, &reporter);
399e50025a656005c4000fb55647373475eb5dfda54reed@android.com        }
400e50025a656005c4000fb55647373475eb5dfda54reed@android.com    }
401fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
402e50025a656005c4000fb55647373475eb5dfda54reed@android.com    if (0 == reporter.fFailureCount) {
403e50025a656005c4000fb55647373475eb5dfda54reed@android.com        SkDebugf("--- success!\n");
404e50025a656005c4000fb55647373475eb5dfda54reed@android.com    } else {
405e50025a656005c4000fb55647373475eb5dfda54reed@android.com        SkDebugf("--- %d failures\n", reporter.fFailureCount);
406e50025a656005c4000fb55647373475eb5dfda54reed@android.com    }
407e50025a656005c4000fb55647373475eb5dfda54reed@android.com}
408