Keywords can be called as passed fns

This commit is contained in:
Scott Richmond 2022-04-03 15:39:41 -04:00
parent 9fd69b57f3
commit 7a4034d920

View File

@ -1,11 +1,11 @@
(ns ludus.interpreter (ns ludus.interpreter
(:require (:require
[ludus.parser :as parser] [ludus.parser :as parser]
[ludus.scanner :as scanner] [ludus.scanner :as scanner]
[ludus.ast :as ast] [ludus.ast :as ast]
[ludus.prelude :as prelude] [ludus.prelude :as prelude]
[ludus.data :as data] [ludus.data :as data]
[clojure.pprint :as pp])) [clojure.pprint :as pp]))
;; right now this is not very efficient: ;; right now this is not very efficient:
;; it's got runtime checking ;; it's got runtime checking
@ -115,7 +115,7 @@
(throw (ex-info "Called keywords must be unary" {})) (throw (ex-info "Called keywords must be unary" {}))
(let [kw (interpret kw ctx) (let [kw (interpret kw ctx)
map (second (interpret tuple ctx))] map (second (interpret tuple ctx))]
(if (::ast/struct map) (if (::data/struct map)
(if (contains? map kw) (if (contains? map kw)
(kw map) (kw map)
(throw (ex-info (str "Struct error: no member at " kw) {}))) (throw (ex-info (str "Struct error: no member at " kw) {})))
@ -145,14 +145,20 @@
(recur (first clauses) (rest clauses)))) (recur (first clauses) (rest clauses))))
(throw (ex-info "Match Error: No match found" {:fn-name (:name fn)}))))) (throw (ex-info "Match Error: No match found" {:fn-name (:name fn)})))))
(if (= clojure.lang.Keyword (type fn))
(throw (ex-info "I don't know how to call that" {:fn fn}))))) (if (::data/struct passed)
(if (contains? map fn)
(fn map)
(throw (ex-info (str "Struct error: no member at " fn) {})))
(get map fn))
(throw (ex-info "I don't know how to call that" {:fn fn}))
))))
;; TODO: add placeholder partial application ;; TODO: add placeholder partial application
(defn- interpret-synthetic-term [prev-value curr ctx] (defn- interpret-synthetic-term [prev-value curr ctx]
(let [type (::ast/type curr)] (let [type (::ast/type curr)]
(if (= type ::ast/atom) (if (= type ::ast/atom)
(if (::ast/struct prev-value) (if (::data/struct prev-value)
(if (contains? prev-value (:value curr)) (if (contains? prev-value (:value curr))
(get prev-value (:value curr)) (get prev-value (:value curr))
(throw (ex-info (str "Struct error: no member " (:value curr)) {})))) (throw (ex-info (str "Struct error: no member " (:value curr)) {}))))
@ -244,7 +250,7 @@
::ast/struct ::ast/struct
(let [members (:members ast)] (let [members (:members ast)]
(into {::ast/struct true} (map-values #(interpret % ctx)) members)) (into {::data/struct true} (map-values #(interpret % ctx)) members))
(throw (ex-info "Unknown AST node type" {:node ast})))) (throw (ex-info "Unknown AST node type" {:node ast}))))
@ -252,8 +258,9 @@
(def source " (def source "
let s = @{:foo @{:baz 12}, :bar 23} fn call (callable, target) -> callable (target)
s :foo :baz fn id (x) -> x
call (:foo, 12)
") ")
@ -263,11 +270,11 @@
(println "") (println "")
(-> source (-> source
(scanner/scan) (scanner/scan)
(parser/parse) (parser/parse)
(::parser/ast) (::parser/ast)
(interpret {}) (interpret {})
(pp/pprint))) (pp/pprint)))
(comment " (comment "