// 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.Set(t.Local(i), 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() hh := t.Local(1).AsHash() if hh != nil { if i := hh.Lookup(t.Local(2)); i >= 0 { t.PushValue(hh.Values[i]) t.RetValue() return } } t.PushNil() t.RetValue() } // HbHGetDef gets a value from a hash by key, returning a default if missing. // Harbour: hb_HGetDef(hHash, xKey, xDefault) → xValue func HbHGetDef(t *hbrt.Thread) { t.Frame(3, 0) defer t.EndProc() if hh := t.Local(1).AsHash(); hh != nil { if i := hh.Lookup(t.Local(2)); i >= 0 { t.PushValue(hh.Values[i]) t.RetValue() return } } t.PushValue(t.Local(3)) 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) if hh := hVal.AsHash(); hh != nil { hh.Set(t.Local(2), t.Local(3)) } 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) if hh := hVal.AsHash(); hh != nil { hh.Delete(t.Local(2)) } 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() hh := t.Local(1).AsHash() t.PushBool(hh != nil && hh.Has(t.Local(2))) 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() }