Table of Contents
Star Forth Test Suite
Current version: 1.0
| Version | Pass/Fail | Test | Expected Results |
|---|---|---|---|
| 1.0 260313 | PASS | signed >-3 0 > . | 0 |
| 1.0 260313 | PASS | : ;: TEST 42 . ; | 42 |
| 1.0 260313 | PASS | IF/THEN: SIGN DUP 0 > IF 43 EMIT THEN . ;5 SIGN-3 SIGN0 SIGN | +5-30 |
| 1.0 260313 | PASS | DO/LOOP/I: TENS 10 0 DO I . LOOP ;TENS | 0 1 2 3 4 5 6 7 8 9 |
| 1.0 260313 | PASS | BEGIN/UNTIL: COUNT3 3 BEGIN DUP . 1 - DUP 0 = UNTIL DROP ;COUNT3 | 3 2 1 |
| 1.0 260313 | PASS | BEGIN/WHILE: COUNTDOWN BEGIN DUP WHILE DUP . 1 - REPEAT DROP ;5 COUNTDOWN0 COUNTDOWN | 5 4 3 2 10 |
| 1.0 260313 | PASS | HERE . | $030800 |
| 1.0 260313 | PASS | HEX $030800 @ . | 0 |
| 1.0 260313 | PASS | $030800 C@ . | 0 |
| 1.0 260313 | PASS | 42 HERE ! HERE @ . | 42 |
| 1.0 260313 | PASS | : GREET .“ Hello, World!” CR ;GREET | Hello, world! |
| 1.0 260313 | PASS | : FIZZBUZZ 21 1 DO I 15 MOD 0 = IF .“ FizzBuzz” ELSE I 3 MOD 0 = IF .“ Fizz” ELSE I 5 MOD 0 = IF .“ Buzz” ELSE I . THEN THEN THEN CR LOOP ; | not shown (but it works) |
| 1.0 260313 | PASS | : SIMPLE 500000 0 DO LOOP ;SIMPLE | ~6 seconds (170,000 w/s) at 4MHz |
| 1.0 260313 | PASS | : BENCH 500000 0 DO I DUP * DROP LOOP ;BENCH | 22 seconds (140,000 w/s) at 4Mhz |
| 1.0 260314 | PASS | : #WORDS 0 $030003 P@ BEGIN DUP WHILE SWAP 1 + SWAP P@ REPEAT DROP . .“ words” CR ; | Shows 73 words (see WORDS, which shows 72). |
Note that AS-IS, SD/FORTH 1.0 is not FORTH-79 compliant. That's fine, the following self-hosted words act as a sort of test suite, and also bring us up squarely into FORTH-79.
: 1+ 1 + ;
: 1- 1 - ;
: 2+ 2 + ;
: 2- 2 - ;
: 0= 0 = ;
: 0< 0 < ;
: 0> 0 > ;
: NEGATE 0 SWAP - ;
: ABS DUP 0< IF NEGATE THEN ;
: NIP SWAP DROP ;
: TUCK SWAP OVER ;
: ?DUP DUP IF DUP THEN ;
: ROT >R SWAP R> SWAP ;
: 2DUP OVER OVER ;
: MAX 2DUP < IF SWAP THEN DROP ;
: MIN 2DUP > IF SWAP THEN DROP ;
: SPACE 32 EMIT ;
: SPACES 0 DO SPACE LOOP ;
: /MOD 2DUP MOD >R / R> SWAP ;
: +! DUP @ ROT + SWAP ! ;
: TYPE 0 DO DUP C@ EMIT 1 + LOOP DROP ;
: TYPE ( addr len -- ) 0 DO DUP C@ EMIT 1 + LOOP DROP ;
: MOVE CMOVE ;
FORTH-79 TESTS
You could also try this; if you see all PASS and then ABC and then A on the next line underneath the space beside the C, it works!
: TEST= = IF ." PASS " ELSE ." FAIL " THEN ;
( Arithmetic )
5 1+ 6 TEST=
5 1- 4 TEST=
5 2+ 7 TEST=
5 2- 3 TEST=
5 NEGATE -5 TEST=
-7 NEGATE 7 TEST=
-5 ABS 5 TEST=
5 ABS 5 TEST=
( Comparisons )
0 0= 1 TEST=
5 0= 0 TEST=
-1 0< 1 TEST=
5 0< 0 TEST=
5 0> 1 TEST=
-1 0> 0 TEST=
( Stack ops )
1 2 NIP 2 TEST=
1 2 TUCK 2 TEST= DROP DROP
1 2 TUCK DROP 1 TEST= DROP
1 2 TUCK DROP DROP 2 TEST=
5 ?DUP + 10 TEST=
0 ?DUP 0 TEST=
1 2 3 ROT 1 TEST= DROP DROP
3 4 2DUP + >R + R> + 14 TEST=
( Math )
7 3 MAX 7 TEST=
3 7 MAX 7 TEST=
7 3 MIN 3 TEST=
3 7 MIN 3 TEST=
7 3 /MOD SWAP 1 TEST=
7 3 /MOD 2 TEST=
DROP
( Variable and +! )
VARIABLE TV
10 TV !
3 TV +!
TV @ 13 TEST=
( SPACE and SPACES )
65 EMIT 66 EMIT 67 EMIT CR
3 SPACES 65 EMIT CR
( Bit Shifting Ops )
1 0 LSHIFT 1 TEST=
1 1 LSHIFT 2 TEST=
1 4 LSHIFT 16 TEST=
1 8 LSHIFT 256 TEST=
$FF 4 LSHIFT $FF0 TEST=
16 1 RSHIFT 8 TEST=
256 8 RSHIFT 1 TEST=
$FF0 4 RSHIFT $FF TEST=
1 1 RSHIFT 0 TEST=
Benchmarking
The SIMPLE and BENCH tests indicate SD/FORTH is:
- 75x faster than Stellar BASIC (1,800 lines/sec) × ~5 ops/line ≈ 9,000 ops/sec)
- 5x to 7x faster than a real C64 running DurexForth (~25,000 words/sec)
- Comparable to a 4 MHz Z80 running Forth850 or an 8MHz Z80B running CamelForth.
However, this is an upper end. The following MUL and DIV heavy benchmarks operate a bit slower. Here's a summary of the followinf programs:
| Benchmark | Words/Sec. | Notes |
| Bare Loop | 176,000 | Only dispatch overhead |
| Stackbench | 160,000 | Only stack operations |
| DUP * DROP | 136,000 | Multiply, Stack Ops |
| ADD only | 120,000 | Same as Mixed but no DIV or MUL |
| Mixed no DIV | 100,000 | Same as Mixed but no DIV |
| FizzBench | 97,000 | 3x MOD, branches |
| Mixed +-*/ | 90,000 | Division, Heavy Stack |
The estimate is that 70% overhead is dispatch. So with a touch of opt I think the system wants to run at 180,000 words/sec, but gets tinted down by various factors. Stack operations are cheap, then come other types of operation, then MUL, DIV and MOD are considered 'heavy'. This is not unusual, and is in fact a great sign; this is a very fast FORTH.
STACKBENCH
: STACKBENCH ( -- )
1 2 3
300000 0 DO
DUP DROP SWAP OVER DROP
LOOP
DROP DROP DROP ;
STACKBENCH
FIZZBENCH
: FIZZBUZZ 21 1 DO I 15 MOD 0 = IF ." FizzBuzz" ELSE I 3 MOD
0 = IF ." Fizz" ELSE I 5 MOD
0 = IF ." Buzz" ELSE I . THEN THEN THEN CR LOOP ;
: FIZZBENCH 0 10000 0
DO I 15 MOD 0 = IF 1 + ELSE
I 3 MOD 0 = IF 1 + ELSE
I 5 MOD 0 = IF 1 + THEN
THEN
THEN
LOOP
;
: FB10 10 0 DO FIZZBENCH LOOP . ." hits" CR ;
FB10
This executes in 18.5 seconds, indicating 97,000 words/sec.
BENCH-ARITH
: ARITH ( n -- n )
DUP 42 +
DUP 7 -
DUP 3 *
DUP 2 /
DROP DROP DROP DROP ;
: BENCH-ARITH ( -- )
." Arithmetic benchmark" CR
100000 0 DO
I ARITH DROP
LOOP
." Done" CR ;
BENCH-ARITH
Same without DIV:
: ARITH3 ( n -- n )
DUP 42 +
DUP 7 -
DUP 3 *
DROP DROP DROP ;
: BENCH3 ( -- )
." Add/Sub/Mul benchmark" CR
100000 0 DO
I ARITH3 DROP
LOOP
." Done" CR ;
BENCH3
