PILOT Commands Detail

Description

PILOT is a lightweight educational language embedded within PowerBASIC via #PCODE/#END PCODE blocks. Each PILOT command is lowered to PowerBASIC statements and then compiled to native x64 machine code. PILOT provides a simple command set for text-based interactive programs: type output (T:), accept input (A:), pattern matching (M:), conditional branching (Y:/N:, J:, U:), computation (C:), and flow control (J:, E:).

Syntax

Block: #PCODE ... #END PCODE
Standalone (V11): program.pilot — top-level PILOT source file
Commands: T: A: M: Y: N: C: J: U: E: R: S:

V11 New Features

NEW in V11: The PILOT subsystem has been significantly extended with standalone file support, conditional suffixes, parenthesized conditions, multi-pattern matching, and advanced variable support.

Standalone .pilot Files

In V11, a .pilot file can be compiled directly without wrapping in #PCODE/#END PCODE blocks. The compiler auto-generates the necessary PBMAIN wrapper. This makes PILOT a first-class compile target.

Conditional Suffixes

Every command that produces a match result (T:, Y:, N:, J:, U:) now supports conditional suffixes that test the match flag before executing:

SuffixMeaningExample
TY:Execute if match is TRUETY: Correct! — print only if last M: matched
TN:Execute if match is FALSETN: Wrong, try again — print only if last M: failed
JY:Jump if match is TRUEJY: *CORRECT — jump to CORRECT if matched
JN:Jump if match is FALSEJN: *WRONG — jump to WRONG if not matched
UY:Conditional use if match TRUEUY: score>=3: *WIN — test condition only if matched
UN:Conditional use if match FALSEUN: score>=10: *QUIT — test condition only if not matched

Parenthesized Conditions (T: command)

The T: (Type) command now supports parenthesized conditional expressions. If the expression evaluates to FALSE, the text output is suppressed:

