From 5fc2c8ee2ffd53aec8c93ff42f42e6433dbdbd67 Mon Sep 17 00:00:00 2001 From: soukev Date: Mon, 15 Jun 2026 18:20:37 +0200 Subject: Base hash-table convenience functionality --- src/hash-table.lisp | 37 +++++++++++++++++++++++++++++++++++++ src/package.lisp | 6 ++++++ substrate-hash-table.asd | 9 +++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/hash-table.lisp create mode 100644 src/package.lisp create mode 100644 substrate-hash-table.asd diff --git a/src/hash-table.lisp b/src/hash-table.lisp new file mode 100644 index 0000000..a53eb72 --- /dev/null +++ b/src/hash-table.lisp @@ -0,0 +1,37 @@ +(in-package #:substrate/hash-table) + +(defmacro hash (&rest pairs) + "Convenience macro for hash-table creation. +Combines `make-hash-table` action with `(setf (gethash key table) val)` in one call. +Arguments have to be in even numbers forming pairs, e.g.: `(% :x 1 :y 2)`." + (unless (evenp (length pairs)) + (error "% - hash table requires an even number of arguments for key-value pairs.")) + `(load-time-value + (let ((table (make-hash-table :test 'equal))) + ,@(loop for (key val) on pairs by #'cddr + collect `(setf (gethash ,key table) ,val)) + table))) + +(defun keys (hash-table) + "Convenience function which returns all keys of hash-table." + (loop for key being the hash-keys of hash-table + collect key)) + +(defun vals (hash-table) + "Convenience function which returns all values from hash-table." + (loop for val being the hash-values of hash-table + collect val)) + +(defun get-in (lookup-item keys &key default) + "Returns the value in nested associative structure (hash-table, list vector)" + (loop for key in keys + for current = lookup-item then next + for next = (cond + ((hash-table-p current) (gethash key current)) + ((listp current) (nth key current)) + ((vectorp current) (elt current key)) + (t nil)) + while next + finally (return (if (and default (not next)) + default + next)))) diff --git a/src/package.lisp b/src/package.lisp new file mode 100644 index 0000000..c0af7dc --- /dev/null +++ b/src/package.lisp @@ -0,0 +1,6 @@ +(defpackage #:substrate/hash-table + (:use #:cl) + (:export #:hash + #:keys + #:vals + #:get-in)) diff --git a/substrate-hash-table.asd b/substrate-hash-table.asd new file mode 100644 index 0000000..3a15c88 --- /dev/null +++ b/substrate-hash-table.asd @@ -0,0 +1,9 @@ +(defsystem "substrate-hash-table" + :author "soukev " + :license "GPL 3.0" + :version "0" + :description "Hash-table convinience library" + :components ((:module "src" + :serial t + :components ((:file "package") + (:file "hash-table"))))) -- cgit v1.2.3