FoxDev StudioFor Visual FoxPro 9 applications
The runtime

Instruction reference

All 199 instructions of bytecode format 9, with their operands and stack effect, in the order and groups the VM source lists them.

The bytecode is a stack machine. Every entry below gives the instruction as it is spelled in a disassembly, its operands (the values carried in the instruction itself), and its stack effect as [before] -> [after] with the top of the stack on the right, where the source states one. Jump targets are absolute program counters. The magic is FXVM and the format version is 9.

The prose is the doc comment from crates/foxvm/src/bytecode.rs, verbatim. The bytecode page explains the module around these and shows what real programs compile to.

statements

InstructionOperandsStackWhat it does
Stmt
u32
Statement boundary: records the current source line (and is the breakpoint hook).

constants

[] -> [v]

InstructionOperandsStackWhat it does
Const
u32
Truenone
Falsenone
Nullnone
OmittednoneThe value of a skipped argument (f(1,,3)): .F.

stack

InstructionOperandsStackWhat it does
Popnone
Dupnone
Nopnone

variables

InstructionOperandsStackWhat it does
LoadLocal
u32
[] -> [v]
StoreLocal
u32
[v] -> []
LoadName
u32
Dynamic lookup: privates in this frame, then callers, then PUBLIC. [] -> [v]
StoreName
u32
Dynamic store; an unknown name becomes a PRIVATE of the current frame. [v] -> []
DeclLocal
u32
Sets the slot to .F. (LOCAL declaration).
DeclPrivate
u32
Declares a PRIVATE (hides any outer variable of that name) initialised to .F.
DeclPublic
u32
Declares a PUBLIC initialised to .F. (keeps an existing value).
DeclareNamed
public: flag
[name] -> []PRIVATE (cName) / PUBLIC (cName): the same declaration for a name the program worked out when it ran.
StoreByNamenone[value, name] -> []STORE x TO (cName): writes the value to whatever the name names - a variable, or a property some way down an object - which is only known when it runs. The name is read as a target and the value taken off the stack by the code compiled for it, so anything that can be assigned to can be named here.
ParamToPrivate
arg: u32
name: u32
PARAMETERS-style: pops the n-th argument and stores it as a PRIVATE. [] -> []
Dim
target: Var
ndims: byte
Creates an array in the target. [dims...] -> []
LoadIndex
byte
[array, i (, j)] -> [v]
StoreIndex
byte
[v, array, i (, j)] -> []
Ref
Var
Pushes a by-reference cell for the variable (converts it in place). [] -> [ref]
RefOrMakeArray
Var
The same, for a name that need not exist yet: an array function is handed the array it is to fill, and Visual FoxPro makes one when the program never declared it. [] -> [ref]
ReleaseName
u32
Releases variables: RELEASE a, b.
ReleaseLocal
u32
RELEASE of a LOCAL. A local lives in a numbered slot, so there is nowhere to take it from: the slot is marked instead, and reads as a variable that is not there until something writes it again.
ReleaseAllnone

operators

[a, b] -> [r] / [a] -> [r]

InstructionOperandsStackWhat it does
Negnone
Notnone
Addnone
Subnone
Mulnone
Divnone
Modnone
Pownone
Eqnone
ExactEqnone
Nenone
Ltnone
Lenone
Gtnone
Genone
Containsnone
AndnoneThree-valued AND/OR applied after the short-circuit jump kept the left operand.
Ornone

control flow (targets are absolute pcs)

InstructionOperandsStackWhat it does
Jump
u32
JumpIfFalse
u32
Pops; jumps when .F. or NULL; errors on a non-logical.
JumpIfTrue
u32
JumpIfFalseKeep
u32
Short-circuit for AND: peeks (never pops); jumps when the top is .F. The left operand stays on the stack either way, so a AND b compiles to a; JumpIfFalseKeep(end); b; And; end:.
JumpIfTrueKeep
u32
Short-circuit for OR: peeks; jumps when the top is .T.
ForTest
u32
FOR loop test. [var, end, step] -> [] ; jumps to the exit when the loop is finished.
ForEachNext
u32
FOR EACH support: [array, index] -> [array, index+1, element]; at the end pops both and jumps to the exit.
ReturnTo
u32
[] -> []RETURN TO: leave every routine between here and the one this names, which is the program the run started in when the name is empty (RETURN TO MASTER).

