Interpret cond; allow else in cond & match
This commit is contained in:
parent
03713c67bc
commit
917e4f7ab5
|
@ -109,6 +109,23 @@
|
|||
(recur (first clauses) (rest clauses))))
|
||||
(throw (ex-info "Match Error: No match found" {}))))))
|
||||
|
||||
(defn- interpret-cond [ast ctx]
|
||||
(let [clauses (:clauses ast)]
|
||||
(loop [clause (first clauses)
|
||||
clauses (rest clauses)]
|
||||
(if (not clause)
|
||||
(throw (ex-info "Cond Error: No match found" {}))
|
||||
(let [test-expr (:test clause)
|
||||
body (:body clause)
|
||||
truthy? (boolean (interpret-ast test-expr ctx))]
|
||||
(if truthy?
|
||||
(interpret-ast body ctx)
|
||||
(recur (first clauses) (rest clauses))
|
||||
)
|
||||
)
|
||||
)
|
||||
)))
|
||||
|
||||
(defn- interpret-called-kw [kw tuple ctx]
|
||||
;; TODO: check this statically
|
||||
(if (not (= 1 (:length tuple)))
|
||||
|
@ -228,6 +245,8 @@
|
|||
|
||||
::ast/match (interpret-match ast ctx)
|
||||
|
||||
::ast/cond (interpret-cond ast ctx)
|
||||
|
||||
::ast/synthetic (interpret-synthetic ast ctx)
|
||||
|
||||
::ast/fn (interpret-fn ast ctx)
|
||||
|
@ -286,10 +305,13 @@
|
|||
|
||||
(def source "
|
||||
|
||||
fn square (x) -> mult (x, x)
|
||||
|
||||
let foo = square (_)
|
||||
let foo = 2
|
||||
|
||||
match foo with {
|
||||
1 -> :one
|
||||
2 -> :two
|
||||
else -> :oops
|
||||
}
|
||||
|
||||
")
|
||||
|
||||
|
|
|
@ -487,7 +487,9 @@
|
|||
(parse-then (accept ::token/newline ast))))
|
||||
|
||||
(defn- parse-match-clause [parser]
|
||||
(let [pattern (parse-pattern parser)
|
||||
(let [pattern (if (= ::token/else (token-type parser))
|
||||
(-> parser (advance) (assoc ::ast {::ast/type ::ast/placeholder}))
|
||||
(parse-pattern parser))
|
||||
rarrow (expect* #{::token/rarrow} "Expected arrow after pattern" pattern)]
|
||||
(if (:success rarrow)
|
||||
(let [body (parse-expr (:parser rarrow))]
|
||||
|
@ -531,7 +533,13 @@
|
|||
(panic parser "Expected with after match expression"))))
|
||||
|
||||
(defn- parse-cond-clause [parser]
|
||||
(let [expr (parse-expr parser)
|
||||
(let [expr (if (= ::token/else (token-type parser))
|
||||
(-> parser
|
||||
(advance)
|
||||
(assoc ::ast {::ast/type ::ast/atom
|
||||
:token ::token/else
|
||||
:value true}))
|
||||
(parse-expr parser))
|
||||
rarrow (expect* #{::token/rarrow} "Expected arrow after expression in cond clause" expr)]
|
||||
(if (:success rarrow)
|
||||
(let [body (parse-expr (:parser rarrow))]
|
||||
|
@ -543,7 +551,6 @@
|
|||
(loop [parser (accept-many #{::token/newline} parser)
|
||||
clauses []]
|
||||
(let [curr (current parser)]
|
||||
(println "parsing a clause: " curr)
|
||||
(case (::token/type curr)
|
||||
::token/rbrace
|
||||
(if (< 0 (count clauses))
|
||||
|
@ -562,7 +569,6 @@
|
|||
(expect* #{::token/lbrace} "Expected { after cond" (advance parser))]
|
||||
(if (:success header)
|
||||
(let [clauses (parse-cond-clauses (:parser header))]
|
||||
(println "Found all the clauses")
|
||||
(assoc clauses ::ast {::ast/type ::ast/cond
|
||||
:clauses (get-in clauses [::ast :clauses])})
|
||||
)
|
||||
|
@ -711,9 +717,12 @@
|
|||
(parser)
|
||||
(parse-script)))
|
||||
|
||||
(do
|
||||
(comment
|
||||
(def pp pp/pprint)
|
||||
(def source "cond {}
|
||||
(def source "match foo with {
|
||||
1 -> :foo
|
||||
else -> bar
|
||||
}
|
||||
|
||||
")
|
||||
(def lexed (scanner/scan source))
|
||||
|
|
Loading…
Reference in New Issue
Block a user