[IF] [THEN] [ELSE]

license

Software that runs in several system environments often contains some source code that is environmentally dependent. Conditional compilation - the selective inclusion or exclusion of portions of the source code at compile time - is one technique that is often used to assist in the maintenance of such source code.

Conditional compilation is sometimes done with smart comments - definitions that either skip or do not skip the remainder of the line based on some test. For example:

If 16-Bit? contains TRUE, lines preceded by 16BIT\ will be skipped. Otherwise, they will not be skipped.

  
ram_variable 16-BIT?

: 16BIT\  ( -- )  16-BIT? @  IF  POSTPONE \  THEN ;  IMMEDIATE
 

This technique works on a line by line basis, and is good for short, isolated variant code sequences.

More complicated conditional compilation problems suggest a nestable method that can encompass more than one source line at a time. The words included in the ANS Forth optional Programming tools extensions word set are useful for this purpose.

ANS 15.6.2.2531 [ELSE]

Compilation: Perform the execution semantics given below.

Execution: ( "< spaces >name" ... -- )

Skipping leading spaces, parse and discard space-delimited words from the parse area, including nested occurrences of [IF] ... [THEN] and [IF] ... [ELSE] ... [THEN], until the word [THEN] has been parsed and discarded. If the parse area becomes exhausted, it is refilled as with REFILL. [ELSE] is an immediate word.

 
Typical use: ... flag [IF] ... [ELSE] ... [THEN] ... 
 
	: [ELSE]  ( -- )
		1 BEGIN                                   \ level(--
			BEGIN
				BL (word) DUP  
			WHILE                                 \ level adr len(--
				2DUP  S" [IF]"  COMPARE 0=
				IF                                \ level adr len(--
					2DROP 1+                      \ level'(--
				ELSE                              \ level adr len(--
					2DUP  S" [ELSE]"
					COMPARE 0= IF                 \ level adr len(--
						2DROP 1- DUP IF            
							1+ 
						THEN      \ level'
					 ELSE                         \ level adr len(--
						S" [THEN]"  COMPARE 0= IF \ level(--
							1-                    \ level'(--
						THEN
					THEN
				THEN ?DUP 0=  IF 
					EXIT 
				THEN                              \ level'(--
		  REPEAT  2DROP                           \ level(--
		REFILL 0=  UNTIL                          \ level(--
		DROP
	;  IMMEDIATE
	 
ANS 15.6.2.2532 [IF]

Compilation: Perform the execution semantics given below.

Execution: ( flag | flag "< spaces >name" ... -- )

If flag is true, do nothing. Otherwise, skipping leading spaces, parse and discard space-delimited words from the parse area, including nested occurrences of [IF] ... [THEN] and [IF] ... [ELSE] ... [THEN], until either the word [ELSE] or the word [THEN] has been parsed and discarded. If the parse area becomes exhausted, it is refilled as with REFILL. [IF] is an immediate word.

An ambiguous condition exists if [IF] is POSTPONEd, or if the end of the input buffer is reached and cannot be refilled before the terminating [ELSE] or [THEN] is parsed.

 
Typical use: ... flag [IF] ... [ELSE] ... [THEN] ... 
 
 
	: [IF]  ( flag -- )
		0= IF [COMPILE] [ELSE] THEN 
	;  IMMEDIATE
	 
ANS 15.6.2.2533 [THEN]

Compilation: Perform the execution semantics given below.

Execution: ( -- )

Does nothing. [THEN] is an immediate word.

  
Typical use: ... flag [IF] ... [ELSE] ... [THEN] ... 
 
 
	: [THEN]
	; IMMEDIATE