Interpret cond; allow else in cond & match

This commit is contained in:
Scott Richmond 2022-04-06 19:41:36 -04:00
parent 03713c67bc
commit 917e4f7ab5
2 changed files with 40 additions and 9 deletions

View File

@ -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
}
")

View File

@ -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))