Expressions¶
This page explains expressions, the parts of a program that work out a value: arithmetic, comparisons, logic, string joining, and calls to functions and methods. It lists the operators in the order d/BASIC applies them and the built-in functions you can reach for. After reading it you will be able to write any calculation and know exactly how it will be evaluated.
An expression answers one question: what value should this become? d/BASIC's operator ladder has a few ordering rules that reward knowing rather than guessing.
Operator precedence¶
Precedence decides which operator is applied first when several appear together. From the operators applied last to those applied first:
| Level | Operators | Meaning |
|---|---|---|
| 1 | IMP |
logical implication |
| 2 | EQV |
logical equivalence |
| 3 | XOR |
exclusive-or |
| 4 | OR |
inclusive-or |
| 5 | AND |
and |
| 6 | NOT |
logical/bitwise not (one operand) |
| 7 | =, <>, ><, <, <=, >, >=, IS |
comparison, and whether two references name the same object |
| 8 | +, - |
addition, subtraction, string joining |
| 9 | MOD |
remainder |
| 10 | \ |
integer division |
| 11 | *, / |
multiplication and real division |
| 12 | unary +, unary - |
sign |
| 13 | ^ |
power, grouped from the right |
Power binds more tightly than a leading minus:
When code is meant to teach, or to survive a hurried review, parentheses are cheap documentation.
Arithmetic¶
Area# = Width# * Height#
Mean# = Total# / Count#
Page% = Item% \ ItemsPerPage%
Slot% = Item% MOD ItemsPerPage%
/ is real division. \ is integer division. MOD gives the remainder. ^ raises to a power.
When two numbers of different types meet, the narrower one is widened to the wider type before the arithmetic happens. The result may then be converted again when it is stored. See Source, Names & Types.
Strings¶
+ joins strings:
Strings are compared with the same operators as numbers. Built-in functions cover slicing, searching, changing case, padding, and conversion:
Useful string functions:
| Purpose | Functions |
|---|---|
| length and character codes | LEN, ASC, CHR$ |
| slices | LEFT$, RIGHT$, MID$ |
| find | INSTR |
| case | UCASE$, LCASE$ |
| trim | LTRIM$, RTRIM$ |
| construct | SPACE$, STRING$ |
| convert | STR$, VAL |
MID$ above is used as an expression. In its classic assignment form it overwrites part of an existing string instead:
The first position is 1. If you leave out the length, the whole replacement is written; an explicit length limits how much is overwritten. Because this is an assignment, the target must be something you can write to.
See Strings & Text for the exact rules on slices that reach past the end, byte positions, fixed-width record fields, converting numbers, UTF-8 boundaries, and building text efficiently.
Comparisons and logic¶
IsAdult% = Age% >= 18
Inside% = X% >= Left% AND X% < Left% + Width%
Changed% = OldValue% <> NewValue%
AND, OR, XOR, EQV, IMP, and NOT work on whole-number values, bit by bit. Because true is -1 (every bit set), the same operators double as bit-mask tools.
Do not use = to ask whether two object references point at the same object. Use IS:
IF Selected IS Hovered THEN PRINT "ONE OBJECT, TWO REFERENCES"
IF Selected IS NOTHING THEN PRINT "NO SELECTION"
TYPEOF(value) IS ClassName asks whether an object belongs to a class:
Parentheses carry meaning at calls¶
Parentheses normally just group an expression. At a procedure call they also carry a rule inherited from classic BASIC: an extra pair around a variable passes a copy of its value instead of the variable itself. (By default a variable is passed by reference, which means the procedure can change it.)
CALL Nudge(Score) ' ordinary variable: BYREF by default
CALL Nudge((Score)) ' parenthesized expression: pass a value
In new procedure declarations, write BYVAL explicitly. Know the parentheses rule so that code brought over from an old machine behaves as its author expected.
Variables, elements, and members¶
An array name followed by empty parentheses, Names$(), means the whole array. It is allowed only in the particular statements and parameter positions that accept a whole array; it is not a way to name an element.
Function and method calls¶
Functions produce values:
Methods are called with a dot after the object. NEW builds an object; NOTHING is the empty reference, the value of a variable that points at no object:
Numeric intrinsics¶
Intrinsics are the functions built into the language.
| Family | Functions |
|---|---|
| magnitude and sign | ABS, SGN |
| rounding and conversion | INT, FIX, CINT, CLNG, CSNG, CDBL |
| roots and exponentials | SQR, LOG, EXP |
| trigonometry | SIN, COS, TAN, ATN |
| random values | RND |
RND takes zero or one argument. Use RANDOMIZE seed when a program needs the same sequence of random numbers every time.
Runtime values¶
These built-in values take no arguments and report on the program as it is running:
TIMER: seconds on the standard timer;INKEY$: a key waiting at the console, or an empty string if none is;ERR: the current error code;ERL: the source line number where the error happened, when one is known.
What the host machine can actually do still matters. If a program runs in the browser Playground and nothing on the host supplies console input, calling INKEY$ cannot create it.
Evaluation and optimization¶
d/BASIC keeps the visible order of calls, property reads, conversions, and built-ins that have side effects. Inside a floating-point calculation that is pure (it calls nothing with side effects) and uses one number type throughout, the compiler may bundle the whole calculation into one portable request to the host instead of crossing to it once per operation:
That changes how the request is delivered, not what the arithmetic means. Compiler & Optimizer explains where the line is drawn.
Next: Flow Control →