From 4e7590226ba3f9f1f70e582e5b16d1664bf57c83 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Sun, 19 Jun 2022 14:52:38 -0400 Subject: [PATCH] Copypasta splat patterns to dict, struct, tuple in parser --- src/ludus/parser.clj | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/src/ludus/parser.clj b/src/ludus/parser.clj index fd1331e..7400444 100644 --- a/src/ludus/parser.clj +++ b/src/ludus/parser.clj @@ -522,7 +522,7 @@ :token (current origin) :length (count ms) :members ms}) - (panic parser "A splat my only appear once in a pattern, at the end of a pattern."))) + (panic parser "A splat my only appear once in a list pattern, at the end of the pattern."))) (::token/comma ::token/newline) (recur @@ -548,11 +548,15 @@ current_member nil] (let [curr (current parser)] (case (token-type parser) - ::token/rbrace (let [ms (add-member members current_member)] - (assoc (advance parser) ::ast - {::ast/type ::ast/dict - :token (current origin) - :members ms})) + ::token/rbrace + (let [ms (add-member members current_member)] + (if (not-any? #(= (::ast/type %) ::ast/splat) (drop-last ms)) + (assoc (advance parser) ::ast + {::ast/type ::ast/tuple + :token (current origin) + :length (count ms) + :members ms}) + (panic parser "A splat my only appear once in a dict pattern, at the end of the pattern."))) (::token/comma ::token/newline) (recur @@ -565,6 +569,10 @@ ::token/eof (panic (assoc origin ::errors (::errors parser)) "Unterminated dict pattern" ::token/eof) + ::token/splat + (let [splatted (parse-splat-pattern parser)] + (recur splatted members (::ast splatted))) + ::token/word (if (not current_member) (let [parsed (parse-word parser) word (get-in parsed [::ast :word])] @@ -585,11 +593,15 @@ current_member nil] (let [curr (current parser)] (case (token-type parser) - ::token/rbrace (let [ms (add-member members current_member)] - (assoc (advance parser) ::ast - {::ast/type ::ast/struct - :token (current origin) - :members ms})) + ::token/rbrace + (let [ms (add-member members current_member)] + (if (not-any? #(= (::ast/type %) ::ast/splat) (drop-last ms)) + (assoc (advance parser) ::ast + {::ast/type ::ast/tuple + :token (current origin) + :length (count ms) + :members ms}) + (panic parser "A splat my only appear once in a struct pattern, at the end of the pattern."))) (::token/comma ::token/newline) (recur @@ -602,6 +614,10 @@ ::token/eof (panic (assoc origin ::errors (::errors parser)) "Unterminated struct pattern" ::token/eof) + ::token/splat + (let [splatted (parse-splat-pattern parser)] + (recur splatted members (::ast splatted))) + ::token/word (if (not current_member) (let [parsed (parse-word parser) word (get-in parsed [::ast :word])] @@ -625,11 +641,13 @@ (case (token-type parser) ::token/rparen (let [ms (add-member members current_member)] + (if (not-any? #(= (::ast/type %) ::ast/splat) (drop-last ms)) (assoc (advance parser) ::ast {::ast/type ::ast/tuple :token (current origin) :length (count ms) - :members ms})) + :members ms}) + (panic parser "A splat my only appear once in a tuple pattern, at the end of the pattern."))) (::token/comma ::token/newline) @@ -643,6 +661,10 @@ ::token/eof (panic (assoc origin ::errors (::errors parser)) "Unterminated tuple" ::token/eof) + ::token/splat + (let [splatted (parse-splat-pattern parser)] + (recur splatted members (::ast splatted))) + (let [parsed (parse-pattern parser)] (recur parsed members (::ast parsed)))))))