





			An Icon Pre-Processor


			    Frank J. Lhota
			 Mei Associates, Inc.
			 1050 Waltham Street
		       Lexington, MA 02173-8024
			Voice: (617) 862-3390
			 FAX: (617) 862-5053



    The Icon Programming Library comes with an Icon preprocessor
called IPP.  I have made several enhancements to this program, and I
would like to submit the enhanced version of the IPP to the IPL.





			  New IPP features

    For those who are not familiar with the IPP, the header comments
in the IPP.ICN file provide complete intructions on its use.  The rest
of this section assumes a familiarity with the previous version of
the IPP.

    This new version of the IPP processes #line directives, which can
be used to change the value of the _LINE_ and _FILE_ symbols.  Also,
the new IPP wiil generates #line directives when needed, so that the
preprocessor output will always indicate the original source of its
text.  As a result, if we pipe the output of IPP to icont, e.g.,

	iconx ipp.icx foo.icn | icont -ofoo -

then (assuming that the source itself does not have any line
directives) the &file and &line keywords refer to the lines in the
original source file, not to "stdin" and the line numbers of the IPP
output.  The #line directives will be generated even when other
comments are being stripped from the input.  

    The preprocessor command syntax has been relaxed a bit.  The
basic form of a preprocessor command line is still

	$command [arguments]

but now the user is permitted to include spaces around the '$', so
that preproccessor commands can have a pretty-print look, e.g.

	$ifndef FOO
	  $if BAR = 0
	    $ define FOO -1
	  $else
	    $ define FOO BAR
	  $endif
	$endif	# ndef FOO



				- 1 -








    On non-UNIX systems, the new IPP has a more liberal search
algorithm for $include files.  For files enclosed with <>, the
directories specified in the IPATH environment variable are searched
for the file.  The search for file enclosed in "" starts with the
current directory, then proceeds to the IPATH directories.  As
before, the -I command line option can be used to add directories to
the beginning of the standard search path.

    The following preprocessor commands have been added to IPP:

    $elif:
	    Invoked as 'elif constant-expression'.  If the lines
	preceding this command were processed, this command and the
	lines following it up to the matching $endif command are
	ignored.  Otherwise, the constant-expression is evaluated,
	and the lines following this command are processed only if
	it produces a result.
  
    $error:
	    This command issues a error, with the text coming from
	the argument field of the command.  As with all errors,
	processing is terminated.

    $warning:
	    This command issues a warning, with the text coming from
	the argument field of the command.

    In addition to the operators previously supported, the constant
expressions appearing in $if / $elif command can now use the unary
versions of the '+' and '-' operators, and the 'not' control
structure.  Also, backtracking is used in the evaluation of constant
expressions, so that when the command 

	$if FOO = (2|3)

is processed, the lines following it are processed precisely when
either FOO equals 2 or FOO equals 3.


			   Uses of the IPP

    To understand the following examples, the reader should keep in
mind this feature of the IPP:  The IPP creates a pre-defined symbol
out of each string generated by &features.  These symbols are created
by taking the non-letter characters of the &features strings and
replacing them with underscores.  Thus, if &features includes UNIX,
the symbol UNIX is defined; if co-expressions are supported, the
symbol co_expressions is defined, and so on.

    The IPP can be an handy tool for distributing Icon programs that
require some customization for specific implementations.  A prime
example of this is the IPP itself.  IPP must be able to contruct a




				- 2 -







full pathname for a file, given a directory and file name.  On many
systems, this is done by performing the catenation

	directory || "/" || filename

This file naming convention is not, however, universal.  On DOS and 
OS/2 systems, "\\" should be used instead of "/" to separate the
directory and filename.  Under VMS, the separator should be "".

    To accomodate these system-dependant variations, the IPP source
(in the file IPP.ICN, on this disk) is written using the symbol
DIR_SEP for the string that separates the directory and filename
portions of a complete path.  The IPP code starts with the
preprocessor directives:

	$ifndef DIR_SEP
	  $ifdef UNIX
	    $define DIR_SEP "/"
	  $elif def(MS_DOS) | def(MS_DOS_386) | def(OS_2)
	    $define DIR_SEP "\\"
	  $elif def(VMS)
	    $define DIR_SEP ""
	  $else
	    $error Need a definition for DIR_SEP
	  $endif
	$endif # ndef DIR_SEP

After preprocessing this code, DIR_SEP will be "/" on UNIX systems,
and "\\" on DOS and OS/2 systems.  For other systems, an appropriate
value for DIR_SEP could be specified on the preprocessor command line
by using the -D options, e.g.

	ipp -D DIR_SEP=\"\" ipp.ipp ipp.icn

    Another example of Icon software that could exploit IPP
customization is BINCVT, the IPL package of utilities for converting
between integers and their internal binary representations.  The
version of BINCVT currently included in the IPL assumes a
"big-endian" system. On "big-endian" systems, the bytes in the binary
representation of an integer are arranged from most significant to
least significant. However, major platforms such as the IBM PC family
or the VAX machines use the "little-endian" method for storing
integers, in which the bytes representing an integer go from least
significant to most significant.  

    Using IPP, one can write a version of BINCVT that can be
preprocessed to produce a working package for either big-endian or
little-endian systems.  The symbol LITTLE_ENDIAN will be defined (via
the command line option -D LITTLE_ENDIAN) to produce output for
little endian systems.  Most of the functions in BINCVT can be
expressed in terms of starting at the most significant byte, and
moving to the less significant bytes.  Hence, the generalized BINCVT
starts with the definitions:




				- 3 -








	$ifdef LITTLE_ENDIAN
	   $define GOTO_BIG_END tab (0)
	   $define TO_SMALL_END -1
	$else
	   $define GOTO_BIG_END
	   $define TO_SMALL_END 1
	$endif

    Using these definitions, we can write a version of the unsigned
function that will work for either integer storage method:

	procedure unsigned(s)
	  local result
	  result := 0
	  s ? {
	    GOTO_BIG_END
	    while result := ord(move(TO_SMALL_END)) + result * 16r100
	    }
	  return result
	end

The file BINCVT.IPP on this disk contains the source code for this
example.


			     Conclusions

    The IPP allows Icon programmers to write more flexable and more
portable code.  The latest version of the IPP is easier to use and
more powerful than the previous version.


























				- 4 -
