1     Now we can start fleshing out this Forth implementation
     
2     with some basic words. I'll start with the stack manipulation
     
3     words as defined in assembly (for speed) in JonesFORTH:
     
4 
     5         ; drop top of stack
     
6         DEFCODE "DROP",4,,DROP
     
7         pop eax
     
8         NEXT
     
9 
    10     I'll test each one out as I go. Here's DROP:
    
11 
    12 65 EMIT
    
13 A
    
14 65 66 67
    
15 DROP EMIT
    
16 B
    
17 EMIT
    
18 A
    
19 
    20     Good, it dropped 67 ('c') from the top of the stack.
    
21 
    22     And swap:
    
23 
    24         ; swap top two elements
    
25         DEFCODE "SWAP",4,,SWAP
    
26         pop eax
    
27         pop ebx
    
28         push eax
    
29         push ebx
    
30         NEXT
    
31 
    32     Which is easy to test:
    
33 
    34 65 66 EMIT EMIT
    
35 BA
    
36 65 66 SWAP EMIT EMIT
    
37 AB
    
38 
    39     Finally,
    
40 
    41         ; duplicate element on top of stack
    
42         DEFCODE "DUP",3,,DUP
    
43         mov eax, [esp]
    
44         push eax
    
45         NEXT
    
46 
    47 65 DUP 66 DUP EMIT EMIT EMIT EMIT
    
48 BBAA
    
49 
    50     Awesome.
    
51 
    52     Next night: okay I've ported over OVER, ROT, -ROT, 
    
53     2DROP, 2DUP, 2SWAP, and ?DUP. I'll just test them all
    
54     at once and won't bother with the source - they're
    
55     as simple as the above - so it's really easy to read
    
56     their assembly definitions in the source file.
    
57 
    58 : A 65 ;
    
59 A EMIT
    
60 A
    
61 : B 66 ;
    
62 : C 67 ;
    
63 : D 68 ;
    
64 : e EMIT ;
    
65 A B C D e e e e
    
66 DCBA
    
67 A B C OVER e e e e
    
68 BCBA
    
69 A B C ROT e e e
    
70 ACB
    
71 A B C -ROT e e e
    
72 BAC
    
73 A B C D DROP e e e
    
74 CBA
    
75 A B C D 2DROP e e
    
76 BA
    
77 A B C D 2SWAP e e e e
    
78 BADC
    
79 A B ?DUP e e e
    
80 BBA
    
81 A B 0 ?DUP e e e
    
82 
    83 Program received signal SIGSEGV, Segmentation fault.
    
84 _FIND.test_word () at nasmjf.asm:532
    
85 532         mov al, [edx+4]           ; al = flags+length field
    
86 (gdb)
    
87 
    88     LOL, well, ?DUP is a little hard to test compared
    
89     to the others. Though a segfault for trying to print
    
90     an ASCII NUL seems weird, and is GDB telling me it
    
91     crashed in FIND? Hmm. I'll have to keep an eye on that.
    
92 
    93     The next series of words to define in assembly are
    
94     math operators, which is great. But I think I'm going
    
95     to need to be able to display numbers before that'll
    
96     be any fun to test.
    
97 
    98     ...
    
99 
   100     Several nights later: Done! Thanks to one of the utility
   
101     routines I wrote as part of the excellent asmtutor.com,
   
102     I was able to slap in a temporary stand-in for the DOT
   
103     word which Jones defines in pure Forth.
   
104 
   105     DOT (.) pops and prints the numeric value at the top of
   
106     the stack. At least, I think it's supposed to pop the
   
107     value...well, mine does, for now.
   
108 
   109 Starting program: /home/dave/nasmjf/nasmjf
   
110 Continuing.
   
111 1 .
   
112 1
   
113 11 .
   
114 11
   
115 111 .
   
116 111
   
117 1111 .
   
118 1111
   
119 11111 .
   
120 
   121 Program received signal SIGSEGV, Segmentation fault.
   
122 _FIND.test_word () at nasmjf.asm:532
   
123 532         mov al, [edx+4]           ; al = flags+length field
   
124 
   125     Works great, but for some reason, accessing edx+4 causes a
   
126     segfault when we try to match a word with a 5-digit number?
   
127     I started stepping throuh it, but I wasn't feeling like
   
128     chasing the rabbit into that particular hole tonight. We've
   
129     got some new math-related words to test!
   
130 
   131     1+ and 1- increment and decrement.
   
132     4+ and 4- do the same, but by 4.
   
133 
   134 5 1+ .
   
135 6
   
136 5 1- .
   
137 4
   
138 5 4+ .
   
139 9
   
140 5 4- .
   
141 1
   
142 
   143     Then we have + and -.
   
144 
   145 5 4 + .
   
146 134521461
   
147 
   148     LOL, what?
   
149 
   150 5 4 + .
   
151 Program received signal SIGSEGV, Segmentation fault.
   
152 0x00000004 in ?? ()
   
153 
   154     Well, clearly "+" has a bug.
   
155 
   156 5 4 - .
   
157 1
   
158 
   159     But "-" looks good. I'm curious about a negative
   
160     value:
   
161 
   162 4 5 - .
   
163 4294967295
   
164 
   165     I'll have to check thia answer. Is this -1?
   
166 
   167     Moving on, we have multiplication and division:
   
168 
   169 2 3 * .
   
170 6
   
171 10 5 /MOD . .
   
172 2 0
   
173 100 3 /MOD . .
   
174 33 1
   
175 
   176     Great! Note: I added space beween the quotient and remainder
   
177     for readability. The 'real' DOT in forth prints a space after
   
178     each digit.
   
179 
   180     Cool! So we've got math!
   
181 
   182     Oh, and we need a satisfying conclusion on the ?DUP operator
   
183     from our stack manipulation words from the beginning of this
   
184     particular log.
   
185 
   186     ?DUP duplicates the value on the top of the stack IF it's not 
   
187     zero:
   
188 
   189 1 2 3 ?DUP . . .
   
190 332
   
191 1 2 0 ?DUP . . .
   
192 021
   
193 
   194     Yup, that works!
   
195 
   196     Looks like I'll find the bug in "+" next. :-)
   
197 
   198     Yup, fixed that with the next set of words. See next log.