2.4. Variables

A variable is simply an identifier that holds a value. These identifiers have types associated which define how much space is required to hold the value. The following types are built-in:

The complete format for defining a variable is:

      VAR [VOLATILE] [SHARED] type[*cexpr] identifier [ '[' [ cexpr ] ']' ]
        [ { AT cexpr [ ':' bit ] | var [ ':' bit ] | '{' cexpr1[',' cexpr2...] '}'
          | IS var }
        [ '=' cexpr | '{' cexpr1',' ... '}' | '"'...'"' ]
        [',' identifier2...]

This is, by far, the most complex construct in all of JAL, so I'll describe it one piece at a time below. Once variable definition is understood, everything else is easy!


Denotes the beginning of a variable definition.


The VOLATILE keyword guarantees that a variable that is either used or assigned will not be optimized away, and the variable will be only read (or written) once when evaluating an expression.

Normally, if a variable is assigned a value that is never used, the assignment is removed and the variable is not allocated any space. If the assignment is an expression, the expression *will* be fully evaluated. If a variable is used, but never assigned, all instances of the variable will be replaced with the constant 0 (of the appropriate type) and the variable will not be allocated any space.


Tells the compiler that this variable exists in shared memory, so there is no need to set bank bits (14 bit cores), or the BSR register (16 bit cores).


type is one of the predefined types (above). If type is BIT, BYTE, or SBYTE it can be extended using [*cexpr]. For BYTE and SBYTE, this means the variable will be defined as an integer using cexpr bytes, eg WORD is simply shorthand for BYTE*2.

If type is BIT, the definition changes. A BIT variable, as defined in JAL, is really of type boolean. When assigned any non-zero value, it takes on the value of 1. Using the [*cexpr], the definition changes to be more like a C bit field: assignment is masked. For example:

                VAR BIT*2 cc
when assigning to cc, the assignment is:

                cc = (value & 0x03)


Any valid JAL identifier

'[' [ cexpr ] ']'

Defines an array of cexpr elements. The array index starts at 0 and continues through (cexpr - 1). cexpr must be >= 1. An array *must* fit entirely within a single PIC data bank.

If cexpr is ommitted, the '=' term must exist and the size of the array will be set to the number of initializers present.

BIT arrays are *not* supported.

AT cexpr [ ':' bit ]

Places the new variable at location cexpr. If it is a BIT variable, [ ':' bit ] defines the bit offset with the location. Any location uses for explicit placement will not be allocated to another variable.

AT var [ ':' bit ]

Places the new variable at the same location as an existing variable. Any location uses for explicit placement will not be allocated to another variable.

AT '{' cexpr1[',' cexpr2...] '}'

Places the new variable at multiple locations. On the PIC, many of the special purpose registers are mirrored in two or more data banks. Telling the compiler which locations hold the variable allows it to optimize the data access bits.

IS var

Tells the compiler that this identifier is simply an alias for another. This has been deprecated, use "ALIAS identifier IS identifier1" instead.

'=' expr

Shorthand assignment. The variable will be assigned expr.

'=' '{' expr1 [',' expr2...] '}'

For an array variable, the elements will be assigned expr1, expr2, ...

'=' '"' ... '"'

For a variable array, this assigns each ASCII value between '"' and '"' to one element of the constant array. Unlike C, there is no terminating NUL.

'=' "..."

For an array variable, the elements will be assigned one the ASCII values inside the quotes.

= "abc" is equivalent to = {"a", "b", "c"}

',' identifier2...

Allows defining multiple variables with the same attributes:

                VAR BYTE a,b,c