This repository has been archived by the owner on Jul 4, 2018. It is now read-only.
/
evaluator.clj
63 lines (55 loc) · 1.72 KB
/
evaluator.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(ns misaki.compiler.default.evaluator
"S-exp Template Evaluator.
Template string is evaluated as Function."
(:require [misaki.compiler.default.reader :refer [read-from-string]]))
; =def?
(defn def?
"Check whether `def` or `defn` s-exp or not."
[x]
(and (seq? x)
(case (first x)
(def defn defn- defmacro defmacro-) true
false)))
; =split-into-def-and-body
(def split-into-def-and-body
"Split s-exp into definition and template body using `def?`."
(juxt (partial filter def?)
(partial remove def?)))
; =enclose-sexp-with-list
(defn enclose-sexp-with-list
"Enclose s-exp with list."
[ls]
{:pre [(sequential? ls)]}
(cons 'list ls))
; =enclose-sexp-with-function
(defn enclose-sexp-with-function
"Enclose read s-exp with common function like below.
(fn [contents]
(let [site (meta contents)]
bodies))
"
[sexp]
{:pre [(sequential? sexp)]}
(let [[defs sexp] (split-into-def-and-body sexp)]
`(do (use 'misaki.compiler.default.html.core
'misaki.compiler.default.html.conv
'misaki.compiler.default.html.util
'misaki.util.date)
~@defs
(fn [~'contents]
(let [~'site (meta ~'contents)] ~sexp)))))
; =*eval-functions*
(def ^:dynamic *eval-functions*
"Definition of evaluating functions."
[enclose-sexp-with-list
enclose-sexp-with-function
eval])
; =evaluate-to-function
(defn evaluate-to-function
"Evaluate template's sexp string to template function."
([#^String sexp-str]
(evaluate-to-function sexp-str ""))
([#^String sexp-str, #^String filename]
{:pre [(string? sexp-str)]}
(let [sexp (read-from-string sexp-str :path filename)]
(reduce #(%2 %) sexp *eval-functions*))))