calls

InstructionOperandsStackWhat it does
IndexOrCall
name: u32
argc: byte
name(args): array element access when name resolves to an array, else a user function (this module, then loaded programs). [args...] -> [v]
CallBuiltin
id: u16
argc: byte
Built-in function by id (see builtins::REGISTRY). [args...] -> [v]
Do
name: u32
argc: byte
in_prog: flagA program name went on the stack under the arguments.
DO name [WITH args] [IN prog]: procedure call as a statement. [args...] -> []
DoDynamic
argc: byte
in_prog: flagA program name went on the stack under the arguments.
[name, args...] -> []DO (cProgram): the name is computed, not written in the source.
Returnnone[v] -> returns v to the caller (RETURN without a value pushes .T. first).
MakeLambda
u32
LAMBDA(...) ... ENDLAMBDA: builds a function value out of the function at this index, the captured slots its proto lists, and the frame's THIS. [] -> [f]
IndexOrCallValue
byte
f(args) where f is a local: the value under the arguments is subscripted when it is an array and called when it is a function, which is the same question IndexOrCall asks about a name. [v, args...] -> [result]

objects

InstructionOperandsStackWhat it does
LoadThisnone
LoadThisFormnone
LoadThisFormSetnoneTHISFORMSET: the formset the object belongs to. A formset is a container whose members are whole forms, shown together, so this is not the form above the object but the thing above that; an object in no formset raises error 1938 rather than answering.
LoadScreennone
GetMember
u32
[obj] -> [value or child object]
GetMemberByNamenone[obj, name] -> [value]the same, for a member named by a variable: obj.&cName.
SetMemberByNamenoneobj.&cName = v: the member a variable names is written. [value, obj, name] -> []
CallMethodByName
byte
[obj, name, a1 .. an] -> [value](yields HostRequest::CallMethod) for obj.&cName(...).
SetMember
u32
[v, obj] -> [](yields HostRequest::SetProp)
SetMemberIndex
name: u32
argc: byte
[v, obj, subs...] -> [](yields HostRequest::SetPropIndex) for obj.Prop[1] = v
DimMember
name: u32
ndims: byte
[obj, d1 .. dn] -> [](yields HostRequest::DimProp) for DIMENSION obj.aProp[2, 3]. Sizing an array property is its own instruction rather than an assignment of a fresh array, because the two are different statements: DIMENSION keeps the elements that still fit, and a plain assignment of an array to a property is not a way to give a property an array at all.
CallMethod
name: u32
argc: byte
[obj, args...] -> [v](yields HostRequest::CallMethod)
PushWithnone[obj] -> []pushes onto the WITH stack
PopWithnone
LoadWithnone[] -> [obj]
ReleaseObjectnone[obj] -> [](yields HostRequest::ReleaseObject)
DoMenu
u32
DO menu.fxm: installs a menu. [] -> [] (yields HostRequest::DoMenu)

runtime compilation

InstructionOperandsStackWhat it does
Macronone&name in an expression: compiles the text on the stack as an expression in this frame. [text] -> [v]
ToTextnoneTEXTMERGE <<expr>>: replaces the top of the stack with its display text. [v] -> [text]
MergeText
always: flag
Text merge: replaces the raw text on the stack with the same text, every expression between the merge delimiters worked out and put in its place. Which characters those delimiters are, and whether the merge happens at all, is what SET TEXTMERGE says at the time; always is the TEXTMERGE clause of TEXT, which merges whatever the setting says. [raw] -> [text]
TextOut
newline: flag
noshow: flag
\, \\ and a TEXT block with nowhere to go: sends the text on the stack to wherever SET TEXTMERGE TO points. newline ends the line before it first, and noshow is the command's own NOSHOW, which stops it also being shown. [text] -> []

statements with host effects

