eX version 0.4b User's Manual                         File eXMan03.txt
(C) Copyright 1995, 1996 William E. Wilgus III.   All rights reserved.


Data Types and Entities

All data falls within one of two classes: numeric or alpha-numeric.  
Since some eX language components either can return a either a numeric
value or an alpha-numeric value---or both simultaneously---the concept
of a data class becomes a bit more significant than in more
traditional programming languages. 


Data Types

Numeric

All of the numeric data types are stored in in LSB ... MSB order.  The
short, long and single data types are converted to the data type
double when returned.  

Signed Integers
     The most significant bit is the sign bit, 0 for positive values
     and 1 for negative values, which are represented as a two's
     compliment. 

     Short     occupies 16 bits, or two (2) bytes, and has the range

                       -32,768 to +32,767

     Long      occupies 32 bits, or four (4) bytes, and has the range 
                -2,147,483,648 to +2,147,483,647


Floating-Point
     Floating-point numbers are in IEEE format, and consist of a sign,
     a mantissa, and an exponent.  The mantissa employs an implied
     bit, always considered to be set (1), just to the left of its
     most significant actual bit.  The exponent is biased, i.e. a
     fixed value is added to the true exponent.  The sign bit is the
     most significant bit. 
      
     Single    occupies four (4) bytes, is accurate to six (6) digits
               for positive numbers and seven (7) digits for negative
               numbers, and has the ranges

                      -3.402823^+38 to -1.40129^-45
                      +1.40129^-45  to +3.402823^+38

               The mantissa occupies bits 0--22, the exponent occupies
               bits 23--30, and bit 31 is the sign bit.  The exponent
               bias is 127.  


     Double    occupies eight (8) bytes, is accurate to fifteen (15)
               digits for positive numbers and sixteen (16) digits for
               negative numbers, and has the ranges

                   -1.797693134862316^+308 to -4.94065^-324
                   +4.94065^-324           to +1.797693134862316^+308

               The mantissa occupies bits 0---51, the exponent
               occupies bits 52---62, and bit 63 is the sign bit.
               The exponent bias is 1023.  


Alpha-Numerics

The single data type within the alpha-numeric data class is:  

String         is of variable-length and may be 0 to a theoretical
               32,767 characters.  The valid range of character values
               is 0---255.  In this implementation, a character
               occupies one byte (and is un-signed). 


String space is limited in this version because of the implementation
language.  


Literals
 
Literals are, as expected, not (themselves) addressable and therefore
may not be referenced or re-assigned values (in the usual sense). 
Numeric literals have the range of double values and may include
formatting commas.  String literals must be delimited with either
double quotes (", ASCII code 34) or reverse apostrophes (`, ASCII code
96) and may be 0 to a theoretical 32,767 characters in length.  


Converting Data Types

Data Type Cast Functions

eX provides a data type cast function for each of the numeric data
types.  They're primarily provided to convert numeric values to and
from string values that contain the numeric's value in its internal
storage format.  The general form is

                        function<<$>> Value#

The four functions are 

             double      long        short       single


The dollar sign $ is an optional string suffix, which tells the
function that the output is to be a string containing the argument
numeric in its internal storage format.  (You might like to note that
if you don't provide a value with a numeric component, eX will use the
numeric value 0.0 and go on about its business.)  If the string suffix
is absent and you provide the function with a string value, eX
presumes the string is an internal storage format numeric of the 
function's name data type and returns its value as a numeric.  If the
string value provided is not the proper length, eX will abort.  