T(#x>=0): Score is non-negative         ' only prints if #x >= 0
T(#count=1): There is 1 item            ' only prints if #count = 1

Multi-Pattern M: Command

The M: command now accepts multiple patterns separated by commas. The match result is TRUE if any pattern matches. Each matched group is captured:

M: YES, Y, OK, SURE   ' matches any of these four responses

Match Variables: $MATCH, $LEFT, $RIGHT

After a successful M: with wildcards, three special variables contain the matched portions:

VariableContent
$MATCHThe full substring that matched the pattern
$LEFTThe text to the left of the first wildcard match
$RIGHTThe text to the right of the first wildcard match
M: *IS*
A: Enter something with IS:
T: Matched: $MATCH, Left: $LEFT, Right: $RIGHT

U: *LABEL as GOSUB

The U: (Use) command with a label target (*LABEL) now performs a GOSUB (call with return) instead of a GOTO:

U: score>=3: *BONUS         ' calls subroutine BONUS, returns here
T: Back from bonus round

Multiple A: Targets

The A: (Accept) command now accepts multiple comma-separated variables in a single command:

A: $NAME, #AGE, $CITY       ' reads three values on one line

Command-to-PowerBASIC Lowering Table

PILOTGenerated PowerBASICGenerated ASM Pattern
T: text $var #num PRINT "text "; var$; " "; num# See PRINT (WriteFile)
A: INPUT a$ See Console INPUT (ReadFile)
A: $NAME INPUT name$ ReadFile + assign to named string variable
A: #COUNT INPUT tmp$ : count# = VAL(tmp$) ReadFile + string-to-number conversion
A: $NAME, #AGE, $CITY INPUT name$ : INPUT age# : INPUT city$ V11 Sequential ReadFile for multiple targets
M: YES match = (TRIM$(UCASE$(a$)) = "YES") String comparison via memcmp
M: Y* match = (LEFT$(TRIM$(UCASE$(a$)), 1) = "Y") Prefix check after case normalization
M: *ING match = (RIGHT$(TRIM$(UCASE$(a$)), 3) = "ING") Suffix check
M: *ORL* match = (INSTR(TRIM$(UCASE$(a$)), "ORL") > 0) Substring search
M: * match = 1 Always true
M: 42 match = (#A = 42) CMP + SETcc for numeric equality
M: #EXPECTED match = (#A = #EXPECTED) CMP with numeric variables
M: $EXPECTED match = (TRIM$(UCASE$(a$)) = TRIM$(UCASE$(expected$))) String comparison
M: PAT1, PAT2, PAT3 match = (match1 OR match2 OR match3) V11 Multi-pattern OR combination
Y: text $var #num IF match THEN PRINT "text "; var$; " "; num# Conditional jump around PRINT code
Y: *LABEL IF match THEN GOTO LABEL Conditional JMP
TY: text IF match THEN PRINT "text" V11 Y: alias (match-true type)
TN: text IF NOT match THEN PRINT "text" V11 N: alias (match-false type)
JY: *LABEL IF match THEN GOTO LABEL V11 Conditional JMP on match TRUE
JN: *LABEL IF NOT match THEN GOTO LABEL V11 Conditional JMP on match FALSE
N: text $var #num IF NOT match THEN PRINT "text ... Inverted conditional jump
N: *LABEL IF NOT match THEN GOTO LABEL Inverted conditional JMP
C: score = score + 1 score# = score# + 1 Standard assignment + arithmetic
C: name = $A name$ = a$ String assignment
J: *LABEL GOTO LABEL jmp __pb_label_xxx_LABEL
U: score>=3: *WIN IF score# >= 3 THEN GOTO WIN CMP + conditional JMP
U: score>=3: You win! IF score# >= 3 THEN PRINT "You win!" CMP + conditional around PRINT
U: score>=3: *BONUS IF score# >= 3 THEN GOSUB BONUS V11 CMP + CALL (not JMP)
UY: score>=3: *WIN IF match AND score# >= 3 THEN GOTO WIN V11 Match AND condition
UN: score>=10: *QUIT IF NOT match AND score# >= 10 THEN GOTO QUIT V11 NOT match AND condition
E: GOTO EndOfPilotBlock_N jmp __pb_pilot_end_N
R: comment PB comment No ASM generated
S: DRAW 50 PB comment No ASM generated (no-op)
*LABEL __pb_pilot_blockN_LABEL: ASM label definition

PILOT Variable Mapping

; PILOT variables are prefixed internally to prevent collisions:
$A     -> a$                        (string variable)
#A     -> a#                        (numeric variable from VAL)
$NAME  -> pilot_block1_NAME$        (block-scoped string)
#SCORE -> pilot_block1_SCORE#       (block-scoped numeric)
*LOOP  -> __pb_pilot_block1_LOOP    (block-scoped label)

; V11 match capture variables:
$MATCH -> pilot_block1_MATCH$       (matched substring)
$LEFT  -> pilot_block1_LEFT$        (text left of wildcard)
$RIGHT -> pilot_block1_RIGHT$       (text right of wildcard)

Block Structure

; Each #PCODE block generates:
; 1. LOCAL declarations for all PILOT variables
; 2. Lowered PB statements for each PILOT command
; 3. An end-of-block label for E: command target
; 4. Unique prefix ensures no name clashes between blocks
;
; V11: Standalone .pilot files auto-generate the #PCODE wrapper
; and PBMAIN entry point. Variables are scoped per file.
;
; V11: T(#expr): conditions emit CMP/TEST before the PRINT code
; with a conditional jump to skip output if the expression is FALSE.
;
; V11: U:*LABEL emits CALL instead of JMP for subroutine semantics.

; V13: PILOT restoration brings back D:, GR:, SO: (no-op comments
; for Atari-style display/graphic/sound commands) and #POS state
; variable tracking. All V10/V11 features retained.
;
; V13: Standalone .pilot/.pil/.plt/.pcode files compile via
; auto-generated PB wrapper with PBMAIN entry point.

V13 PILOT Restoration NEW in V13

V13 restores the full PILOT layer that was introduced in V10/V11, including newly covered commands and state variables:

D: (Display/Graphics No-Op)

Syntax: D: x, y, "text" | D: CLEAR

Atari-style display positioning command. Accepted as a no-op comment for compatibility. Future graphics runtime will render text at screen coordinates.

GR: (Graphic Mode No-Op)

Syntax: GR: mode | GR: DRAW x1,y1 TO x2,y2

Atari-style graphics mode and drawing commands. Accepted as no-op comments. Turtle graphics and screen rendering are deferred to a future runtime.

SO: (Sound No-Op)

Syntax: SO: freq, duration | SO: NOTE "C4", 100

Atari-style sound/music command. Accepted as a no-op comment. Audio output is deferred to a future runtime.

#POS (Match Position Variable)

Syntax: #POS (read-only numeric variable)

After a successful M: pattern match, #POS contains the 1-based character position where the match was found in the input string. Returns 0 if no match.

M: *HELLO*
Y: Found at position #POS!

V13 PILOT Command Summary

CommandV10V11V13Description
T:YesYesYesType (print)
A:YesYesYesAccept (input)
M:YesYesYesMatch pattern
Y:YesYesYesYes (match success)
N:YesYesYesNo (match failure)
C:YesYesYesCompute (assign)
J:YesYesYesJump (goto)
U:YesYesYesUse (conditional)
E:YesYesYesEnd block
R:YesYesYesRemark (comment)
S:YesYesYesScreen (no-op)
D:----YesDisplay (no-op)
GR:----YesGraphic (no-op)
SO:----YesSound (no-op)
TY:/TN:--YesYesConditional type
JY:/JN:--YesYesConditional jump
UY:/UN:--YesYesConditional use
T(#expr):--YesYesParenthesized condition
$MATCH--YesYesMatched text variable
$LEFT--YesYesLeft of match
$RIGHT--YesYesRight of match
#POS----YesMatch position