InstructionOperandsStackWhat it does
Print
newline: flag
argc: byte
? / ??. [items...] -> []
WaitWindow
byte
[text? , timeout?] -> []per wait_flags; TO var is a following StoreName.
ReadEventsnone
ClearEventsnone
Quitnone
Cancelnone
DoForm
flags: byte
argc: byte
[name, args...] -> [obj?, result?]per form_flags.
SetCmd
name: u32
argc: byte
to: flag
SET name ON|OFF|TO args. [args...] -> [] ; ON/OFF push True/False first. to says the command was the TO form. One setting can hold two things at once - SET HELP ON and SET HELP TO afile are both remembered, and SET("HELP") answers the first where SET("HELP", 1) answers the second - so which of them the command wrote has to travel with the instruction. The values alone cannot say.
NoDefaultnone
DoDefault
byte
[args...] -> [v]

exceptions

InstructionOperandsStackWhat it does
TryPush
catch: u32
finally: u32
Installs a handler; either target may be NO_TARGET. On an error the VM unwinds to the stack depth at the push, then jumps to catch (installing a finally-only handler for the CATCH block) or, without CATCH, to finally with the error pending for EndFinally.
TryPopnoneRemoves the innermost handler; when it has a FINALLY block a "no error pending" entry is recorded and the compiler jumps to the block next.
Erasenone[path] -> [](yields HostRequest::FileDelete) for ERASE.
RetrynoneReturns from this frame and runs the statement that called it again, for RETRY.
Thrownone[v] -> raises a user error carrying v (a NULL re-raises the last caught error).
CatchObjectnone[] -> [exception object](yields HostRequest::CreateException) for CATCH TO oErr.
EndFinallynoneEnd of a FINALLY block: re-raises the error that was propagating when the block was entered.
OnError
u32 or none
ON ERROR command: installs (Some(const)) or clears (None) the error handler text.

data

