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.