- 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>
4.2 KiB
Five — Where Harbour Meets Go
Keep your xBase code. Gain all of Go.
Five is a fusion language that transpiles Harbour PRG code to Go native binaries. Don't throw away 30 years of xBase business logic — use Go's modern power with PRG syntax.
Why Five
1. Your existing code just works
USE customers NEW
INDEX ON Upper(name) TO cust_name
SEEK "CHARLES"
? customers->name, customers->balance
This runs as-is. DBF, NTX, CDX — all supported. Thousands of lines of existing PRG code build with Five unchanged.
2. Every Go package, directly from PRG
IMPORT "strings"
IMPORT "database/sql"
IMPORT _ "modernc.org/sqlite"
PROCEDURE Main()
LOCAL db, aRows, i
? strings.ToUpper("hello five!")
db := sql.Open("sqlite", ":memory:")
db:Exec("CREATE TABLE users (id INTEGER, name TEXT)")
db:Exec("INSERT INTO users VALUES (1, 'Charles')")
aRows := SqlScan(db, "SELECT * FROM users")
FOR i := 1 TO Len(aRows)
? aRows[i]["name"]
NEXT
db:Close()
RETURN
One IMPORT line gives you access to 500,000+ Go packages.
SQL, HTTP, WebSocket, JSON, crypto, regex — all from PRG code.
No #pragma BEGINDUMP needed.
3. Goroutines are PRG syntax
LOCAL ch := Channel()
SPAWN {|| ch <- HeavyWork() } // launch goroutine
? "doing other work..."
result := <- ch // receive result
WATCH
CASE msg := <- chServer1
? "Server 1 replied:", msg
CASE msg := <- chServer2
? "Server 2 replied:", msg
CASE <- chTimeout
? "Timeout!"
END WATCH
Concurrency that's impossible in Harbour — natural in Five.
SPAWN, <-, WATCH — these ARE Go's goroutine, channel, select.
4. Builds to native binary
five build myapp.prg -o myapp
./myapp # single executable, zero dependencies
No JVM. No interpreter. No runtime. Go compiler produces native binary. Cross-compile to Linux, macOS, Windows.
5. Safe code by default
PROCEDURE Main()
LOCAL cName, nAge // all variables must be declared
cName := "Charles"
nAge := 30
? cName, nAge
DEFER db:Close() // guaranteed resource cleanup
RETURN
Five's compiler checks automatically:
- Undeclared variable → warning
- Unused variable → hint
DEFERprevents resource leaks
For Harbour Developers
Nothing to change. Everything to gain.
| Existing Harbour | Five adds |
|---|---|
| DBF/NTX/CDX | + SQLite, PostgreSQL, MySQL |
| Single thread | + goroutine parallelism |
| C library dependency | + 500K Go packages |
| Interpreter/HRB | + native binary |
| Windows focused | + Linux, macOS, cloud |
For Go Developers
Data processing, 10x faster to write.
// Look how concise this is
USE sales NEW
INDEX ON DToS(date) + Str(amount) TO sales_idx
SET FILTER TO amount > 1000
GO TOP
DO WHILE !Eof()
? date, customer, amount
SKIP
ENDDO
In Go, this requires CSV parsing, struct definitions, sort interfaces, filter loops... One xBase command replaces 20 lines of Go code.
Key Numbers
Harbour compat: 98% (232/236 test files)
RTL functions: 351
Go interop: FastPath 15M calls/sec
Tests: 13 packages ALL PASS
Build output: single native binary
Five-Only Syntax
// Multi-return
cName, nAge := GetUserInfo()
// DEFER — automatic cleanup
DEFER db:Close()
// Channel operators
ch <- "hello"
msg := <- ch
// WATCH — channel multiplexing
WATCH
CASE msg := <- ch1
CASE <- chTimeout
END WATCH
// Parallel FOR
PARALLEL FOR i := 1 TO 100000
aResult[i] := Process(aData[i])
NEXT
// ASYNC/AWAIT
future := ASYNC HeavyQuery()
result := AWAIT future
// Nil-safe
? customer?:address?:city
// f-string
? f"Name: {cName}, Age: {nAge}"
// Slice
aSub := aData[2:5]
// Direct Go package calls
? strings.ToUpper("hello")
? math.Sqrt(144)
? fmt.Sprintf("%.2f", 3.14)
Getting Started
# Install
go install github.com/aspect-build/five@latest
# Run
five run hello.prg
# Build
five build hello.prg -o hello
# Debug
five debug hello.prg
// hello.prg
PROCEDURE Main()
? "Hello, Five!"
? f"Today: {Date()}"
RETURN
Five — 30 years of xBase heritage, powered by Go's future.