-
Notifications
You must be signed in to change notification settings - Fork 0
/
ohm-set-algebra.lisp
55 lines (48 loc) · 1.38 KB
/
ohm-set-algebra.lisp
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
;;; ohm-set-algebra.lisp
(in-package #:cl-ohm)
(defvar *commands*
'((red:sinter . red:sinterstore)
(red:sunion . red:sunionstore)
(red:sdiff . red:sdiffstore))
"Command mappings.")
(defun command (expr)
(cdr (assoc expr *commands*)))
(defun convert-expr (expr)
(declare (special *ids* *ops*))
(let* ((head (car expr))
(tail (cdr expr))
(id (format nil "stal:~D" (length *ids*)))
(op (list (command head) id)))
(push id *ids*)
(setf op (append op
(compile-expr tail)))
(push op *ops*)
id))
(defun compile-expr (expr)
(mapcar (lambda (item)
(if (listp item)
(convert-expr item)
item))
expr))
(defun explain (expr)
(let ((*ops* '())
(*ids* '()))
(declare (special *ops* *ids*))
(push (compile-expr expr)
*ops*)
(values (nreverse *ops*)
*ids*)))
(defun execute (expr)
(multiple-value-bind (ops ids)
(explain expr)
(with-connection ()
(cond
((onep (length ops))
(apply #'funcall (car ops)))
(t
(let ((results (with-pipelining
(with-transaction
(dolist (op ops)
(apply #'funcall op))
(apply #'red:del ids)))))
(nth 1 (cl:first (cl:last results)))))))))