f4ed42556b
checkpoint: season-wide bug fix campaign + infra
...
Cumulative season's silent-bug hunting (~62 fixes) across the FiveSql2
SQL engine, the Five compiler/runtime, and the hbrdd RDD layer. Saved
as a single checkpoint before refactoring the parser to delegate xBase
command translation to the preprocessor.
Highlights:
FiveSql2 engine (_FiveSql2/src/)
- prefix-glob index attach -> explicit convention (<table>_pk.ntx,
<table>_uq.ntx, <table>.cdx) — fixes silent multi-row INSERT row-drop
- DROP/CREATE TABLE FErase chain extended (.cdx, .fsc, .fsv, .dbt, .fpt)
- COUNT(DISTINCT col) parsed + aggregated via hSeen hash
- UNION column-count mismatch returns SQL_ERR_GRAMMAR (was silent)
- DISTINCT + ORDER BY hidden-col leak fixed (trim before DISTINCT)
- Derived table FROM (SELECT...) + JOIN right-side derived
- Self-FK CASCADE depth 2+ via SqlGetSingleColPK pre-collect
- LAG/LEAD default arg uses SqlEvalRowExpr (handles -N const exprs)
- DATE literal round-trip validation (Feb 29 non-leap rejected)
- CREATE OR REPLACE VIEW; CREATE VIEW errors on already-exists
- AlterTable type dispatcher comma-wrapped (1-char type "A" no longer
matches CHARACTER)
Compiler / runtime
- gengo: HB_ -> FV_ prefix on emitted Go function names (Five identity)
- gengo split: emit_block.go, emit_stmt.go, folding.go extracted
- parser/stmtreg.go nudges
- hbrt: debug TUI/CLI restructure (debugcmd, debugkey, termios_*),
windows debug stubs collapsed
- thread/vm/value/class/pcinterp tightening from panic traces
RDD layer (hbrdd/)
- dbf: null bitmap support (null.go + null_test.go), mmap split
(mmap_posix.go / mmap_windows.go), byte-level numeric parse
- ntx/cdx: windows mmap parity
- workarea + mem RDD: cross-area state-bleed fixes
RTL (hbrtl/)
- errorlog rewrite with platform-specific FD (errorlog_fd_unix /
errorlog_fd_other)
- sqlscan, sqlhelpers, indexrtl, datetime extensions
Gates green at checkpoint:
- 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 09:26:25 +09:00
3adc9d7d59
fix: PCount, Break/RECOVER, SET INDEX TO — 3 Harbour compat fixes
...
Release-blocking compatibility issues discovered during the 258-test
pre-release validation suite (100 syntax + 44 RDD + 114 RTL).
1. PCount() always returned 0 in PRG code
Root cause: ParamCount() returned t.pendingParams, which is
overwritten by every nested Function() call. By the time the
PCount() RTL's Frame() executes, pendingParams is already 0.
Fix: Frame() now stores pendingParams in frame.paramCount.
PCount() RTL uses CallerParamCount() which reads callSP-2
(the PRG caller's frame), while RTL functions still use
ParamCount() (reads pendingParams before their own Frame).
Verified: PCount(1,2,3)=3, PCount(1)=1, PCount()=0
2. Break("string") panicked instead of being caught by RECOVER USING
Root cause: Generated SEQUENCE code only caught *HbError panics.
Break() panics with BreakValue (a different type), which fell
through to EndProc's "runtime error" message and re-panic.
Fix (two parts):
a) gengo emitBeginSequence: recover closure now catches any
panic (interface{}), then dispatches via type switch:
- *HbError → extract .Error() string
- hasValue interface (BreakValue) → extract .GetValue()
- other → static "error" string
b) hbrtl/error.go: BreakValue gets GetValue() method for
duck-type detection without import cycles
c) hbrt/thread.go EndProc: BreakValue type name check added
so it re-panics silently (no stderr noise)
3. SET INDEX TO a, b, c only opened the last file
Root cause: Parser's parseSet() called parseExpr() once for
INDEX setting, stopping at the first comma. Remaining file
names were consumed by the "eat rest of line" loop.
Fix: Parser now collects comma-separated identifiers into a
single string literal "a,b,c". gengo splits on comma and
calls OrderListAdd() for each file.
Verified: SET INDEX TO si_name, si_city → OrdCount=2
All tests pass:
go test ./... 14 packages OK
FiveSql2 43/43 100%
compat_harbour 51/51
Syntax test 100/100
RDD test 44/44
RTL test 114/114
Windows cross-compile OK
Linux cross-compile OK
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-13 18:06:28 +09:00
486e466592
feat: FiveSql2 43/43, @byref, mutable closure, RTL 479, DateTime fix
...
Major changes since last commit:
- FiveSql2 SQL:1999 engine (10,458 LOC) — 43/43 ALL PASS
- 21 compiler/runtime bugs fixed (short-circuit AND/OR, FOR LOOP, etc.)
- @byref pass-by-reference via RefCell pattern
- Mutable closure capture (EnsureLocalRef + RefCell sharing)
- RTL: 400 → 479 functions (+79: file, string, datetime, hash, UTF-8)
- DateTime/Timestamp fully working (hb_DateTime, hb_Hour/Min/Sec, display)
- Reserved word guard (39 keywords blocked from function calls)
- AEval arg order fix (element before index)
- Closure capture redecl fix (unique _cap_ names per block)
- Hash/string indexing in ArrayPush/ArrayPop
- Harbour compat test suite: 51/51
- 4 docs: Porting Report, Implementation Plan, Optimization Plan, Commercialization
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-11 11:35:37 +09:00
d451b836a6
perf: inline Str/PadR/PadL/SubStr/Left/Right/At/IIF in gengo
...
13 more RTL functions inlined — no Frame/EndProc, no VM dispatch:
- Str(n,w,d) → fmt.Sprintf("%*.*f", w, d, n)
- PadR(s,n) → s + hbrtl.Spaces(n-len(s))
- PadL(s,n[,fill]) → Spaces(pad) + s or Repeat(fill, pad) + s
- SubStr(s,p,l) → s[p:p+l] with bounds check
- Left(s,n) → s[:n], Right(s,n) → s[len-n:]
- At(search,target) → strings.Index + 1
- IIF(cond,a,b) → if/else without function call
Also: Spaces() exported for generated code access.
50K SEEK random: 62ms (Harbour 67ms — Five FASTER!)
82/82 stress PASS. 14 packages ALL PASS.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 23:16:38 +09:00
05ccef05e2
perf: EndProcFast — eliminate defer recover() from RTL hot paths
...
Problem: every RTL function calls defer t.EndProc() which does recover().
50K SEEK loop = 250K recover() calls = ~12ms wasted.
Solution: EndProcFast() skips recover (only needs endFrame restore).
Applied to ALL RTL functions in strings.go, rdd.go, missing.go, database.go.
EndProc() with recover kept for generated PRG code (needs BEGIN SEQUENCE).
Analysis (50K sequential SEEK breakdown):
Go NTX Seek direct: 7ms (faster than Harbour 27ms!)
PRG VM overhead: 38ms (Frame + RTL calls + key generation)
Key generation: 25ms (Str+LTrim+PadL+PadR = 5 RTL Frame/EndProc per iter)
With EndProcFast: RTL overhead reduced ~30%.
CDX SCOPE: 2ms (Harbour 4ms — 2x FASTER!)
82/82 stress PASS. 14 packages ALL PASS.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 21:43:39 +09:00
5b378318a0
perf: RTL optimization — cached WA, spaces pool, stack-alloc fmt_int64
...
rdd.go:
- getWA() cached type assertion (avoid repeated interface check)
- waCache stores last WA pointer → O(1) for repeated calls
strings.go:
- spacesCache[257]: pre-built space strings for pad sizes 0-256
- spaces(n) returns cached string (no Repeat allocation)
- PadR/PadL use spaces() for fill=" " (most common case)
- Str() uses spaces() for right-padding
missing.go:
- fmt_int64: stack-allocated [20]byte array (was heap make([]byte))
- Reverse iteration (no prepend overhead)
- PadC uses spaces() for left/right padding
Benchmark (ext4, home dir):
10K APPEND: 28ms → 26ms (Harbour 27ms!)
50K APPEND: 130ms → 113ms (13% improvement)
50K SCAN: 24ms → 23ms
50K DUPKEY: 42ms → 35ms (17% improvement)
CDX SCOPE: 12ms → 10ms (17% improvement)
82/82 stress PASS. 14 packages ALL PASS.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 18:16:22 +09:00
827adeeb99
feat: SET commands + ErrorBlock/Break error handling
...
SET commands (setcmd.go):
- SetDateFunc: __SetDateFormat([cNew]) → cOld
- SetDecimalsFunc: SET DECIMALS TO n
- SetEpochFunc: SET EPOCH TO n
- 11 toggle functions: SetExact, SetDeleted, SetSoftSeek, SetExclusive,
SetFixed, SetCancel, SetBell, SetConfirm, SetInsert, SetEscape, SetWrap
- SET constants: _SET_EXACT, _SET_DELETED, etc. for PRG code
- GetSetDateFormat(), GetSetDecimals(), GetSetEpoch() helpers
- Default: DATE="mm/dd/yy", EPOCH=1900, DECIMALS=2
Error handling (error.go):
- Break(xValue): panics with BreakValue, caught by BEGIN SEQUENCE
- BreakBlock(): returns {|e| Break(e)} code block
- LaunchError(): dispatches error through ErrorBlock handler
- RuntimeError(): creates + launches standard runtime error
- IsBreak(): checks if recovered panic is a BreakValue
- createErrorHash(): builds Harbour-compatible error hash
Registration: ErrorBlock, ErrorNew, DosError, FError, Break + all SET functions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-02 15:33:07 +09:00
59568f3301
Five v0.9 — Harbour + Go fusion language
...
- Compiler: PP → Lexer → Parser → Analyzer → Gengo pipeline
- Parser: 232/236 (98%) Harbour compatibility, registry-based dispatch
- RTL: 351 Harbour-compatible functions
- RDD: DBF/NTX/CDX engines with Rushmore bitmap optimization
- Go Interop: IMPORT + pkg.Func() + obj:Method() with FastPath (15M calls/sec)
- HB_FUNC API: Full Harbour C API compatible Go bridge
- Concurrency: SPAWN/LAUNCH/GOROUTINE, <-, WATCH, PARALLEL FOR, ASYNC/AWAIT
- Extensions: Multi-return, DEFER, Slice, f-string, Nil-safe ?:, CONST
- Macro Compiler: Runtime AST parsing and evaluation
- Debugger: TUI debugger with source display, breakpoints, stepping
- FRB: Native + Pcode dual mode runtime binary
- Tests: 13 packages ALL PASS
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-03-31 09:41:50 +09:00