InstructionOperandsStackWhat it does
Use
alias: u32 or none
named_alias: flagAn alias went on the stack under the path, worked out when the statement ran.
exclusive: flag
online: flagONLINE or ADMIN: the table opens, and then the command answers for what those two ask of it, which only an offline view can give.
in_area: flagTrue when a work area was pushed under the path: USE x IN 0 opens the table somewhere else and leaves the selected area where it was.
[path] -> []USE table [ALIAS x] [EXCLUSIVE|SHARED] [AGAIN]; an empty path closes the work area. alias is the name index of an explicit ALIAS, if there was one.
SelectArea
u32 or none
SELECT n / SELECT alias: name is a name index, or none when a number is on the stack.
Go
GoTarget
GO TOP / GO BOTTOM / GO n (the record number is on the stack for Record).
SkipnoneSKIP [n], with the count on the stack.
PushAreanone[area] -> []The work area a command says IN: it is selected, and what was selected before is remembered so PopArea can put it back.
PopAreanone[] -> []The work area PushArea remembered, selected again.
CloseTables
all: flag
USE with nothing open to close, or CLOSE TABLES/CLOSE ALL.
SetFoundnone[flag] -> []what FOUND() will report for the selected work area, after a LOCATE.
ReplaceField
field: u32
additive: flag
[value] -> []Changes one field of the record the pointer is on, in the page in hand. additive is REPLACE ... ADDITIVE, which adds to a memo field rather than replacing it.
ReplaceFieldNamed
additive: flag
[name, value] -> []REPLACE (expr) WITH value: the field the name works out to.
MarkDeleted
flag
[] -> []DELETE and RECALL: the flag at the front of the record.
ZapnoneZAP: empties the selected table.
FileCommand
byte
A file command: 1 COPY FILE, 2 RENAME, 3 MD, 4 RD, 5 DIR, 6 TYPE. Pops its names.
DeclareDll
u32
DECLARE ... DLL: pops the library name and registers the declaration at that index.
EndOfCodenoneThe routine ran out of statements: it returns the value on top of the stack, and stops there. A RETURN the program wrote goes further - out of a line a macro put together and out of the routine that line belongs to - so the two are not the same instruction.
ExecMacroText
u32
A command with a macro in it, kept as the source text at that constant: every &name in it is replaced by the text that variable holds, and what comes out is compiled and run in this frame.
CreateTable
index: u32The definition in the module: the columns the new table has.
from_array: flag
columns: byteHow many column names went on the stack instead, worked out when it ran.
CREATE TABLE: pops a path and asks the host to write an empty table of the fields in Module::cursors at that index. With from_array the columns are described by an array on the stack under the path instead, and the module holds none.
CreateTableAllowednone[path] -> [logical]Asks the open database whether a table of its own may be made: dbc_BeforeCreateTable, answering whether the statement is to go ahead. A .F. stops the whole of CREATE TABLE - no file is written and no work area taken - so the rest of the statement is jumped over rather than run. A free table never reaches this.
RaiseErrornoneERROR: pops a message (or Omitted) and a number or text, and raises it.
AppendBlanknone[] -> []APPEND BLANK: an empty record at the end, which the pointer moves to.
InsertBlank
before: flag
[] -> []INSERT [BEFORE] [BLANK]: an empty record beside the one the pointer is on, with everything below it moved down one. The pointer ends on the new record.
InsertFrom
from: byte0 an array, 1 a variable per field, 2 an object - as GATHER numbers them.
[source, row] -> [more, next]One record of INSERT INTO ... FROM ARRAY | MEMVAR | NAME: appends a blank and fills it from that row of the source, then says whether another row follows and which it is. An array of two dimensions holds a record per row, so the statement loops over this; the other two sources have the one row.
CreateCursorFromArray
index: u32The name written in the statement, when it was not worked out on the stack.
named: flag
[array] -> []CREATE CURSOR name FROM ARRAY a: a cursor whose columns the array describes, in the shape AFIELDS() hands back. The name works the same way as CreateCursor's.
FlushRecordnone[] -> []Sends the changed record back to the host, if anything changed it.
NewDocument
u32
[path] -> []CREATE FORM, CREATE MENU and the rest: a new one of that kind, in its designer. The constant says which kind.
Import
sheet: flag
IMPORT: the file is on the stack, with the sheet name over it when there is one. Reads the workbook, gathers the table it describes, and pushes where it is to go.
Build
what: u32
count: u16
recompile: flag
BUILD: the kind is a constant, the target and count sources are on the stack.
Compile
what: u32
flags: byte
COMPILE: the kind is a constant and the file expression is on the stack.
ModifyInContainer
what: byte
flags: u16NOWAIT and NOEDIT, which dbc_ModifyData is handed.
[path] -> []MODIFY TABLE, MODIFY VIEW, MODIFY PROCEDURE and MODIFY DATABASE: the designer for something the open database holds, which the database is told about either side of. 0 a table, 1 a view, 2 the stored procedures, 3 the database itself.
Unsupported
u32
[] -> []A command this runtime cannot honour: raises "Feature is not available" with the constant's text when the line is reached. It compiles, as it does in the product.
Redefined
u32
[] -> []Assigning to THIS, THISFORM, THISFORMSET or _SCREEN: "Cannot redefine X.", which the constant names. The line compiles, as it does in the product.
OpenDocument
u32
[path] -> [](yields HostRequest::OpenDocument) for MODIFY and BROWSE. The constant holds the word that followed MODIFY, because each kind of document brings its own extension when the name written has none: MODIFY DATABASE dvds opens dvds.dbc.
LoadTablePathnone[] -> [path]The file behind the selected work area, for BROWSE.
MakeArray
byte
[d1 .. dn] -> [array]A fresh array of that shape, for DIMENSION of something that is not a variable: an array property, which is assigned to rather than declared.
CreateCursor
index: u32The definition in the module: its columns, and the name it was written with.
named: flagA name went on the stack instead, worked out when the statement ran.
columns: byteHow many column names went on the stack too, under that name.
[] -> []CREATE CURSOR: an empty table of that shape, in a free work area.
ReplaceFieldAt
byte
[value] -> []Changes the field at that position of the record the pointer is on, for an INSERT that gave its values in the table's own order.
ClearAll
tables: flag
[] -> []CLEAR MEMORY and, with tables, CLEAR ALL.
LoadField
area: u32 or none
field: u32
[] -> [value]a field, or a member: area is a bare name the VM resolves - an object variable, the m. memory-variable prefix, or the alias of an open table.
Blank
u32
[] -> []BLANK: the fields of the record in hand go back to empty. The constant names the fields, a comma apart, or is empty for all of them.

