Files
five/hbrtl/register.go
CharlesKWON 80a18daf8d feat(pp): UPDATE FROM via std.ch + nested-bracket fix in matchSegment
`UPDATE [FROM <alias>] [ON <key>] [RANDOM] REPLACE <f1> WITH <x1>
[, <fN> WITH <xN>]` becomes a preprocessor rewrite to a new RTL
primitive __dbUpdate. For each detail record, find the master
record with matching key (forward-walk if both sorted, full scan
when RANDOM) and apply the REPLACE clauses in master's context.

Same shape as harbour-core/src/rdd/dbupdat.prg. The REPLACE clauses
expand to comma-separated assignments inside one block —
`{|| _FIELD->total := del->amt, _FIELD->status := "OK" }` — using
the multi-pair `[, <fN> WITH <xN>]` optional-repeat that std.ch
already establishes for SUM and DEFAULT.

Five-specific tweak: ON <key> wraps as `{|| _FIELD-><key> }` rather
than Harbour's bare `<{key}>`. Five doesn't auto-resolve a bare
identifier in a code block to the current workarea's field, and the
UPDATE block must evaluate against both detail and master so an
explicit alias prefix won't do — _FIELD-> dispatches to whichever
area is selected at eval time, which is what's needed.

Wiring up UPDATE surfaced one further matchSegment gap that fell
out of the multi-pair `[REPLACE ... [, ...]]` shape:

  * matchSegment didn't handle nested `[...]` inside its body.
    `[REPLACE <f1> WITH <x1> [, <fN> WITH <xN>]]` gave the inner
    `[` as a literal token to match against the line, so even the
    single-pair `REPLACE total WITH del->amt` form failed and f1/x1
    came back empty. Now matchSegment runs the same repeat-loop on
    inner `[...]` blocks that the top-level matcher uses, with its
    own outer-tail computed from the segment tail past the inner
    `]`.

Parser cleanup: UPDATE removed from the IDENT-statement no-op switch.

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 17:49:33 +09:00

823 lines
32 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("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()
}