Every reserved word in Arcade BASIC, grouped by what it does. Each entry has a
one-paragraph description and a runnable example. Comments inside examples
start with ! (Arcade BASIC's line-comment marker — REM works too).
Keywords are case-insensitive: PRINT, print, and Print are the same
token. Examples use uppercase by convention.
Companion docs:
architecture.mdfor the pipeline,conformance.mdfor ISO 10279 deviations and the Extensions table (which keyword/function belongs to which spec — e.g.INKEY$is a Microsoft BASIC extension, not ISO Full BASIC),../examples/README.mdfor full programs that exercise these features together.
Declarations: DIM · REDIM · DEF · FUNCTION · SUB · CALL · MODULE · PUBLIC · HANDLER · OPTION BASE
Values & assignment: LET · REM / !
Output: PRINT · PRINT USING ·
TAB · , and ; in PRINT lists
Input & data: INPUT · LINE INPUT · READ · DATA · RESTORE
Selection: IF / THEN / ELSEIF / ELSE / END IF · SELECT CASE / IS / TO / CASE ELSE
Iteration: FOR / TO / STEP / NEXT · DO / LOOP / WHILE / UNTIL · EXIT
Jumps: GOTO · GOSUB / RETURN · ON ... GOTO / GOSUB · STOP · END · RANDOMIZE · RUN · SLEEP · SOUND · BEEP · PLAY
Word-form operators: AND, OR, NOT, XOR, IMP, EQV · MOD, REMAINDER · BAND, BOR, BXOR, BNOT
Arrays & MAT: MAT · ZER · IDN · CON · NUL$ · TRN · INV
Files: OPEN · CLOSE · PRINT # · INPUT # · LINE INPUT # · WRITE # · READ #
Exceptions: WHEN ... USE · CAUSE EXCEPTION · RETRY · CONTINUE
Graphics (§13): SET WINDOW / VIEWPORT / DEVICE … · SET CLIP · SET … STYLE / COLOR · ASK … · CLEAR · GRAPH POINTS / LINES / AREA / TEXT
Allocate an array with explicit bounds. Bounds may be literal numbers or any
numeric expression. The default lower bound is 1 (or 0 if OPTION BASE 0 is
in effect). Multi-dimensional arrays declare bounds for each axis separated
by commas. Both numeric arrays and string arrays (name$) are supported.
DIM A(10) ! 1-D numeric array, indices 1..10 (or 0..10 with OPTION BASE 0)
DIM B(0 TO 9) ! explicit lower bound
DIM GRID(8, 8) ! 2-D numeric array (rows × cols)
DIM NAMES$(3) ! 1-D string array
DIM CUBE(2, 2, 2) ! N-dimensional, up to 7 dims(Spelled MAT REDIM — see also MAT.) Re-dimension an existing
array. Elements that fit the overlap of the old and new bounds are
preserved; new cells are zero-initialised for numeric arrays and "" for
string arrays.
DIM HIST(5)
LET HIST(1) = 7
LET HIST(2) = 8
MAT REDIM HIST(10) ! grow the array; HIST(1)=7, HIST(2)=8 preserved
PRINT HIST(1); HIST(2); HIST(3) ! 7 8 0Define a short user-defined function. The single-line form is one expression; the multi-line form is a statement list. Single-line DEFs can read enclosing program-scope variables.
DEF SQUARE(X) = X * X ! single-line: expression body
PRINT SQUARE(7) ! 49
LET K = 10
DEF SHIFT(X) = X + K ! sees K from the outer program scope
PRINT SHIFT(5) ! 15
DEF GUARD(X) ! multi-line form
IF X < 0 THEN EXIT DEF
PRINT "non-negative:"; X
END DEFDefine a multi-line, named function with parameters and a return value. The function returns by assigning to a variable with its own name. Functions can be recursive.
FUNCTION FACT(N) ! recursive factorial
IF N <= 1 THEN
FACT = 1
ELSE
FACT = N * FACT(N - 1)
END IF
END FUNCTION
PRINT FACT(6) ! 720Define a procedure (no return value). Call with CALL.
SUB GREET(NAME$)
PRINT "hi "; NAME$
END SUB
CALL GREET("Adam") ! hi AdamInvoke a SUB. Required — there's no implicit-call syntax for SUBs.
SUB DOUBLE(N)
PRINT N; "*2 ="; N * 2
END SUB
CALL DOUBLE(21) ! 21 *2 = 42Group SUB/FUNCTION/DEF declarations behind a namespace boundary.
Declarations inside a module are private to it by default; prefix them with
PUBLIC to make them visible from the main program.
MODULE MATHLIB
FUNCTION HELPER(X) ! private: not callable from outside
HELPER = X * X + 1
END FUNCTION
PUBLIC FUNCTION POLY(X) ! public: re-exported to the main program
POLY = HELPER(X) * 2
END FUNCTION
END MODULE
PRINT POLY(3) ! 20Marker that re-exports a SUB/FUNCTION/DEF from a MODULE into the
enclosing program scope. See MODULE.
Define a named exception-handler block that one or more WHEN ... USE
sites can reference. Body runs with EXTYPE/EXLINE/EXTEXT$ populated
from the raised exception.
HANDLER LOGGER
PRINT "caught"; EXTYPE; "at line"; EXLINE
END HANDLER
WHEN EXCEPTION IN
LET X = 1 / 0
USE LOGGER ! reference the named handler instead of inlining
END WHENSet the default lower bound for DIMmed arrays whose DIM doesn't specify
one explicitly. Valid values are 0 and 1. Must appear before any DIM
in source order; per spec it's a module-level directive.
OPTION BASE 0
DIM A(2) ! indices 0..2
LET A(0) = 10
LET A(2) = 30
PRINT A(0); A(2) ! 10 30Assign a value to a variable, parameter, or array element. The LET
keyword is optional in Arcade BASIC, but writing it makes the intent
explicit and matches ISO 10279.
LET X = 42 ! explicit
Y = X + 1 ! also fine — LET implied
LET A$ = "hi" ! string targets end in $
DIM G(3)
LET G(2) = 99 ! array-element targetSingle-line comment. The exclamation mark ! is the modern shorthand and
behaves identically: the rest of the line is ignored.
REM This is a comment.
! This is also a comment.
PRINT 1 + 2 ! inline comment after a statementWrite expressions to standard output. Items are separated by , (advance to
the next zone — every 16 columns by default) or ; (no space added).
Numeric values are formatted with a leading space for non-negatives and
trailing space; strings are written verbatim. A trailing ; suppresses the
final newline.
PRINT "hello" ! hello
PRINT 6 * 7 ! 42
PRINT "a", "b", "c" ! a b c (16-col zones)
PRINT "x ="; X ! x = 5 (semicolon: no zone padding)
PRINT "no newline"; ! suppresses the trailing newlineFormatted output via a picture string. Numeric fields: # (digit, space if
absent), 0 (zero-fill), * (asterisk-fill), $ (floating currency), ,
(thousands grouping), . (decimal point), +/- (sign). String fields:
<#### / >#### / =#### (left / right / centre, width = count of #). Any
other characters are literal. A value too big for its field overflows to *.
The ^^^^ exponent field is not implemented.
PRINT USING "###": 42 ! 42
PRINT USING "###.##": 3.14159 ! 3.14
PRINT USING " ## ##.##": 7, 7 / 2 ! 7 3.50
PRINT USING "##,###": 12345 ! 12,345
PRINT USING "$$,$$$.##": 12345.67 ! $12,345.67
PRINT USING "*****": 42 ! ***42
PRINT USING ">###########": "TABULATED" ! right-aligned string fieldInside a PRINT list, TAB(n) pads spaces out to column n (1-based). If
the cursor is already past column n the call is a no-op (does not go
back or insert a newline).
PRINT "x"; TAB(10); "y" ! x y ← 'y' begins at column 10
PRINT "hello"; TAB(3); "!" ! hello! ← TAB(3) is past current col → no-op, separates items and advances to the next 16-column print zone. ;
separates items without inserting whitespace. A trailing , or ; on the
end of a PRINT list suppresses the otherwise-automatic newline.
Prompt and read one or more values from standard input. A semicolon after a
literal prompt suppresses the auto-? ; a comma adds it. On bad input
(too few fields, or a non-numeric value supplied for a numeric target),
the runtime prints Not enough data — redo from start. or
'…' is not numeric — redo from start. and re-prompts.
INPUT N ! prompt: "? "
INPUT "Name: ", N$ ! prompt: "Name: ? "
INPUT "Age: "; A ! prompt: "Age: " (no ?)
INPUT X, Y, Z ! one line, comma-separated values
DIM A(3)
INPUT A(2) ! array element targetRead a whole line from input (or a channel — see LINE INPUT #)
into a single string target. No comma splitting.
LINE INPUT A$ ! prompt: "? "
LINE INPUT "Quote: "; Q$ ! prompt: "Quote: "
PRINT "you said: "; Q$Read the next item(s) from the program's DATA pool into variables. The
DATA pool is a single ordered sequence collected from every DATA
statement, no matter where they appear. A runtime error fires if the pool
is exhausted.
DATA 10, 20, 30
READ A, B, C
PRINT A; B; C ! 10 20 30Declare items to populate the program's DATA pool. Statements may appear
anywhere — they're all concatenated in source order at compile time.
Strings can be quoted or bare (a bare item is parsed as numeric if READ
expects a numeric target, otherwise as a string).
DATA "alpha", "beta" ! quoted strings
DATA 1, 2, 3 ! numerics
DATA bare-string-ish ! bare → string when a string target reads
READ NAME1$, NAME2$, X, Y, Z, S$Rewind the DATA cursor to the start of the pool, so the next READ
re-reads from the beginning.
DATA 1, 2, 3
READ A, B
RESTORE
READ C, D
PRINT A; B; C; D ! 1 2 1 2Single-line and block forms. The single-line form puts the conditional
statement (often PRINT or GOTO) directly after THEN. A bare line-number
after THEN (or ELSE) is shorthand for an implicit GOTO: IF X < 0 THEN 900
means IF X < 0 THEN GOTO 900. The block form opens with THEN at end-of-line
and closes with END IF, optionally nesting ELSEIF and ELSE.
! Single-line form
IF X > 0 THEN PRINT "positive"
IF Y < 0 THEN PRINT "neg" ELSE PRINT "non-neg"
! Bare line-number after THEN/ELSE is an implicit GOTO
IF X < 0 THEN 900
IF X = 0 THEN 100 ELSE 200
! Block form
IF X = 1 THEN
PRINT "one"
ELSEIF X = 2 THEN
PRINT "two"
ELSE
PRINT "other"
END IFMulti-branch dispatch on a single subject expression. CASE clauses can be
literal values, ranges (value TO value), or relational (IS op value).
CASE ELSE catches anything not matched.
SELECT CASE GRADE
CASE 90 TO 100 ! range
PRINT "A"
CASE 80 TO 89, 70 TO 79 ! multiple specs per CASE
PRINT "B-C"
CASE IS < 60 ! relational
PRINT "fail"
CASE ELSE ! catch-all
PRINT "?"
END SELECTCounted loop. STEP defaults to 1; non-default step values may be
negative. The loop body re-evaluates the test before each iteration.
FOR I = 1 TO 10 ! 1, 2, 3, ..., 10
PRINT I
NEXT I
FOR I = 0 TO 10 STEP 2 ! 0, 2, 4, 6, 8, 10
PRINT I
NEXT IPre- or post-test indefinite loop. Both WHILE (loop while condition is
true) and UNTIL (loop until condition is true) work on either end.
LET X = 0
DO WHILE X < 5 ! pre-test: enter only if X < 5
LET X = X + 1
LOOP
PRINT X ! 5
LET Y = 0
DO
LET Y = Y + 1
LOOP UNTIL Y >= 3 ! post-test: always run once
PRINT Y ! 3Leave a block early. The keyword takes the kind of block as a clause:
EXIT FOR, EXIT DO, EXIT SELECT, EXIT SUB, EXIT FUNCTION,
EXIT DEF, EXIT WHEN, EXIT HANDLER.
FOR I = 1 TO 100
IF I = 5 THEN EXIT FOR ! stop the loop at I=5
NEXT I
PRINT I ! 5
SUB GREET(N$)
PRINT "hi"
IF N$ = "" THEN EXIT SUB ! return early from the SUB
PRINT N$
END SUBBranch unconditionally to a line label. Labels are leading integers on a
line. Forward and backward jumps both work. A label on a block terminator
(120 NEXT I, 999 END IF, …) is a valid target: jumping to a NEXT/LOOP
runs the loop's increment/test next, and jumping to an END IF/END SELECT
falls past the block.
GOTO 200
PRINT "skipped"
200 PRINT "landed"Call a labelled subroutine and return to the statement after the GOSUB.
The return-PC stack is local to the enclosing scope.
PRINT "before"
GOSUB 100
PRINT "after"
STOP
100 PRINT "inside"
RETURNComputed jump. The index expression is rounded to an integer that selects a
1-based line-number from the list (GO TO / GO SUB two-word spellings also
work). ON ... GOSUB pushes a return address like a plain GOSUB, so RETURN
comes back to the statement after the ON. An optional ELSE <statement> runs
when the index is out of range; without ELSE, an out-of-range index raises
exception 10001, catchable with WHEN ... USE.
ON CHOICE GOTO 100, 200, 300 ! CHOICE=2 jumps to line 200
ON K GOSUB 1000, 2000, 3000 ! call the K-th subroutine, then continue
ON N GOTO 100, 200 ELSE PRINT "out of range"Halt the program at the current statement (cleanly, exit code 0). Useful for halting before a labelled subroutine block.
PRINT "main done"
STOP
100 PRINT "subroutine"
RETURNHalt the program normally. May appear anywhere; commonly the final
statement of the program. END IF, END SUB, END FUNCTION, END SELECT,
END WHEN, END HANDLER, END MODULE, END DEF close their respective
block statements (these are two-token forms — END followed by the block
keyword).
PRINT "hello"
END ! explicit halt at the end of mainReseed the random-number generator used by the RND builtin. With no
argument, uses a time-based seed; with a numeric argument, seeds
deterministically.
RANDOMIZE ! time-seeded
RANDOMIZE 42 ! deterministic — useful for reproducibility
PRINT RNDRestart the program from the top, clearing all variable state. Rarely used in modern style.
PRINT "boot"
RUN ! starts over (clears X, etc.)Pause execution for a number of seconds (fractional allowed). Paces real-time
loops — pair it with the INKEY$ function (non-blocking keyboard) for games.
Extension: Microsoft BASIC (QuickBASIC), not ISO/ECMA Full BASIC — see the
Extensions table.
DO
LET K$ = INKEY$ ! "" if no key is waiting
IF K$ = "q" THEN EXIT DO
! ... update + redraw ...
SLEEP 0.05 ! ~20 frames/second
LOOPSOUND freq, duration emits a tone: freq in Hz (37–32767), duration in
clock ticks of 18.2/second (so duration/18.2 seconds). duration = 0 stops
the current sound. Extension: Microsoft BASIC (GW-BASIC/QuickBASIC) — see the
Extensions table. Render
audio with arcade-basic run file.bas --wav out.wav.
SOUND 440, 9 ! 440 Hz (concert A) for about half a secondBEEP emits the standard alert tone (~800 Hz for ~0.25 s, like PRINT CHR$(7)).
Extension: Microsoft BASIC (GW-BASIC/QuickBASIC).
BEEPPLAY notes$ plays a Music Macro Language (MML) string. Extension: Microsoft
BASIC (GW-BASIC/QuickBASIC). Commands (case-insensitive, spaces ignored):
A–G |
a note in the current octave; suffix #/+ sharp, - flat; optional length digit + dots |
O n / > / < |
octave 0–6 (default 4) / up one / down one |
N n |
note by number 0–84 (0 = rest) |
L n |
default note length 1–64 (default 4 = quarter) |
P n |
rest of length n |
T n |
tempo: quarter notes per minute, 32–255 (default 120) |
MN / ML / MS |
normal / legato / staccato articulation |
MF / MB |
foreground / background — foreground waits for the music to finish; background plays asynchronously (up to 32 buffered tones) |
PLAY "T120 O4 L8 CDEFGAB>C" ! a C major scale
PLAY "MS T140 O5 L16 C C G G" ! staccatoAND, OR, NOT, XOR, IMP, EQV operate on truth values. BASIC's
truth model: non-zero is true, 0 is false; the operators return -1
(all-ones) for true and 0 for false.
IF X > 0 AND X < 10 THEN PRINT "in range"
IF NOT FLAG THEN PRINT "off"
IF A OR B THEN PRINT "either"
PRINT A XOR B ! exclusive-or
PRINT A IMP B ! A → B (false only if A true and B false)
PRINT A EQV B ! A ≡ B (true iff both sides agree)Numeric modulo and remainder. MOD follows mathematical floor-division
semantics (result has the sign of the divisor). REMAINDER truncates
toward zero (result has the sign of the dividend).
PRINT 7 MOD 3 ! 1
PRINT -7 MOD 3 ! 2 (floor-division)
PRINT 7 REMAINDER 3 ! 1
PRINT -7 REMAINDER 3 ! -1 (truncated)BAND, BOR, BXOR, BNOT operate on the integer representation of
their operands.
PRINT 12 BAND 10 ! 8 (1100 & 1010 = 1000)
PRINT 12 BOR 10 ! 14 (1100 | 1010 = 1110)
PRINT 12 BXOR 10 ! 6 (1100 ^ 1010 = 0110)
PRINT BNOT 0 ! -1 (bitwise complement)Apply an operation to a whole array. MAT is always followed by one of:
name = rhs (assign), REDIM (resize), PRINT name (output),
INPUT name (read), READ name (DATA pool). The rhs for an assignment
can be another array name, a binary operation (+, -, *), a scalar
multiply (k) * name, a transpose TRN(name), an inverse INV(name),
or a constant array: ZER, IDN, CON, NUL$.
DIM A(2, 2), B(2, 2), C(2, 2)
LET A(1, 1) = 1
LET A(1, 2) = 2
LET A(2, 1) = 3
LET A(2, 2) = 4
MAT B = A ! copy
MAT C = A + B ! element-wise sum
MAT C = A * B ! matrix product (inner dims must match)
MAT C = (3) * A ! scalar multiply
MAT C = TRN(A) ! transpose
MAT C = INV(A) ! inverse (square, non-singular)
MAT PRINT C ! print with row-per-line layoutIn a MAT assignment RHS, produces a zero-filled array shaped like the target's current bounds.
DIM A(3, 3)
MAT A = ZER ! all elements = 0In a MAT RHS, produces an identity matrix (1s on the diagonal, 0s elsewhere). Requires a square target.
DIM I(3, 3)
MAT I = IDN ! diag = 1, else 0In a MAT RHS, produces an array of all-ones shaped like the target.
DIM A(4)
MAT A = CON ! 1, 1, 1, 1In a string-array MAT RHS, produces an array of empty strings shaped like the target. The only constant supported for string arrays.
DIM S$(2)
LET S$(1) = "stale"
MAT S$ = NUL$ ! S$(1) = "", S$(2) = ""In a MAT RHS, returns the transpose of a 2-D matrix. Bounds flip too:
TRN of an m × n matrix has shape n × m.
DIM A(2, 3), T(3, 2)
! ... populate A ...
MAT T = TRN(A)In a MAT RHS, returns the inverse of a square 2-D matrix via LU decomposition with partial pivoting. A singular matrix raises runtime error 6016.
DIM A(2, 2), B(2, 2)
LET A(1, 1) = 4
LET A(1, 2) = 7
LET A(2, 1) = 2
LET A(2, 2) = 6
MAT B = INV(A) ! [[0.6, -0.7], [-0.2, 0.4]]File I/O uses channels — small positive integers introduced with #. A
channel is opened with OPEN and released with CLOSE. Two record types:
DISPLAY (text) — written with PRINT #, read with INPUT # / LINE INPUT #;
and INTERNAL (exact-value, RECTYPE INTERNAL) — written with WRITE #, read
with READ #, storing numbers at full precision so they round-trip exactly.
SEQUENTIAL or STREAM organization is supported.
Open a file on a channel. The full clause shape is
OPEN #ch: NAME path$, [ACCESS kind, ORGANIZATION kind, CREATE kind, RECTYPE kind].
Each clause has defaults: ACCESS OUTIN, ORGANIZATION SEQUENTIAL,
CREATE NEWOLD. ACCESS OUTPUT with no explicit CREATE truncates on
open per spec.
LET P$ = "/tmp/notes.txt"
OPEN #1: NAME P$, ACCESS OUTPUT ! write-only; truncates on open
PRINT #1: "line one"
PRINT #1: "line two"
CLOSE #1
OPEN #1: NAME P$, ACCESS INPUT ! read-only; file must exist
LINE INPUT #1: A$
LINE INPUT #1: B$
CLOSE #1ACCESS values: INPUT, OUTPUT, OUTIN (read+write).
ORGANIZATION values: SEQUENTIAL, STREAM.
CREATE values: NEW (must not exist), OLD (must exist), NEWOLD
(open if present, create otherwise).
RECTYPE values: DISPLAY (text — the default, use PRINT #/INPUT #) or
INTERNAL (exact-value records — use WRITE #/READ #).
Release the file behind a channel and flush any pending writes.
CLOSE #1Like PRINT, but to a channel. Same item formatting rules — expressions,
commas (zone padding), semicolons (no padding), TAB(n).
OPEN #1: NAME "scores.txt", ACCESS OUTPUT
PRINT #1: "name", "score" ! tab-separated via zone padding
PRINT #1: "Adam", 42
CLOSE #1Read comma-separated fields from a channel into variables. No interactive retry loop — a malformed line raises a runtime error.
OPEN #1: NAME "data.csv", ACCESS INPUT
INPUT #1: NAME$, SCORE
CLOSE #1
PRINT NAME$; "scored"; SCORERead a whole line (newline-terminated) from a channel into a string variable.
OPEN #1: NAME "log.txt", ACCESS INPUT
LINE INPUT #1: ENTRY$
CLOSE #1
PRINT ENTRY$Write exact-value records to an INTERNAL channel. Each item is a field;
numbers are stored at full precision (no display rounding), strings verbatim.
The counterpart to READ #. (WRITE/READ are the INTERNAL statements;
PRINT/INPUT are DISPLAY-only.)
OPEN #1: NAME "save.dat", ACCESS OUTPUT, RECTYPE INTERNAL
WRITE #1: HISCORE, PLAYER$ ! HISCORE round-trips exactly, not as rounded text
CLOSE #1Read exact-value records back from an INTERNAL channel, one field per target,
in order — numbers come back byte-exact, strings verbatim. (Distinct from the
DATA-reading READ: the #channel is what selects file input.)
OPEN #1: NAME "save.dat", ACCESS INPUT, RECTYPE INTERNAL
READ #1: HISCORE, PLAYER$
CLOSE #1Exceptions in Arcade BASIC are integer-typed events that propagate up the
statement stack. A WHEN ... USE block catches both implicit runtime
errors (division by zero, file errors, array-bounds violations, …) and
user-raised CAUSE EXCEPTION events. Inside the USE body, three
builtins read the active exception: EXTYPE (integer code), EXLINE
(source line of the failing statement), EXTEXT$ (message text).
WHEN EXCEPTION IN <body> USE <handler-body> END WHEN. The IN body
runs normally; if it raises, control transfers to the USE body.
USE can be inline (a statement list) or a reference to a named
HANDLER.
WHEN EXCEPTION IN
LET X = 1 / 0 ! raises runtime error 1001
PRINT "skipped"
USE
PRINT "caught at line"; EXLINE; "type"; EXTYPE
END WHENRaise a user-defined exception with an explicit integer type. Numeric
expression after EXCEPTION is the type; runtime-error codes occupy the
low integer range, so user codes are conventionally ≥ 9000.
WHEN EXCEPTION IN
LET N = 0
IF N = 0 THEN CAUSE EXCEPTION 9001
USE
PRINT "user error type"; EXTYPE ! 9001
END WHENInside the USE body, restart the IN body from the top with a fresh
handler. Useful for retry loops that recover from a transient failure.
LET ATTEMPTS = 0
WHEN EXCEPTION IN
LET ATTEMPTS = ATTEMPTS + 1
IF ATTEMPTS < 3 THEN CAUSE EXCEPTION 9000
PRINT "succeeded after"; ATTEMPTS; "tries"
USE
PRINT " handler saw type"; EXTYPE
RETRY ! restart the IN body
END WHENInside the USE body, resume the IN body at the statement immediately
after the one that raised. Useful when the offending operation can be
treated as a no-op.
WHEN EXCEPTION IN
CAUSE EXCEPTION 1
PRINT "after-failing" ! CONTINUE jumps here
USE
PRINT "caught"
CONTINUE ! resume past the CAUSE
END WHEN
PRINT "done"ECMA-116 §13 graphics. Output goes to a pluggable device; the CLI can render to
SVG with --svg:
arcade-basic run examples/graphics.bas --svg out.svgDrawing happens in problem (world) coordinates that you choose with SET WINDOW; they're mapped into the [0,1] viewport, clipped, and handed to the
backend. The run and vm engines produce identical output.
SET WINDOW 0, 360, -1, 1 ! world coordinate range (left,right,bottom,top)
SET VIEWPORT 0, 1, 0, 1 ! where it lands in normalized device space
SET DEVICE WINDOW 0, 1, 0, 1 ! (advanced) sub-rectangle of the surface
SET DEVICE VIEWPORT 0, 1, 0, 1 ! (advanced) target rectangle on the device
SET CLIP "ON" ! clip drawing to the viewport ("ON"/"OFF")
SET LINE STYLE 2 ! 1 solid, 2 dashed, 3 dotted
SET POINT STYLE 3 ! 1 dot, 2 plus, 3 asterisk
SET LINE COLOR 4 ! also POINT / TEXT / AREA COLOR
CLEAR ! clear the display
GRAPH LINES: 0,0; 10,5; 20,0 ! connected segments (≥2 points)
GRAPH POINTS: 1,1; 2,2 ! markers
GRAPH AREA: 0,0; 4,0; 2,3 ! filled polygon (≥3 points)
GRAPH TEXT, AT 1,1: "label" ! text; also: GRAPH TEXT, AT x,y, USING img$: v
ASK WINDOW L, R, B, T ! read back current settings into variables
ASK DEVICE SIZE W, H, U$ ! device width/height + unit ("METERS"/"OTHER")
ASK MAX COLOR M ! capability queries; optional " STATUS s" clauseTo build a curve or any shape with a variable number of vertices, drive GRAPH
from a loop (coordinate expressions may reference variables) — see
examples/graphics.bas.
- Every keyword above is implemented end-to-end — parser → semantic
analysis → tree-walker → bytecode VM. The bytecode
vmandbuildpaths produce byte-identical output to the tree-walkingrunpath on every example program. - The §13 graphics statements (
SET/ASK/GRAPH/CLEAR— see Graphics below) are implemented. A handful of other keywords are still reserved by the lexer for future spec features (DISPLAY, PLOT, DRAW, POLYGON, TRANSFORM, MASK, MARGIN, ZONEWIDTH, PIC, PICTURE, FORMAT, TEMPLATE, TIMEOUT, BREAK, TRACE, COLLATE, native types like FIXED/REAL/STRING/NUMERIC, FILES/FILETYPE, RANDOM, REWRITE, RSET, …) — the parser rejects statements built around them with a clear error. See conformance.md for the full deviation list. - Function names like
SIN,COS,LEN,MID$,CHR$,RND,EXTYPE, etc. are builtins, not keywords — they're resolved by name at semantic analysis time and can in principle be shadowed (avoid). Seesrc/ArcadeBasic.Runtime/BuiltinImpls.csfor the complete catalogue.