                   Chapter 3 - The simple Modula-2 data types


             The material in this chapter is extremely important  to
        you as you strive to become a good Modula-2 programmer,  but
        you  may  also  find it to be somewhat  tedious  because  it
        contains so many facts.  This material is needed in order to
        develop the topics in the next few chapters,  but all of the
        details are not necessarily required.   For that reason, you
        may wish to go through it rather rapidly picking up the high
        points  and come back to this chapter for the details  later
        when  they will be much more meaningful.   Do not completely
        pass  over  this  material  at this time  or  the  next  few
        chapters  will be meaningless unless you are already  highly
        experienced in other programming languages.

                          A PROGRAM WITH VARIABLES

             Load  and display the program named INTVAR.MOD for  our
        first  program  with  some variables in  it.   This  program
        begins in the usual way since it has a MODULE header and the
        IMPORT  list.   Next we come to a new  reserved  word,  VAR.
        This  word is used to indicate to the compiler that we  wish
        to  define one or more variables.   In Modula-2,  there is a
        rule that says you can use nothing until it is defined.   If
        we  wish  to use a variable in the program,  we  must  first
        define  that it will exist,  and what kind of a variable  it
        is.  After  that,  it can be used in the program to do  what
        needs to be done.

             Following the reserved word VAR,  we have the  variable
        named "Count" defined.   The reserved word INTEGER following
        the  colon states that the variable "Count" will be of  type
        INTEGER.  This  means  that it can store  any  whole  number
        between  -32768 to 32767.   Don't worry too much about  this
        yet, the next program will completely define what an INTEGER
        type  variable is.   It is important to recognize that after
        we have defined the variable "Count",  it still doesn't have
        a value stored in it, that will come later.

             The  next line has two more variables  defined,  namely
        "x",  and "y".   They are also INTEGER type variables and do
        not  have a value stored in them yet.   You can think of the
        three  variables  as  three empty  boxes,  each  capable  of
        storing a number but with no number in them yet.   It  would
        be  perfectly permissible to put all three variables on  one
        line,  or  to  have separated them such that each was  on  a
        separate line.  At this point, the program doesn't know that
        there  is any difference between them,  because there  isn't
        any.   The  fact that one will contain the sum of the  other
        two  has no meaning yet,  the comments are only for us,  not
        the computer.




                                   Page 13









                   Chapter 3 - The simple Modula-2 data types


                        USING VARIABLES IN A PROGRAM

             Now  we will go to the program itself.   The first line
        sets  the variable "x" equal to 12,  in effect  putting  the
        number 12 in the box mentioned earlier.   The sign := is the
        Modula-2  symbol for assignment.   It is most meaningful  to
        read  the symbol "gets the value of" since it is not  really
        stating  a  mathematical equality but is saying  in  effect,
        "assign the value of this to the variable at the left."  The
        entire  line can be read as "x gets the value of 12."  There
        is now a value assigned to the variable "x" declared in  the
        header.   The  next statement assigns the value of 13 to the
        variable "y".   Finally the value of the data stored in  the
        variable "x" is added to the value of the data stored in the
        variable "y", and the sum is stored in the variable "Count".
        We  have  therefore done our first calculations in  Modula-2
        but we will do many more before this tutorial is completed.

             Notice  that  each  statement  is  terminated  with   a
        semicolon,  a Modula-2 requirement.

             The  three variables are then displayed on the  monitor
        with  appropriate  prose to identify  them.   The  only  new
        statement  here  is  the "WriteInt" procedure that  needs  a
        little  explanation.  This  procedure is used to  output  an
        INTEGER  type variable to the monitor or whatever device  is
        being  used.   By  definition,  it contains  two  quantities
        within the parentheses,  the variable name and the number of
        columns it should fill.   If there are not enough columns to
        output the data, more will be used so that no digits will be
        truncated.   If all are not needed,  leading blanks will  be
        output.   If  the variable "x" had the value of 1234 when we
        came to program line 18,  all four digits would be output in
        spite of the request for three.  Since "x" has the value  of
        12, only two columns will be used and one leading blank will
        be  output.   In like manner,  "y" is allotted 4 columns and
        "Count" is to be output in 6 columns.

             The last two lines of the program assign new values  to
        two  of  the variables.   The variable "x" is  assigned  the
        value  of  FF hexadecimal which is 256 decimal,  and "y"  is
        assigned the value of 177 octal which is 127 decimal.   This
        is only done as an illustration to you of how it is done. If
        you  don't understand these two  numbering  systems,  simply
        ignore this until you have a need for it.

             Compile and run this program to see if it does what you
        expect  it  to do.   The important thing to notice  in  this
        program is the variable definition in the definition part of
        the module and the variable assignment in the program  part.
        It  should be obvious,  but it would be well to mention that


                                   Page 14









                   Chapter 3 - The simple Modula-2 data types


        the  definition part of the module extends from  the  module
        name   to  the  reserved  word  "BEGIN"  and  is  where  all
        definitions  are put.   Likewise,  the program part  of  the
        module  includes  all  statements from the  "BEGIN"  to  the
        "END".

                           SIMPLE VARIABLE TYPES

             Modula-2 has several predefined data types that you can
        use  in your programs.   You also have the ability to define
        any  number of complex types built up from the simple  types
        but  we will not discuss this until we get to chapter 6  and
        beyond.   The  simple types  are  INTEGER,  CARDINAL,  REAL,
        BOOLEAN,  and  CHAR.   Each has its own purpose and its  own
        peculiarities and we will cover each type one at a time.

                       THE SIMPLE VARIABLE - INTEGER

             Load  and display the program named INTMATH.MOD for  an
        example  of  INTEGER math.   In the declaration part of  the
        program (the part prior to the BEGIN) we have 7 INTEGER type
        variables defined for use in the program.   We will use them
        to illustrate INTEGER arithmetic.

            An INTEGER variable, by definition,  can store any whole
        number  between -32768 and 32767.   An attempt to store  any
        other  value in an INTEGER type variable should  produce  an
        error by your compiler but it may produce some other result.
        Some  compilers may store a -32769,  which is one count  too
        low,  as a 32767 which is at the top end of the range.  This
        is  due  to the two's complement arithmetic that  you  don't
        need to understand at this point.  It will be left to you to
        determine what your compiler does in such a case.

             The first line in the program is nothing new to you, it
        simply assigns the variable "A" the value of 9.   The second
        line adds 4 to the value stored in the variable "A" and  the
        result,  13, is stored in the variable "B".  Next the values
        stored  in the variables "A" and "B" are added together  and
        the  sum,  which  is  9  + 13,  is stored  in  the  variable
        "IntSum".  Continuing in the same manner, the difference and
        the  product  are calculated and stored.   When we  come  to
        INTEGER  division,  we are breaking new ground  because  the
        result  is  truncated to the largest whole number  resulting
        from the division.   Thus 13 DIV 9 results in 1 because  the
        remainder  is simply dropped.   The next construct,  B MOD A
        results  in the remainder of the division,  in this case  4.
        You  will find these operations very useful as you  progress
        as a Modula-2 programmer.




                                   Page 15









                   Chapter 3 - The simple Modula-2 data types


             The  intent of the next line is to illustrate that  you
        can  do  several math operations in a statement if  you  are
        careful to put the parentheses in the proper places.   There
        are definite rules about operator precedence but I recommend
        that  you use lots of parentheses to remove all doubt as  to
        what the results will be.

             The  results  of  the operations  are  displayed  in  6
        columns and we move on to several new operations.  The first
        new  operation is the "INC" which is short for  "increment".
        This  simply  increments the variable contained  within  the
        parentheses and if a second argument is given,  the variable
        is incremented by the value of that variable. In like manner
        the   "DEC"  procedure  decrements  the  variable   in   the
        parentheses  by  one  unless a second argument is  given  in
        which case the variable is decremented by the value of  that
        variable.

             It  may  not  be clear at this point,  but  the  second
        variable  itself  may  be another variable name  or  even  a
        composite  of  several as long as it results in  an  INTEGER
        type variable.  This is illustrated in the program.

             Finally,  we  come  to the last two procedures in  this
        program, the "MIN" and the "MAX".  These two procedures will
        return  the value of the smallest possible  INTEGER,  -32768
        and  the largest possible INTEGER,  32767.   These  are  the
        values returned for a 16 bit microcomputer which is what you
        are  probably  using  since that is what  this  tutorial  is
        intended for.  It would be well to add that not all Modula-2
        compilers  implement  these  functions so you  may  need  to
        comment out these two lines in order to compile and run this
        program.

             Compile  and run this program and observe  the  output.
        If  your  compiler results in errors,  you may have to  make
        some  changes  in  order  to  compile  it.    Refer  to  the
        COMPILER.DOC file on the distribution disk for notes on some
        of the more popular Modula-2 compilers.

                       THE SIMPLE VARIABLE - CARDINAL

             Load  and  display the file named CARDMATH.MOD  for  an
        example of CARDINAL mathematics and output.  In this file, 7
        variables are defined as CARDINAL and one more as INTEGER. A
        CARDINAL variable can store any whole number from 0 to 65535
        in  a  16  bit  microcomputer,  although the  range  may  be
        different if you are using an unusual computer or compiler.

             The first few lines are the same as the last program so
        very  little  needs  to be said about them  except  for  the


                                   Page 16









                   Chapter 3 - The simple Modula-2 data types


        subtraction  example.   In  this  case,  the result  of  the
        subtraction  would be negative if it were carried out as  in
        the  last program so "A" is subtracted from "B".   It is  an
        error  to attempt to store a negative number in  a  CARDINAL
        type  variable.   For that reason,  a CARDINAL should not be
        used  if there is any chance that it will be required to  go
        negative.   Programming experience will be the best  teacher
        when  it  comes  to deciding what variables to use  in  each
        situation.

             In this program the variables are once again displayed,
        but  now the procedure named "WriteCard" is used for  output
        because the variables to output are CARDINAL.

             The  next  two  statements indicate  that  INTEGER  and
        CARDINAL variables are "assignment compatible" meaning  that
        they  can  be assigned to each other with the  :=  operator.
        They cannot however, be mixed in calculations.  Constants in
        an  expression  are  assumed to be of the same type  as  the
        variables in the expression and they must agree.   For  that
        reason,  the expression in line 36 is invalid because (-112)
        is required to be a CARDINAL constant but it is negative and
        therefore not CARDINAL.  In the prior line it is permissible
        to  subtract 112 from the value of "A" as long as the result
        is still positive.  As an exercise, change line 34 such that
        a number less than 112 is assigned to "A".  The program will
        compile without error but when you run it,  you should get a
        runtime  error  because the CARDINAL assignment  is  out  of
        range.   Notice  that the constant value of -112 is allright
        for use an an INTEGER variable.

             The remaining statements in the program are the same as
        the last program so additional explanation is unneeded.   It
        would be good to point out that in the case of CARDINAL, the
        "MIN"  and  "MAX"  procedures will return values  of  0  and
        65535 for most 16 bit implementations.

             Compile and run this program remembering that it may be
        necessary  to comment out the "MIN" and "MAX" statements  to
        get a successful compilation.

                         THE SIMPLE VARIABLE - REAL

             Load  and display the program named REALMATH.MOD for  a
        demonstration of the data type REAL.  The definition part of
        this  program is similar to the last with some additions  to
        the IMPORT list.   Your compiler may use different names for
        some of the procedures here,  so if you get a compile  error
        you  will  need to modify these.   We will study the  IMPORT
        (and EXPORT) list in detail later, so be patient.



                                   Page 17









                   Chapter 3 - The simple Modula-2 data types


             Several  REAL variables and one each of the INTEGER and
        CARDINAL types are defined for use in the program.  The REAL
        type  variable can contain numbers in a wide range and  with
        fractional  parts  included.    The  exact  range,  and  the
        accuracy will vary widely depending on your  implementation.
        It  will be up to you to check your reference manual for the
        limits on your computer and compiler.  A REAL type number is
        defined  as one with a decimal point.   The mathematics  are
        the  same  as with the other two except  that  the  division
        symbol  is the slash (/).   There is no "MOD" for REAL  type
        numbers because there is theoretically no remainder, since a
        fractional part is computed as part of the calculation.

             The  four results are displayed on the monitor with  12
        columns  allowed  for  each  result  and  two  extra  blanks
        displayed  between each number.   Unfortunately,  we have no
        control over how many digits will be displayed following the
        decimal point.   This would be nice for outputting data in a
        financial  model  where  we would like to  have  two  digits
        following  the decimal point.   When we get to the  advanced
        part  of this tutorial,  we will write our own procedure for
        doing  that  in  such a way that we can  call  it  from  any
        program just like we call these output procedures.

                       CONVERSION BETWEEN DATA TYPES

             Beginning  in  line  37,  we  assign  the  INTEGER  and
        CARDINAL  variables  some values and convert the  values  to
        type REAL by using the procedure "FLOAT".   We then  convert
        the  variable  "Sum" to INTEGER and CARDINAL by use  of  the
        procedure "TRUNC".  The fractional part, if any, will simply
        be  thrown away.   These procedures will be very  useful  in
        many of your programs.

             The  last  two  lines return the value of  the  largest
        possible  REAL number and the smallest REAL number for  your
        implementation.   Once again,  your compiler may not support
        these two functions and they may have to be commented out in
        order to compile.

             Compile and run this program.

                       THE SIMPLE VARIABLE - BOOLEAN

             Load  and display the file named BOOLMATH.MOD  on  your
        monitor  for  an example of BOOLEAN  variables.   A  BOOLEAN
        variable  can only have one of two possible values,  TRUE or
        FALSE.   These variables cannot be printed directly but  can
        be  used  to control other print statements to print  out  a
        representation of their value.  We will see how later.



                                   Page 18









                   Chapter 3 - The simple Modula-2 data types


             We  define 3 BOOLEAN variables and 3 INTEGER  variables
        and  assign values to the 3 INTEGER variables in the program
        for  use  in these illustrations.   In line 13  the  BOOLEAN
        expression "A = 22" is TRUE,  therefore the BOOLEAN variable
        "IsIt"  is  assigned the value TRUE.   The  variable  "IsIt"
        could be used later in the program to make a decision,  by a
        yet undefined method, to do something or bypass it.  In like
        manner,  the  next statement assigns "IsIt" the value  FALSE
        because A is not equal to 23.   The remainder of the allowed
        BOOLEAN  expressions are defined in the next few  lines  and
        are left for your inspection and study.

             Beginning in line 25, composite BOOLEAN expressions are
        illustrated.   As many BOOLEAN expressions as desired can be
        combined with AND and OR operators.   If two or more BOOLEAN
        expressions are combined with the AND, the result is TRUE if
        all   expressions  are  TRUE.    If  two  or  more   BOOLEAN
        expressions are combined with the OR,  the result is true if
        any of them are TRUE.  The NOT operator inverts the sense of
        what it modifies,  it turns a TRUE to FALSE and  vice-versa.
        Finally a couple of composite BOOLEAN expressions are  given
        for  illustration  of  the  amount  of  complexity  that  is
        allowed,  although there is no real limit as to how far  you
        can go with the complexity.  Good programming practice would
        dictate that you keep it simple and understandable.

                      TWO RULES FOR BOOLEAN EVALUATION

             First  it  is important that you use the same  type  of
        variables  within  a  BOOLEAN  expression.   REAL's  can  be
        compared  to  REAL's and INTEGER's to INTEGERs,  but  REAL's
        cannot  be compared to INTEGER's.   CARDINAL and CHAR  types
        can  also  be compared to their own types,  but none of  the
        four can be compared directly to each other.

             Secondly, Modula-2 uses a shortcut evaluation technique
        for  BOOLEAN evaluation.   Evaluation proceeds from left  to
        right  and  if  it  finds a  result  which  will  positively
        determine the outcome, evaluation stops.  For example, if it
        is evaluating a string of 5 comparisons all combined with an
        AND,  and it finds that the second term is FALSE, evaluation
        stops there.  Since all terms must be TRUE for the result to
        be TRUE,  it makes no difference what values the last  three
        are, the result will be FALSE because of the second term.

                         THE SIMPLE VARIABLE - CHAR

             Load  and display the program named CHARDEMO.MOD for an
        illustration of the last simple variable type,  CHAR.   Text
        data is stored in a computer in a format utilizing the  CHAR
        data type.  Although there are exceptions, such as when text


                                   Page 19









                   Chapter 3 - The simple Modula-2 data types


        is  stored  in some form of a packed mode,  this  is  nearly
        always  true.    This  tutorial  was  written  with  a  word
        processor  that uses a CHAR type for text storage,  and  few
        word processors use any other method.

             Although  there are many different ways to store  text,
        only  two are used to any level of significance,  EBCDIC and
        ASCII.  ASCII is used almost exclusively in micro computers.
        I have never heard of an implementation that used EBCDIC  in
        a  microcomputer,  so we will limit our discussion to ASCII.
        This merely refers to the way the characters of the alphabet
        and  all other characters are represented in  the  computer.
        The  ASCII standard defines that the value of 65 will be the
        letter 'A',  66 will be the letter 'B',  etc.   If  everyone
        uses  the same standard,  transfer of data from one computer
        to another is greatly simplified.

             The program named CHARDEMO has the usual header with  4
        CHAR  type  variables defined for use in  the  program.   An
        INTEGER is also defined.  In the program itself, we begin by
        assigning  2 of the variables some CHAR data.   Since a CHAR
        variable  is  capable of storing  one  letter,  numeral,  or
        special  character,  each variable is assigned  one  letter.
        The single or double quotes are used as an indication to the
        compiler  that you intend for it to use the letter as a CHAR
        type  variable  rather than as another  variable  name.   Of
        course  if  you wanted to use "A" as a  variable  name,  you
        would  have  to  define  it in the definition  part  of  the
        module.

                        TWO SPECIAL CHAR PROCEDURES

             The  next  instruction gets the ordinal  value  of  the
        letter  "A",  adds two to it,  and assigns that value to the
        variable  "Index",  which  must be an INTEGER  (although  it
        could  have  been  defined as a  CARDINAL).   Refer  to  the
        documentation that came with your computer and you will find
        an  ASCII  table  that will define the  letter  "A"  as  65.
        Finally,  the  CHAR  type  variable "Dog3" is  assigned  the
        character value of "Index".  Your ASCII table should  define
        67  as the letter "C".   It is important to understand  that
        the    CHAR   variable   "Dog3"   contains   the   character
        representation of the letter "C",  and the INTEGER  variable
        "Index"   contains   the  numerical  value  of   the   ASCII
        representation  of  the letter "C".   It would be  perfectly
        allright  to  use  the  variable  "Index"  for  any  desired
        numerical calculations,  but not to display the letter  "C".
        On the other hand,  it would be allright to use the variable
        "Dog3" to display the letter "C" on the monitor but it could
        not be used for any calculations.  The purpose therefore, of
        the two procedures "ORD" and "CHR", is to translate from one


                                   Page 20









                   Chapter 3 - The simple Modula-2 data types


        type to the other.

             The  variable  "Cat4" is assigned the double  quote  by
        enclosing  it in the single quotes,  and the characters  are
        output in a funny order to spell "CAT.  The variable "Char1"
        is  assigned  the  value "S",  and  the  word  is  completed
        resulting  in the full word "CATS" on the monitor after  the
        program  is compiled and run.

            If this were the only way to use the CHAR type variable,
        it  would  be very tedious and frustrating,  but  there  are
        other  methods to use the CHAR type that are far more useful
        as you will see.

             Next,  an  additional  means of assigning a  CHAR  type
        variable is given.  By assigning the CHAR variable "65C", it
        is  the same as writing CHR(65),  resulting in the  variable
        having  the  internal  value "A".   A number less  than  256
        followed  by  a "C" is defined by Modula-2 as  a  CHAR  type
        constant.

             Finally,  the  variable "Char1" is assigned the  letter
        "a" and it is converted to upper case "A" with the procedure
        CAP.   This procedure will convert the argument to its upper
        case  equivalent  if  it is a lower  case  letter.   If  its
        argument is an upper case letter or any other character,  it
        will do nothing to it.

             Compile and run this program and observe the output.

                          USING THE TRANSFER PROCEDURES

             Load  and  display  the  file  named  TRANSFER.MOD  for
        several  examples of transferring data between  the  various
        simple  data types.   The transfer functions given here  may
        not  seem  too important at this time,  but some time  spent
        here will help to reduce the frustration later when you  get
        seemingly  wrong errors that say you are using  incompatible
        types  in  a  statement.   All of the program  will  not  be
        discussed,  only  those statements that use some of the more
        unusual capabilities of Modula-2.

             In  line  13,  the  calculations are  done  in  INTEGER
        format,  but  due to the assignment compatibility of INTEGER
        and CARDINAL, the result is converted to CARDINAL across the
        ":=".  Line 16 is an illustration of mixed mathematics using
        the  transfer  procedure  INTEGER.   Line 20  is  the  first
        example  of "nested" procedures which must be  done  because
        FLOAT only uses a CARDINAL for an argument.




                                   Page 21









                   Chapter 3 - The simple Modula-2 data types


             The  expression  in line 22 is an error  because  TRUNC
        results  in a CARDINAL which cannot be added to an  INTEGER.
        Either  of the next two lines fix the problem by making  the
        addition  type-compatible then making use of the  assignment
        compatibility  between INTEGER and CARDINAL for line  number
        23.   The same error occurs in line 26 and is fixed the same
        way in either of the next two lines.   Once again,  in  line
        31,  the  incompatible  type  error occurs and is  fixed  in
        either of two ways in the next two lines.

             Lines  35  and  36 illustrate converting CHAR  data  to
        first  CARDINAL  then REAL which requires  nested  procedure
        calls.  The last line of the program is a nest of procedures
        which  converts a character from CHAR to CARDINAL,  then  to
        REAL,  back  to CARDINAL,  and finally back to the  original
        CHAR  variable.   It  does  nothing except  act  as  a  good
        illustration to you of what can be done.

             Conversion  between types is very important.   You will
        use  these techniques often so it is important to  know  how
        they  work.   A  very  simple yet helpful memory aid  is  to
        remember  that any simple type can be converted to  CARDINAL
        and  CARDINAL  can be converted to  any  type.   Most  other
        conversions require two steps to get from one to the other.

             Chapter  14  will readdress this topic with  even  more
        extensive type transfer procedures.

        PROGRAMMING PROBLEMS

        1.   Write  a program in which you define,  using the CHAR
             type variable, the letters "a" and "z", and the numbers
             "0" and "9".  Convert them to CARDINAL, and display the
             four characters and their ASCII (numerical) values.

        2.   Write a program that you can easily modify to experiment
             with conversions between the various types that result in
             incorrect conversions to see the results on your compiler.
             For example, convert a -1 as an INTEGER to a CARDINAL.














                                   Page 22
