Files
five/hbrtl/hash.go
Charles KWON OhJun 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

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()
}