forked from carp-lang/Carp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTuples.carp
More file actions
94 lines (82 loc) · 3.12 KB
/
Copy pathTuples.carp
File metadata and controls
94 lines (82 loc) · 3.12 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
(defmodule Dynamic
(private deftuple-type-)
(hidden deftuple-type-)
(defndynamic deftuple-type- [name props]
`(deftype (%name %@props)
%(collect-into (flatten (map (fn [x] `(%x %x)) props)) array)))
(private deftuple-lt-)
(hidden deftuple-lt-)
(defndynamic deftuple-lt- [name props]
(if (empty? props)
'false
(let [fst (Symbol.prefix name (car props))]
(if (= (length props) 1)
`(< (%fst t1) (%fst t2))
`(if (= (%fst t1) (%fst t2))
%(deftuple-lt- name (cdr props))
(< (%fst t1) (%fst t2)))))))
; this is basically just a giant template
(private deftuple-module-)
(hidden deftuple-module-)
(defndynamic deftuple-module- [name props]
(let [module-name (Symbol.concat [name 'Ref])]
`(do
(defmodule %module-name
(defn < [t1 t2] %(deftuple-lt- name props))
(implements < %(Symbol.prefix module-name '<))
(defn > [t1 t2] (%(Symbol.prefix module-name '<) t2 t1))
(implements > %(Symbol.prefix module-name '>)))
(doc %name %(str "is a tuple of length " (length props) "."))
(defmodule %name
(doc init-from-refs
%(str "initializes a `" name "` from member references."))
%(let [prop-vars (map (fn [x] (Symbol.concat [x '-val])) props)]
`(defn init-from-refs %(collect-into prop-vars array)
(init %@(map (fn [x] `(copy %x)) prop-vars))))
(defn < [t1 t2]
(%(Symbol.prefix module-name '<) &t1 &t2))
(implements < %(Symbol.prefix name '<))
(defn > [t1 t2]
(%(Symbol.prefix module-name '>) &t1 &t2))
(implements > %(Symbol.prefix name '>))
(doc reverse
%(str "reverses a `" name "` by reversing its member positions."))
(defn reverse [t]
(init %@(map (fn [x] `(copy (%x t))) (reverse props))))))))
(private deftuple-derive-zero-)
(hidden deftuple-derive-zero-)
(defndynamic deftuple-derive-zero- [name props]
(list 'defmodule name
(list 'defn 'zero (array)
(cons 'init (map (fn [_] '(zero)) props)))
(list 'implements 'zero (Symbol.prefix name 'zero))))
(private deftuple-derive-eq-)
(hidden deftuple-derive-eq-)
(defndynamic deftuple-derive-eq- [name props]
(list 'defmodule name
(list 'defn '= (array 'o1 'o2)
(reduce
(fn [acc p]
(list 'and (list '= (list p 'o1) (list p 'o2)) acc))
true
props))
(list 'implements '= (Symbol.prefix name '=))))
(doc deftuple "defines a tuple type.
For example:
```
; is the definition of Pair in the stdlib
(deftuple Pair a b)
```")
(defmacro deftuple [name :rest props]
(list 'do
(deftuple-type- name props)
(deftuple-derive-zero- name props)
(deftuple-derive-eq- name props)
(deftuple-module- name props)))
)
(doc Pair "is a 2-tuple, i.e. a datatype with two members.")
(deftuple Pair a b)
(doc Triple "is a 3-tuple, i.e. a datatype with three members.")
(deftuple Triple a b c)
(doc Quadruple "is a 4-tuple, i.e. a datatype with four members.")
(deftuple Quadruple a b c d)