The data type cast functions are also capable of coercing a numeric
data type to another data type.  The functions perform this task if
the string suffix $ is absent and a string value is not provided.  
(While at your current knowledge level it will make you scratch your
head, it is possible to provide a function with a `value' that has
neither a string component nor a numeric component; and in this case
eX uses the numeric value 0.0.)  
The capability is of dubious value: 

1. As with all numerics, the value is converted to data type 
   double when it is returned,
2. numerics are automatically converted to the appropriate data type  
   when a data entity is assigned, and
3. if the numeric value provided to the function exceeds that data
   type's range, an overflow occurs and eX crashes.

About the only valid use of this capability is to round to an integer.



String/Numeric Conversions

There are two eX functions that return the ASCII representation of the
argument numeric.  Both are actually filter functions (described in
the chapter `Functions and Filters') and are shown here in their
un-parenthesized argument form.  

The first, `str', provides no formatting capabilities. 

          str eev#
          str 123.45           returns the string 123.45

The second, `form', described in the chapter `Terminal', provides quite 
complete formatting capabilities. 


The eX function `val' returns the value of an ASCII representation 
numeric within a string.  The representation may be in any of the
numeric formats possible through the function form.  `val' expects the
ASCII numeric to be at the beginning of the string.  However, eX
provides several sub-string functions that can handle situations 
where this is not the case.  Both of the following, given without
explanation, return the numeric value 1234.56: 

         val nTerm("Amount due: $1,234.56", 1)
         val term("Amount due: $1,234.56", 3)


Data Entities

A data entity is a structure that has the capacity to store data that 
can be accessed via its identifier.  The type of data it may store
depends upon the data entity type.  eX includes the following data
entities, and their scope is global. 

     accumulators                      macros (programs)
     dequeues (double-ended queues)    variables
     disk files

eX currently lacks the ability to dimension data entities (create
vectors, arrays, matrices) other than the accumulator array. 
 
All data entities execpt the accumulators, disk files and dequeues are
created and initialized to either zero (numeric types) or null (string
types) when they are first encountered (referenced or addressed).  
The value of the data stored by a data entity is returned whenever it
is addressed, and the value of the data stored may be specified by an 
assignment operation; in this case, the value returned is the
post-assignment value.  All data entities except the accumulators can
be `destroyed' by use of the eX word `forget'.  (In the case of disk
files, this destruction is limited to knowledge of the file---the file
and its contents remain un-altered.)  

I'll discuss the two data entity concepts reference and address in
case you're not familiar with them or something in the preceding
paragraph struck you as a bit odd. 

A reference may be described in general as the process of providing
the identity of a data entity to be used in or by a process.  In eX,
all references are accomplished by providing the identity of a data 
entity as a value, and they often appear as literals in a program,
e.g.

              $alpha

An address may be described in general as the process of accessing the
data within a data entity, or returning the value stored by a data
entity.  In eX, all addresses are accomplished by providing a data
entity identifier, e.g. 

               $alpha. 

Returning to

                $alpha := "Hello!",

the variable identifier is indeed an address, but since it is an
assignment object, it has the auxiliary mission of reference.  (That's
the odd part.)  The post assignment value is made available to any
preceding tasks that are `looking' for a value.  (If you watch a data
entity assignment with eX's debugging facilities you'll notice that
the entity's value is actually returned twice---the pre-assignment
value when the address is encountered and then the post-assignment
value.)  An assignment is the only time an address is also a
reference.  A reference itself is never an address. 


Data Entity Allocation
 
Provision for individual data entities of each data type are made by
an allocation.   An eX allocation command may be given on the eX
invocation line, within a macro, or inter-actively to specify the
allocation for each data entity type.   The default allocations are
given later in the manual.  (Eliminating the need for allocations is
on the list of things to do.)  
 

                              WARNING:

With the exception that the currently executing macro is protected,   
allocation destroys all data within the data type.  An un-intentional
or erroneous allocation command might be catastrophic.


The Accumulators  
 
The foundation of eX is a two-dimensional array of dual accumulators,
one accumulator for numeric values, the other for alpha-numeric.  The
numeric accumulators are of the data type double and the alpha-numeric
accumulators are of the data type string.  The major array dimension
is termed the `plane' and the minor dimension is termed the `level',
and both dimensions may be allocated by the user/programmer. The
accumulators are initialized to zero (0) and null ("") upon entry to
eX and whenever they are re-dimensioned.  Accumulators values may be
loaded from or saved to disk files, but no specific commands are
provided to do so.  
 
