Variables in XC=BASIC are statically allocated memory areas that are assigned an identifier (name) and a type that can not be changed.
Variables don't need to be explicitly defined. The compiler will create the variable the first time it encounters them in a LET
, DIM
or DATA
statement.
Example:
let a = 1 rem -- a is now defined print a rem -- the following is invalid because b is used prior to being defined print b let b = 2
Since version 2.1, some variables can be placed on the zeropage for faster load/store operations. You can use the DIM
directive to define a variable as fast variable, for example:
dim myFastVar fast
This is limited however (max 15 bytes currently). The compiler will emit a warning if no more variables can be placed on the zeropage.
The type of a variable is specified using a sigil that is appended to the variable name. If omitted, the variable will be recognized as integer. The following types are supported:
Type | Sigil | Numeric range | Size in bytes |
---|---|---|---|
Byte | ! | 0 to 255 | 1 |
Integer | # or none 1) | -32768 to +32767 | 2 |
Float | % | ±2.93873588E−39 to ±1.70141183E38 | 5 |
String pointer | $ | 0 to 65535 | 2 |
If different types take part of an expression, all members of the expression will be implicitly promoted to the larger type and a warning will be emitted in compile time. This means that:
Example:
let anInt = 5 let anotherInt = 6 let aFloat% = 3.14 print anInt + anotherInt + aFloat% rem -- the above expression will return a float while anInt and anotherInt rem -- will be promoted to floats
The above program will compile fine, with a warning:
Warning: implicit type conversion in line 4
Implicit conversion from byte to integer does not emit a warning.
A parenthesized sub-expression is considered to be a single member of its parent expression. Implicit type casting does not apply to members of the sub-expression. Take the following code sniplet for example:
anInteger = 4 aByte! = 255 anotherByte! = 1 result = anInteger * (aByte! + anotherByte!)
You may expect that someByte
and anotherByte
will be converted to integers first and then their sum will be multiplied with anInteger
. This is not how it will work though. The expression will be evaluated as follows:
aByte! + anotherByte!
) is evaluated as byte. The numbers are added up, and an overflow occurs (255 + 1 = 0)anInteger
) is an integer. So the other member (which is now evaluated to 0) is converted to an integer and the two factors are multiplied. The result is 0.To solve this problem you have to explicitly cast at least one of the members of the sub-expression to integer and thus the compiler will implicitly convert the other member, too:
result = anInteger * (cast(aByte!) + anotherByte!)
Now the result will is 4 * (255 + 1) = 4 * 256 = 1024
.
You can use the CAST()
function to convert between different types. For example:
let aFloat% = 3.14 let anInt = cast(aFloat%) rem -- the above will print 3 let anInt = 3 let aFloat% = cast%(anInt) rem -- note you can't just "let aFloat% = anInt" let anInt = 256 let aByte! = cast!(anInt) rem -- the above will print 1 and you'll be warned of truncation
Constants are not variables in a sense that they do not reserve memory at all. However, you can use them just like a variable, except that they may not change value in runtime.
The benefit of using constants instead of variables are:
Always prefer constants over variables, whenever possible. See the documentation for the CONST statement for more information.
Variables, constants and labels can be global or local.
Any variable or constant declared using a CONST
, LET
, DIM
or DATA
statement outside a PROC … ENDPROC
pair is considered to be a global variable and are only accessible within a procedure by using the global modifier (\
).
Any variable or constant declared using a CONST
, LET
, DIM
or DATA
statement inside a PROC … ENDPROC
pair, including the procedure's parameters, is considered to be a local variable and can only be accessed within that procedure.
Please see the documentation for the PROC ... ENDPROC statements for more details.