- 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>
142 lines
2.9 KiB
Go
142 lines
2.9 KiB
Go
// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
|
|
// All rights reserved.
|
|
|
|
// Hash functions for the Five runtime library.
|
|
// Harbour: hb_Hash, hb_HGet, hb_HSet, hb_HDel, hb_HHasKey, etc.
|
|
package hbrtl
|
|
|
|
import "five/hbrt"
|
|
|
|
// HbHash creates a hash from key-value pairs.
|
|
// Harbour: hb_Hash(key1, val1, key2, val2, ...) → hHash
|
|
func HbHash(t *hbrt.Thread) {
|
|
nParams := t.ParamCount()
|
|
t.Frame(nParams, 0)
|
|
defer t.EndProc()
|
|
|
|
h := hbrt.MakeHash()
|
|
hh := h.AsHash()
|
|
for i := 1; i <= nParams-1; i += 2 {
|
|
hh.Keys = append(hh.Keys, t.Local(i))
|
|
hh.Values = append(hh.Values, t.Local(i+1))
|
|
}
|
|
t.PushValue(h)
|
|
t.RetValue()
|
|
}
|
|
|
|
// HbHGet gets a value from a hash by key.
|
|
// Harbour: hb_HGet(hHash, xKey) → xValue
|
|
func HbHGet(t *hbrt.Thread) {
|
|
t.Frame(2, 0)
|
|
defer t.EndProc()
|
|
hVal := t.Local(1)
|
|
key := t.Local(2)
|
|
hh := hVal.AsHash()
|
|
if hh != nil {
|
|
for i, k := range hh.Keys {
|
|
if valuesEqual(k, key) {
|
|
t.PushValue(hh.Values[i])
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
}
|
|
t.PushNil()
|
|
t.RetValue()
|
|
}
|
|
|
|
// HbHSet sets a value in hash by key.
|
|
// Harbour: hb_HSet(hHash, xKey, xValue) → hHash
|
|
func HbHSet(t *hbrt.Thread) {
|
|
t.Frame(3, 0)
|
|
defer t.EndProc()
|
|
hVal := t.Local(1)
|
|
key := t.Local(2)
|
|
val := t.Local(3)
|
|
hh := hVal.AsHash()
|
|
if hh != nil {
|
|
for i, k := range hh.Keys {
|
|
if valuesEqual(k, key) {
|
|
hh.Values[i] = val
|
|
t.PushValue(hVal)
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
hh.Keys = append(hh.Keys, key)
|
|
hh.Values = append(hh.Values, val)
|
|
}
|
|
t.PushValue(hVal)
|
|
t.RetValue()
|
|
}
|
|
|
|
// HbHDel deletes a key from hash.
|
|
// Harbour: hb_HDel(hHash, xKey) → hHash
|
|
func HbHDel(t *hbrt.Thread) {
|
|
t.Frame(2, 0)
|
|
defer t.EndProc()
|
|
hVal := t.Local(1)
|
|
key := t.Local(2)
|
|
hh := hVal.AsHash()
|
|
if hh != nil {
|
|
for i, k := range hh.Keys {
|
|
if valuesEqual(k, key) {
|
|
hh.Keys = append(hh.Keys[:i], hh.Keys[i+1:]...)
|
|
hh.Values = append(hh.Values[:i], hh.Values[i+1:]...)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
t.PushValue(hVal)
|
|
t.RetValue()
|
|
}
|
|
|
|
// HbHHasKey checks if hash contains a key.
|
|
// Harbour: hb_HHasKey(hHash, xKey) → lExists
|
|
func HbHHasKey(t *hbrt.Thread) {
|
|
t.Frame(2, 0)
|
|
defer t.EndProc()
|
|
hVal := t.Local(1)
|
|
key := t.Local(2)
|
|
hh := hVal.AsHash()
|
|
if hh != nil {
|
|
for _, k := range hh.Keys {
|
|
if valuesEqual(k, key) {
|
|
t.PushBool(true)
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
}
|
|
t.PushBool(false)
|
|
t.RetValue()
|
|
}
|
|
|
|
// HbHKeys returns an array of hash keys.
|
|
// Harbour: hb_HKeys(hHash) → aKeys
|
|
func HbHKeys(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
hh := t.Local(1).AsHash()
|
|
if hh != nil {
|
|
t.PushValue(hbrt.MakeArrayFrom(hh.Keys))
|
|
} else {
|
|
t.PushValue(hbrt.MakeArray(0))
|
|
}
|
|
t.RetValue()
|
|
}
|
|
|
|
// HbHValues returns an array of hash values.
|
|
// Harbour: hb_HValues(hHash) → aValues
|
|
func HbHValues(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
hh := t.Local(1).AsHash()
|
|
if hh != nil {
|
|
t.PushValue(hbrt.MakeArrayFrom(hh.Values))
|
|
} else {
|
|
t.PushValue(hbrt.MakeArray(0))
|
|
}
|
|
t.RetValue()
|
|
}
|