Improve parse-block

This commit is contained in:
Scott Richmond 2022-02-21 14:57:23 -05:00
parent 3357248b3c
commit 33fad7656c

View File

@ -215,27 +215,41 @@
(let [parsed (parse-expr parser)]
(recur parsed members (::ast parsed)))))))
(defn- parse-block [parser]
(loop [parser (advance parser)
(defn- parse-block [origin]
(loop [
parser (accept-many #{::token/newline ::token/semicolon} (advance origin))
exprs []
current_expr nil]
(case (::token/type (current parser))
::token/rbrace
(assoc (advance parser) ::ast
(if (and (empty? exprs) (nil? current_expr))
{::ast/type ::ast/poison :message "Blocks must have at least one expression"}
{::ast/type ::ast/block :exprs (add-member exprs current_expr)}))
current_expr nil
]
(let [curr (current parser)]
(case (token-type parser)
::token/rbrace (let [es (add-member exprs current_expr)]
(if (empty? es)
(panic parser "Blocks must have at least one expression")
(assoc (advance parser) ::ast {
::ast/type ::ast/block
:exprs es
})))
(::token/semicolon ::token/newline)
(recur (advance parser) (add-member exprs current_expr) nil)
(::token/rbracket ::token/rparen)
(panic parser (str "Mismatched enclosure in block: " (::token/lexeme curr)))
::token/eof
(panic (assoc origin ::errors (::errors parser)) "Unterminated block" ::token/eof)
(let [parsed
(if current_expr
(-> parser
(advance)
(assoc ::ast {::ast/type ::ast/poison :message "Expected end of expression"}))
(let [parsed (parse-expr parser)]
(recur parsed exprs (::ast parsed))))
)))
(panic parser "Expected end of expression" #{::token/semicolon ::token/newline})
(parse-expr parser))]
(recur parsed exprs (::ast parsed))
)
)
)
))
(defn- parse-script [parser]
(loop [parser parser
@ -396,7 +410,8 @@
(do
(def pp pp/pprint)
(def source "${32, (23, 42}")
(def source "{ 1; 2; \"foo
}")
(def lexed (scanner/scan source))
(def tokens (:tokens lexed))
(def p (parser tokens))