SELECT-SQL

The loops are ordinary bytecode; these four hold the query together.

InstructionOperandsStackWhat it does
SqlOpen
table: u32
alias: u32
named: flag
[name?] -> []Opens (or borrows) one FROM source and selects it. table is a constant and alias a name index; named says the name is on the stack instead, which is what FROM (cPath) compiles to.
SelectSource
u16
[] -> []Selects the work area of the query's nth FROM source. The source is named by where it is in the FROM clause rather than by what it is called, because a source named by an expression is only called something once it has been opened.
JoinMiss
u16
[] -> []The nth FROM source has no record matching the row being built, so it is parked past its last record and every field of it reads as .NULL. until it is moved again. That is what an outer join puts on the side that missed.
SqlBegin
u32
[top?] -> []Starts gathering rows for the plan at plan, expanding its * columns against the sources just opened.
SqlRow
u16
[v1 .. vn] -> []One gathered row: the column values, then the GROUP BY keys, then the ORDER BY keys.
SqlEndnone[] -> []Folds, sorts and installs the result, then lets go of the sources.
SqlHavingNextnone[] -> [logical]Folds the gathered rows the first time, then moves the HAVING clause on to the next group and says whether there is one. The three that follow are the loop the compiler emits between the gathering and SqlEnd: HAVING is an expression of the program's own, so it is run as bytecode, a group at a time.
SqlHavingValue
u16
[] -> [value]The nth thing the plan's HAVING clause names, out of the group being asked about.
SqlHavingKeepnone[logical] -> []What the predicate came to for that group: keeps it or drops it.
SqlSourceField
u32
[] -> [value]The field of that name in whichever of the query's sources has one, read from the record that source is on, or .NULL. when none of them has such a field. It is what a HAVING clause gathers for a name the select list gave with AS, since the name itself means nothing to a record but a field of the same name would shadow it.
SqlRequireGroupBynone[] -> []Raises 1807 unless SET ENGINEBEHAVIOR 70 is in force. It stands in front of a query whose HAVING clause names an aggregate the select list has not got and which groups by nothing, which the older rules allow and the current ones do not.
InCursor
u32
[value] -> [logical]Is the value one of those in the first column of that cursor: what IN (SELECT ...) and = ANY (SELECT ...) come to once the subquery has been run.

indexes

InstructionOperandsStackWhat it does
OpenIndexnone[] -> []Reads the compound index beside the table a USE has just opened, when the table's header says one sits there.
SetOrder
descending: flag or none
[tag] -> []SET ORDER TO: a tag name, a tag number, or Omitted for record order. descending overrides the tag's own direction when the command said which way to go.
Seeknone[key] -> []SEEK: to the first record the controlling order holds under that key, or to end of file. FOUND() answers with whether it was there.
IndexBeginnone[path?, name, key, for, flags] -> []INDEX ON: starts gathering the keys of a new index. The flags are 1 UNIQUE, 2 CANDIDATE, 4 DESCENDING, 8 a single-entry index of its own rather than a tag, 16 COMPACT, 32 ADDITIVE; the path is there when 8 is set.
IndexKeynone[key] -> []One key of the tag being built, for the record the pointer is on.
IndexEndnone[] -> []The tag is complete: it is sorted, becomes the controlling order, and the index is written back beside the table.
DeleteTag
all: flag
[name] -> []DELETE TAG: that tag, or every tag, and the index is written back.
Reindexnone[] -> []REINDEX: writes the index back beside the table.
OpenIdx
count: byte
[path...] -> []USE ... INDEX x, y: single-entry indexes opened beside the table, the first of them the controlling order. What SET INDEX TO does goes through set_cmd instead, so that the setting and the command stay one thing.
CopyIndexes
count: byte
all: flag
[path..., target] -> []COPY INDEXES: a tag per single-entry index, in the structural compound index or in the file the target names. all copies every index open beside the table and leaves the list empty.
CopyTagnone[tag, of, target] -> []COPY TAG: that tag of the compound index, or of the file of names, written out as a single-entry index of its own.

