Add splats to list patterns in parser
This commit is contained in:
parent
4254359934
commit
68bc37ef61
|
@ -484,17 +484,45 @@
|
||||||
|
|
||||||
(def sync-pattern (s/union sync-on #{::token/equals ::token/rarrow}))
|
(def sync-pattern (s/union sync-on #{::token/equals ::token/rarrow}))
|
||||||
|
|
||||||
|
(defn- parse-splat-pattern [origin]
|
||||||
|
(let [splatted (advance origin)]
|
||||||
|
(case (token-type splatted)
|
||||||
|
::token/word
|
||||||
|
(assoc (advance splatted) ::ast
|
||||||
|
{::ast/type ::ast/splat
|
||||||
|
:token (current origin)
|
||||||
|
:into (::ast (parse-word splatted))})
|
||||||
|
|
||||||
|
::token/placeholder
|
||||||
|
(assoc (advance splatted) ::ast
|
||||||
|
{::ast/type ::ast/splat
|
||||||
|
:token (current origin)
|
||||||
|
:into {::ast/type ::ast/placeholder :token (current splatted)}})
|
||||||
|
|
||||||
|
(::token/comma ::token/newline ::token/rbrace ::token/rparen ::token/rbracket)
|
||||||
|
(assoc splatted ::ast
|
||||||
|
{::ast/type ::ast/splat
|
||||||
|
:token (current origin)
|
||||||
|
:into {::ast/type ::ast/placeholder :token (current origin)}})
|
||||||
|
|
||||||
|
(panic origin "Splat patterns may only splat into words or placeholders.")
|
||||||
|
)))
|
||||||
|
|
||||||
(defn- parse-list-pattern [origin]
|
(defn- parse-list-pattern [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)
|
||||||
::token/rbracket (let [ms (add-member members current_member)]
|
::token/rbracket
|
||||||
|
(let [ms (add-member members current_member)]
|
||||||
|
(if (not-any? #(= (::ast/type %) ::ast/splat) (drop-last ms))
|
||||||
(assoc (advance parser) ::ast
|
(assoc (advance parser) ::ast
|
||||||
{::ast/type ::ast/list
|
{::ast/type ::ast/tuple
|
||||||
:token (current origin)
|
:token (current origin)
|
||||||
:members ms}))
|
:length (count ms)
|
||||||
|
:members ms})
|
||||||
|
(panic parser "A splat my only appear once in a pattern, at the end of a pattern.")))
|
||||||
|
|
||||||
(::token/comma ::token/newline)
|
(::token/comma ::token/newline)
|
||||||
(recur
|
(recur
|
||||||
|
@ -507,6 +535,10 @@
|
||||||
::token/eof
|
::token/eof
|
||||||
(panic (assoc origin ::errors (::errors parser)) "Unterminated list pattern" ::token/eof)
|
(panic (assoc origin ::errors (::errors parser)) "Unterminated list pattern" ::token/eof)
|
||||||
|
|
||||||
|
::token/splat
|
||||||
|
(let [splatted (parse-splat-pattern parser)]
|
||||||
|
(recur splatted members (::ast splatted)))
|
||||||
|
|
||||||
(let [parsed (parse-pattern parser)]
|
(let [parsed (parse-pattern parser)]
|
||||||
(recur parsed members (::ast parsed)))))))
|
(recur parsed members (::ast parsed)))))))
|
||||||
|
|
||||||
|
@ -584,19 +616,22 @@
|
||||||
|
|
||||||
(panic parser "Struct patterns may only include single words or keyword+pattern pairs." #{::token/rbrace})))))
|
(panic parser "Struct patterns may only include single words or keyword+pattern pairs." #{::token/rbrace})))))
|
||||||
|
|
||||||
|
|
||||||
(defn- parse-tuple-pattern [origin]
|
(defn- parse-tuple-pattern [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)
|
||||||
::token/rparen (let [ms (add-member members current_member)]
|
::token/rparen
|
||||||
|
(let [ms (add-member members current_member)]
|
||||||
(assoc (advance parser) ::ast
|
(assoc (advance parser) ::ast
|
||||||
{::ast/type ::ast/tuple
|
{::ast/type ::ast/tuple
|
||||||
:token (current origin)
|
:token (current origin)
|
||||||
:length (count ms)
|
:length (count ms)
|
||||||
:members ms}))
|
:members ms}))
|
||||||
|
|
||||||
|
|
||||||
(::token/comma ::token/newline)
|
(::token/comma ::token/newline)
|
||||||
(recur
|
(recur
|
||||||
(accept-many #{::token/comma ::token/newline} parser)
|
(accept-many #{::token/comma ::token/newline} parser)
|
||||||
|
@ -1070,10 +1105,9 @@
|
||||||
(parser)
|
(parser)
|
||||||
(parse-script)))
|
(parse-script)))
|
||||||
|
|
||||||
(comment
|
(do
|
||||||
(def pp pp/pprint)
|
(def pp pp/pprint)
|
||||||
(def source "if let foo = bar then foo else bar")
|
(def source "let [a, b, (c, d), ...e] = [1, 2, (4, 5), 6]")
|
||||||
|
|
||||||
|
|
||||||
(println "")
|
(println "")
|
||||||
(println "")
|
(println "")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user