/*
* std.ch — Five standard preprocessor rules
*
* Equivalent to harbour-core/include/std.ch. Translates xBase legacy
* commands into function calls so the parser does not have to know
* about them. Auto-loaded by compiler/pp at startup.
*
* Phase A: only rules whose backend RTL function already exists in
* Five. Rules whose backend is not yet implemented (COPY, SORT,
* COUNT, SUM, AVERAGE, TOTAL, JOIN, LIST, DISPLAY, LABEL, REPORT,
* DIR) are deliberately NOT included here — the parser still handles
* them as silent no-ops until their RTL backend lands.
*
* Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
* All rights reserved.
*/
/* --- file system --- */
#command ERASE <(f)> => FErase(<(f)>)
#command DELETE FILE <(f)> => FErase(<(f)>)
#command RENAME <(s)> TO <(d)> => FRename(<(s)>, <(d)>)
/* --- workarea lifecycle ---
Order matters: literal-keyword forms first, then bare CLOSE,
then the alias-form last so it doesn't shadow the others. */
#command CLOSE ALL => DbCloseAll()
#command CLOSE DATABASES => DbCloseAll()
#command CLOSE => DbCloseArea()
#command CLOSE => ->( DbCloseArea() )
/* --- record state --- */
#command COMMIT => DbCommit()
#command UNLOCK ALL => DbUnlock()
#command UNLOCK => DbRUnlock()
/* --- record search --- */
#command LOCATE [FOR ] [WHILE ] ;
[NEXT ] [RECORD ] [] [ALL] => ;
__dbLocate(<{for}>, <{while}>, , , <.rest.>)
#command CONTINUE => __dbContinue()
/* --- analytical (no extra RTL — just dbEval) ---
These mirror Harbour's std.ch but use single-value forms. Multi-
expression SUM/AVERAGE (`SUM x, y TO sx, sy`) use optional-repeat
syntax in Harbour and can be added here once a real test exercises
the more elaborate form. */
#command COUNT [TO ] [FOR ] [WHILE ] ;
[NEXT ] [RECORD ] [] [ALL] => ;
:= 0 ; dbEval( {|| := + 1 }, ;
<{for}>, <{while}>, , , <.rest.> )
#command SUM TO ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [ALL] => ;
:= 0 ; dbEval( {|| := + }, ;
<{for}>, <{while}>, , , <.rest.> )
#command AVERAGE TO ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [ALL] => ;
:= __dbAverage( <{x}>, ;
<{for}>, <{while}>, , , <.rest.> )
/* --- bulk record export ---
COPY TO copies visible records of the current workarea into a fresh
DBF. FIELDS/FOR/WHILE/NEXT/RECORD/REST work as in Harbour. SDF and
DELIMITED variants stay as silent no-ops in the parser until their
backends land. */
#command COPY [TO <(f)>] [FIELDS ] ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [ALL] => ;
__dbCopy( <(f)>, { <(fields)> }, ;
<{for}>, <{while}>, , , <.rest.> )
/* SORT TO copies the visible records into a fresh DBF in key order.
Each key in `` may carry `/D` for descending; default is
ascending. */
#command SORT [TO <(f)>] [ON ] ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [ALL] => ;
__dbSort( <(f)>, { <(fields)> }, ;
<{for}>, <{while}>, , , <.rest.> )
/* --- console output ---
LIST emits every record matching the filter; DISPLAY without ALL
shows just the current record. Both share __dbList — lAll
distinguishes them. TO PRINTER / TO FILE accepted but unused;
stdout is the only sink for now. */
#command LIST [] [] ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [ALL] => ;
__dbList( <.off.>, { <{v}> }, .T., ;
<{for}>, <{while}>, , , <.rest.> )
#command DISPLAY [] [] ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [] => ;
__dbList( <.off.>, { <{v}> }, <.all.>, ;
<{for}>, <{while}>, , , <.rest.> )
/* TOTAL TO writes one record per consecutive run of equal key values
from the source. Numeric fields named in FIELDS are summed; every
other (non-memo) field takes the first record's value. The source
must already be sorted/indexed on the key for the grouping to
produce one row per distinct value. */
#command TOTAL [TO <(f)>] [ON ] [FIELDS ] ;
[FOR ] [WHILE ] [NEXT ] ;
[RECORD ] [] [ALL] => ;
__dbTotal( <(f)>, <{key}>, { <(fields)> }, ;
<{for}>, <{while}>, , , <.rest.> )
/* --- bulk maintenance --- */
#command REINDEX => DbReindex()
#command PACK => DbPack()
#command ZAP => DbZap()
/* --- input / shell --- */
#command KEYBOARD => Keyboard()
#command RUN <*cmd*> => hb_Run(<(cmd)>)
/* --- legacy GET system --- */
#command MENU TO => := __MenuTo()
#command CLEAR GETS => GetList := {}