OpenBoot 3.x Command Reference Manual

Control Commands

The following sections describe words used in a Forth program to control the flow of execution.

The if-else-then Structure

The commands if, else and then provide a simple control structure.

The commands listed in Table 4-28 control the flow of conditional execution.

Table 4-28 ifelsethen Commands


Stack Diagram 



( flag -- ) 

Execute the following code when flag is true.


( -- ) 

Execute the following code when flag is false.


( -- ) 

Terminate ifelsethen.

The format for using these commands is:

flag	if
	(do this if true)
(continue normally) 


flag	if
	(do this if true)
	(do this if false)
(continue normally) 

The if command consumes a flag from the stack. If the flag is true (nonzero), the commands following the if are performed. Otherwise, the commands (if any) following the else are performed.

ok : testit  ( n -- ) 
] 5 >  if  ." good enough " 
] else  ." too small " 
] then 
] ." Done. "  ; 
ok 8 testit
good enough Done. 
ok 2 testit 
too small Done. 

Note -

The ] prompt reminds you that you are part way through creating a new colon definition. It reverts to ok after you finish the definition with a semicolon.

The case Statement

A high-level case command is provided for selecting alternatives with multiple possibilities. This command is easier to read than deeply-nested ifthen commands.

Table 4-29 lists the conditional case commands.

Table 4-29 case Statement Commands


Stack Diagram 



( selector -- selector )  

Begin a caseendcase conditional.


( selector -- ) 

Terminate a caseendcase conditional.


( -- ) 

Terminate an ofendof clause in a case...endcase


( selector test-value -- selector | {empty} ) 

Begin an ofendof clause in a case conditional.

Here is a simple example of a case command:

ok : testit  ( testvalue -- )
]	case
]		0  of  ." It was zero "										endof 
]		1  of  ." It was one "										endof 
]		ff of  ." Correct "										endof 
]		-2 of  ." It was minus-two "										endof 
]		( default )  ." It was this value: "  dup . 
]	endcase   ." All done."  ; 
ok 1 testit
It was one All done.
ok ff testit
Correct All done.
ok 4 testit
It was this value: 4 All done.

Note -

The (optional) default clause can use the test value which is still on the stack, but should not remove it (use the phrase "dup ." instead of "."). A successful of clause automatically removes the test value from the stack.

The begin Loop

A begin loop executes the same commands repeatedly until a certain condition is satisfied. Such a loop is also called a conditional loop.

Table 4-30 lists commands to control the execution of conditional loops.

Table 4-30 begin (Conditional) Loop Commands


Stack Diagram 



( -- ) 

End a beginagain infinite loop.


( -- ) 

Begin a beginwhilerepeat, beginuntil, or beginagain loop.


( -- ) 

End a beginwhilerepeat loop.


( flag -- ) 

Continue executing a beginuntil loop until flag is true.


( flag -- ) 

Continue executing a beginwhilerepeat loop while flag is true.

There are two general forms:

begin 		any commandsflag until 


begin			any commands				flag		while
			more commands						repeat

In both cases, the commands in the loop are executed repeatedly until the proper flag value causes the loop to be terminated. Then execution continues normally with the command following the closing command word (until or repeat).

In the beginuntil case, until removes a flag from the top of the stack and inspects it. If the flag is false, execution continues just after the begin, and the loop repeats. If the flag is true, the loop is exited.

In the beginwhilerepeat case, while removes a flag from the top of the stack and inspects it. If the flag is true, the loop continues by executing the commands just after the while. The repeat command automatically sends control back to begin to continue the loop. If the flag is false when while is encountered, the loop is exited immediately; control goes to the first command after the closing repeat.

An easy mnemonic for either of these loops is: If true, fall through.

A simple example follows.

ok begin 4000 c@ . key? until   (
repeat until any key is pressed)
43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43

The loop starts by fetching a byte from location 4000 and displaying the value. Then, the key? command is called, which leaves a true on the stack if the user has pressed any key, and false otherwise. This flag is consumed by until and, if the value is false, then the loop continues. Once a key is pressed, the next call to key? returns true, and the loop terminates.

Unlike many versions of Forth, the User Interface allows the interactive use of loops and conditionals -- that is, without first creating a definition.

The do Loop

A do loop (also called a counted loop) is used when the number of iterations of the loop can be calculated in advance. A do loop normally exits just before the specified ending value is reached.

Table 4-31 lists commands to control the execution of counted loops.

Table 4-31 do (Counted) Loop Commands


Stack Diagram 



( n -- ) 

End a do+loop construct; add n to loop index and return to do (if n < 0, index goes from start to end inclusive).


( end start -- ) 

Begin ?doloop to be executed 0 or more times. Index goes from start to end-1 inclusive. If end = start, loop is not executed.


( flag -- ) 

Exit from a doloop if flag is non-zero.


( end start -- ) 

Begin a doloop. Index goes from start to end-1 inclusive.

Example: 10 0 do i . loop (prints 0 1 2...d e f).


( -- n ) 

Leaves the loop index on the stack. 


( -- n ) 

Leaves the loop index of the next outer enclosing loop on the stack. 


( -- ) 

Exit from doloop.


( -- ) 

End of doloop.

The following screen shows several examples of how loops are used.

ok 10 5 do i .  loop 
5 6 7 8 9 a b c d e f
ok 2000 1000 do i .  i c@ . cr   i c@ ff = if leave then  4 +loop 
1000 23
1004 0
1008 fe
100c 0
1010 78
1014 ff
ok : scan ( byte -- ) 
]    6000 5000     (Scan memory 5000 - 6000 for bytes not equal to the specified byte)
]    do dup i c@ <> ( byte error? ) 
]      if i . then  ( byte ) 
]    loop 
]    drop ( the original byte was still on the stack, discard it ) 
]  ; 
ok 55 scan 
5005 5224 5f99 
ok 6000 5000 do i i c! loop     (Fill a region of memory with a stepped pattern)
ok 500 value testloc 
ok : test16 ( -- ) 1.0000 0 ( do 0-ffff )     (Write different 16-bit values to a location)
]     do i testloc w! testloc w@ i <> ( error? )     (Also check the location)
]       if ." Error - wrote " i . ." read " testloc w@ . cr 
]        leave ( exit after first error found )     (This line is optional)
]       then 
]     loop 
]  ; 
ok test16 
ok 6000 to testloc 
ok test16 
Error - wrote 200 read 300 

Additional Control Commands

Table 4-32 contains descriptions of additional program execution control commands.

Table 4-32 Program Execution Control Commands


Stack Diagram 



( -- ) 

Abort current execution and interpret keyboard commands. 

abort" ccc"

( abort? -- ) 

If abort? is true, abort and display message.


( addr len -- ) 

Interpret Forth source from addr len.  


( xt -- ) 

Execute the word whose execution token is on the stack. 


( -- ) 

Return from the current word. (Cannot be used in counted loops.) 


( -- ) 

Same as abort, but leave stack intact.

abort causes immediate termination and returns control to the keyboard. abort" is similar to abort but is different in two respects. abort" removes a flag from the stack and only aborts if the flag is true. Also, abort" prints any desired message when the abort takes place.

eval takes a string from the stack (specified as an address and a length). The characters in that string are then interpreted as if they were entered from the keyboard. If a Forth text file has been loaded into memory (see Chapter 5, Loading and Executing Programs), then eval can be used to compile the definitions contained in the file.