Interpret refs

This commit is contained in:
Scott Richmond 2022-05-17 19:13:00 -04:00
parent b0212b7e41
commit b1022ad832

View File

@ -267,6 +267,16 @@
result ;; TODO: test this! result ;; TODO: test this!
)))) ))))
(defn- interpret-ref [ast ctx]
(let [name (:name ast) expr (:expr ast)]
(if (contains? @ctx name)
(throw (ex-info (str "Name " name " is already bound") {})))
(let [value (interpret-ast expr ctx)
box (atom value)
ref {::data/ref true ::data/value box ::data/name name}]
(vswap! ctx update-ctx {name ref})
ref)))
(defn interpret-ast [ast ctx] (defn interpret-ast [ast ctx]
(case (::ast/type ast) (case (::ast/type ast)
@ -294,6 +304,8 @@
::ast/import (interpret-import ast ctx) ::ast/import (interpret-import ast ctx)
::ast/ref (interpret-ref ast ctx)
::ast/block ::ast/block
(let [exprs (:exprs ast) (let [exprs (:exprs ast)
inner (pop exprs) inner (pop exprs)
@ -346,23 +358,28 @@
(pp/pprint (ex-data e)) (pp/pprint (ex-data e))
(System/exit 67)))) (System/exit 67))))
(comment (defn interpret-safe [parsed]
(try
(interpret-ast (::parser/ast parsed) {})
(catch clojure.lang.ExceptionInfo e
(println "Ludus panicked!")
(println (ex-message e))
(pp/pprint (ex-data e)))))
(do
(def source " (def source "
let foo = 2 fn swap! (r, f) -> {
let val = deref (r)
match foo with { let new = f (val)
1 -> :one set! (r, new)
2 -> :two
else -> :oops
} }
ns bar { ref foo = 0
foo
}
bar :foo swap! (foo, inc)
swap! (foo, inc)
") ")
@ -374,7 +391,7 @@
(-> source (-> source
(scanner/scan) (scanner/scan)
(parser/parse) (parser/parse)
(interpret) (interpret-safe)
(pp/pprint))) (pp/pprint)))
(comment " (comment "