Part IV: The ACTION! Language

Chapter 3: Fundamental Data Types

Before discussing the Fundamental Data Types, something must be said about variables and constants, since they are the basic data objects the computer manipulates.

3.1 Variables

Legal variable names must be valid identifiers. Other than this there is no restrictions on variable names. Because a working knowledge of functions and procedures is required before discussing the scope of a variable, the topic is presented later in Chapter 6.3.

3.2 Constants

There are three types of constants in ACTION!: numeric constants, string constants, and compiler constants.

Numeric constants may be entered in theree different formats:

  1. Hexadecimal
  2. Decimal
  3. Character

Hexadecimal constants are represented by a dollar sign ($) in front of the number.

Examples:

$4A00
$0D
$300

Decimal constants require no special character to define them as decimal.

Examples:

65500
2
324
46

NOTE: Both hexadecimal and decimal numeric constants may have a negative sign in front of them, thus:

-$8C
-4360

Character constants are represented by a single quote (') preceeding the character. Characters are numeric constants because they are internally represented as one byte numbers, as per the ATASCII character code set.

Examples:

'A
'@
'"
'v

String constants consist of a string of zero or more characters enclosed by a double quotes ("). When stored in memory, they are preceeded by their length. The double quotes are not considered as part of the string; if you want a " in your string, place two double quotes together (see examples).

Examples:

"This is a string constant"
"a "" double quote in a string"
"58395"
"q"         ; a single character string constant

Compiler constants are different from the above types of constants, in that they are used at compile time to set certain attributes of variables, procedures, functions, and code blocks, and are not evaluated at run-time. The following formats are valid:

  1. A Numeric Constant
  2. A Predefined Identifier
  3. A Pointer Reference (see Chapter 8.1.2)
  4. The Sum of Any Two of the Above

We have already talked about the first format, but the other three require some explanation. When you use a predefined identifier (i.e., a variable, procedure or function name) in a compiler constant, the value used is the address of that identifier. The third format allows pointer references as compiler constants. The last one permits you to do simple addition of a combination of any two of the other three types. Here are some examples which show the valid formats in use:

cat     ;uses the address of the variable 'cat'
$8D00   ;a hex constant
dog^    ;a pointer reference as a constant
5+ptr^  ;5 plus the contents of the pointer 'ptr'
$80+p   ;evaluates to $80 plus the address of 'p'

3.3 Fundamental Data Types

Data types allow humans to make sense out of the stream of bits the computer understands and manipulates. They allow us to use concepts we understand, so we need not know how the computer does what it does. ACTION! supports three fundamental types and some advanced extensions of these (see Chapter 8 for the extended types). The basic ones are BYTE, CARD, and INT, and are numeric, and so allow you to use numeric format when entering data.

3.3.1 BYTE

The type BYTE is used for positive integers less than 256. It is internally represented as a one-byte, unsigned number -- its values range between 0 and 255. At first glance this might seem a useless type, but it has two worthwhile applications. When used as a counter in loops (WHILE, UNTIL, FOR) program speed will increase because it's easier for the computer to manipulate one byte than many.

Also, since characters are represented inside the computer as one-byte number, BYTE is also useful as a character type. In fact, the ACTION! compiler allows you to use the keywords BYTE and CHAR interchangably, so those of you with PASCAL and C experience can use CHAR when dealing with characters and feel more at home.

3.3.2 CARDinal

The CARD type is very similar to the BYTE type, except that it handles much larger numbers. This is because it is internally represented as a two-byte unsigned number. Hence its values range from 0 to 65,535.

TECHNICAL NOTE: a CARD is stored in the LSB, MSB form which is standard on 6502-based machines.

3.3.3 INTeger

This type is like BYTE and CARD in that it is integer only, and can be entered in numeric format, but that is where the similarity ends. INT allows both positive and negative numbers ranging from -32768 to 32767. It is internally represented as a two byte signed number.

TECHNICAL NOTE: INTs are stored LSB, MSB like CARDs.

3.4 Declarations

Declarations are used to let the computer know that you wish to define something. For example, if you want the variable 'cost' to be of the type CARD, somehow you have to tell this to the computer. Otherwise the computer won't know what to do when it sees 'cost'.

Every identifier you use must be declared before it is used, whether it's a variable, procedure, or function name. Variable declarations will be explained here, followed by a note about numeric constant declarations; procedure and function declarations are explained in chapter 6.

3.4.1 Variable Declaration

The procedure for declaring a variable is the same no matter what fundamental type you want it to be. The basic format is:

<type> <ident>{=<init info>} |:,<ident>{=<init info>}:|

where

<type>        is the fundamental type of the
              variable(s) being declared
<ident>       is an identifier naming the variable
<init info>   allows you to initialize the value
              of the variable, or define the
              memory location of that variable

'<init info>' has the form:

<addr> | [<value>]

where

<addr>    is the address of the variable,
          and must be a compiler constant
<value>   is the initial value of that
          variable, and must be a numeric
          constant

NOTE: an explanation of <, >, {, }, |:, :|, and | can be found in the vocabulary (Chapter 2).

Notice that you can optionally have more than one variable declared by one <type>. You can also optionally tell the compiler where you want each variable to reside in memory or initialize the variable to a value. The following examples should help clarify this format:

BYTE top,hat     ;declare 'top' and 'hat' as BYTE
                 ;variables

INT num=[0]      ;declare 'num' as an INT variable
                 ;and initialize it to 0

BYTE x=$8000,    ;declare 'x' as BYTE, placing it
                 ;at memory location $8000
     y=[0]       ;declare and initialize 'y'

CARD ctr=[$83D4],    ;declares and initializes
     bignum=[0],     ;three variables as CARD
     cat=[30000]     ;type

In the last two examples you may note that the variables need not be on the same line. The ACTION! compiler will keep reading in variables of the type given as long as there are commas separating them, so remember not to put a comma after the last variable in a list (strange things will happen if you do).

Variable declarations must come immediately after a MODULE statement (see Chapter 7.4) or at the beginning of a procedure or function (see Chapters 6.1.1 and 6.2.1). If you use them anywhere else, you will get an error.

3.4.2 Numeric Constants

Numeric constants are not explicitly declared. Their usage declares their type. A numeric constant is considered to be of type BYTE if it is less than 256, otherwise it is considered to be of type CARD. For all practical purposes, negative constants (e.g. -7) are treated as type INT:

ConstantType
543CARD
$0DBYTE
$F42CARD
'WBYTE