The accumulator type to which accumulation occurs is automatically
appropriate for the data type of the operation taking place; i.e.,
numeric data is accumulated in a numeric accumulator and string data
is accumulated in a string accumulator.  The plane to which
accumulation is to occur is referred to as the `current plane' and may
be directly specified by the programmer, but this statement is only 
essentially true.  (The eX function `cPlane' can be used to obtain the
current plane number.)  The level to which accumulation is to occur is
referred to as the `current level', which is controlled by eX and may
not be directly specified by the programmer.  (The eX function cLevel
can be used to obtain the current level number of any plane.) 


Addressing the Accumulators

The accumulators are addressable and may be fully used as data
entities.  The symbol @, ASCII code 64, is used to address the
accumulators.  The numeric suffix #, ASCII code 35 is used to address
the numeric accumulator and the string suffix $, ASCII code 36 is used
to address the string accumulator.  In the absence of a suffix, both
accumulators are addressed simultaneously.  The accumulator plane,
level to be addressed may be specified within a parenthesized
argument.

                    @(plane#, level#)
                    @#(plane#, level#)
                    @$(plane#, level#)

Although I won't explain why until a later chapter, you should know
that the accumulator symbol and the arguments are at different
accumulator levels, and might be in different planes.  Therefore, 

                 @(cPlane, cLevel cPlane)

addresses the accumulators of the argument's plane and level, not
those of the accumulator symbol.  While there may be times when this
is what you want to do, there's hope for when it isn't and you don't
want to go to the trouble of keeping track of the plane and level
manually.  eX evaluates an accumulator argument as a function and
miracle of miracles, eX includes the functions fPlane (function plane)
and fLevel (function level) to solve the problem.  They return the
plane and level of the function name---not it's argument.  The
following addresses the accumulators of the plane, level in which the
accumulator symbol appears: 

                          @(fPlane, fLevel)

But now that I dragged you through all of that, if the current plane,
level accumulator(s) is (are) to be addressed, the argument may be
omitted: 

                    @
                    @#
                    @$


Changing Planes
    
The vertical bar `|', ASCII Code 124 is the token to change the plane.
The plane to change to must immediately follow the token and may be
specified as a numeric literal, numeric data entity identifier,
eXpression, or one or more plane, level stack `pop' operations, which
are specified by an apostrophe (', ASCII code 39).    
    
The current plane and level may be saved on a plane, level stack
internal to eX.  The token to do so is the apostrophe ('), and the
command may be placed anywhere except immediately after a left parens
or left bracket ([), or immediately after a right parens or right 
bracket (]).  (Those sequences have different meanings.)  The usual
place to push the plane and level would be just before the change
plane token (|), as illustrated in the following: 

                        '|1 ... |'

There aren't many circumstances where changing the plane is
advantageous, and it's likely that the process language symbology will
change.


Variables
 
The variable types provided in eX mirror the data types provided by
the language.  Variable identifiers have two parts: a data type prefix
and a name.  Commands to load variables from and save to disk files
are provided.  

      Prefix    Name             ASCII Code     Data Type
      ----------------------------------------------------------------
           $    Dollar sign        36             String
           _    Underscore         95             Short
          __    Dbl Underscore     95, 95         Long
           .    Period             46             Single
          ..    Dbl Period         46, 46         Double

Variable names must start with an alphabetic character but may include
ASCII numeric characters.  (Actually, except for the single precision
numeric data type, whose prefix is a period, all variable names may
begin with an ASCII digit in this version of eX.  However, this may
change.)  All variable name characters, as well their alphabetic case,
are significant.  Variable identifiers may be any length, but only the
first 31 characters, including the data type prefix, are significant. 
I've always liked the way some languages permit a punctuation-type
character, often an underscore `_' in a variable name: var_name. 
While eX doesn't permit them, you can aide readability with alphabetic
case: VarName.

Noting that I've used a hyphen in the preceding paragraph while
discussing readability, I can't help mentioning how rapidly they're
becoming extinct in printed text.  Is there no longer a difference
between `flower-like' (which I take to mean delicate) and `flowerlike'
(which I take to be Freudian)?  Are authors and editors simply
conserving paper?  If the latter, I think half-way measures should be
abandonedAndSimplyAdoptNewAndDifferentTechniquesAltogether.DYaGree?



Other Addressing Methods

Variable Type Numbers

