diff --git a/doc/reference/std/sugar.md b/doc/reference/std/sugar.md index 259b04266..cce98476b 100644 --- a/doc/reference/std/sugar.md +++ b/doc/reference/std/sugar.md @@ -294,16 +294,17 @@ resolve as hash references. More specifically, the macro rebinds `%%ref` so that identifiers starting with a `.` are resolved with the following rules: -- `.x -> (hash-ref hash 'x)` ; strong accessor -- `.?x -> (hash-get hash 'x)` ; weak accessor -- `..x -> (%%ref .x)` ; escape +- `.x -> (hash-ref hash 'x)` ; strong accessor +- `.?x -> (hash-get hash 'x)` ; weak accessor +- `.$x -> (hash-get hash "x")` ; string weak accessor +- `..x -> (%%ref .x)` ; escape ::: tip Examples: ```scheme > (def .c 4) -> (def h (hash (a 1) (b 2) (c 3))) -> (let-hash h [.a .?b ..c .?d]) -(1 2 4 #f) +> (def h (hash (a 1) (b 2) (c 3) ("d" 5))) +> (let-hash h [.a .?b ..c .$d .?e]) +(1 2 4 5 #f) ``` ::: diff --git a/src/std/sugar-test.ss b/src/std/sugar-test.ss index 919a17b2a..fe174cf93 100644 --- a/src/std/sugar-test.ss +++ b/src/std/sugar-test.ss @@ -113,8 +113,8 @@ (test-case "let-hash" (def .c 4) - (def h (hash (a 1) (b 2) (c 3))) - (check (let-hash h [.a .?b ..c .?d]) => [1 2 4 #f])) + (def h (hash (a 1) (b 2) (c 3) ("d" 5))) + (check (let-hash h [.a .?b ..c .$d .?e]) => [1 2 4 5 #f])) (test-case "awhen" (def (foo c) (awhen (v (char-ascii-digit c)) (* v v))) diff --git a/src/std/sugar.ss b/src/std/sugar.ss index a41651caf..c99e33e56 100644 --- a/src/std/sugar.ss +++ b/src/std/sugar.ss @@ -197,9 +197,10 @@ ;; the hash deconstructor macro ;; usage: (let-hash a-hash body ...) ;; rebinds %%ref so that identifiers starting with a dot are looked up in the hash: -;; .x -> (hash-ref a-hash 'x) ; strong accessor -;; .?x -> (hash-get a-hash 'x) ; weak accessor -;; ..x -> (%%ref .x) ; escape +;; .x -> (hash-ref a-hash 'x) ; strong accessor +;; .?x -> (hash-get a-hash 'x) ; weak accessor +;; .$x -> (hash-get a-hash "x") ; string weak accessor +;; ..x -> (%%ref .x) ; escape (defsyntax (let-hash stx) (syntax-case stx () ((macro expr body ...) @@ -217,6 +218,8 @@ (let (str (symbol->string (stx-e #'id))) (def (str->symbol start) (string->symbol (substring str start (string-length str)))) + (def (substr start) + (substring str start (string-length str))) (if (eq? (string-ref str 0) #\.) ; hash accessor? (cond ((eq? (string-ref str 1) #\.) ; escape @@ -225,6 +228,9 @@ ((eq? (string-ref str 1) #\?) ; weak (with-syntax ((sym (str->symbol 2))) #'(hash-get ht 'sym))) + ((eq? (string-ref str 1) #\$) ; string weak + (with-syntax ((sub (substr 2))) + #'(hash-get ht 'sub))) (else (with-syntax ((sym (str->symbol 1))) #'(hash-ref ht 'sym))))