tables, databases and transactions

InstructionOperandsStackWhat it does
Unlock
record: flag
area: u32 or none
all: flag
[record?] -> []UNLOCK: one record, or everything the work area has locked.
AlterTable
list of AlterStep
[path, names...] -> []ALTER TABLE: the table is read, given its new columns and written back. The names the program worked out sit above the path, in the order the changes were written.
Transaction
byte
[] -> []A transaction: 0 begins one, 1 writes what it held, 2 throws it away.
DbCommand
kind: byte
named: flagA name was pushed for it.
target: flagA second name was pushed, for a rename.
sql: u32 or noneThe SELECT a view stands for, as a constant.
flags: u16The clauses the command was written with, as crate::ast::db_flags bits: what the database event that goes with the command is handed.
[name?, target?] -> []A command that works on a database container. kind is 0 create, 1 open, 2 close, 3 set, 4 delete, 5 validate, 6 add a table, 7 remove one, 8 free one, 9 rename one, 10 create a view, 11 drop one, 12 list what is in it.

listing, reports and browsing

InstructionOperandsStackWhat it does
ShowInfo
kind: byte
skeleton: flagA LIKE skeleton is on the stack, narrowing what is listed to the names it matches.
[] -> []LIST and DISPLAY of something the runtime holds: 0 the structure of the table, 1 the variables, 2 the settings and work areas, 3 the files, 4 the database's tables, 5 its views, 6 the declared library functions, 7 the loaded programs, 8 the objects, 9 the connections.
ListBeginnone[] -> []A record listing is starting, so the row of field names is due. It is written above the first record there is to write and not before, because a LIST that matches nothing writes nothing at all. SET HEADINGS OFF means none is due.
ListRecord
fields: u32
numbers: flag
[] -> []One record, written out as LIST writes it. fields is a constant naming the fields the command asked for, a comma apart, or empty for every field of the table; numbers is false when the command said OFF, which drops the record-number column.
ReportBegin
flags: byte
label: flag
to_file: flag
[path, file?] -> []REPORT FORM: reads the report file and starts it, writing the bands that print once at the top. flags is the statement's own.
ReportRownone[] -> []One record of it: the detail band, worked out against the record the pointer is on.
ReportEndnone[] -> []The bands that print once at the end, and the report goes where it was told.
Browse
fields: u32 or none
cond: u32 or none
flags: byte
titled: flag
[title?] -> []BROWSE: the records of the work area go to the host, which shows them in a window of their own. The constant names the columns, a comma apart.

events, memos and saved variables

InstructionOperandsStackWhat it does
OnEvent
what: u32
given: flag
[command?] -> []The ON family: what it hangs off, and the command it hangs there. A command of nothing takes the one that was there away.
Memo
what: byte
fields: u32
pathed: flag
named: flag
flags: byte
[field?, path?] -> []APPEND MEMO, COPY MEMO, MODIFY MEMO, CLOSE MEMO and APPEND GENERAL. The constant names the fields, a comma apart; named says the one field is on the stack instead, under the file, because the program worked its name out.
Variables
save: flag
memo: flag
skeleton: flagA skeleton went on the stack after the target.
except: flag
additive: flag
[target, skeleton?] -> []SAVE TO and RESTORE FROM.

input, windows and menus

