Files
five/hbrtl/register.go
CharlesKWON 5b1d3fb32f feat(pp,rtl): pre-release accuracy round (Wave 3)
Four audit findings around correctness/consistency in std.ch and the
SORT/UPDATE/TOTAL handlers:

  * #13: TOTAL/UPDATE key idiom inconsistency documented as inherent.
    TOTAL evaluates `<key>` only in the source workarea so verbatim
    `<{key}>` (alias-qualified or `_FIELD->`-prefixed by the user)
    works. UPDATE evaluates the same block in BOTH master and detail
    context, so it must wrap as `_FIELD-><key>` to dispatch to
    whichever WA is selected at eval time. The two rules look alike
    but their evaluation contexts differ — also documented in
    std.ch alongside both rules so the asymmetry isn't a surprise.
    Plus: TOTAL TO and ON are now mandatory (matching the COUNT/
    UPDATE pattern from Wave 1) — bare TOTAL would have produced
    broken syntax via the unconditional `<(f)>`/`<{key}>` template
    references.

  * #15/#16: SDF / DELIMITED variants of COPY and TO PRINTER /
    TO FILE variants of LIST / DISPLAY are now matched by stub
    rules (placed *before* the regular rules so they win) that
    expand to a new `__dbNotImpl(reason)` RTL primitive raising a
    clear `&hbrt.HbError`. BEGIN SEQUENCE / RECOVER catches the
    panic, so callers get a real error instead of the previous
    silent dispatch-to-regular-DBF-copy.

  * #19: SORT /C (case-insensitive) now actually folds case before
    the string compare, instead of being silently treated as
    ascending. Suffix parser also rebuilt as a multi-letter scanner
    so `name/CD`, `name/DC`, `name/C/D`, `name/D/C` all parse the
    same way — combine /C and /D freely. Unknown suffix letters
    (e.g., `name/X`) leave the suffix attached to the field name
    so a stray slash in user input doesn't get silently mangled
    into a broken field reference.

  * #27 SET DELETED: verified with a regression test that
    `SET DELETED ON` causes COUNT/COPY (and by extension
    SORT/TOTAL/JOIN/UPDATE — all of which iterate via Area.Skip)
    to skip rows marked deleted. The filtering is implemented at
    the workarea level (skipFilter in dbf.go honors hbrdd.IsSetDeleted)
    so no RTL changes were needed; this commit just adds the
    coverage so the behavior doesn't silently regress.

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-05-01 08:01:42 +09:00

824 lines
33 KiB
Go

// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
// All rights reserved.
// RTL registration for the Five runtime library.
// Centralized registration following tsgo's NodeFactory pattern.
package hbrtl
import (
"five/hbrdd"
"five/hbrt"
"strings"
)
// RegisterRTL registers all standard library functions with the VM.
func RegisterRTL(vm *hbrt.VM) {
// Auto-create WorkAreaManager for each thread
vm.SetWAFactory(func() interface{} {
return hbrdd.NewWorkAreaManager()
})
// Restore terminal on exit
vm.SetOnExit(func() {
RestoreTerminal()
})
mod := hbrt.NewModule("_RTL",
// Console
hbrt.Sym("QOUT", hbrt.FsPublic, rtlQOut),
hbrt.Sym("QQOUT", hbrt.FsPublic, rtlQQOut),
hbrt.Sym("OUTSTD", hbrt.FsPublic, rtlOutStd),
hbrt.Sym("OUTERR", hbrt.FsPublic, rtlOutErr),
// Strings / Conversion
hbrt.Sym("STR", hbrt.FsPublic, Str),
hbrt.Sym("VAL", hbrt.FsPublic, Val),
hbrt.Sym("LEN", hbrt.FsPublic, Len),
hbrt.Sym("SUBSTR", hbrt.FsPublic, SubStr),
hbrt.Sym("UPPER", hbrt.FsPublic, Upper),
hbrt.Sym("LOWER", hbrt.FsPublic, Lower),
hbrt.Sym("ALLTRIM", hbrt.FsPublic, AllTrim),
hbrt.Sym("LTRIM", hbrt.FsPublic, LTrim),
hbrt.Sym("RTRIM", hbrt.FsPublic, RTrim),
hbrt.Sym("TRIM", hbrt.FsPublic, RTrim), // TRIM = RTRIM in Harbour
hbrt.Sym("SPACE", hbrt.FsPublic, Space),
hbrt.Sym("PADR", hbrt.FsPublic, PadR),
hbrt.Sym("PADL", hbrt.FsPublic, PadL),
hbrt.Sym("REPLICATE", hbrt.FsPublic, Replicate),
// Type / Conversion
hbrt.Sym("VALTYPE", hbrt.FsPublic, ValType),
hbrt.Sym("EMPTY", hbrt.FsPublic, Empty),
hbrt.Sym("ABS", hbrt.FsPublic, Abs),
hbrt.Sym("INT", hbrt.FsPublic, Int),
// Array
hbrt.Sym("AADD", hbrt.FsPublic, AAdd),
hbrt.Sym("ADEL", hbrt.FsPublic, ADel),
hbrt.Sym("AINS", hbrt.FsPublic, AIns),
hbrt.Sym("ASIZE", hbrt.FsPublic, ASize),
hbrt.Sym("ACLONE", hbrt.FsPublic, AClone),
hbrt.Sym("HBDEEPCLONE", hbrt.FsPublic, HbDeepClone),
hbrt.Sym("HB_DEEPCOPY", hbrt.FsPublic, HbDeepClone),
hbrt.Sym("ACOPY", hbrt.FsPublic, ACopy),
hbrt.Sym("AFILL", hbrt.FsPublic, AFill),
hbrt.Sym("ASORT", hbrt.FsPublic, ASort),
hbrt.Sym("AEVAL", hbrt.FsPublic, AEval),
hbrt.Sym("ASCAN", hbrt.FsPublic, AScan),
hbrt.Sym("ATAIL", hbrt.FsPublic, ATail),
// Hash
hbrt.Sym("HB_HASH", hbrt.FsPublic, HbHash),
hbrt.Sym("HB_HGET", hbrt.FsPublic, HbHGet),
hbrt.Sym("HB_HSET", hbrt.FsPublic, HbHSet),
hbrt.Sym("HB_HDEL", hbrt.FsPublic, HbHDel),
hbrt.Sym("HB_HHASKEY", hbrt.FsPublic, HbHHasKey),
hbrt.Sym("HB_HKEYS", hbrt.FsPublic, HbHKeys),
hbrt.Sym("HB_HVALUES", hbrt.FsPublic, HbHValues),
// Date / Time
hbrt.Sym("DATE", hbrt.FsPublic, Date),
hbrt.Sym("TIME", hbrt.FsPublic, Time),
hbrt.Sym("YEAR", hbrt.FsPublic, Year),
hbrt.Sym("MONTH", hbrt.FsPublic, Month),
hbrt.Sym("DAY", hbrt.FsPublic, Day),
hbrt.Sym("DOW", hbrt.FsPublic, DOW),
hbrt.Sym("SECONDS", hbrt.FsPublic, Seconds),
hbrt.Sym("DTOC", hbrt.FsPublic, DToC),
hbrt.Sym("DTOS", hbrt.FsPublic, DToS),
hbrt.Sym("STOD", hbrt.FsPublic, SToD),
// Eval
hbrt.Sym("EVAL", hbrt.FsPublic, rtlEval),
hbrt.Sym("DO", hbrt.FsPublic, rtlDo),
// String (new)
hbrt.Sym("AT", hbrt.FsPublic, At),
hbrt.Sym("LEFT", hbrt.FsPublic, Left),
hbrt.Sym("RIGHT", hbrt.FsPublic, Right),
hbrt.Sym("ASC", hbrt.FsPublic, Asc),
hbrt.Sym("CHR", hbrt.FsPublic, Chr),
hbrt.Sym("STRTRAN", hbrt.FsPublic, StrTran),
hbrt.Sym("STUFF", hbrt.FsPublic, Stuff),
hbrt.Sym("PADC", hbrt.FsPublic, PadC),
hbrt.Sym("HB_STRREPLACE", hbrt.FsPublic, HbStrReplace),
hbrt.Sym("HB_NTOS", hbrt.FsPublic, HbNToS),
// Math (new)
hbrt.Sym("ROUND", hbrt.FsPublic, Round),
hbrt.Sym("MAX", hbrt.FsPublic, Max),
hbrt.Sym("MIN", hbrt.FsPublic, Min),
hbrt.Sym("SQRT", hbrt.FsPublic, Sqrt),
hbrt.Sym("LOG", hbrt.FsPublic, Log),
hbrt.Sym("EXP", hbrt.FsPublic, Exp),
hbrt.Sym("MOD", hbrt.FsPublic, Mod),
// Date (new)
hbrt.Sym("CTOD", hbrt.FsPublic, CToD),
hbrt.Sym("CDOW", hbrt.FsPublic, CDoW),
hbrt.Sym("CMONTH", hbrt.FsPublic, CMonth),
// Misc (new)
hbrt.Sym("TYPE", hbrt.FsPublic, TypeFunc),
hbrt.Sym("PCOUNT", hbrt.FsPublic, PCount),
hbrt.Sym("BREAK", hbrt.FsPublic, Break),
hbrt.Sym("ARRAY", hbrt.FsPublic, ArrayFunc),
hbrt.Sym("FCOUNT", hbrt.FsPublic, FCount),
hbrt.Sym("FIELDNAME", hbrt.FsPublic, FieldName),
hbrt.Sym("SELECT", hbrt.FsPublic, SelectFunc),
hbrt.Sym("FILE", hbrt.FsPublic, FileFunc),
hbrt.Sym("INKEY", hbrt.FsPublic, Inkey),
hbrt.Sym("TRANSFORM", hbrt.FsPublic, Transform),
hbrt.Sym("SETDATEFORMAT", hbrt.FsPublic, rtlSetDateFormat),
hbrt.Sym("SETEPOCH", hbrt.FsPublic, rtlSetEpoch),
hbrt.Sym("SETCENTURY", hbrt.FsPublic, rtlSetCentury),
// Terminal
hbrt.Sym("SETPOS", hbrt.FsPublic, SetPos),
hbrt.Sym("ROW", hbrt.FsPublic, Row),
hbrt.Sym("COL", hbrt.FsPublic, Col),
hbrt.Sym("DEVPOS", hbrt.FsPublic, DevPos),
hbrt.Sym("DEVOUT", hbrt.FsPublic, DevOut),
hbrt.Sym("DISPOUT", hbrt.FsPublic, DispOut),
hbrt.Sym("DEVOUTPICT", hbrt.FsPublic, DevOutPict),
hbrt.Sym("DISPBOX", hbrt.FsPublic, DispBox),
hbrt.Sym("CLS", hbrt.FsPublic, Cls),
hbrt.Sym("SCROLL", hbrt.FsPublic, Scroll),
hbrt.Sym("SETCOLOR", hbrt.FsPublic, SetColor),
hbrt.Sym("SETCURSOR", hbrt.FsPublic, SetCursor),
hbrt.Sym("MAXROW", hbrt.FsPublic, MaxRow),
hbrt.Sym("MAXCOL", hbrt.FsPublic, MaxCol),
// dbEdit / Browse / TBrowse
hbrt.Sym("DBEDIT", hbrt.FsPublic, DbEdit),
hbrt.Sym("TBROWSEDB", hbrt.FsPublic, rtlTBrowseDB),
hbrt.Sym("TBROWSENEW", hbrt.FsPublic, rtlTBrowseNew),
hbrt.Sym("TBCOLUMNNEW", hbrt.FsPublic, rtlTBColumnNew),
// RDD functions
hbrt.Sym("EOF", hbrt.FsPublic, rtlEOF),
hbrt.Sym("BOF", hbrt.FsPublic, rtlBOF),
hbrt.Sym("FOUND", hbrt.FsPublic, rtlFound),
hbrt.Sym("RECNO", hbrt.FsPublic, rtlRecNo),
hbrt.Sym("RECCOUNT", hbrt.FsPublic, rtlRecCount),
hbrt.Sym("LASTREC", hbrt.FsPublic, rtlRecCount), // alias
hbrt.Sym("DELETED", hbrt.FsPublic, rtlDeleted),
hbrt.Sym("FIELDGET", hbrt.FsPublic, rtlFieldGet),
// Database callable functions
hbrt.Sym("FIELDPUT", hbrt.FsPublic, rtlFieldPut),
hbrt.Sym("ALIAS", hbrt.FsPublic, rtlAlias),
hbrt.Sym("DBEVAL", hbrt.FsPublic, rtlDbEval),
hbrt.Sym("USED", hbrt.FsPublic, Used),
hbrt.Sym("DBUSEAREA", hbrt.FsPublic, rtlDbUseArea),
hbrt.Sym("DBCLOSEAREA", hbrt.FsPublic, rtlDbCloseArea),
hbrt.Sym("DBCLOSEALL", hbrt.FsPublic, rtlDbCloseAll),
hbrt.Sym("DBGOTO", hbrt.FsPublic, rtlDbGoTo),
hbrt.Sym("DBSKIP", hbrt.FsPublic, rtlDbSkip),
hbrt.Sym("DBGOTOP", hbrt.FsPublic, rtlDbGoTop),
hbrt.Sym("DBGOBOTTOM", hbrt.FsPublic, rtlDbGoBottom),
hbrt.Sym("DBAPPEND", hbrt.FsPublic, rtlDbAppend),
hbrt.Sym("DBDELETE", hbrt.FsPublic, rtlDbDelete),
hbrt.Sym("DBRECALL", hbrt.FsPublic, rtlDbRecall),
hbrt.Sym("DBCOMMIT", hbrt.FsPublic, rtlDbCommit),
hbrt.Sym("DBRLOCK", hbrt.FsPublic, rtlDbRLock),
hbrt.Sym("DBRUNLOCK", hbrt.FsPublic, rtlDbRUnlock),
hbrt.Sym("FLOCK", hbrt.FsPublic, rtlFLock),
hbrt.Sym("DBUNLOCK", hbrt.FsPublic, rtlDbUnlock),
hbrt.Sym("DBSEEK", hbrt.FsPublic, rtlDbSeek),
hbrt.Sym("DBSELECTAREA", hbrt.FsPublic, rtlDbSelectArea),
hbrt.Sym("DBPACK", hbrt.FsPublic, rtlDbPack),
hbrt.Sym("DBZAP", hbrt.FsPublic, rtlDbZap),
hbrt.Sym("RECALL", hbrt.FsPublic, rtlDbRecall),
hbrt.Sym("PACK", hbrt.FsPublic, rtlDbPack),
hbrt.Sym("ZAP", hbrt.FsPublic, rtlDbZap),
hbrt.Sym("__DBPACK", hbrt.FsPublic, rtlDbPack),
hbrt.Sym("__DBZAP", hbrt.FsPublic, rtlDbZap),
hbrt.Sym("DBRECALL", hbrt.FsPublic, rtlDbRecall),
// Locate / Filter
hbrt.Sym("DBLOCATE", hbrt.FsPublic, rtlDbLocate),
hbrt.Sym("__DBLOCATE", hbrt.FsPublic, rtlDbLocate),
hbrt.Sym("__DBCONTINUE", hbrt.FsPublic, rtlDbContinue),
hbrt.Sym("__DBAVERAGE", hbrt.FsPublic, rtlDbAverage),
hbrt.Sym("__DBCOPY", hbrt.FsPublic, rtlDbCopy),
hbrt.Sym("__DBSORT", hbrt.FsPublic, rtlDbSort),
hbrt.Sym("__DBLIST", hbrt.FsPublic, rtlDbList),
hbrt.Sym("__DBTOTAL", hbrt.FsPublic, rtlDbTotal),
hbrt.Sym("__DBJOIN", hbrt.FsPublic, rtlDbJoin),
hbrt.Sym("__DBUPDATE", hbrt.FsPublic, rtlDbUpdate),
hbrt.Sym("__DBNOTIMPL", hbrt.FsPublic, rtlDbNotImpl),
hbrt.Sym("DBSETFILTER", hbrt.FsPublic, rtlDbSetFilter),
hbrt.Sym("DBCLEARFILTER", hbrt.FsPublic, rtlDbClearFilter),
hbrt.Sym("DBFILTER", hbrt.FsPublic, rtlDbFilter),
// Encoding / Hashing (Go stdlib)
hbrt.Sym("HB_MD5", hbrt.FsPublic, HbMD5),
hbrt.Sym("HB_SHA256", hbrt.FsPublic, HbSHA256),
hbrt.Sym("HB_BASE64ENCODE", hbrt.FsPublic, HbBase64Encode),
hbrt.Sym("HB_BASE64DECODE", hbrt.FsPublic, HbBase64Decode),
hbrt.Sym("HB_CRC32", hbrt.FsPublic, HbCRC32),
// Bit operations (Go native)
hbrt.Sym("HB_BITAND", hbrt.FsPublic, HbBitAnd),
hbrt.Sym("HB_BITOR", hbrt.FsPublic, HbBitOr),
hbrt.Sym("HB_BITXOR", hbrt.FsPublic, HbBitXor),
hbrt.Sym("HB_BITNOT", hbrt.FsPublic, HbBitNot),
hbrt.Sym("HB_BITSHIFT", hbrt.FsPublic, HbBitShift),
hbrt.Sym("HB_BITTEST", hbrt.FsPublic, HbBitTest),
hbrt.Sym("HB_BITSET", hbrt.FsPublic, HbBitSet),
hbrt.Sym("HB_BITRESET", hbrt.FsPublic, HbBitReset),
// Regex (Go regexp)
hbrt.Sym("HB_REGEXCOMP", hbrt.FsPublic, HbRegexComp),
hbrt.Sym("HB_REGEXMATCH", hbrt.FsPublic, HbRegexMatch),
hbrt.Sym("HB_REGEXSPLIT", hbrt.FsPublic, HbRegexSplit),
hbrt.Sym("HB_REGEXALL", hbrt.FsPublic, HbRegexAll),
hbrt.Sym("HB_REGEXREPLACE", hbrt.FsPublic, HbRegexReplace),
// String (additional)
hbrt.Sym("RAT", hbrt.FsPublic, Rat),
hbrt.Sym("STRZERO", hbrt.FsPublic, StrZero),
hbrt.Sym("DESCEND", hbrt.FsPublic, Descend),
hbrt.Sym("HB_VALTOSTR", hbrt.FsPublic, HbValToStr),
hbrt.Sym("HB_VALTOEXP", hbrt.FsPublic, HbValToExp),
hbrt.Sym("HB_CSTR", hbrt.FsPublic, HbCStr),
hbrt.Sym("HB_NTOS", hbrt.FsPublic, HbNtos),
hbrt.Sym("MEMOREAD", hbrt.FsPublic, MemoRead),
hbrt.Sym("MEMOWRIT", hbrt.FsPublic, MemoWrit),
hbrt.Sym("MEMOTRAN", hbrt.FsPublic, MemoTran),
// Binary conversion
hbrt.Sym("BIN2I", hbrt.FsPublic, Bin2I),
hbrt.Sym("BIN2L", hbrt.FsPublic, Bin2L),
hbrt.Sym("BIN2W", hbrt.FsPublic, Bin2W),
hbrt.Sym("I2BIN", hbrt.FsPublic, I2Bin),
hbrt.Sym("L2BIN", hbrt.FsPublic, L2Bin),
hbrt.Sym("W2BIN", hbrt.FsPublic, W2Bin),
// Keyboard
hbrt.Sym("LASTKEY", hbrt.FsPublic, LastKey),
hbrt.Sym("NEXTKEY", hbrt.FsPublic, NextKey),
hbrt.Sym("READKEY", hbrt.FsPublic, ReadKeyFunc),
hbrt.Sym("SETKEY", hbrt.FsPublic, SetKeyFunc),
hbrt.Sym("KEYBOARD", hbrt.FsPublic, Keyboard),
hbrt.Sym("HB_KEYPUT", hbrt.FsPublic, HbKeyPut),
// Display
hbrt.Sym("DISPBEGIN", hbrt.FsPublic, DispBegin),
hbrt.Sym("DISPEND", hbrt.FsPublic, DispEnd),
hbrt.Sym("DISPCOUNT", hbrt.FsPublic, DispCount),
hbrt.Sym("SAVESCREEN", hbrt.FsPublic, SaveScreen),
hbrt.Sym("RESTSCREEN", hbrt.FsPublic, RestScreen),
hbrt.Sym("ALERT", hbrt.FsPublic, Alert),
// Error handling
hbrt.Sym("ERRORBLOCK", hbrt.FsPublic, ErrorBlock),
hbrt.Sym("ERRORNEW", hbrt.FsPublic, ErrorNew),
hbrt.Sym("DOSERROR", hbrt.FsPublic, DosError),
hbrt.Sym("FERROR", hbrt.FsPublic, FError),
// SET commands
hbrt.Sym("SET", hbrt.FsPublic, SetFunc),
hbrt.Sym("__SETDATEFORMAT", hbrt.FsPublic, SetDateFunc),
hbrt.Sym("__SETDECIMALS", hbrt.FsPublic, SetDecimalsFunc),
hbrt.Sym("__SETEPOCH", hbrt.FsPublic, SetEpochFunc),
// SET toggle functions
hbrt.Sym("SETDELETED", hbrt.FsPublic, SetDeletedFunc),
hbrt.Sym("SETEXACT", hbrt.FsPublic, SetExactFunc),
hbrt.Sym("SETSOFTSEEK", hbrt.FsPublic, SetSoftSeekFunc),
hbrt.Sym("SETEXCLUSIVE", hbrt.FsPublic, SetExclusiveFunc),
hbrt.Sym("SETFIXED", hbrt.FsPublic, SetFixedFunc),
hbrt.Sym("SETCANCEL", hbrt.FsPublic, SetCancelFunc),
hbrt.Sym("SETBELL", hbrt.FsPublic, SetBellFunc),
hbrt.Sym("SETCONFIRM", hbrt.FsPublic, SetConfirmFunc),
hbrt.Sym("SETINSERT", hbrt.FsPublic, SetInsertFunc),
hbrt.Sym("SETESCAPE", hbrt.FsPublic, SetEscapeFunc),
hbrt.Sym("SETWRAP", hbrt.FsPublic, SetWrapFunc),
// SET constants
hbrt.Sym("_SET_EXACT", hbrt.FsPublic, SetConstExact),
hbrt.Sym("_SET_DELETED", hbrt.FsPublic, SetConstDeleted),
hbrt.Sym("_SET_SOFTSEEK", hbrt.FsPublic, SetConstSoftSeek),
hbrt.Sym("_SET_EXCLUSIVE", hbrt.FsPublic, SetConstExclusive),
hbrt.Sym("_SET_DATEFORMAT", hbrt.FsPublic, SetConstDateFmt),
hbrt.Sym("_SET_DECIMALS", hbrt.FsPublic, SetConstDecimals),
hbrt.Sym("_SET_EPOCH", hbrt.FsPublic, SetConstEpoch),
// Error handling
hbrt.Sym("ERRORBLOCK", hbrt.FsPublic, ErrorBlock),
hbrt.Sym("ERRORNEW", hbrt.FsPublic, ErrorNew),
hbrt.Sym("DOSERROR", hbrt.FsPublic, DosError),
hbrt.Sym("FERROR", hbrt.FsPublic, FError),
hbrt.Sym("BREAK", hbrt.FsPublic, Break),
hbrt.Sym("HB_ERRORLOG", hbrt.FsPublic, HbErrorLog),
hbrt.Sym("HB_SETERRORLOGPATH", hbrt.FsPublic, HbSetErrorLogPath),
hbrt.Sym("HB_SETERRORLOGHOOK", hbrt.FsPublic, HbSetErrorLogHook),
// File I/O
hbrt.Sym("FOPEN", hbrt.FsPublic, FOpen),
hbrt.Sym("FCREATE", hbrt.FsPublic, FCreate),
hbrt.Sym("FCLOSE", hbrt.FsPublic, FClose),
hbrt.Sym("FREAD", hbrt.FsPublic, FRead),
hbrt.Sym("FWRITE", hbrt.FsPublic, FWrite),
hbrt.Sym("FSEEK", hbrt.FsPublic, FSeek),
hbrt.Sym("FERASE", hbrt.FsPublic, FErase),
hbrt.Sym("FRENAME", hbrt.FsPublic, FRename),
hbrt.Sym("HB_FILEEXISTS", hbrt.FsPublic, HbFileExists),
// Directory/Disk
hbrt.Sym("CURDIR", hbrt.FsPublic, CurDir),
hbrt.Sym("DIRCHANGE", hbrt.FsPublic, DirChange),
hbrt.Sym("DIRECTORY", hbrt.FsPublic, Directory),
hbrt.Sym("DIRMAKE", hbrt.FsPublic, DirMake),
hbrt.Sym("DIRREMOVE", hbrt.FsPublic, DirRemove),
// Type checking (HB_IS*)
hbrt.Sym("HB_ISARRAY", hbrt.FsPublic, HbIsArray),
// Classic Clipper/Harbour aliases — `common.ch` #translate rules
// map these to HB_IS*. Registering the short names as direct
// symbols bypasses the PP altogether and makes them work even
// when code doesn't include common.ch.
hbrt.Sym("ISARRAY", hbrt.FsPublic, HbIsArray),
hbrt.Sym("HB_ISBLOCK", hbrt.FsPublic, HbIsBlock),
hbrt.Sym("ISBLOCK", hbrt.FsPublic, HbIsBlock),
hbrt.Sym("HB_ISCHAR", hbrt.FsPublic, HbIsChar),
hbrt.Sym("HB_ISSTRING", hbrt.FsPublic, HbIsString),
hbrt.Sym("ISCHARACTER", hbrt.FsPublic, HbIsString),
hbrt.Sym("ISMEMO", hbrt.FsPublic, HbIsString), // memo ≈ string for Five
hbrt.Sym("HB_ISDATE", hbrt.FsPublic, HbIsDate),
hbrt.Sym("ISDATE", hbrt.FsPublic, HbIsDate),
hbrt.Sym("HB_ISDATETIME", hbrt.FsPublic, HbIsDateTime),
hbrt.Sym("HB_ISLOGICAL", hbrt.FsPublic, HbIsLogical),
hbrt.Sym("ISLOGICAL", hbrt.FsPublic, HbIsLogical),
hbrt.Sym("HB_ISNUMERIC", hbrt.FsPublic, HbIsNumeric),
hbrt.Sym("ISNUMBER", hbrt.FsPublic, HbIsNumeric),
hbrt.Sym("ISNUMERIC", hbrt.FsPublic, HbIsNumeric),
hbrt.Sym("HB_ISOBJECT", hbrt.FsPublic, HbIsObject),
hbrt.Sym("ISOBJECT", hbrt.FsPublic, HbIsObject),
hbrt.Sym("HB_ISHASH", hbrt.FsPublic, HbIsHash),
hbrt.Sym("HB_ISNIL", hbrt.FsPublic, HbIsNil),
hbrt.Sym("ISNIL", hbrt.FsPublic, HbIsNil),
hbrt.Sym("HB_ISPOINTER", hbrt.FsPublic, HbIsPointer),
// OS/Environment
hbrt.Sym("GETENV", hbrt.FsPublic, GetEnv),
hbrt.Sym("HB_GETENV", hbrt.FsPublic, HbGetEnv),
hbrt.Sym("SETENV", hbrt.FsPublic, SetEnvFunc),
hbrt.Sym("OS", hbrt.FsPublic, OSFunc),
hbrt.Sym("VERSION", hbrt.FsPublic, VersionFunc),
hbrt.Sym("HB_RUN", hbrt.FsPublic, HbRun),
hbrt.Sym("HB_FNAMEDIR", hbrt.FsPublic, HbFNameDir),
hbrt.Sym("HB_FNAMEEXT", hbrt.FsPublic, HbFNameExt),
hbrt.Sym("HB_FNAMENAME", hbrt.FsPublic, HbFNameName),
hbrt.Sym("HB_FNAMEMERGE", hbrt.FsPublic, HbFNameMerge),
// Character classification
hbrt.Sym("ISDIGIT", hbrt.FsPublic, IsDigit),
hbrt.Sym("ISALPHA", hbrt.FsPublic, IsAlpha),
hbrt.Sym("ISALNUM", hbrt.FsPublic, IsAlnum),
hbrt.Sym("ISUPPER", hbrt.FsPublic, IsUpper),
hbrt.Sym("ISLOWER", hbrt.FsPublic, IsLower),
hbrt.Sym("ISSPACE", hbrt.FsPublic, IsSpace),
// Harbour extension functions
hbrt.Sym("HB_ISEVALITEM", hbrt.FsPublic, HbIsEvalItem),
hbrt.Sym("HB_ASCIIUPPER", hbrt.FsPublic, HbAsciiUpper),
hbrt.Sym("HB_ASCIILOWER", hbrt.FsPublic, HbAsciiLower),
hbrt.Sym("HB_DEFAULT", hbrt.FsPublic, HbDefault),
hbrt.Sym("HB_DEFAULTVALUE", hbrt.FsPublic, HbDefaultValue),
hbrt.Sym("HB_DISPOUTAT", hbrt.FsPublic, HbDispOutAt),
hbrt.Sym("HB_COLORINDEX", hbrt.FsPublic, HbColorIndex),
hbrt.Sym("HB_LEFTEQ", hbrt.FsPublic, HbLeftEq),
hbrt.Sym("HB_VAL", hbrt.FsPublic, HbVal),
hbrt.Sym("HB_KEYCHAR", hbrt.FsPublic, HbKeyChar),
hbrt.Sym("HB_KEYINS", hbrt.FsPublic, HbKeyIns),
hbrt.Sym("FIELDWBLOCK", hbrt.FsPublic, FieldWBlock),
hbrt.Sym("MEMVARBLOCK", hbrt.FsPublic, MemVarBlock),
hbrt.Sym("__DEFAULTNIL", hbrt.FsPublic, DefaultNIL),
hbrt.Sym("HB_DISPOUTATBOX", hbrt.FsPublic, HbDispOutAtBox),
hbrt.Sym("HB_DISPBOX", hbrt.FsPublic, HbDispBox),
hbrt.Sym("HB_TOKENGET", hbrt.FsPublic, HbTokenGet),
hbrt.Sym("HB_TOKENCOUNT", hbrt.FsPublic, HbTokenCount),
// Bitmap/Rushmore
hbrt.Sym("BM_DBSETFILTER", hbrt.FsPublic, BmDbSetFilter),
hbrt.Sym("BM_DBSEEKWILD", hbrt.FsPublic, BmDbSeekWild),
hbrt.Sym("BM_TURBO", hbrt.FsPublic, BmTurbo),
hbrt.Sym("BM_DBGETFILTERARRAY", hbrt.FsPublic, BmDbGetFilterArray),
hbrt.Sym("BM_DBSETFILTERARRAY", hbrt.FsPublic, BmDbSetFilterArray),
hbrt.Sym("BM_DBSETFILTERARRAYADD", hbrt.FsPublic, BmDbSetFilterArrayAdd),
hbrt.Sym("BM_DBSETFILTERARRAYDEL", hbrt.FsPublic, BmDbSetFilterArrayDel),
// HBSIX compatibility
hbrt.Sym("SX_SETTAG", hbrt.FsPublic, SxSetTag),
hbrt.Sym("SX_INDEXTAG", hbrt.FsPublic, SxIndexTag),
hbrt.Sym("SX_TAGORDER", hbrt.FsPublic, SxTagOrder),
hbrt.Sym("SX_TAGCOUNT", hbrt.FsPublic, SxTagCount),
hbrt.Sym("SX_TAGS", hbrt.FsPublic, SxTags),
hbrt.Sym("SX_SETFILEORD", hbrt.FsPublic, SxSetFileOrd),
hbrt.Sym("SX_ISDBT", hbrt.FsPublic, SxIsDBT),
hbrt.Sym("SX_ISFPT", hbrt.FsPublic, SxIsFPT),
hbrt.Sym("SX_ISSMT", hbrt.FsPublic, SxIsSMT),
hbrt.Sym("SX_AUTOOPEN", hbrt.FsPublic, SxAutoOpen),
hbrt.Sym("SX_AUTOSHARE", hbrt.FsPublic, SxAutoShare),
hbrt.Sym("SX_BLOB2FILE", hbrt.FsPublic, SxBlob2File),
hbrt.Sym("SX_FILE2BLOB", hbrt.FsPublic, SxFile2Blob),
hbrt.Sym("SX_SETTRIGGER", hbrt.FsPublic, SxSetTrigger),
hbrt.Sym("SX_VFGET", hbrt.FsPublic, SxVFGet),
hbrt.Sym("SX_DBFENCRYPT", hbrt.FsPublic, SxDbfEncrypt),
hbrt.Sym("SX_DBFDECRYPT", hbrt.FsPublic, SxDbfDecrypt),
hbrt.Sym("SX_COMPRESS", hbrt.FsPublic, SxCompress),
hbrt.Sym("SX_DECOMPRESS", hbrt.FsPublic, SxDecompress),
hbrt.Sym("RDDINFO", hbrt.FsPublic, RddInfo),
hbrt.Sym("RDDNAME", hbrt.FsPublic, RddName),
hbrt.Sym("RDDLIST", hbrt.FsPublic, RddList),
// Timestamp
hbrt.Sym("HB_DATETIME", hbrt.FsPublic, HbDateTime),
hbrt.Sym("HB_HOUR", hbrt.FsPublic, HbHour),
hbrt.Sym("HB_MINUTE", hbrt.FsPublic, HbMinute),
hbrt.Sym("HB_SEC", hbrt.FsPublic, HbSec),
hbrt.Sym("HB_TTOC", hbrt.FsPublic, HbTToC),
hbrt.Sym("HB_CTOT", hbrt.FsPublic, HbCToT),
hbrt.Sym("HB_SECOND", hbrt.FsPublic, HbSecond),
hbrt.Sym("HB_ATOKENS", hbrt.FsPublic, HbATokens),
hbrt.Sym("HB_CDPSELECT", hbrt.FsPublic, HbCdpSelect),
hbrt.Sym("DBSETINDEX", hbrt.FsPublic, rtlDbSetIndex),
hbrt.Sym("HB_TTOS", hbrt.FsPublic, HbTToS),
hbrt.Sym("HB_STOT", hbrt.FsPublic, HbSToT),
hbrt.Sym("HB_MILLISECONDS", hbrt.FsPublic, HbMilliseconds),
// Index / DB introspection
hbrt.Sym("INDEXORD", hbrt.FsPublic, IndexOrd),
hbrt.Sym("INDEXKEY", hbrt.FsPublic, IndexKey),
hbrt.Sym("ORDSETFOCUS", hbrt.FsPublic, OrdSetFocus),
hbrt.Sym("ORDCREATE", hbrt.FsPublic, OrdCreate),
hbrt.Sym("DBCREATEINDEX", hbrt.FsPublic, DbCreateIndex),
hbrt.Sym("DBCLEARINDEX", hbrt.FsPublic, DbClearIndex),
hbrt.Sym("FIELDTYPE", hbrt.FsPublic, FieldType),
hbrt.Sym("FIELDLEN", hbrt.FsPublic, FieldLen),
hbrt.Sym("FIELDDEC", hbrt.FsPublic, FieldDec),
hbrt.Sym("ORDCOUNT", hbrt.FsPublic, OrdCount),
hbrt.Sym("ORDLISTREBUILD", hbrt.FsPublic, OrdListRebuild),
hbrt.Sym("ORDERLISTREBUILD", hbrt.FsPublic, OrdListRebuild),
hbrt.Sym("DBREINDEX", hbrt.FsPublic, OrdListRebuild),
hbrt.Sym("ORDNAME", hbrt.FsPublic, OrdName),
hbrt.Sym("ORDKEY", hbrt.FsPublic, OrdKey),
hbrt.Sym("ORDFOR", hbrt.FsPublic, OrdFor),
hbrt.Sym("DBINFO", hbrt.FsPublic, DbInfo),
hbrt.Sym("ORDINFO", hbrt.FsPublic, OrdInfo),
hbrt.Sym("ORDSCOPE", hbrt.FsPublic, OrdScope),
hbrt.Sym("DBORDERINFO", hbrt.FsPublic, DbOrderInfo),
hbrt.Sym("RDDSETDEFAULT", hbrt.FsPublic, RddSetDefault),
hbrt.Sym("DBCREATE", hbrt.FsPublic, DbCreate),
// Directory / Temp file (session 1)
hbrt.Sym("HB_DIREXISTS", hbrt.FsPublic, HbDirExists),
hbrt.Sym("HB_DIRCREATE", hbrt.FsPublic, HbDirCreate),
hbrt.Sym("HB_FTEMPCREATE", hbrt.FsPublic, HbFTempCreate),
hbrt.Sym("HB_FNAMESPLIT", hbrt.FsPublic, HbFNameSplit),
// File extended (session 2)
hbrt.Sym("HB_FSIZE", hbrt.FsPublic, HbFSize),
hbrt.Sym("HB_FCOPY", hbrt.FsPublic, HbFCopy),
hbrt.Sym("HB_FEOF", hbrt.FsPublic, HbFEof),
hbrt.Sym("HB_FCOMMIT", hbrt.FsPublic, HbFCommit),
hbrt.Sym("HB_FREADLEN", hbrt.FsPublic, HbFReadLen),
hbrt.Sym("HB_FGETATTR", hbrt.FsPublic, HbFGetAttr),
hbrt.Sym("HB_FSETATTR", hbrt.FsPublic, HbFSetAttr),
hbrt.Sym("HB_FGETDATETIME", hbrt.FsPublic, HbFGetDateTime),
hbrt.Sym("HB_FSETDATETIME", hbrt.FsPublic, HbFSetDateTime),
hbrt.Sym("HB_FLOCK", hbrt.FsPublic, HbFLock),
hbrt.Sym("HB_FUNLOCK", hbrt.FsPublic, HbFUnlock),
hbrt.Sym("HB_FILEDELETE", hbrt.FsPublic, HbFileDelete),
hbrt.Sym("HB_FILEMATCH", hbrt.FsPublic, HbFileMatch),
hbrt.Sym("HB_FNAMEEXISTS", hbrt.FsPublic, HbFNameExists),
hbrt.Sym("HB_FNAMEEXTSET", hbrt.FsPublic, HbFNameExtSet),
hbrt.Sym("HB_FNAMENAMEEXT", hbrt.FsPublic, HbFNameNameExt),
hbrt.Sym("HB_MEMOREAD", hbrt.FsPublic, HbMemoRead),
hbrt.Sym("HB_MEMOWRIT", hbrt.FsPublic, HbMemoWrit),
hbrt.Sym("HB_DIRTEMP", hbrt.FsPublic, HbDirTemp),
hbrt.Sym("HB_DISKSPACE", hbrt.FsPublic, HbDiskSpace),
hbrt.Sym("DISKSPACE", hbrt.FsPublic, DiskSpaceFunc),
// String extended (session 2)
hbrt.Sym("HB_AT", hbrt.FsPublic, HbAt),
hbrt.Sym("HB_RAT", hbrt.FsPublic, HbRat),
hbrt.Sym("HB_ATI", hbrt.FsPublic, HbAtI),
hbrt.Sym("HB_ATX", hbrt.FsPublic, HbAtX),
hbrt.Sym("HB_LEFTEQI", hbrt.FsPublic, HbLeftEqI),
hbrt.Sym("HB_ASCIIISALPHA", hbrt.FsPublic, HbAsciiIsAlpha),
hbrt.Sym("HB_ASCIIISDIGIT", hbrt.FsPublic, HbAsciiIsDigit),
hbrt.Sym("HB_ASCIIISLOWER", hbrt.FsPublic, HbAsciiIsLower),
hbrt.Sym("HB_ASCIIISUPPER", hbrt.FsPublic, HbAsciiIsUpper),
hbrt.Sym("HB_STRISUTF8", hbrt.FsPublic, HbStrIsUtf8),
hbrt.Sym("HB_STRDECODESCAPE", hbrt.FsPublic, HbStrDecodeEscape),
hbrt.Sym("HB_STRXOR", hbrt.FsPublic, HbStrXor),
hbrt.Sym("HB_WILDMATCH", hbrt.FsPublic, HbWildMatch),
hbrt.Sym("HB_WILDMATCHI", hbrt.FsPublic, HbWildMatchI),
hbrt.Sym("HARDCR", hbrt.FsPublic, HardCR),
// DateTime extended (session 2)
hbrt.Sym("HB_DATE", hbrt.FsPublic, HbDate),
hbrt.Sym("HB_CTOD", hbrt.FsPublic, HbCToD),
hbrt.Sym("HB_DTOC", hbrt.FsPublic, HbDToC),
hbrt.Sym("HB_STOD", hbrt.FsPublic, HbSToD),
hbrt.Sym("HB_DTOT", hbrt.FsPublic, HbDToT),
hbrt.Sym("HB_TTOD", hbrt.FsPublic, HbTToD),
hbrt.Sym("HB_TTOHOUR", hbrt.FsPublic, HbTToHour),
hbrt.Sym("HB_TTOMIN", hbrt.FsPublic, HbTToMin),
hbrt.Sym("HB_TTOSEC", hbrt.FsPublic, HbTToSec),
hbrt.Sym("HB_TTOMSEC", hbrt.FsPublic, HbTToMsec),
hbrt.Sym("HB_TTON", hbrt.FsPublic, HbTToN),
hbrt.Sym("HB_NTOT", hbrt.FsPublic, HbNToT),
hbrt.Sym("HB_NTOHOUR", hbrt.FsPublic, HbNToHour),
hbrt.Sym("HB_NTOMIN", hbrt.FsPublic, HbNToMin),
hbrt.Sym("HB_NTOSEC", hbrt.FsPublic, HbNToSec),
hbrt.Sym("HB_WEEK", hbrt.FsPublic, HbWeek),
hbrt.Sym("HB_CDAY", hbrt.FsPublic, HbCDay),
hbrt.Sym("DAYS", hbrt.FsPublic, Days),
hbrt.Sym("ELAPTIME", hbrt.FsPublic, ElapTime),
hbrt.Sym("AMPM", hbrt.FsPublic, AMPM),
hbrt.Sym("SECS", hbrt.FsPublic, Secs),
// Utilities (session 2)
hbrt.Sym("HB_SETENV", hbrt.FsPublic, HbSetEnv),
hbrt.Sym("HB_PS", hbrt.FsPublic, HbPS),
hbrt.Sym("HB_EOL", hbrt.FsPublic, HbEOL),
hbrt.Sym("HB_ISNULL", hbrt.FsPublic, HbIsNull),
hbrt.Sym("ERRORSYS", hbrt.FsPublic, ErrorSys),
// Token
hbrt.Sym("TOKEN", hbrt.FsPublic, Token),
hbrt.Sym("NUMTOKEN", hbrt.FsPublic, NumToken),
// Hex conversion
hbrt.Sym("HB_NUMTOHEX", hbrt.FsPublic, HbNumToHex),
hbrt.Sym("HB_HEXTONUM", hbrt.FsPublic, HbHexToNum),
// Hash position access
hbrt.Sym("HB_HPOS", hbrt.FsPublic, HbHPos),
hbrt.Sym("HB_HKEYAT", hbrt.FsPublic, HbHKeyAt),
hbrt.Sym("HB_HVALUEAT", hbrt.FsPublic, HbHValueAt),
hbrt.Sym("HB_HCLONE", hbrt.FsPublic, HbHClone),
// Sleep
hbrt.Sym("HB_IDLESLEEP", hbrt.FsPublic, HbIdleSleep),
// UTF-8
hbrt.Sym("HB_UTF8TOSTR", hbrt.FsPublic, HbUTF8ToStr),
hbrt.Sym("HB_STRTOUTF8", hbrt.FsPublic, HbStrToUTF8),
hbrt.Sym("HB_UTF8LEN", hbrt.FsPublic, HbUTF8Len),
hbrt.Sym("HB_UTF8SUBSTR", hbrt.FsPublic, HbUTF8SubStr),
// Stack introspection
hbrt.Sym("PROCNAME", hbrt.FsPublic, ProcName),
hbrt.Sym("PROCLINE", hbrt.FsPublic, ProcLine),
hbrt.Sym("PROCFILE", hbrt.FsPublic, ProcFile),
hbrt.Sym("ERRORLEVEL", hbrt.FsPublic, ErrorLevel),
// Field/DB introspection
hbrt.Sym("FIELDPOS", hbrt.FsPublic, FieldPos),
hbrt.Sym("FIELDBLOCK", hbrt.FsPublic, FieldBlockFunc),
hbrt.Sym("FIELDNAME", hbrt.FsPublic, FieldNameFunc),
hbrt.Sym("AFIELDS", hbrt.FsPublic, AFields),
hbrt.Sym("DBSTRUCT", hbrt.FsPublic, DbStruct),
// Misc
hbrt.Sym("TONE", hbrt.FsPublic, Tone),
hbrt.Sym("CENTER", hbrt.FsPublic, Center),
hbrt.Sym("SOUNDEX", hbrt.FsPublic, Soundex),
// JSON — Harbour compatible
hbrt.Sym("HB_JSONENCODE", hbrt.FsPublic, HbJsonEncode),
hbrt.Sym("HB_JSONDECODE", hbrt.FsPublic, HbJsonDecode),
// JSON — Five extensions (Go-native)
hbrt.Sym("JSONPRETTY", hbrt.FsPublic, JsonPretty),
hbrt.Sym("JSONTO", hbrt.FsPublic, JsonTo),
hbrt.Sym("JSONFROM", hbrt.FsPublic, JsonFrom),
hbrt.Sym("JSONPATH", hbrt.FsPublic, JsonPath),
hbrt.Sym("JSONMERGE", hbrt.FsPublic, JsonMerge),
hbrt.Sym("JSONTYPE", hbrt.FsPublic, JsonType),
hbrt.Sym("JSONVALID", hbrt.FsPublic, JsonValid),
hbrt.Sym("JSONHTTPGET", hbrt.FsPublic, JsonHttpGet),
hbrt.Sym("JSONHTTPPOST", hbrt.FsPublic, JsonHttpPost),
// Random
hbrt.Sym("HB_RANDOM", hbrt.FsPublic, HbRandom),
hbrt.Sym("HB_RANDOMINT", hbrt.FsPublic, HbRandomInt),
hbrt.Sym("HB_RANDOMSEED", hbrt.FsPublic, HbRandomSeed),
hbrt.Sym("HB_RANDSTR", hbrt.FsPublic, HbRandStr),
// OS Info
hbrt.Sym("HB_VERSION", hbrt.FsPublic, HbVersion),
hbrt.Sym("HB_COMPILER", hbrt.FsPublic, HbCompiler),
hbrt.Sym("HB_OSNEWLINE", hbrt.FsPublic, HbOsNewLine),
hbrt.Sym("HB_OSPATHSEPARATOR", hbrt.FsPublic, HbOsPathSeparator),
hbrt.Sym("HB_CWD", hbrt.FsPublic, HbCwd),
hbrt.Sym("HB_DIRBASE", hbrt.FsPublic, HbDirBase),
hbrt.Sym("HB_PROGNAME", hbrt.FsPublic, HbProgName),
hbrt.Sym("HB_USERNAME", hbrt.FsPublic, HbUserName),
hbrt.Sym("HB_GETHOSTNAME", hbrt.FsPublic, HbGetHostName),
// Process
hbrt.Sym("HB_PROCESSRUN", hbrt.FsPublic, HbProcessRun),
hbrt.Sym("WAIT", hbrt.FsPublic, WaitCmd),
// UTF-8 String
hbrt.Sym("HB_UTF8LEN", hbrt.FsPublic, HbUtf8Len),
hbrt.Sym("HB_UTF8SUBSTR", hbrt.FsPublic, HbUtf8Substr),
hbrt.Sym("HB_UTF8LEFT", hbrt.FsPublic, HbUtf8Left),
hbrt.Sym("HB_UTF8RIGHT", hbrt.FsPublic, HbUtf8Right),
hbrt.Sym("HB_UTF8AT", hbrt.FsPublic, HbUtf8At),
hbrt.Sym("HB_STRTOHEX", hbrt.FsPublic, HbStrToHex),
hbrt.Sym("HB_HEXTOSTR", hbrt.FsPublic, HbHexToStr),
hbrt.Sym("HB_STRFORMAT", hbrt.FsPublic, HbStrFormat),
// Memo line
hbrt.Sym("MEMOLINE", hbrt.FsPublic, MemoLine),
hbrt.Sym("MLCOUNT", hbrt.FsPublic, MlCount),
// FRB (Five Runtime Binary)
hbrt.Sym("FRBLOAD", hbrt.FsPublic, FrbLoadFunc),
hbrt.Sym("FRBDO", hbrt.FsPublic, FrbDoFunc),
hbrt.Sym("FRBUNLOAD", hbrt.FsPublic, FrbUnloadFunc),
hbrt.Sym("FRBRUN", hbrt.FsPublic, FrbRunFunc),
hbrt.Sym("FRBCOMPILE", hbrt.FsPublic, FrbCompileFunc),
hbrt.Sym("FRBEXEC", hbrt.FsPublic, FrbExecFunc),
// Expression bytecode compilation (FiveSql2 hot-path optimization)
hbrt.Sym("PCCOMPILE", hbrt.FsPublic, PcCompile),
hbrt.Sym("PCEVAL", hbrt.FsPublic, PcEval),
// Go-native SQL scan loop (bypasses PRG interpreter for hot path)
hbrt.Sym("SQLSCAN", hbrt.FsPublic, SqlScan),
hbrt.Sym("SQLEACH", hbrt.FsPublic, SqlEach),
hbrt.Sym("SQLHASHBUILD", hbrt.FsPublic, SqlHashBuild),
hbrt.Sym("SQLHASHJOIN", hbrt.FsPublic, SqlHashJoin),
hbrt.Sym("SQLORDERBY", hbrt.FsPublic, SqlOrderBy),
hbrt.Sym("SQLGROUPBY", hbrt.FsPublic, SqlGroupBy),
hbrt.Sym("SQLDISTINCT", hbrt.FsPublic, SqlDistinct),
hbrt.Sym("SQLUNIONDISTINCT", hbrt.FsPublic, SqlUnionDistinct),
hbrt.Sym("SQLBUILDSUBCACHEKEY", hbrt.FsPublic, SqlBuildSubCacheKey),
hbrt.Sym("SQLEXPRHASAGG", hbrt.FsPublic, SqlExprHasAgg),
hbrt.Sym("SQLBULKINSERT", hbrt.FsPublic, SqlBulkInsert),
hbrt.Sym("SQLBULKUPDATE", hbrt.FsPublic, SqlBulkUpdate),
hbrt.Sym("SQLBULKDELETE", hbrt.FsPublic, SqlBulkDelete),
hbrt.Sym("SQLWINDOWSLIDEAGG", hbrt.FsPublic, SqlWindowSlideAgg),
hbrt.Sym("SQLWINDOWPARTITIONS", hbrt.FsPublic, SqlWindowPartitions),
hbrt.Sym("SQLGROUPROWS", hbrt.FsPublic, SqlGroupRows),
hbrt.Sym("SQLCOMPUTEAGGSIMPLE", hbrt.FsPublic, SqlComputeAggSimple),
hbrt.Sym("SQLEVALHAVING", hbrt.FsPublic, SqlEvalHaving),
hbrt.Sym("SQLCOERCESTR", hbrt.FsPublic, SqlCoerceStr),
hbrt.Sym("SQLCOERCENUM", hbrt.FsPublic, SqlCoerceNum),
hbrt.Sym("SQLCOERCEFORCMP", hbrt.FsPublic, SqlCoerceForCmp),
hbrt.Sym("SQLISTRUE", hbrt.FsPublic, SqlIsTrue),
hbrt.Sym("SQLISAGGNAME", hbrt.FsPublic, SqlIsAggName),
hbrt.Sym("SQLFETCHROWFAST", hbrt.FsPublic, SqlFetchRowFast),
hbrt.Sym("SQLCMPEQ", hbrt.FsPublic, SqlCmpEq),
hbrt.Sym("SQLCMPLT", hbrt.FsPublic, SqlCmpLt),
hbrt.Sym("SQLEXTRACTTEMPLATE", hbrt.FsPublic, SqlExtractTemplate),
hbrt.Sym("SQLLEXERTOKENIZE", hbrt.FsPublic, SqlLexerTokenize),
hbrt.Sym("SQLLEXANDEXTRACTTEMPLATE", hbrt.FsPublic, SqlLexAndExtractTemplate),
hbrt.Sym("SQLWACACHEENABLE", hbrt.FsPublic, SqlWACacheEnable),
hbrt.Sym("SQLWACACHEDISABLE", hbrt.FsPublic, SqlWACacheDisable),
hbrt.Sym("SQLWACACHEISENABLED", hbrt.FsPublic, SqlWACacheIsEnabled),
hbrt.Sym("SQLWACACHEGET", hbrt.FsPublic, SqlWACacheGet),
hbrt.Sym("SQLWACACHEPUT", hbrt.FsPublic, SqlWACachePut),
hbrt.Sym("SQLWACACHEINVALIDATE", hbrt.FsPublic, SqlWACacheInvalidate),
hbrt.Sym("SQLWACACHECLOSEALL", hbrt.FsPublic, SqlWACacheCloseAll),
hbrt.Sym("SQLWINDOWSORTPARTITION", hbrt.FsPublic, SqlWindowSortPartition),
hbrt.Sym("SQLWINDOWASSIGNRANK", hbrt.FsPublic, SqlWindowAssignRank),
// Goroutine / Concurrency
hbrt.Sym("GO", hbrt.FsPublic, GoFunc),
hbrt.Sym("CHANNEL", hbrt.FsPublic, ChannelFunc),
hbrt.Sym("CHSEND", hbrt.FsPublic, ChSend),
hbrt.Sym("CHRECEIVE", hbrt.FsPublic, ChReceive),
hbrt.Sym("CHCLOSE", hbrt.FsPublic, ChClose),
hbrt.Sym("WAITGROUP", hbrt.FsPublic, WaitGroupFunc),
hbrt.Sym("WGDONE", hbrt.FsPublic, WgDone),
hbrt.Sym("WGWAIT", hbrt.FsPublic, WgWait),
hbrt.Sym("WGADD", hbrt.FsPublic, WgAdd),
hbrt.Sym("MUTEX", hbrt.FsPublic, MutexFunc),
hbrt.Sym("LOCK", hbrt.FsPublic, LockFunc),
hbrt.Sym("UNLOCK", hbrt.FsPublic, UnlockFunc),
hbrt.Sym("SLEEP", hbrt.FsPublic, SleepFunc),
)
vm.RegisterModule(mod)
}
// rtlQOut implements ? command as a variadic function.
func rtlQOut(t *hbrt.Thread) {
nParams := t.ParamCount()
t.Frame(nParams, 0)
defer t.EndProc()
args := make([]hbrt.Value, nParams)
for i := 0; i < nParams; i++ {
args[i] = t.Local(i + 1)
}
qoutImpl(args)
t.RetNil()
}
// rtlQQOut implements ?? command.
func rtlQQOut(t *hbrt.Thread) {
nParams := t.ParamCount()
t.Frame(nParams, 0)
defer t.EndProc()
args := make([]hbrt.Value, nParams)
for i := 0; i < nParams; i++ {
args[i] = t.Local(i + 1)
}
qqoutImpl(args)
t.RetNil()
}
// rtlDo — Harbour DO(xTarget, [arg1, ...]) → xResult.
//
// Dispatches the named function, code block, or symbol dynamically.
// String target: looked up in the VM symbol table (uppercased, like
// compile-time calls) and invoked. Block target: evaluated with the
// remaining args just like Eval. Anything else returns NIL.
//
// Reference: harbour-core/src/rtl/do.c HB_FUNC( DO ).
func rtlDo(t *hbrt.Thread) {
nParams := t.ParamCount()
t.Frame(nParams, 0)
defer t.EndProc()
if nParams < 1 {
t.RetNil()
return
}
target := t.Local(1)
nArgs := nParams - 1
switch {
case target.IsString():
name := strings.ToUpper(target.AsString())
vm := t.VM()
if vm == nil {
t.RetNil()
return
}
sym := vm.FindSymbol(name)
if sym == nil {
panic(&hbrt.HbError{
Description: "DO: unknown function " + target.AsString(),
Operation: "DO",
SubSystem: "BASE",
})
}
t.PushSymbol(sym)
t.PushNil() // self placeholder
for i := 2; i <= nParams; i++ {
t.PushValue(t.Local(i))
}
t.Function(nArgs)
// Function() leaves the callee's return value on the stack.
t.RetValue()
case target.IsBlock():
blk := target.AsBlock()
for i := 2; i <= nParams; i++ {
t.PushValue(t.Local(i))
}
t.PendingParams2(nArgs)
blk.Fn(t)
t.PushValue(t.GetRetValue())
t.RetValue()
default:
t.RetNil()
}
}
// rtlEval evaluates a code block.
// Harbour: Eval(bBlock, [xArg1, ...]) → xResult
func rtlEval(t *hbrt.Thread) {
nParams := t.ParamCount()
t.Frame(nParams, 0)
defer t.EndProc()
blkVal := t.Local(1)
if !blkVal.IsBlock() {
t.RetNil()
return
}
blk := blkVal.AsBlock()
// Push block args onto stack for the block's Frame() to pick up
blockArgs := nParams - 1
for i := 2; i <= nParams; i++ {
t.PushValue(t.Local(i))
}
// Call block function — it will call Frame(N, 0) internally
t.PendingParams2(blockArgs)
blk.Fn(t)
// Return block's result
t.PushValue(t.GetRetValue())
t.RetValue()
}