Parse loop/recur, and reindent all the things
This commit is contained in:
parent
e7eccca000
commit
362e76c323
|
@ -594,6 +594,69 @@
|
||||||
|
|
||||||
(panic parser "Expected with after match expression"))))
|
(panic parser "Expected with after match expression"))))
|
||||||
|
|
||||||
|
(defn- parse-loop-clause [parser]
|
||||||
|
(if (not (= ::token/lparen (token-type parser)))
|
||||||
|
(panic parser "Loop clauses must begin with tuple patterns")
|
||||||
|
(let [pattern (parse-tuple-pattern parser)
|
||||||
|
arrow (expect* #{::token/rarrow} "Expected arrow" pattern)
|
||||||
|
body (parse-expr (:parser arrow))]
|
||||||
|
(if (:success arrow)
|
||||||
|
(assoc body ::ast {::ast/type ::ast/clause
|
||||||
|
:pattern (::ast pattern) :body (::ast body)})
|
||||||
|
(panic pattern "Expected -> in loop clause. Clauses must be in the form of (pattern) -> expression")))))
|
||||||
|
|
||||||
|
(defn- parse-loop-clauses [parser]
|
||||||
|
(loop [parser (accept-many #{::token/newline} (advance parser))
|
||||||
|
clauses []]
|
||||||
|
(let [curr (current parser)]
|
||||||
|
(case (::token/type curr)
|
||||||
|
::token/rbrace
|
||||||
|
(if (< 0 (count clauses))
|
||||||
|
(assoc (advance parser) ::ast {::ast/type ::ast/clauses :clauses clauses})
|
||||||
|
(panic parser "Expected one or more loop clauses" #{::token/rbrace}))
|
||||||
|
|
||||||
|
::token/newline
|
||||||
|
(recur (accept-many #{::token/newline} parser) clauses)
|
||||||
|
|
||||||
|
(let [clause (parse-loop-clause parser)]
|
||||||
|
(recur (accept-many #{::token/newline} clause) (conj clauses (::ast clause))))))))
|
||||||
|
|
||||||
|
(defn- parse-loop [parser]
|
||||||
|
(let [next (advance parser)]
|
||||||
|
(if (= ::token/lparen (token-type next))
|
||||||
|
(let [loop-tup (parse-tuple (advance next))
|
||||||
|
loop-header (expect* #{::token/with} "Expected with" loop-tup)]
|
||||||
|
(if (:success loop-header)
|
||||||
|
(let [clauses (:parser loop-header)]
|
||||||
|
(if (= (token-type clauses) ::token/lbrace)
|
||||||
|
;; loop expression with one or many clauses in braces
|
||||||
|
(let [clauses (parse-loop-clauses clauses)]
|
||||||
|
(assoc clauses ::ast {::ast/type ::ast/loop
|
||||||
|
:expr (::ast loop-tup)
|
||||||
|
:clauses (get-in clauses [::ast :clauses])}))
|
||||||
|
;; loop expression with single match clause
|
||||||
|
(let [clause (parse-loop-clause clauses)]
|
||||||
|
(assoc clause ::ast {::ast/type ::ast/loop
|
||||||
|
:expr (::ast loop-tup)
|
||||||
|
:clauses [(::ast clause)]}))))
|
||||||
|
|
||||||
|
(panic parser "Expected with after loop expression")))
|
||||||
|
(panic parser "Expected tuple as loop expression")
|
||||||
|
)))
|
||||||
|
|
||||||
|
(defn- parse-recur [parser]
|
||||||
|
(let [next (advance parser)]
|
||||||
|
(if (= ::token/lparen (token-type next))
|
||||||
|
(let [tuple (parse-tuple (advance next))]
|
||||||
|
(assoc tuple ::ast {::ast/type ::ast/recur
|
||||||
|
:tuple (::ast tuple)})
|
||||||
|
)
|
||||||
|
(panic parser "Expected tuple after recur")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
(defn- parse-cond-clause [parser]
|
(defn- parse-cond-clause [parser]
|
||||||
(let [expr (if
|
(let [expr (if
|
||||||
(contains? #{::token/else ::token/placeholder} (token-type parser))
|
(contains? #{::token/else ::token/placeholder} (token-type parser))
|
||||||
|
@ -791,6 +854,10 @@
|
||||||
|
|
||||||
::token/ref (parse-ref parser)
|
::token/ref (parse-ref parser)
|
||||||
|
|
||||||
|
::token/loop (parse-loop parser)
|
||||||
|
|
||||||
|
::token/recur (parse-recur parser)
|
||||||
|
|
||||||
;; TODO: improve handling of comments?
|
;; TODO: improve handling of comments?
|
||||||
;; Scanner now just skips comments
|
;; Scanner now just skips comments
|
||||||
;; ::token/comment (advance parser)
|
;; ::token/comment (advance parser)
|
||||||
|
@ -813,7 +880,13 @@
|
||||||
|
|
||||||
(do
|
(do
|
||||||
(def pp pp/pprint)
|
(def pp pp/pprint)
|
||||||
(def source "ref foo = 42
|
(def source "loop (10) with {
|
||||||
|
(0) -> print (:boom)
|
||||||
|
(n) -> {
|
||||||
|
print (:tick)
|
||||||
|
recur (dec (n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
")
|
")
|
||||||
(def lexed (scanner/scan source))
|
(def lexed (scanner/scan source))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user