Department of Computer Science The University of Arizona Tucson, Arizona IPD238d May 17, 1999 http://www.cs.arizona.edu/icon/docs/ipd238.htm |
icon
is:
|-bin------ executable binaries and support files |-config--- configurations |-icon----|-src------ source code |-tests---- testsThere are several subdirectories in
config
for different operating
systems:
|-acorn---- |-amiga---- |-atari_st- |-ibm370--- |-macintosh --config--|-msdos---- |-nt------- |-os2------ |-port----- |-unix----- |-vms------Not all of these subdirectories are included in all distributions of Icon. Some configuration directories contain subdirectories for different platforms. These subdirectories contain various files, depending on the platform.
src
contains the source code for various components
of Icon.
|-common---- common source |-h--------- header files |-iconc----- Icon compiler source -src------|-icont----- Icon translator source |-preproc--- C preprocessor source |-rtt------- run-time translator source |-runtime--- run-time support |-wincap---- BMP image-file format support |-xpm------- XPM image-file format supportThe directory
tests
contains the test material for various
components of Icon.
|-bench----- benchmarks |-calling--- calling C functions from Icon |-general--- general tests |-graphics-- tests for graphics -tests----|-ipl------- tests for the Icon program library |-preproc--- C preprocessor tests |-samples--- short sample programs |-special--- tests of special featuresSome distributions contain other, optional components of Icon. The Icon compiler is no longer supported, and it is not included in all distributions of Icon.
src/h/define.h
. There are many existing define.h
files that can be used as guides. One for a "vanilla" 32-bit platform
is:
#define HostStr "new host" #define NoCoexpr #define PORT 1
HostStr
provides the value used in the Icon keyword &host
and should be changed as appropriate. NoCoexpr
causes Icon
to be configured without co-expressions. This definition can be removed
when co-expressions are implemented. See Appendix B. PORT
indicates
an implementation for an unspecified operating system. It should be changed
to a name for the operating system for the new platform (see Section 8).
Other definitions probably need to be added, of course.
define.h
, a UNIX configuration also contains
headers used to construct Makefile
s. These headers are named
*.hdr
. Check these headers for appropriateness.iconx
is
built and when iconc
links a compiled Icon executable. Normally,
the answer will be -lX11
, but on some platforms additional
libraries or alternate paths are required. Consult appropriate manuals to
find out what libraries are needed.-lX11
, no additional
steps are required in creating your configuration. If your platform requires
additional libraries, you will need to add files to the configuration directory
for your particular system.xiconx.mak
and xiconc.def
, if they are
present, are used during Icon configuration to supply non-default library
information to the interpreter and the compiler.xiconx.mak
file with the line
and a correspondingXLIB= -L../../bin -lX11 -lpt -lbsd
xiconc.def
file with the line
The former file gets prepended to the#define ICONC XLIB "-lX11 -lpt -lbsd"
Makefile
that builds
iconx
, while the latter file gets included and compiled into
iconc
when X is configured. Then proceed to the make
X-Configure
build step./usr/include/X11
;
if they are in some other place on your platform, you will need to locate
them and identify the appropriate option to add to the C compiler command
line, usually -I
path, where path is the directory
above the X11 include directory.COpts
macro
in define.h
for your configuration. The COpts
macro must define a quoted C string. For the interpreter, the option is
added to the CFLAGS
argument of the common.hdr
,
icont.hdr
, runtime.hdr
, and xpm.hdr Makefile
headers for your configuration.
Makefile
s, batch scripts,
and response files for linking. These files should be modified for the new
platform as appropriate. See Reference 9 for more information concerning
the installation of Icon on an MS-DOS platform.
Conditional compilation uses logical expressions composed from these symbols. An example is:constant operating system AMIGA AmigaDos ARM RISC OS for the Acorn Archimedes ATARI ST Atari ST TOS MACINTOSH Macintosh MSDOS MS-DOS MVS MVS NT Windows NT OS2 OS/2 PORT new UNIX UNIX VM VM/CMS VMS VAX/VMS
Each symbol is defined to be either 1 (for the target operating system) or 0 (for all other operating systems). This is accomplished by defining the symbol for the target operating system to be 1 in... #if MSDOS ... /* code for MS-DOS */ ... #endif #if UNIX || VMS ... /* code for UNIX and VMS */ ... #endif ...
define.h
.
In config.h
, which includes define.h
, all other
operating-system symbols are defined to be 0.#if
are used instead of defined or
undefined names with #ifdef
to avoid nested conditionals, which
become very complicated and difficult to understand when there are several
alternative operating systems. Note that it is important not to use #ifdef
in place of #if
, since all the names are defined.define.h
for a different operating system should initially
contain
as indicated in Section 4. You can use#define PORT 1
PORT
during the configuration
for a different operating system. Later you should come back and change
PORT
to some more appropriate name.PORT
sections contain deliberate syntax errors (so
marked) to prevent sections from being overlooked during configuration.
These syntax errors must, of course, be removed before compilation.Between these beginning and ending comments, the code for different operating systems is provided using conditional expressions such as those indicated above./* * The following code is operating-system dependent. */ ... /* * End of operating-system specific code. */
PORT
. In some cases, no code will
be needed. In others, code for an existing operating system may suffice
for the new one.and removing the present code for#if MSDOS || UNIX || PORT ... #endif #if VMS ... #endif
PORT
or by filling in the
segment with the appropriate code, as in
If no code is needed for the target operating system in a particular situation, a comment should be provided so that it is clear that the situation has been considered.#if PORT ... /* code for the new operating system */ ... #endif
PORT
as shown above. If the situation appears to need different
code for several operating systems, add a new segment similar to the other
ones, being sure to provide something appropriate for all operating systems.#else
constructions in these segments; this increases
the probability of logical errors and obscures the mutually exclusive nature
of operating system differences.
If you run into problems, contact us at the Icon Project:Please also let us know of any suggestions for improvements to the configuration process.
Icon Project
Department of Computer Science
The University of Arizona
P.O. Box 210077
Tucson, AZ 85721-0077
U.S.A.
(520) 621-6613 (voice)
(520) 621-4246 (fax)
icon-project@cs.arizona.edu
define.h
contains
If an alternative typedef is used for pointer, addtypedef huge void *pointer;
to#define PointerDef
define.h
to avoid the default one.DiffPtrs(p1, p2)
,
which has the default definition:
where word is a typedef that is provided automatically and usually is long int.#define DiffPtrs(p1, p2) (word)((p1)-(p2))
define.h
. For example,
Microsoft C for the MS-DOS large memory model uses
If you provide an alternate definition for pointer differencing, be careful to enclose all arguments in parentheses.#define DiffPtrs(p1, p2) ((word)(p1)-(word)(p2))
to#define EBCDIC 1
define.h
.
WordBits (default: 32) IntBits (default: WordBits)
IntBits
is the number of bits in a C int. It may be
16, 32, or 64. WordBits
is the number of bits in a C long
(Icon's "word"). It may be 32 or 64.to#define Double
define.h
.If your platform needs a different alignment, provide an appropriate definition inStackAlign (default: 2)
define.h
.to#define UpStack
define.h
.
The values ofBig (default: 9007199254740092.) LogHuge (default: 309) Precision (default: 10)
Big
, LogHuge
, and Precision
give, respectively, the largest floating-point number that does not lose
precision, the maximum base-10 exponent + 1 of a floating-point number,
and the number of digits provided in the string representation of a floating-point
number. If the default values given above do not suit the floating-point
arithmetic on your platform, add appropriate definitions to define.h
.
to#define NoLargeInts
define.h
.
Since users can override the set values with environment variables, it is unwise to change them from their defaults except in unusual cases.MaxAbrSize (default: 500000) MaxStrSize (default: 500000)
As for the block and string storage regions, it is unwise to change the default values except in unusual cases.MStackSize (default: 10000) StackSize (default: 2000)
Like the sizes above, this one normally is best left unchanged.QualLstSize (default: 5000)
malloc()
is used to allocate space for Icon's storage regions.
This limits region sizes to the value of the largest unsigned int. Some
platforms provide alternative allocation routines for allocating larger
regions. To change the allocation procedure for regions, add a definition
for AllocReg
to define.h
. For example, the huge-memory-model
implementation of Icon for Microsoft C uses the following:
Note: Icon still uses#define AllocReg(n) halloc((long)n, sizeof(char))
malloc()
for allocating other blocks.
If this is a problem, it may be possible to change this by defining malloc
in define.h
, as in
where#define malloc lmalloc
lmalloc()
is a local routine for allocating large blocks
of memory. If this is done, and the size of the allocation is not unsigned
int, add an appropriate definition for the type by defining AllocType
in define.h
, such as
It is also necessary to add a definition for the limit on the size of an Icon region:#define AllocType unsigned long int
where#define MaxBlock n
n
is the maximum size allowed (the default for MaxBlock
is MaxUnsigned
, the largest unsigned int). It generally
is not advisable to set MaxBlock
to the largest size an alternative
allocation routine can return. For the huge-memory-model implementation
mentioned above, MaxBlock
is 256000.
define.h
:
#define SourceSuffix (default: ".icn") #define U1Suffix (default: ".u1") #define U2Suffix (default: ".u2") #define USuffix (default: ".u") #define IcodeSuffix (default: "") #define IcodeASuffix (default: "")
USuffix
is used for the abbreviation that icont
understands in place of the complete U1Suffix
or U2Suffix
.
IcodeASuffix
is an alternative suffix that iconx
uses when searching for icode files specified without a suffix. For example,
on MS-DOS, IcodeSuffix
is ".icx"
and
IcodeASuffix
is ".ICX"
.icont
is given a source program in a directory different
from the local one ("current working directory"), there is a question
as to where ucode and icode files should be created: in the local directory
or in the directory that contains the source program. On most platforms,
the appropriate place is in the local directory (the user may not have write
permission in the directory that contains the source program). However,
on some platforms, the directory that contains the source file is appropriate.
By default, the directory for creating new files is the local directory.
The other choice can be selected by adding
#define TargetDir SourceDir
icont
and iconc
are defined by IconOptions
. The default value (see config.h
)
will do for most platforms, but an alternative can be included in define.h
.TUsage
for icont
and CUsage
for
iconc
. The default values, which should correspond to the value
of IconOptions
, are in config.h
, but may be overridden
by definitions in define.h
.
getopt()
, you can add
to use the library function instead of Icon's private version.#define SysOpt
uname()
library function,
the value of the Icon keyword &host
must be specified
by adding
to#define HostStr "identification"
define.h
.opendir()
and readdir()
functions for reading directories, add
to#define ReadDirectory
define.h
.
getch()
, getche()
,
and kbhit()
, add
to#define KeyboardFncs
define.h
.KeyboardFncs
if you supply your own
keyboard functions; see src/runtime/rlocal.r
for examples.
dlopen()
and dlsym()
functions for dynamic loading, add
to#define LoadFunc
define.h
.
to#define NoCoexpr
define.h
.
src/h/sys.h
to reflect the local location.iconic
. If this is the case for your platform, add
to#define NoIconify
define.h
. This disables the attribute iconic
,
causing references to it to fail.
iconc
, to process
its output defaults to cc
. If you want to use a different C
compiler, add
to#define CComp "name"
define.h
, where name
is the name of
the C compiler you want the Icon compiler to use. Note the quotation marks
surrounding the name. For example, to use Gnu C, add
By default, the C compiler is called with no options. If you want specific options, add#define CComp "gcc"
to#define COpts "options"
define.h
. Again, note the quotation marks. For example,
to request C optimizations, you might add
If your system does not have#define COpts "-O"
ranlib
, add
to#define NoRanlib
define.h
.
The default values (listed below) are appropriate for most platforms. If you want to change the values, read the discussion that follows.HSlots Initial number of hash buckets; it must be a power of 2 HSegs Maximum number of hash bucket segments MaxHLoad Maximum allowable loading factor MinHLoad Minimum loading factor for new structures
HSlots
hash buckets, using one
bucket segment. When the average hash bucket exceeds MaxHLoad
entries, the number of buckets is doubled and one more segment is consumed.
This repeats until HSegs
segments are in use; after that, structure
still grows but no more hash buckets are added.MinHLoad
is used only when copying a set or table or when creating
a new set through the intersection, union, or difference of two other sets.
In these cases a new set may be more lightly loaded than otherwise, but
it is never less than MinHLoad
if it exceeds a single bucket
segment.MaxHLoad
and 1 for MinHLoad
. Because splitting or combining buckets
halves or doubles the load factor, MinHLoad
should be no more
than half MaxHLoad
. The average number of elements in a hash
bucket over the life of a structure is about (2/3)*MaxHLoad
,
assuming the structure is not so huge as to be limited by HSegs
.
Increasing MaxHLoad
delays the creation of new hash buckets,
reducing memory demands at the expense of increased search times. It has
no effect on the memory requirements of minimally-sized structures.HSlots
and HSegs
interact to determine the minimum
size of a structure and its maximum efficient capacity. The size of an empty
set or table is directly related to HSegs+HSlots
; smaller values
of these parameters reduce the memory needs of programs using many small
structures. Doubling HSlots
delays the onset of the first structure
reorganization until twice as many elements have been inserted. It also
doubles the capacity of a structure, as does increasing HSegs
by 1.HSlots*(2^(HSegs-1))
.
A structure can be considered "full" when it contains MaxHLoad
times that many entries; beyond that, lookup times gradually increase as
more elements are added. Until a structure becomes full, the values of HSlots
and HSegs
do not affect lookup times.HSlots
and 6 for HSegs
. Sets and tables grow from 4 hash buckets to
a maximum of 128, and become full at 640 elements. For other machines, the
defaults are 8 for HSlots
and 10 for HSegs
. Sets
and tables grow from 8 hash buckets to a maximum of 4096, and become full
at 20480 elements.
All three of these are automatically defined if#define DeBugTrans /* debugging code for the translator in icont */ #define DeBugLinker /* debugging code for the linker in icont */ #define DeBugIconx /* debugging code for the run-time */
DeBu
g is defined.icont/tsym.c
). These functions are rarely
needed and there are no calls to them in the source code as it is distributed.icont/lcode.c
) and code for generating a debugging
file that is a printable image of the icode file produced by the linker.
This debugging file, which is produced if the option -L
is
given on the command line when icont
is run, may be useful
if icode files are incorrect.runtime/rmisc.r
and
runtime/rmemmgt.r
.define.h
as the final step in the implementation for a new
operating system.
coswitch()
is needed for context switching. This
routine requires assembly language, since it must manipulate hardware registers.
It either can be written as a C routine with asm directives or directly
as an assembly language routine.coswitch(old_cs,new_cs,first)
,
where old_cs
is a pointer to an array of words (C longs)
that contain C state information for the current co-expression, new_cs
is a pointer to an array of words that hold C state information for a co-expression
to be activated, and first
is 1 or 0, depending on whether
or not the new co-expression has or has not been activated before. The zeroth
element of a C state array always contains the hardware stack pointer (sp
)
for that co-expression. The other elements can be used to save any C frame
pointers and any other registers your C compiler expects to be preserved
across calls.to#define CStateSize n
define.h
, where n
is the number of elements
needed.coswitch
does is to save the current pointers
and registers in the old_cs
array. Then it tests first
.
If first
is zero, coswitch
sets sp
from new_cs[0]
, clears the C frame pointers, and calls new_context
.
If first
is not zero, it loads the (previously saved) sp
,
C frame pointers, and registers from new_cs
and returns.coswitch
has the form:
After you implement/* * coswitch */ coswitch(old_cs, new_cs, first) long *old_cs, *new_cs; int first; { ... /* save sp, frame pointers, and other registers in old_cs */ ... if (first == 0) { /* this is first activation */ ... /* load sp from new_cs[0] and clear frame pointers */ ... new_context(0, 0); syserr("new_context() returned in coswitch"); } else { ... /* load sp, frame pointers, and other registers from new cs */ ... } }
coswitch
, remove the #define NoCoexpr
from define.h
. Verify that StackAlign
and UpStack
,
if needed, are properly defined.tests/general/coexpr.lst
.
Ideally, there should be no differences in the comparison of outputs.