InstructionOperandsStackWhat it does
Mouse
clicks: byte
at: flagAn AT position went on the stack first.
drags: byteHow many DRAG TO positions followed it.
window: flagA WINDOW name went on last.
style: u32The words that came after, as one constant.
[row?, col?, drag rows and columns ...] -> []MOUSE: the pointer moves and presses.
Ask
kind: byte
prompted: flag
target: u32The variable the answer goes into.
[prompt?] -> []INPUT, ACCEPT or GETEXPR: ask, and put the answer where the statement said. kind is 0 text, 1 worked out as an expression, 2 an expression kept as text.
Run
nowait: flag
[command] -> []RUN: a command line handed to the operating system.
Diagnostic
checked: flag
argc: byte
[cond?, v1 .. vn] -> []ASSERT and DEBUGOUT.
Yield
events: flag
[] -> []FLUSH and DOEVENTS: let the host catch up.
Keyboard
plain: flag
clear: flag
[keys] -> []KEYBOARD: keys into the buffer as if they had been typed.
KeyStack
push: flag
clear: flag
[] -> []PUSH KEY / POP KEY.
Ejectnone[] -> []EJECT: the page ends here.
WindowCommand
kind: byte
given: byteOne bit each from the least significant: the name, the two corners and the title.
text: u32 or none
flags: byte
[name?, r1?, c1?, r2?, c2?, title?] -> []A window command. kind says which one, and text the words that say how the window looks.
AtCommand
kind: byte
given: u16
style: u32 or noneThe words that say how it is drawn, what a GET is called, and its two conditions.
name: u32 or none
valid: u32 or none
when: u32 or none
[row?, col?, value?, r2?, c2?, picture?, function?, amount?] -> []One thing an @ line draws. given is one bit each, in that order.
MenuCommand
kind: byte
given: byteWhich of the operands were pushed, one bit each from the least significant: the name, the OF, the number, the prompt, the key and the message.
text: u32 or none
flags: byte
[name?, of?, number?, prompt?, key?, message?] -> []A menu command. kind says which one, and text the command a choice runs or the condition it is skipped for.

copying, appending and aggregates

InstructionOperandsStackWhat it does
Packnone[] -> []PACK: the table is read, the records that are left are written back from the top, and the header is told how many there are.
AppendFrom
except: flag
count: u16
cond: u32 or none
text: byte0 a table, 1 fixed-width text, 2 comma-separated, 3 delimited.
[path, name1 .. nameN] -> []APPEND FROM: the file to read and which columns to take from it. cond is the FOR condition as written, or 0 when there is none.
CopyBegin
kind: byte
except: flag
count: u16
descending: u32Which sort keys run backwards, one bit per key from the least significant.
text: byte0 a table, 1 fixed-width text, 2 comma-separated, 3 delimited by what follows.
[path, name1 .. nameN] -> []COPY TO, SORT TO and TOTAL ON: the table to make and which of the columns go in it. kind is 0 records, 1 structure, 2 sorted, 3 totals.
CopyRow
u16
[key1 .. keyN] -> []One record for the copy: its keys, and the record itself.
CopyEndnone[] -> []The copy is complete: the file is written.
AggBegin
list of byte
[] -> []COUNT/SUM/AVERAGE/CALCULATE: starts one accumulator per column, each named by what it works out - 0 CNT, 1 SUM, 2 AVG, 3 MIN, 4 MAX, 5 STD, 6 VAR, 7 NPV.
AggStep
u16
[value] -> []One record's worth for the column at that index. NPV takes the rate and the flow, so it pops two.
AggEndnone[] -> [array]The columns worked out, in the order they were asked for.
Scatter
to: byte0 an array, 1 a variable each, 2 an object.
except: flagThe names are the fields to leave out rather than the ones to take.
count: u16
blank: flagBLANK: the shape of the record rather than what is in it.
[name1 .. nameN] -> [row?]SCATTER: the record's fields, as an array or an object on the stack, or as a variable each. The field names named by FIELDS are on the stack, or none of them when the command named none.
Gather
to: byte
except: flag
count: u16
[row?, name1 .. nameN] -> []GATHER: the other way, into the record in hand.
SetFilter
u32
[] -> []SET FILTER TO: the condition at that constant, empty for none.
SetRelation
count: u16
additive: flag
off: flag
[expr1, alias1, ...] -> []SET RELATION TO ... INTO ...: count pairs of expression text and work-area alias. off takes one relation away instead of setting them.

the debugger

InstructionOperandsStackWhat it does
Debug
DebugVerb
[] -> []SUSPEND and RESUME: hand the program over to the debugger, or take it back.