As they're created, variables within a type are sorted in ASCII order
by identifier, and the list is re-sorted if one or more is forgotten
(via the eX word `forget').  Although it may and probably will change as
variables are created or forgotten, each variable always has a
variable type (position) number as long as it exists, and may be
addressed by it.  To do so, the variable type prefix is followed by
the number sign (#) and then the variable type number, which may be
given as a literal or a numeric variable or eXpression.   

                   ..#_NumericVariable
                   .#(1 + _NumVar)

(Changing eX so that a variable's type number remains constant as long
as it exists is quite high on the `things to do' list.)  
 
The eX function `VarId' (variable identity) may be used to determine the
reference argument variables's type number or identifier, as in either 

                      VarId .."Identifier"
                      VarId ..#1

VarId returns both the variable type number as an eev# and the
identifier as an eev$.  An attempt to address a variable via a type
number for which no variable exists will cause an error and macro
termination.  An argument given as an identifier will create the
variable if it did not already exist. 


Indirect Addressing
 
Variables may be indirectly addressed via a term or eXpression that 
provides the variable's type variable number or variable's name 
(no variable type prefix included).  

                     .(VariableName$)
                     .(TypeVariableNumber#)

The technique's syntax is similar to that of a parenthesized function
in that the variable type prefix serves as the `function name', and a
string or numeric literal, data entity, or eXpression serves as the
argument.  The technique may be `nested' to any depth in any mixture
of numeric and/or string `arguments', as in 

                  .($(StringVariableNumber#))
                  $(_(NumericVariableName$))

In the first, StringVariableNumber# `points' to the string variable
that contains the name of the single precision variable you wish to
address.  In the second, NumericVariableName$ contains the name of
the short integer variable that holds the variable type number of the
string variable you wish to address.  I find this capability very
useful with sub-programming.  (Are you starting to appreciate how
obscure eX macros CAN be?) 


Dequeues
 
eX implements dequeues (double-ended queues) by using ordinary string 
variables, and multiple dequeues may co-exist.  A string variable
becomes a dequeue host simply by using it for a dequeue operation, and
the variable does not need to exist (or be null "") prior to its use
as a dequeue.  The left side of the string is the bottom of the
dequeue and the right side is the top.  You'll need to remember that
with all of the dequeue operations and functions, the dequeue must be
referenced, not addressed. 

The four dequeue operations are:  

      push    Places a data item on top of the dequeue.  
      pop     Retrieves and removes a data item from the top of the 
              dequeue.  
      slide   Places a data item on the bottom of the dequeue.  
      slip    Retrieves and removes a data item from the bottom of the
              dequeue. 

I remember them from the facts that the top operations are the usual
assembly language nmemonics for `stack' operations, that the operation
words for each end both start with the same letter, and the word to
place data on the dequeue is longer than the word to remove it.  But I
must say eX was more fun before I re-named the operations to their
present names, because there was no possible way to remember the old
ones!

Push and slide will take list of values seperated by a
comma/whitespace combination (ASCII codes 44, < 33), and the comma
must immediately follow its preceding value producing term.  Numerics
are placed on dequeues as data type double.  In the case a term
provides both a numeric and a string, the numeric is pushed before the
string; but in a slide, the string goes on the dequeue first, then the
numeric.  In other words, when both a numeric and a string are placed
on a dequeue through a single value producing term or expression, the
numeric will be to the left side (or bottom) of the dequeue relative
to the string.  Although not covered until a subsequent chapter, a
data class filter may preceed a value producing term to restrict the
data placed on the dequeue to a single data class. 

The syntax for push and slide is

     Operation DequeueReference Value1<<, ..., ValueN>>

Assuming that the value of the variable $DequeueIdentifier is 
`$Dequeue1' prior to execution, the following are functionally
equivalent:

              push "$Dequeue1" 123.45
              push $DequeueIdentifier 123.45

The following demonstrates the use of an argument list:

            slide "$Dequeue2", ..Number, $String

Assuming `$Dequeue2' was null prior to the preceding, you can either 

                  pop "$Dequeue2"

to get the value that was within $String, or 

                  slip "$Dequeue2"

to get the value that was within `..Number'.  (A dequeue is
double-ended.)  You might like to note that a dequeue can be put on
itself as a string.  

The data type available at either end of a dequeue may be determined
by the functions  

      PopType, which returns the data type at the top of the dequeue, 

and  
      SlipType, which returns the data type at the bottom of the
                dequeue.  

The syntax is 

                Function DequeueReference



Macros
 
eX macros are executed from memory and stored as data type string, and
they're addressable and modifiable in all the ways that a string may
be.  Because it is usual that macros are `loaded' into memory from
disk files, macro identifiers must be valid eX file specifications. 
Un-like data files, a macro file must not be defined at the time it is
addressed (the address would be assumed to refer to a data file).  A
macro (usually) must be prefaced by a colon : (which serves as a data
type prefix) when it is addressed and must not be so prefaced when it
is referenced.  (I'll return to the `usually' above later.)

Macro files are ordinary `text' files and may be created with any text
editor or word processor that is capable of writing text files.  While
an explicit eX command may be employed to load a macro, a program
branch can automatically load the specified macro if it is not memory 
resident.  Although macro files might be employed as data files, no
specific facilities are provided to do so.  As already alluded, eX
macros themselves are capable of generating and/or modifying macros,
and these can be written to files using the eX `save macro' command,
discussed in the chapter `eX Commands'.  

Generally, elements of an eX macro must be separated by whitespace. 
The quantity of whitespace and the character(s) used are immaterial.  
There are exceptions to the rule, however, and those execptions will  
be disclosed at the appropriate points in the text.  The characters
recognized by eX as whitespace include the space (ASCII code 32) and
the carriage return (ASCII code 13).  The `official' whitespace
characters are given at the beginning of the chapter `Non-operator
Characters / Character Sequences'. 

Macros are virtually free-form.  The following (which regrettably use
things yet to be discussed) are equivalent:  

                  [{.x > 1.0}                                      (1)
                       show ".x > 1.0"
                  ~    
                       show ".x <= 1.0"
                  ]


       [{.x > 1.0} show ".x > 1.0" ~ show ".x <= 1.0"]            (2)

(They're if...then...else statements, if you hadn't guessed.)



Macro Components
 
In addition to operators, functions and data files (discussed in
subsequent chapters), macros may include the following components. 

Comments
 
Comments or remarks, are delimited with double asterisks (**, ASCII 
code 42).  Since they are inert, they may appear almost anywhere.  The
macro fragment 

        (5 + ** This is a comment in an aggregation ** 10)

is an illustration.  Delimited literals placed in a program in a way
that they do not alter the result of the process may also be employed
as remarks. 


eX Words
 
eX recognizes many specific ASCII alphabetic and ASCII alphabetic and
numeric character sequences to have meaning to the execution of a
macro, and they are recognized regardless of alphabetic case.  (This
version has 352.)  They perform various tasks; but the majority of
them are functions and produce values.  None of them are
reserved---i.e., all may be used as identifier names.  
 

Terms
 
A term is a macro component that either is, represents, or produces a
value; or, any individual component of the eX Language.  (I should be
shot for allowing the terminology of the language to become as muddled
as it is.)  The values produced or represented by macro components are
refered to as the previosuly introduced character sequence eev's.
 
eXpressions
 
An eXpression is a macro component that consists of one or more macro
terms that may, but not necessarily must, be associated with an
operator or operators.  It may contain one or more eX statements
and/or commands.  
 

Statements
 
eX statements begin with either a non-literal data entity (noun), or  
non-computational verb.  Statements beginning with a data entity have
the purpose of value assignment, and those beginning with a verb
variously have the purpose of data input/output (in which case they
are followed by a data entity or expression), program execution
control (and are usually followed by a program identification term or
eXpression), or ancillary control (and are usually followed by a data
term or expression).  Statements may contain terms, eXpressions, and
eX commands. 
 
Since statements do not incorporate a beginning operator, a statement
may appear within an eXpression and remain inert to the eXpression.  
However, many statements do produce values and may be made part of an
eXpression by preceding them with an operator.  In this case, the
objective of the statement is usually transparent to the eXpression.  
Additionally, such statements may be used as function arguments.  
Typically, those statements fall in the category of input/output and  
assignment statements.  

The no operation operator `nop' should precede a value-producing  
statement that must remain inert to the eXpression when the statement
would otherwise immediately follow an operator.  The nop has the
effect of postponing the operation until the next value-producing term
is encountered. 


eX Commands
 
eX commands are used to perform data entity allocation and to control
some processes, and may be used for the input and output of macros and
variables.  Any eX command may be used on the eX invocation line,
appear in a macro or, with the inter-active command itself excepted,
be used in the inter-active mode.  The data entity allocation commands
have the side effect of destroying all data within the data entity
type.  However, during a macro allocation command, the currently
executing macro (if any) is protected and will continue to execute.  
 

Data Files
 
Four fundamental data file modes are provided: sequential input,
sequential output, append (sequential output) and random access.  
Only sequential input files must exist prior to their use.  Input
and/or output operations may be specified via eX words (explicit
operations) or by addressing the file (implied operations).  

