@effekt-lang/effekt 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +6 -18
  2. package/bin/effekt +0 -0
  3. package/bin/effekt.sh +1 -1
  4. package/libraries/chez/common/effekt_primitives.ss +10 -2
  5. package/libraries/chez/common/immutable/cslist.effekt +13 -7
  6. package/libraries/chez/common/mutable/dict.effekt +8 -10
  7. package/libraries/chez/common/text/regex.effekt +7 -9
  8. package/libraries/common/args.effekt +68 -0
  9. package/libraries/common/array.effekt +220 -0
  10. package/libraries/common/bench.effekt +86 -0
  11. package/libraries/common/buffer.effekt +123 -0
  12. package/libraries/common/bytes.effekt +125 -0
  13. package/libraries/{js/immutable → common}/dequeue.effekt +18 -4
  14. package/libraries/common/effekt.effekt +725 -0
  15. package/libraries/common/exception.effekt +121 -0
  16. package/libraries/common/io/console.effekt +62 -0
  17. package/libraries/common/io/error.effekt +474 -0
  18. package/libraries/common/io/filesystem.effekt +274 -0
  19. package/libraries/common/io/network.effekt +81 -0
  20. package/libraries/common/io/time.effekt +12 -0
  21. package/libraries/common/io.effekt +88 -0
  22. package/libraries/{llvm/immutable → common}/list.effekt +101 -74
  23. package/libraries/common/option.effekt +72 -0
  24. package/libraries/common/process.effekt +9 -0
  25. package/libraries/common/queue.effekt +140 -0
  26. package/libraries/common/ref.effekt +60 -0
  27. package/libraries/common/result.effekt +45 -0
  28. package/libraries/{ml/immutable → common}/seq.effekt +30 -19
  29. package/libraries/common/string/tty.effekt +66 -0
  30. package/libraries/common/string.effekt +361 -0
  31. package/libraries/common/test.effekt +160 -0
  32. package/libraries/js/effekt_builtins.js +37 -6
  33. package/libraries/js/mutable/map.effekt +8 -9
  34. package/libraries/js/text/regex.effekt +7 -8
  35. package/libraries/js/unsafe/cont.effekt +2 -2
  36. package/libraries/js/web/dom.effekt +13 -13
  37. package/libraries/llvm/array.c +53 -0
  38. package/libraries/llvm/buffer.c +181 -76
  39. package/libraries/llvm/forward-declare-c.ll +27 -8
  40. package/libraries/llvm/io.c +423 -1
  41. package/libraries/llvm/main.c +6 -1
  42. package/libraries/llvm/ref.c +45 -0
  43. package/libraries/llvm/rts.ll +515 -354
  44. package/libraries/llvm/types.c +32 -0
  45. package/licenses/eclipse public license, version 2.0 - epl-2.0.html +4 -4
  46. package/licenses/mit license - mit-license.html +532 -62
  47. package/licenses/the bsd license - bsd-license.html +535 -60
  48. package/licenses/the mit license - mit.html +532 -62
  49. package/package.json +2 -2
  50. package/libraries/chez/callcc/effekt.effekt +0 -221
  51. package/libraries/chez/common/effekt_matching.ss +0 -100
  52. package/libraries/chez/common/immutable/dequeue.effekt +0 -78
  53. package/libraries/chez/common/immutable/list.effekt +0 -643
  54. package/libraries/chez/common/immutable/option.effekt +0 -39
  55. package/libraries/chez/common/immutable/result.effekt +0 -29
  56. package/libraries/chez/common/io/args.effekt +0 -20
  57. package/libraries/chez/common/mutable/array.effekt +0 -27
  58. package/libraries/chez/common/mutable/heap.effekt +0 -12
  59. package/libraries/chez/common/test.effekt +0 -59
  60. package/libraries/chez/common/text/string.effekt +0 -46
  61. package/libraries/chez/lift/effekt.effekt +0 -217
  62. package/libraries/chez/lift/effekt.ss +0 -118
  63. package/libraries/chez/monadic/effekt.effekt +0 -218
  64. package/libraries/js/effekt.effekt +0 -284
  65. package/libraries/js/effekt_matching.js +0 -79
  66. package/libraries/js/immutable/list.effekt +0 -643
  67. package/libraries/js/immutable/option.effekt +0 -49
  68. package/libraries/js/immutable/result.effekt +0 -29
  69. package/libraries/js/io/args.effekt +0 -9
  70. package/libraries/js/io/async.effekt +0 -28
  71. package/libraries/js/io/async.js +0 -2
  72. package/libraries/js/io/file.effekt +0 -50
  73. package/libraries/js/io/file_include.js +0 -13
  74. package/libraries/js/mutable/array.effekt +0 -98
  75. package/libraries/js/mutable/heap.effekt +0 -32
  76. package/libraries/js/test.effekt +0 -59
  77. package/libraries/js/text/string.effekt +0 -64
  78. package/libraries/llvm/effekt.effekt +0 -243
  79. package/libraries/llvm/immutable/option.effekt +0 -53
  80. package/libraries/llvm/immutable/result.effekt +0 -29
  81. package/libraries/llvm/io/args.effekt +0 -24
  82. package/libraries/llvm/text/string.effekt +0 -179
  83. package/libraries/ml/effekt.effekt +0 -267
  84. package/libraries/ml/effekt.sml +0 -63
  85. package/libraries/ml/immutable/dequeue.effekt +0 -81
  86. package/libraries/ml/immutable/list.effekt +0 -674
  87. package/libraries/ml/immutable/option.effekt +0 -53
  88. package/libraries/ml/immutable/result.effekt +0 -29
  89. package/libraries/ml/internal/option.effekt +0 -18
  90. package/libraries/ml/io/args.effekt +0 -41
  91. package/libraries/ml/mutable/array.effekt +0 -43
  92. package/libraries/ml/random.effekt +0 -85
  93. package/libraries/ml/test.effekt +0 -60
  94. package/libraries/ml/text/regex.effekt +0 -107
  95. package/libraries/ml/text/string.effekt +0 -81
