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