www.jupiter-ace.co.uk

Listings Index > Ace FORTH .s [dot s] word.


Ace FORTH .s word and depth word

When debugging AceForth words it would be useful to know what values are stored on the stack and how deep the stack is. Some Forth's have a word called 'DEPTH' which would return on the stack the number of values in the stack. When DEPTH is used in a do loop with '.' [dot] it would could print to the screen a copy of the values on the stack. There is a listing of a DEPTH word for the Ace and how it works.

Some Forth systems talk about a Forth word .s [dot s], which lists out a copy of the values on the stack without destroying them, and in the Ace Manual page 143 we have a version .s for the Ace, so how does it work?
.s word listing
 

: .S
  15419 @ HERE 12 +
  ( top, bottom)
  OVER OVER -
  IF ( if stack not empty)
    DO
     I @ . 2
    +LOOP
  ELSE
    DROP DROP
  THEN
;


 

AceForth
Description
Stack values
: .s Start of the .s word definition  
15419
15419 is the address of the first byte past the top of the stack.

15419

@
@ word takes the address [in this case 15419] off the stack and places the contents from that address onto the stack. We will call this value Top.
Top
HERE
The HERE word puts onto the stack the address end of next byte past the end of the dictionary. We will call this value Bottom
Bottom
Top
12
12 is placed on the stack, as there are 12 unused bytes, as a buffer between the end of the Forth dictionary and the Stack. So by adding 12 to the value of bottom makes this value the address of the stack.
12
Bottom
Top
+
+ carries out the addition command, adding together the top two items on the stack [bottom + 12], leaving the result on the stack. So now the value of bottom has increased to 12 more that it was.
Bottom
Top
OVER
The OVER command, copies the second value on the stack [Top], and places it to the top of the stack.
Top
Bottom
Top
OVER
Again the OVER command, copies the second value on the stack [Bottom], and places it to the top of the stack. All that has happened is the values on the stack have been duplicated in the order that they were placed on the stack.
Bottom
Top
Bottom
Top
-
- subtract the two values that are on top of the Stack, leaving the result on the stack. Which we will call D. D is actually the address of the first value on the stack, and is used to list to the screen the stack contents.
D
Bottom
Top
IF
The IF word is testing if the value on the stack is true, for any value greater than 0. If the bottom - top resulted in 0, then it's not true. IF true then execute next Forth word, IF not true jump to the ELSE word. The value on the stack is not destroyed.
D
Bottom
Top
DO
IF the top of the stack is true then DO takes the two top values off the stack for its loop use. DO uses the top stack value as it loop counter,[D]. AceForths DO..LOOPs have a loop counter known as I, and our D is used to set the I counters value. This determines how many times the loop executes. The next value on the stack, bottom, is used as the DO..LOOPs limit, when the counter value [I] reaches the limit value the DO..LOOP ends.
Top
I
The word I puts the value of the loop counter onto the stack. We will call this value Address.
Address
Top
@
The @ word takes the number from the Stack [address], and uses it as a memory address, then reads the contents from that address and places the value on the stack. We will call the value N .
N
Top
.
The '.' dot word takes the value off the stack [N], and prints it to the screen.
Top
2
2 is placed on the stack, which is used to increase the loop counter [I] by the value of 2. Why? well the DO..LOOPs I counter is used as a memory address pointer, and memory addresses use 2 bytes. So increasing the I counter by two will now point to our new memory location, ready to read the next value with the @ word when the DO..LOOP loops.
2
Top
+LOOP
+LOOP takes a value from the stack, [2] and adds it to the I counter of the DO..LOOP, then loops if the counter [I] does not equal the DO..LOOP's limit [limit was set by the value bottom]
Top
ELSE Execute the Forth words here when the IF test was False [0].
? depends on If test
DROP DROP
DROP throws away the top stack value. So if the result from the Forth words OVER OVER - , resulted with our value of D being 0, the IF test would bring the flow of the program here and DROP DROP would throw away the stack values of Bottom and top as they are no longer needed.
 
THEN
the flow of the program reaches here after ELSE or after the DO..LOOP ends. which means the task has been finished.
 
;
end marker of the .s word definition
 

 
DEPTH

The 'depth' word will return a the number of values stacked in the stack, that's it. But notice how I have used the 'depth' word. When you type depth, the Ace prints the word 'depth' to the screen. The program runs and returns with a message ' of stack = 10 OK'. Which results in a meaning full message, depth of stack = 10 OK.

depth word listing
 

: depth
  15419 @ HERE 12 +
  - 2 /
  ." of Stack =" .
;
 

AceFORTH
Description
Stack values
: depth Start of the depth word definition  
15419
15419 is the address of the first byte past the top of the stack.

15419

@
@ word takes the address [in this case 15419] off the stack and places the contents from that address onto the stack. We will call this value Top.
Top
HERE
The HERE word puts onto the stack the address end of next byte past the end of the dictionary. We will call this value Bottom
Bottom
Top
12
12 is placed on the stack, as there are 12 unused bytes, as a buffer between the end of the Forth dictionary and the Stack. So by adding 12 to the value of bottom makes this value the address of the stack.
12
Bottom
Top
+
+ carries out the addition command, adding together the top two items on the stack [bottom + 12], leaving the result on the stack. So now the value of bottom has increased to 12 more that it was.
Bottom
Top
-
- subtract the two values that are on top of the Stack, leaving the result on the stack. Which we will call D. D is actually the address of the first value on the stack, and is used find the depth of the stack.
D
2 /
D now holds the value of the number of bytes that make up the addresses that can be used to point to a stack values. We only want to know how deep the stack is. As each memory address needs 2 bytes, So, by dividing the value of D by two will give us the depth of the stack, left on the stack.
D
." of stack =" prints 'of stack =' to the screen.
D
. '.' takes value off stack and print to screen.
 
; end of definition marker
 

Valid HTML 4.01 Transitional