Keywords can be called as passed fns
This commit is contained in:
parent
9fd69b57f3
commit
7a4034d920
|
@ -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 "
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user