Skip to content

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:

PRINT -2 ^ 2       ' -(2 ^ 2) = -4
PRINT (-2) ^ 2     ' 4
PRINT 2 ^ -3       ' .125

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:

FullName$ = FirstName$ + " " + LastName$

Strings are compared with the same operators as numbers. Built-in functions cover slicing, searching, changing case, padding, and conversion:

Code$ = UCASE$(LTRIM$(RawText$))
Prefix$ = LEFT$(Code$, 3)
Position% = INSTR(1, Code$, "READY")

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:

Title$ = "RED ALERT"
MID$(Title$, 5, 5) = "READY"
PRINT Title$

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:

IF TYPEOF(Control) IS WorksButton THEN
  PRINT "BUTTON"
END IF

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

Count%
Names$(Index%)
Grid%(Row%, Column%)
Point.X
Window.Title

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:

Root# = SQR(Value#)
Width% = Menu.RowHeightAt(Index%)

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:

Save = NEW WorksButton("save", "Save")
Owner = NOTHING

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:

Orbit# = SQR(X# * X# + Y# * Y#)

That changes how the request is delivered, not what the arithmetic means. Compiler & Optimizer explains where the line is drawn.


Next: Flow Control →