32 lines
1.3 KiB
Fennel
32 lines
1.3 KiB
Fennel
; [q X] -> q(X) -> [:literal :q [:var :X]]
|
|
; [q :x] -> q(x) -> [:literal :q [:const :x]]
|
|
; [q #(+ 1 2)] -> q(3) -> [:literal q [:const (+ 1 2)]]
|
|
|
|
(fn clause [c]
|
|
(match c
|
|
(where [escape expr] (list? c) (= (tostring escape) :unquote)) expr
|
|
(where [escape expr] (list? c) (= (tostring escape) :hashfn)) `[:const ,expr]
|
|
(where [name & params] (sequence? c)) `[:literal ,(tostring name) ,(icollect [_ param (ipairs params)] (clause param))]
|
|
(where [head & args] (list? c) (sym? head)) (icollect [_ expr (ipairs args) :into [(tostring head)]] (clause expr))
|
|
(where c (list? c)) (icollect [_ val (ipairs c)] (clause val))
|
|
(where v (sym? c)) `[:var ,(tostring v)]
|
|
_ `[:const ,c]))
|
|
|
|
(fn clauses [...]
|
|
(icollect [_ c (ipairs [...]) :into `(values)] (clause c)))
|
|
|
|
(fn defrule [s ...] `(: ,s :defrule ,(clauses ...)))
|
|
|
|
(fn defrules [s ...]
|
|
(icollect [_ rule (ipairs [...]) :into `(do)]
|
|
(defrule s (table.unpack rule))))
|
|
|
|
(fn query [s ...] `(: ,s :query ,(clauses ...)))
|
|
(fn insert [s ...] `(: ,s :insert ,(clauses ...)))
|
|
(fn delete [s ...] `(: ,s :delete ,(clauses ...)))
|
|
(fn update [s ...] `(: ,s :update ,(clauses ...)))
|
|
(fn specify [s ...] `(: ,s :specify ,(clauses ...)))
|
|
|
|
{: clause : clauses :$ clauses : defrule : defrules : query : insert : delete : update : specify}
|
|
|