- 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>
123 lines
2.3 KiB
Plaintext
123 lines
2.3 KiB
Plaintext
// Five #pragma BEGINDUMP demo — HB_FUNC Go API
|
|
//
|
|
// Harbour's HB_FUNC(name) C API → Five's hbrt.HB_FUNC("name", fn) Go API
|
|
// Parameters: PRG → Go via ctx.ParC/NI/ND/L (1-based)
|
|
// Returns: Go → PRG via ctx.RetC/NI/ND/L
|
|
|
|
PROCEDURE Main()
|
|
LOCAL aResult, nSquared, i
|
|
|
|
? "=== Five Inline Go Demo ==="
|
|
?
|
|
|
|
? "GoUpper('hello world') =", GoUpper("hello world")
|
|
? "GoFib(10) =", GoFib(10)
|
|
? "GoGCD(48, 18) =", GoGCD(48, 18)
|
|
|
|
aResult := GoSplit("one,two,three", ",")
|
|
? "GoSplit result:"
|
|
FOR i := 1 TO Len(aResult)
|
|
? " ", aResult[i]
|
|
NEXT
|
|
|
|
nSquared := 0
|
|
GoSquare(7, @nSquared)
|
|
? "GoSquare(7, @n) => n =", nSquared
|
|
|
|
? "GoTypeOf('abc') =", GoTypeOf("abc")
|
|
? "GoTypeOf(123) =", GoTypeOf(123)
|
|
? "GoTypeOf(.T.) =", GoTypeOf(.T.)
|
|
? "GoTypeOf({1,2}) =", GoTypeOf({1,2})
|
|
? "GoTypeOf(NIL) =", GoTypeOf(NIL)
|
|
|
|
RETURN
|
|
|
|
#pragma BEGINDUMP
|
|
|
|
import (
|
|
"five/hbrt"
|
|
"strings"
|
|
)
|
|
|
|
func init() {
|
|
hbrt.HB_FUNC("GOUPPER", goUpper)
|
|
hbrt.HB_FUNC("GOFIB", goFib)
|
|
hbrt.HB_FUNC("GOGCD", goGCD)
|
|
hbrt.HB_FUNC("GOSPLIT", goSplit)
|
|
hbrt.HB_FUNC("GOSQUARE", goSquare)
|
|
hbrt.HB_FUNC("GOTYPEOF", goTypeOf)
|
|
}
|
|
|
|
func goUpper(ctx *hbrt.HBContext) {
|
|
if ctx.PCount() < 1 || !ctx.IsChar(1) {
|
|
ctx.RetC("")
|
|
return
|
|
}
|
|
ctx.RetC(strings.ToUpper(ctx.ParC(1)))
|
|
}
|
|
|
|
func goFib(ctx *hbrt.HBContext) {
|
|
n := ctx.ParNIDef(1, 0)
|
|
if n <= 1 {
|
|
ctx.RetNI(n)
|
|
return
|
|
}
|
|
a, b := 0, 1
|
|
for i := 2; i <= n; i++ {
|
|
a, b = b, a+b
|
|
}
|
|
ctx.RetNI(b)
|
|
}
|
|
|
|
func goGCD(ctx *hbrt.HBContext) {
|
|
a := ctx.ParNI(1)
|
|
b := ctx.ParNI(2)
|
|
for b != 0 {
|
|
a, b = b, a%b
|
|
}
|
|
ctx.RetNI(a)
|
|
}
|
|
|
|
func goSplit(ctx *hbrt.HBContext) {
|
|
s := ctx.ParC(1)
|
|
delim := ctx.ParC(2)
|
|
if delim == "" {
|
|
delim = ","
|
|
}
|
|
parts := strings.Split(s, delim)
|
|
items := make([]hbrt.Value, len(parts))
|
|
for i, p := range parts {
|
|
items[i] = hbrt.MakeString(p)
|
|
}
|
|
ctx.RetArray(items)
|
|
}
|
|
|
|
func goSquare(ctx *hbrt.HBContext) {
|
|
n := ctx.ParNI(1)
|
|
ctx.StorNI(n*n, 2)
|
|
ctx.RetNI(n * n)
|
|
}
|
|
|
|
func goTypeOf(ctx *hbrt.HBContext) {
|
|
switch {
|
|
case ctx.IsChar(1):
|
|
ctx.RetC("STRING")
|
|
case ctx.IsNum(1):
|
|
ctx.RetC("NUMERIC")
|
|
case ctx.IsLog(1):
|
|
ctx.RetC("LOGICAL")
|
|
case ctx.IsDate(1):
|
|
ctx.RetC("DATE")
|
|
case ctx.IsArray(1):
|
|
ctx.RetC("ARRAY")
|
|
case ctx.IsHash(1):
|
|
ctx.RetC("HASH")
|
|
case ctx.IsNil(1):
|
|
ctx.RetC("NIL")
|
|
default:
|
|
ctx.RetC("UNKNOWN")
|
|
}
|
|
}
|
|
|
|
#pragma ENDDUMP
|