Parse splats in hashmaps *correctly*

This commit is contained in:
Scott Richmond 2022-05-20 18:46:24 -04:00
parent ea5d9fa948
commit f70aa0f4ce

View File

@ -272,7 +272,7 @@
(defn- parse-hash [origin] (defn- parse-hash [origin]
(loop [parser (accept-many #{::token/newline ::token/comma} (advance origin)) (loop [parser (accept-many #{::token/newline ::token/comma} (advance origin))
members {} members []
current_member nil] current_member nil]
(let [curr (current parser)] (let [curr (current parser)]
(case (token-type parser) (case (token-type parser)
@ -294,13 +294,17 @@
(panic (assoc origin ::errors (::errors parser)) "Unterminated hashmap" ::token/eof) (panic (assoc origin ::errors (::errors parser)) "Unterminated hashmap" ::token/eof)
::token/word ::token/word
(if (not current_member) (let [parsed (parse-word parser) word (get-in parsed [::ast :word])] (if (not current_member)
(recur parsed members {(keyword word) (::ast parsed)})) (let [parsed (parse-word parser)
word (get-in parsed [::ast :word])]
(recur parsed members [(keyword word) (::ast parsed)]))
(panic parser "Hashmap entries must be single words or keyword+expression pairs." #{::token/rbrace})) (panic parser "Hashmap entries must be single words or keyword+expression pairs." #{::token/rbrace}))
::token/keyword ::token/keyword
(if (not current_member) (let [kw (parse-atom parser) expr (parse-expr kw #{::token/comma ::token/newline ::token/rbrace})] (if (not current_member)
(recur expr members {(:value (::ast kw)) (::ast expr)})) (let [kw (parse-atom parser)
expr (parse-expr kw #{::token/comma ::token/newline ::token/rbrace})]
(recur expr members [(:value (::ast kw)) (::ast expr)]))
(panic parser "Hashmap entries must be single words or keyword+expression pairs." #{::token/rbrace})) (panic parser "Hashmap entries must be single words or keyword+expression pairs." #{::token/rbrace}))
::token/splat ::token/splat
@ -1042,12 +1046,11 @@
(parser) (parser)
(parse-script))) (parse-script)))
(comment (do
(def pp pp/pprint) (def pp pp/pprint)
(def source "${a, b, ...c, d, ...e} (def source "let foo = #{:a 1,...b}
#{:a b,...d, :e f, ...g}
") ")
(def lexed (scanner/scan source)) (def lexed (scanner/scan source))
(def tokens (:tokens lexed)) (def tokens (:tokens lexed))
(def p (parser tokens)) (def p (parser tokens))