@@ -1,218 +0,0 @@
1
- module effekt
2
-
3
- extern include "../common/effekt_primitives.ss"
4
- extern include "seq0.ss"
5
- extern include "effekt.ss"
6
- extern include "../common/effekt_matching.ss"
7
-
8
-
9
- def locally[R] { f: => R }: R = f()
10
-
11
- // String ops
12
- // ==========
13
- extern pure def infixConcat(s1: String, s2: String): String =
14
- "(string-append ${s1} ${s2})"
15
-
16
- // TODO implement
17
- extern pure def show[R](value: R): String =
18
- "(show_impl ${value})"
19
-
20
- extern io def println[R](r: R): Unit =
21
- "(println_impl ${r})"
22
-
23
- extern io def error[R](msg: String): R =
24
- "(raise ${msg})"
25
-
26
- extern io def random(): Double =
27
- "(random 1.0)"
28
-
29
- // Math ops
30
- // ========
31
- extern pure def infixAdd(x: Int, y: Int): Int =
32
- "(+ ${x} ${y})"
33
-
34
- extern pure def infixMul(x: Int, y: Int): Int =
35
- "(* ${x} ${y})"
36
-
37
- extern pure def infixDiv(x: Int, y: Int): Int =
38
- "(floor (/ ${x} ${y}))"
39
-
40
- extern pure def infixSub(x: Int, y: Int): Int =
41
- "(- ${x} ${y})"
42
-
43
- extern pure def mod(x: Int, y: Int): Int =
44
- "(modulo ${x} ${y})"
45
-
46
- extern pure def infixAdd(x: Double, y: Double): Double =
47
- "(+ ${x} ${y})"
48
-
49
- extern pure def infixMul(x: Double, y: Double): Double =
50
- "(* ${x} ${y})"
51
-
52
- extern pure def infixDiv(x: Double, y: Double): Double =
53
- "(/ ${x} ${y})"
54
-
55
- extern pure def infixSub(x: Double, y: Double): Double =
56
- "(- ${x} ${y})"
57
-
58
- extern pure def cos(x: Double): Double =
59
- "(cos ${x})"
60
-
61
- extern pure def sin(x: Double): Double =
62
- "(sin ${x})"
63
-
64
- extern pure def atan(x: Double): Double =
65
- "(atan ${x})"
66
-
67
- extern pure def tan(x: Double): Double =
68
- "(tan ${x})"
69
-
70
- extern pure def sqrt(x: Double): Double =
71
- "(sqrt ${x})"
72
-
73
- extern pure def square(x: Double): Double =
74
- "(* ${x} ${x})"
75
-
76
- extern pure def log(x: Double): Double =
77
- "(log ${x})"
78
-
79
- extern pure def log1p(x: Double): Double =
80
- "(log (+ ${x} 1))"
81
-
82
- extern pure def exp(x: Double): Double =
83
- "(exp ${x})"
84
-
85
- // since we do not have "extern val", yet
86
- extern pure def _pi(): Double =
87
- "(* 4 (atan 1))"
88
-
89
- val PI: Double = _pi()
90
-
91
- extern pure def toInt(d: Double): Int =
92
- "(round ${d})"
93
-
94
- extern pure def toDouble(d: Int): Double =
95
- "${d}"
96
-
97
- def min(n: Int, m: Int): Int =
98
- if (n < m) n else m
99
-
100
- def max(n: Int, m: Int): Int =
101
- if (n > m) n else m
102
-
103
- // Comparison ops
104
- // ==============
105
- extern pure def infixEq[R](x: R, y: R): Boolean =
106
- "(equal_impl ${x} ${y})"
107
-
108
- extern pure def infixNeq[R](x: R, y: R): Boolean =
109
- "(not (equal_impl ${x} ${y}))"
110
-
111
- extern pure def infixLt(x: Int, y: Int): Boolean =
112
- "(< ${x} ${y})"
113
-
114
- extern pure def infixLte(x: Int, y: Int): Boolean =
115
- "(<= ${x} ${y})"
116
-
117
- extern pure def infixGt(x: Int, y: Int): Boolean =
118
- "(> ${x} ${y})"
119
-
120
- extern pure def infixGte(x: Int, y: Int): Boolean =
121
- "(>= ${x} ${y})"
122
-
123
- extern pure def infixLt(x: Double, y: Double): Boolean =
124
- "(< ${x} ${y})"
125
-
126
- extern pure def infixLte(x: Double, y: Double): Boolean =
127
- "(<= ${x} ${y})"
128
-
129
- extern pure def infixGt(x: Double, y: Double): Boolean =
130
- "(> ${x} ${y})"
131
-
132
- extern pure def infixGte(x: Double, y: Double): Boolean =
133
- "(>= ${x} ${y})"
134
-
135
- // Boolean ops
136
- // ===========
137
- // for now those are considered eager
138
- extern pure def not(b: Boolean): Boolean =
139
- "(not ${b})"
140
-
141
- extern pure def infixOr(x: Boolean, y: Boolean): Boolean =
142
- "(or ${x} ${y})"
143
-
144
- extern pure def infixAnd(x: Boolean, y: Boolean): Boolean =
145
- "(and ${x} ${y})"
146
-
147
- // Should only be used internally since values in Effekt should not be undefined
148
- extern pure def isUndefined[A](value: A): Boolean =
149
- "(eq? ${value} #f)"
150
-
151
- // Pairs
152
- // =====
153
- record Tuple2[A, B](first: A, second: B)
154
- record Tuple3[A, B, C](first: A, second: B, third: C)
155
- record Tuple4[A, B, C, D](first: A, second: B, third: C, fourth: D)
156
- record Tuple5[A, B, C, D, E](first: A, second: B, third: C, fourth: D, fifth: E)
157
- record Tuple6[A, B, C, D, E, F](first: A, second: B, third: C, fourth: D, fifth: E, sixth: F)
158
-
159
- // Exceptions
160
- // ==========
161
- // a fatal runtime error that cannot be caught
162
- extern io def panic[R](msg: String): R =
163
- "(raise ${msg})"
164
-
165
- interface Exception[E] {
166
- def raise(exception: E, msg: String): Nothing
167
- }
168
- record RuntimeError()
169
-
170
- def raise[A](msg: String): A / Exception[RuntimeError] = do raise(RuntimeError(), msg) match {}
171
- def raise[A, E](exception: E, msg: String): A / Exception[E] = do raise(exception, msg) match {}
172
-
173
- // converts exceptions of (static) type E to an uncatchable panic that aborts the program
174
- def panicOn[E] { prog: => Unit / Exception[E] }: Unit =
175
- try { prog() } with Exception[E] { def raise(exception: E, msg: String) = panic(msg) }
176
-
177
- // reports exceptions of (static) type E to the console
178
- def report[E] { prog: => Unit / Exception[E] }: Unit =
179
- try { prog() } with Exception[E] { def raise(exception: E, msg: String) = println(msg) }
180
-
181
- // ignores exceptions of (static) type E
182
- // TODO this should be called "ignore" but that name currently clashes with internal pattern matching names on $effekt
183
- def ignoring[E] { prog: => Unit / Exception[E] }: Unit =
184
- try { prog() } with Exception[E] { def raise(exception: E, msg: String) = () }
185
-
186
- // Control Flow
187
- // ============
188
- interface Control {
189
- def break(): Unit
190
- def continue(): Unit
191
- }
192
-
193
- def loop { f: () => Unit / Control }: Unit = try {
194
- def go(): Unit = { f(); go() }
195
- go()
196
- } with Control {
197
- def break() = ()
198
- def continue() = loop { f }
199
- }
200
-
201
- /**
202
- * Calls provided action repeatedly. `start` is inclusive, `end` is not.
203
- */
204
- def each(start: Int, end: Int) { action: (Int) => Unit / Control } = {
205
- var i = start;
206
- loop {
207
- if (i < end) { val el = i; i = i + 1; action(el) }
208
- else { do break() }
209
- }
210
- }
211
-
212
- def repeat(n: Int) { action: () => Unit / Control } = each(0, n) { n => action() }
213
-
214
- // Benchmarking
215
- // ============
216
- // should only be used with pure blocks
217
- extern control def measure(warmup: Int, iterations: Int) { block: => Unit }: Unit =
218
- "(delayed (display (measure (lambda () (run (${box block}))) ${warmup} ${iterations})))"
@@ -1,284 +0,0 @@
1
- module effekt
2
-
3
- // Runtime
4
- // TODO split runtime into monadic and direct
5
- extern include "effekt_runtime.js"
6
-
7
- // Builtins
8
- extern include "effekt_builtins.js"
9
-
10
- def locally[R] { f: => R }: R = f()
11
-
12
- // Side effecting ops
13
- // ==================
14
- extern io def println[R](value: R): Unit =
15
- "println$impl(${value})"
16
-
17
- extern io def inspect[R](value: R): Unit =
18
- "console.log(${value})"
19
-
20
- extern io def random(): Double =
21
- "Math.random()"
22
-
23
- extern io def timestamp(): Int =
24
- "Date.now()"
25
-
26
- // References and state
27
- // ====================
28
- // the following type is defined in builtins.scala
29
- // interface Ref[T] { def get(): T; def put(t: T): Unit }
30
- extern io def freshIn[T](t: T) {r: Region}: Ref[T] at {r} = "r.fresh(${t})"
31
- extern io def freshGlobal[T](t: T): Ref[T] at {global} = "$effekt.fresh(${t})"
32
-
33
- // String ops
34
- // ==========
35
- extern pure def show[R](value: R): String =
36
- "show$impl(${value})"
37
-
38
- extern pure def infixConcat(s1: String, s2: String): String =
39
- "${s1} + ${s2}"
40
-
41
- // Math ops
42
- // ========
43
- extern pure def infixAdd(x: Int, y: Int): Int =
44
- "(${x} + ${y})"
45
-
46
- extern pure def infixMul(x: Int, y: Int): Int =
47
- "(${x} * ${y})"
48
-
49
- extern pure def infixDiv(x: Int, y: Int): Int =
50
- "Math.floor(${x} / ${y})"
51
-
52
- extern pure def infixSub(x: Int, y: Int): Int =
53
- "(${x} - ${y})"
54
-
55
- extern pure def mod(x: Int, y: Int): Int =
56
- "(${x} % ${y})"
57
-
58
- extern pure def infixAdd(x: Double, y: Double): Double =
59
- "(${x} + ${y})"
60
-
61
- extern pure def infixMul(x: Double, y: Double): Double =
62
- "(${x} * ${y})"
63
-
64
- extern pure def infixSub(x: Double, y: Double): Double =
65
- "(${x} - ${y})"
66
-
67
- extern pure def infixDiv(x: Double, y: Double): Double =
68
- "(${x} / ${y})"
69
-
70
-
71
- extern pure def cos(x: Double): Double =
72
- "Math.cos(${x})"
73
-
74
- extern pure def sin(x: Double): Double =
75
- "Math.sin(${x})"
76
-
77
- extern pure def atan(x: Double): Double =
78
- "Math.atan(${x})"
79
-
80
- extern pure def tan(x: Double): Double =
81
- "Math.tan(${x})"
82
-
83
- extern pure def sqrt(x: Double): Double =
84
- "Math.sqrt(${x})"
85
-
86
- extern pure def square(x: Double): Double =
87
- "(${x} * ${x})"
88
-
89
- extern pure def log(x: Double): Double =
90
- "Math.log(${x})"
91
-
92
- extern pure def log1p(x: Double): Double =
93
- "Math.log1p(${x})"
94
-
95
- extern pure def exp(x: Double): Double =
96
- "Math.exp(${x})"
97
-
98
- // since we do not have "extern val", yet
99
- extern pure def _pi(): Double =
100
- "Math.PI"
101
-
102
- val PI: Double = _pi()
103
-
104
- extern pure def toInt(d: Double): Int =
105
- "Math.round(${d})"
106
-
107
- extern pure def toDouble(d: Int): Double =
108
- "${d}"
109
-
110
- extern pure def floor(d: Double): Int =
111
- "Math.floor(${d})"
112
-
113
- extern pure def ceil(d: Double): Int =
114
- "Math.ceil(${d})"
115
-
116
- def min(n: Int, m: Int): Int =
117
- if (n < m) n else m
118
-
119
- def max(n: Int, m: Int): Int =
120
- if (n > m) n else m
121
-
122
- // Comparison ops
123
- // ==============
124
- extern pure def infixEq[R](x: R, y: R): Boolean =
125
- "equals$impl(${x}, ${y})"
126
-
127
- extern pure def infixNeq[R](x: R, y: R): Boolean =
128
- "!equals$impl(${x}, ${y})"
129
-
130
- extern pure def infixLt(x: Int, y: Int): Boolean =
131
- "(${x} < ${y})"
132
-
133
- extern pure def infixLte(x: Int, y: Int): Boolean =
134
- "(${x} <= ${y})"
135
-
136
- extern pure def infixGt(x: Int, y: Int): Boolean =
137
- "(${x} > ${y})"
138
-
139
- extern pure def infixGte(x: Int, y: Int): Boolean =
140
- "(${x} >= ${y})"
141
-
142
- extern pure def infixLt(x: Double, y: Double): Boolean =
143
- "(${x} < ${y})"
144
-
145
- extern pure def infixLte(x: Double, y: Double): Boolean =
146
- "(${x} <= ${y})"
147
-
148
- extern pure def infixGt(x: Double, y: Double): Boolean =
149
- "(${x} > ${y})"
150
-
151
- extern pure def infixGte(x: Double, y: Double): Boolean =
152
- "(${x} >= ${y})"
153
-
154
- extern pure def infixLt(x: String, y: String): Boolean =
155
- "(${x} < ${y})"
156
-
157
- extern pure def infixLte(x: String, y: String): Boolean =
158
- "(${x} <= ${y})"
159
-
160
- extern pure def infixGt(x: String, y: String): Boolean =
161
- "(${x} > ${y})"
162
-
163
- extern pure def infixGte(x: String, y: String): Boolean =
164
- "(${x} >= ${y})"
165
-
166
- // Boolean ops
167
- // ===========
168
- // for now those are considered eager
169
- extern pure def not(b: Boolean): Boolean =
170
- "!${b}"
171
-
172
- extern pure def infixOr(x: Boolean, y: Boolean): Boolean =
173
- "(${x} || ${y})"
174
-
175
- extern pure def infixAnd(x: Boolean, y: Boolean): Boolean =
176
- "(${x} && ${y})"
177
-
178
- // Undefined and Null
179
- // ==================
180
- // Should only be used for interop with JS, since values in Effekt should not be undefined
181
-
182
- // Is something an undefined JavaScript value?
183
- extern pure def isUndefined[A](value: A): Boolean =
184
- "(${value} === undefined)"
185
-
186
- // Is something a JavaScript null value?
187
- extern pure def isNull[A](value: A): Boolean =
188
- "(${value} === null)"
189
-
190
- // Pairs
191
- // =====
192
- record Tuple2[A, B](first: A, second: B)
193
- record Tuple3[A, B, C](first: A, second: B, third: C)
194
- record Tuple4[A, B, C, D](first: A, second: B, third: C, fourth: D)
195
- record Tuple5[A, B, C, D, E](first: A, second: B, third: C, fourth: D, fifth: E)
196
- record Tuple6[A, B, C, D, E, F](first: A, second: B, third: C, fourth: D, fifth: E, sixth: F)
197
-
198
-
199
- // Exceptions
200
- // ==========
201
- // a fatal runtime error that cannot be caught
202
- extern io def panic[R](msg: String): R =
203
- "(function() { throw ${msg} })()"
204
-
205
- interface Exception[E] {
206
- def raise(exception: E, msg: String): Nothing
207
- }
208
- record RuntimeError()
209
-
210
- def raise[A](msg: String): A / Exception[RuntimeError] = do raise(RuntimeError(), msg) match {}
211
- def raise[A, E](exception: E, msg: String): A / Exception[E] = do raise(exception, msg) match {}
212
-
213
- // converts exceptions of (static) type E to an uncatchable panic that aborts the program
214
- def panicOn[E] { prog: => Unit / Exception[E] }: Unit =
215
- try { prog() } with Exception[E] { def raise(exception: E, msg: String) = panic(msg) }
216
-
217
- // reports exceptions of (static) type E to the console
218
- def report[E] { prog: => Unit / Exception[E] }: Unit =
219
- try { prog() } with Exception[E] { def raise(exception: E, msg: String) = println(msg) }
220
-
221
- // ignores exceptions of (static) type E
222
- // TODO this should be called "ignore" but that name currently clashes with internal pattern matching names on $effekt
223
- def ignoring[E] { prog: => Unit / Exception[E] }: Unit =
224
- try { prog() } with Exception[E] { def raise(exception: E, msg: String) = () }
225
-
226
- // Control Flow
227
- // ============
228
- interface Control {
229
- def break(): Unit
230
- def continue(): Unit
231
- }
232
-
233
- def loop { f: () => Unit / Control }: Unit = try {
234
- def go(): Unit = { f(); go() }
235
- go()
236
- } with Control {
237
- def break() = ()
238
- def continue() = loop { f }
239
- }
240
-
241
- /**
242
- * Calls provided action repeatedly. `start` is inclusive, `end` is not.
243
- */
244
- def each(start: Int, end: Int) { action: (Int) => Unit / Control } = {
245
- var i = start;
246
- loop {
247
- if (i < end) { val el = i; i = i + 1; action(el) }
248
- else { do break() }
249
- }
250
- }
251
-
252
- def repeat(n: Int) { action: () => Unit / Control } = each(0, n) { n => action() }
253
-
254
-
255
- // Benchmarking
256
- // ============
257
-
258
- // Current time in nanoseconds
259
- // TODO use a better timer
260
- extern control def currentTimeNanos(): Int =
261
- "$effekt.delayed(() => new Date().getTime() * 1000000)"
262
-
263
- extern io def setTimeout(callback: () => Unit at {}, timeout: Int): Unit =
264
- "(function() { window.setTimeout(() => ${callback}().run(), ${timeout}); return $effekt.unit; })()"
265
-
266
- // runs the block and returns the time in nanoseconds
267
- def timed { block: => Unit }: Int = {
268
- val before = currentTimeNanos()
269
- block()
270
- val after = currentTimeNanos()
271
- after - before
272
- }
273
-
274
- def measure(warmup: Int, iterations: Int) { block: => Unit }: Unit = {
275
- def run(n: Int, report: Boolean): Unit = {
276
- if (n <= 0) { () } else {
277
- val time = timed { block() };
278
- if (report) { println(time) } else { () };
279
- run(n - 1, report)
280
- }
281
- }
282
- run(warmup, false)
283
- run(iterations, true)
284
- }
@@ -1,79 +0,0 @@
1
- // matchers: Any -> List[Any] | null
2
- const $matching = (function() {
3
-
4
- const any = x => [x]
5
-
6
- const ignore = x => []
7
-
8
- const bind = matcher => x => {
9
- const matched = matcher(x)
10
- if (matched == null) return null;
11
- return [x].concat(matched)
12
- }
13
-
14
- const literal = c => x => {
15
- if (equals$impl(c, x))
16
- return []
17
- else
18
- return null
19
- }
20
-
21
- function tagged(tag) {
22
- const matchers = arguments
23
- return x => {
24
- if (!x || !x.__tag || x.__tag !== tag) return null;
25
- var extracted = [];
26
- // we start at 1 since matchers are shifted by 1
27
- for (var i = 1; i < matchers.length; i++) {
28
- const matched = matchers[i](x.__data[i - 1]);
29
- if (matched === null) return null;
30
- Array.prototype.push.apply(extracted, matched)
31
- }
32
- return extracted;
33
- }
34
- }
35
-
36
- function match(x, alternatives) {
37
- for (var i in alternatives) {
38
- const alt = alternatives[i]
39
- const matched = alt.pattern(x)
40
- if (matched !== null) {
41
- return alt.exec.apply(null, matched)
42
- }
43
- }
44
- }
45
-
46
- return {
47
- any: any,
48
- ignore: ignore,
49
- tagged: tagged,
50
- bind: bind,
51
- literal: literal,
52
- match: match
53
- }
54
- })();
55
-
56
- Object.assign($effekt, $matching);
57
-
58
-
59
- // p0 = bind(tagged("Nil"))
60
- // p1 = bind(tagged("Cons", any, any))
61
- // p2 = tagged("Cons", any, bind(tagged("Cons", any, ignore)))
62
-
63
- // l0 = { tag: "Nil", data: [] }
64
- // l1 = { tag: "Cons", data: [1, l0] }
65
- // l2 = { tag: "Cons", data: [1, { tag: "Cons", data: [2, { tag: "Nil", data: [] }] }] }
66
-
67
- // console.log(p1(l0))
68
- // console.log(p1(l1))
69
- // console.log(p1(l2))
70
-
71
- // console.log(p2(l0))
72
- // console.log(p2(l1))
73
- // console.log(p2(l2))
74
-
75
- // match(l2, [
76
- // { pattern: p0, exec: () => console.log("It is Nil!") },
77
- // { pattern: p2, exec: (x, y) => console.log("It has at least two elements", x, y) },
78
- // { pattern: p1, exec: (x, rest) => console.log("It only has one element", x) }
79
- // ])