A type describes what a value represents and which operations make sense for it. BASIL checks types before the program runs. This catches mistakes such as adding a customer’s name to an invoice total without an explicit conversion.
Declare and initialize variables
LET quantity = 3
DIM price AS DOUBLE = 2.5
DIM description AS STRING
description = "notebook"
quantity += 1
PRINT description
PRINT quantity
PRINT priceLET is optional on a first assignment. DIM ... AS ... supplies a type explicitly.
It is especially useful for empty collections and optionals, where the initializer
does not provide an element type. A declaration without a value requires proven
initialization before a read. Do not expect an ordinary DIM count AS INTEGER to
initialize a local to zero. Dense array cells have separate default rules.
Blocks introduce lexical scope: a variable declared inside a branch is local to that branch. Use an outer typed declaration when multiple branches must initialize one variable used afterward. The compiler checks that every reaching path assigns it.
The scalar types
| Type | Use |
|---|---|
INTEGER |
Signed whole numbers from -2^63 through 2^63 - 1 |
DOUBLE |
Binary64 floating-point measurements and fractional values |
BOOLEAN |
TRUE or FALSE |
BYTE |
Unsigned numbers from 0 through 255; packed binary data |
UINT32 |
Unsigned 32-bit values |
UINT64 |
Unsigned 64-bit values |
STRING |
Valid UTF-8 text |
Decimal whole literals normally have type INTEGER. A decimal point or exponent
produces DOUBLE: 1.0, 2.5, 1.0e3. Hexadecimal &H, binary &B and octal &O
literals have UINT64 type. Numeric types do not generally convert implicitly.
Use explicit conversions such as CDBL(count), BYTE(255) or UINT32(7).
Conversions check the target’s range; do not use conversion as an overflow workaround.
PRINT 7 / 2
PRINT 7 MOD 2
PRINT 7.0 / 2.0
PRINT CDBL(3) + 0.5
PRINT 2 + 3 * 4
PRINT (2 + 3) * 4INTEGER division truncates toward zero. Parentheses make grouping explicit. INTEGER and unsigned arithmetic check overflow and invalid division; these fatal runtime checks are distinct from catchable operational failures. DOUBLE has a finite precision, so decimal fractions such as 0.1 are generally approximate. Use an application’s chosen representation and rounding policy for money.
Operators and conditions
= and == test equality in an expression; <> means unequal. Numeric ordering
uses <, <=, > and >=. Assignment is selected by statement context, as in
count = 3. AND and OR short-circuit: the right operand runs only when needed.
NOT negates a Boolean. &, | and XOR provide integer bit operations; Boolean
XOR is also supported. ^ is not an XOR spelling.
From lowest to highest precedence: optional fallback ??; OR; AND; comparisons; + - | XOR;
* / MOD &; unary + - NOT; primary expressions and postfix access.
Use parentheses whenever the intended grouping might surprise a reader.
count = 4
ready = count > 0 AND count < 10
PRINT ready
PRINT NOT ready
PRINT count <> 0Conditions require BOOLEAN. Zero, an empty string, an empty collection and NONE
are not Boolean false values. Write LEN(items) > 0 or use IF LET for an optional.
This makes a missing value distinguishable from a present zero or empty string.
Constants
CONST MinutesPerHour = 60
CONST Greeting AS STRING = "Hello"
CONST Squares AS LIST OF INTEGER = [0, 1, 4, 9]
PRINT MinutesPerHour
PRINT Greeting
PRINT Squares[3]
copy = Squares
copy[0] = 99
PRINT Squares[0]CONST names a compile-time value. A scalar table is an immutable flat list of scalars or one enum type. It supports reads, iteration and slicing without mutable access to its storage. Assigning it to an ordinary owned variable creates an independent value. It cannot be passed BYREF or moved with TAKE. Constants cannot execute arbitrary functions or initialize arbitrary nested owned objects.
Nonfinite floating-point results
Floating operations can produce NaN (not a number) or infinity. NaN is unequal
even to itself; signed zeros compare equal. Use IsNaN, IsInfinite or IsFinite
to classify results, and Finite when a nonfinite result should be a checked error.
PRINT IsNaN(SQRT(-1.0))
PRINT IsInfinite(EXP(1000.0))
TRY
PRINT Finite(SQRT(-1.0))
CATCH problem AS NonFiniteError
PRINT "A finite result was required"
END TRYFloating results are not automatically operational errors. Integer conversions and integer-result operations still need a representable result. See the floating-point reference for exact policies.