Files
five/compiler/pp/std.ch
CharlesKWON c4f85f494c feat(pp): Phase A — preprocessor std.ch as single source of truth
Introduce compiler/pp/std.ch with 19 #command rules so that ERASE,
RENAME, DELETE FILE, CLOSE [<a>|ALL|DATABASES], COMMIT, UNLOCK,
LOCATE/CONTINUE, REINDEX, PACK, ZAP, KEYBOARD, RUN, MENU TO, and
CLEAR GETS reach the parser pre-rewritten as plain function calls.
Embedded into the compiler binary via //go:embed so it auto-loads
without an explicit #include in user code, exactly the way Harbour
auto-loads its std.ch.

This is a pure dispatch move, not a behavior change for the
already-working forms: the same Five RTL functions get called.
But it does fix three regressions that the parser was masking:

  * ERASE / RENAME / DELETE FILE used to be silent no-ops — the
    parser swallowed the entire line and returned NIL. They now
    actually delete/rename files (FErase / FRename).
  * CLOSE <alias> used to silently ignore the alias and close the
    current area. It now switches to the named area first
    (<a>->( DbCloseArea() )).
  * Two latent #command matcher bugs that surfaced while wiring
    std.ch up:
      - bare `CLOSE` would match rule `CLOSE ALL` because the tail
        of the pattern wasn't checked for unconsumed literals.
      - bare `CLOSE` would match rule `CLOSE <a>` because all
        unconsumed pattern markers were unconditionally treated as
        optional. They are only optional when nested inside `[...]`.

Parser cleanup: parseIdentStmt + parseExprStmt no longer hardcode
ERASE / RENAME / RUN / KEYBOARD / REINDEX / LOCATE / CONTINUE /
COMMIT / CLOSE — the rewriter handles them. Other xBase verbs
(COPY / SORT / COUNT / SUM / AVERAGE / TOTAL / JOIN / LIST /
DISPLAY / LABEL / REPORT / DIR ...) still no-op in the parser
because their RTL backends aren't implemented yet — once the
backends land they move into std.ch the same way.

Gates green:
  go test ./...      : PASS
  FiveSql2 SQL:1999  : 43/43
  Harbour compat     : 56/56

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 12:03:30 +09:00

55 lines
2.2 KiB
Plaintext

/*
* 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 <a> => <a>->( DbCloseArea() )
/* --- record state --- */
#command COMMIT => DbCommit()
#command UNLOCK ALL => DbUnlock()
#command UNLOCK => DbRUnlock()
/* --- record search --- */
#command LOCATE [FOR <for>] [WHILE <while>] ;
[NEXT <next>] [RECORD <rec>] [<rest:REST>] [ALL] => ;
__dbLocate(<{for}>, <{while}>, <next>, <rec>, <.rest.>)
#command CONTINUE => __dbContinue()
/* --- bulk maintenance --- */
#command REINDEX => DbReindex()
#command PACK => DbPack()
#command ZAP => DbZap()
/* --- input / shell --- */
#command KEYBOARD <text> => Keyboard(<text>)
#command RUN <*cmd*> => hb_Run(<(cmd)>)
/* --- legacy GET system --- */
#command MENU TO <var> => <var> := __MenuTo(<var>)
#command CLEAR GETS => GetList := {}