@effekt-lang/effekt 0.2.1 → 0.2.2
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.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/bin/effekt +0 -0
- package/bin/effekt.sh +2 -0
- package/libraries/chez/THIRD-PARTY.txt +11 -0
- package/libraries/chez/callcc/datatype.ss +188 -0
- package/libraries/chez/callcc/effekt.effekt +221 -0
- package/libraries/chez/callcc/effekt.ss +31 -0
- package/libraries/chez/callcc/seq.ss +44 -0
- package/libraries/chez/callcc/seq0.ss +69 -0
- package/libraries/chez/callcc/tail.ss +76 -0
- package/libraries/chez/callcc/tail0.ss +89 -0
- package/libraries/chez/common/effekt_matching.ss +100 -0
- package/libraries/chez/common/effekt_primitives.ss +97 -0
- package/libraries/chez/common/immutable/cslist.effekt +31 -0
- package/libraries/chez/common/immutable/dequeue.effekt +78 -0
- package/libraries/chez/common/immutable/list.effekt +643 -0
- package/libraries/chez/common/immutable/option.effekt +39 -0
- package/libraries/chez/common/immutable/result.effekt +29 -0
- package/libraries/chez/common/io/args.effekt +20 -0
- package/libraries/chez/common/mutable/array.effekt +27 -0
- package/libraries/chez/common/mutable/dict.effekt +30 -0
- package/libraries/chez/common/mutable/heap.effekt +12 -0
- package/libraries/chez/common/test.effekt +59 -0
- package/libraries/chez/common/text/pregexp.scm +772 -0
- package/libraries/chez/common/text/regex.effekt +33 -0
- package/libraries/chez/common/text/string.effekt +46 -0
- package/libraries/chez/lift/effekt.effekt +217 -0
- package/libraries/chez/lift/effekt.ss +118 -0
- package/libraries/chez/monadic/effekt.effekt +218 -0
- package/libraries/chez/monadic/effekt.ss +84 -0
- package/libraries/chez/monadic/seq0.ss +76 -0
- package/libraries/js/effekt.effekt +284 -0
- package/libraries/js/effekt_builtins.js +26 -0
- package/libraries/js/effekt_matching.js +79 -0
- package/libraries/js/effekt_runtime.js +385 -0
- package/libraries/js/immutable/dequeue.effekt +78 -0
- package/libraries/js/immutable/list.effekt +643 -0
- package/libraries/js/immutable/option.effekt +49 -0
- package/libraries/js/immutable/result.effekt +29 -0
- package/libraries/js/io/args.effekt +9 -0
- package/libraries/js/io/async.effekt +28 -0
- package/libraries/js/io/async.js +2 -0
- package/libraries/js/io/file.effekt +50 -0
- package/libraries/js/io/file_include.js +13 -0
- package/libraries/js/mutable/array.effekt +98 -0
- package/libraries/js/mutable/heap.effekt +32 -0
- package/libraries/js/mutable/map.effekt +32 -0
- package/libraries/js/test.effekt +59 -0
- package/libraries/js/text/regex.effekt +34 -0
- package/libraries/js/text/string.effekt +64 -0
- package/libraries/js/unsafe/cont.effekt +11 -0
- package/libraries/js/web/dom.effekt +45 -0
- package/libraries/llvm/buffer.c +181 -0
- package/libraries/llvm/effekt.effekt +243 -0
- package/libraries/llvm/forward-declare-c.ll +24 -0
- package/libraries/llvm/hole.c +11 -0
- package/libraries/llvm/immutable/list.effekt +678 -0
- package/libraries/llvm/immutable/option.effekt +53 -0
- package/libraries/llvm/immutable/result.effekt +29 -0
- package/libraries/llvm/io/args.effekt +24 -0
- package/libraries/llvm/io.c +24 -0
- package/libraries/llvm/main.c +39 -0
- package/libraries/llvm/rts.ll +619 -0
- package/libraries/llvm/sanity.c +16 -0
- package/libraries/llvm/text/string.effekt +179 -0
- package/libraries/llvm/types.c +20 -0
- package/libraries/ml/effekt.effekt +267 -0
- package/libraries/ml/effekt.sml +63 -0
- package/libraries/ml/immutable/dequeue.effekt +81 -0
- package/libraries/ml/immutable/list.effekt +674 -0
- package/libraries/ml/immutable/option.effekt +53 -0
- package/libraries/ml/immutable/result.effekt +29 -0
- package/libraries/ml/immutable/seq.effekt +903 -0
- package/libraries/ml/internal/option.effekt +18 -0
- package/libraries/ml/io/args.effekt +41 -0
- package/libraries/ml/mutable/array.effekt +43 -0
- package/libraries/ml/random.effekt +85 -0
- package/libraries/ml/test.effekt +60 -0
- package/libraries/ml/text/regex.effekt +107 -0
- package/libraries/ml/text/string.effekt +81 -0
- package/licenses/THIRD-PARTY.txt +21 -0
- package/licenses/apache-2.0 - license-2.0.txt +202 -0
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +61 -0
- package/licenses/kiama-license.txt +373 -0
- package/licenses/kiama-readme.txt +186 -0
- package/licenses/mit license - mit-license.html +769 -0
- package/licenses/the apache software license, version 2.0 - license-2.0.txt +202 -0
- package/licenses/the bsd license - bsd-license.html +762 -0
- package/licenses/the mit license - mit.html +769 -0
- package/package.json +26 -18
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
;;; tail.ss
|
|
2
|
+
;;; Copyright (c) 2005, R. Kent Dybvig, Simon L. Peyton Jones, and Amr Sabry
|
|
3
|
+
|
|
4
|
+
;;; Tail-recursive implementation of the operators
|
|
5
|
+
|
|
6
|
+
;(case-sensitive #t)
|
|
7
|
+
|
|
8
|
+
(define-syntax pushPrompt
|
|
9
|
+
(syntax-rules ()
|
|
10
|
+
[(_ p e1 e2 ...)
|
|
11
|
+
($pushPrompt p (lambda () e1 e2 ...))]))
|
|
12
|
+
|
|
13
|
+
(define-syntax pushSubCont
|
|
14
|
+
(syntax-rules ()
|
|
15
|
+
[(_ subk e1 e2 ...)
|
|
16
|
+
($pushSubCont subk (lambda () e1 e2 ...))]))
|
|
17
|
+
|
|
18
|
+
(define abort)
|
|
19
|
+
(define mk)
|
|
20
|
+
(define base-k)
|
|
21
|
+
|
|
22
|
+
(define (PushSeg/t k seq)
|
|
23
|
+
(if (eqv? k base-k)
|
|
24
|
+
seq
|
|
25
|
+
(PushSeg k seq)))
|
|
26
|
+
|
|
27
|
+
(define ($pushPrompt p th)
|
|
28
|
+
(call/cc (lambda (k)
|
|
29
|
+
(set! mk (PushP p (PushSeg/t k mk)))
|
|
30
|
+
(abort th))))
|
|
31
|
+
|
|
32
|
+
(define (state init th)
|
|
33
|
+
(define b (box init))
|
|
34
|
+
(set! mk (PushState b #f mk))
|
|
35
|
+
(th b))
|
|
36
|
+
|
|
37
|
+
(define (getter ref)
|
|
38
|
+
(lambda () (unbox ref)))
|
|
39
|
+
|
|
40
|
+
(define (setter ref)
|
|
41
|
+
(lambda (v) (set-box! ref v)))
|
|
42
|
+
|
|
43
|
+
(define (withSubCont p f)
|
|
44
|
+
(let-values ([(subk mk*) (splitSeq p mk)])
|
|
45
|
+
(set! mk mk*)
|
|
46
|
+
(call/cc (lambda (k)
|
|
47
|
+
(abort (lambda () (f (PushSeg/t k subk))))))))
|
|
48
|
+
|
|
49
|
+
(define ($pushSubCont subk th)
|
|
50
|
+
(call/cc (lambda (k)
|
|
51
|
+
(set! mk (appendSeq subk (PushSeg/t k mk)))
|
|
52
|
+
(abort th))))
|
|
53
|
+
|
|
54
|
+
(define newPrompt (lambda () (string #\p)))
|
|
55
|
+
|
|
56
|
+
(define (run th)
|
|
57
|
+
(set! mk (EmptyS))
|
|
58
|
+
(underflow
|
|
59
|
+
(call/cc/base
|
|
60
|
+
(lambda (k_1)
|
|
61
|
+
(set! base-k k_1)
|
|
62
|
+
((call/cc (lambda (k_2)
|
|
63
|
+
(set! abort k_2)
|
|
64
|
+
(abort th))))))))
|
|
65
|
+
|
|
66
|
+
(define (underflow v)
|
|
67
|
+
(Seq-case mk
|
|
68
|
+
[(EmptyS) v]
|
|
69
|
+
[(PushP _ mk*) (set! mk mk*) (underflow v)]
|
|
70
|
+
[(PushState b _ mk*) (set! mk mk*) (underflow v)]
|
|
71
|
+
[(PushSeg k mk*) (set! mk mk*) (k v)]))
|
|
72
|
+
|
|
73
|
+
(define (go)
|
|
74
|
+
(new-cafe
|
|
75
|
+
(lambda (x)
|
|
76
|
+
(run (lambda () (eval x))))))
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
;;; tail.ss
|
|
2
|
+
;;; Copyright (c) 2005, R. Kent Dybvig, Simon L. Peyton Jones, and Amr Sabry
|
|
3
|
+
|
|
4
|
+
;;; Tail-recursive implementation of the operators
|
|
5
|
+
|
|
6
|
+
;(case-sensitive #t)
|
|
7
|
+
|
|
8
|
+
(define-syntax pushPrompt
|
|
9
|
+
(syntax-rules ()
|
|
10
|
+
[(_ p e1 e2 ...)
|
|
11
|
+
($pushPrompt p (lambda () e1 e2 ...))]))
|
|
12
|
+
|
|
13
|
+
(define-syntax pushSubCont
|
|
14
|
+
(syntax-rules ()
|
|
15
|
+
[(_ subk e1 e2 ...)
|
|
16
|
+
($pushSubCont subk (lambda () e1 e2 ...))]))
|
|
17
|
+
|
|
18
|
+
(define abort)
|
|
19
|
+
(define mk)
|
|
20
|
+
(define base-k)
|
|
21
|
+
|
|
22
|
+
(define ($pushPrompt p th)
|
|
23
|
+
(call/cc (lambda (k)
|
|
24
|
+
(pushFrame k)
|
|
25
|
+
(set! mk (cons (make-Stack (list) (make-arena) p) mk))
|
|
26
|
+
(abort th))))
|
|
27
|
+
|
|
28
|
+
(define (with-region body)
|
|
29
|
+
(let* ([stack (car mk)]
|
|
30
|
+
[arena (Stack-arena stack)])
|
|
31
|
+
(body arena)))
|
|
32
|
+
|
|
33
|
+
(define (withSubCont p f)
|
|
34
|
+
(call/cc (lambda (k)
|
|
35
|
+
(pushFrame k)
|
|
36
|
+
(let-values ([(subk mk*) (splitSeq p mk)])
|
|
37
|
+
(set! mk mk*)
|
|
38
|
+
(abort (lambda () (f subk)))))))
|
|
39
|
+
|
|
40
|
+
(define (pushFrame f)
|
|
41
|
+
(if (eqv? f base-k) (values)
|
|
42
|
+
(if (null? mk) (error "ERROR! Cannot push on empty meta cont" #f)
|
|
43
|
+
(let* ([stack (car mk)]
|
|
44
|
+
[frames (Stack-frames stack)]
|
|
45
|
+
[arena (Stack-arena stack)]
|
|
46
|
+
[prompt (Stack-prompt stack)]
|
|
47
|
+
[rest (cdr mk)])
|
|
48
|
+
(set! mk (cons (make-Stack (cons f frames) arena prompt) rest))))))
|
|
49
|
+
|
|
50
|
+
(define ($pushSubCont subk th)
|
|
51
|
+
(call/cc (lambda (k)
|
|
52
|
+
(pushFrame k)
|
|
53
|
+
(set! mk (appendSeq subk mk))
|
|
54
|
+
(abort th))))
|
|
55
|
+
|
|
56
|
+
(define newPrompt (lambda () (string #\p)))
|
|
57
|
+
|
|
58
|
+
(define (run th)
|
|
59
|
+
(define global (make-Stack '() (make-arena) (newPrompt)))
|
|
60
|
+
(set! mk (list global))
|
|
61
|
+
(underflow
|
|
62
|
+
(call/cc
|
|
63
|
+
(lambda (k_1)
|
|
64
|
+
(set! base-k k_1)
|
|
65
|
+
((call/cc (lambda (k_2)
|
|
66
|
+
(set! abort k_2)
|
|
67
|
+
(abort th))))))))
|
|
68
|
+
|
|
69
|
+
(define (underflow v)
|
|
70
|
+
(if (null? mk) v
|
|
71
|
+
(let* ([stack (car mk)]
|
|
72
|
+
[frames (Stack-frames stack)]
|
|
73
|
+
[arena (Stack-arena stack)]
|
|
74
|
+
[prompt (Stack-prompt stack)]
|
|
75
|
+
[rest (cdr mk)])
|
|
76
|
+
(if (null? frames) (begin (set! mk rest) (underflow v))
|
|
77
|
+
(begin
|
|
78
|
+
(set! mk (cons (make-Stack (cdr frames) arena prompt) rest))
|
|
79
|
+
((car frames) v))))))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
(define-syntax shift0-at
|
|
83
|
+
(syntax-rules ()
|
|
84
|
+
[(_ P id exp ...)
|
|
85
|
+
(withSubCont
|
|
86
|
+
P
|
|
87
|
+
(lambda (s)
|
|
88
|
+
(let ([id (lambda (v) (pushSubCont s v))])
|
|
89
|
+
exp ...)))]))
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
; Matcher = (SCRUTINEE, ANS -> () -> R, () -> R, (ANS -> () -> R) -> R) -> R
|
|
2
|
+
|
|
3
|
+
(define done (lambda (matched) (matched)))
|
|
4
|
+
|
|
5
|
+
(define (any m matched failed k)
|
|
6
|
+
(k (matched m)))
|
|
7
|
+
|
|
8
|
+
(define (ignore m matched failed k)
|
|
9
|
+
(k matched))
|
|
10
|
+
|
|
11
|
+
(define (literal l)
|
|
12
|
+
(lambda (m matched failed k)
|
|
13
|
+
(if (equal_impl m l)
|
|
14
|
+
(k matched)
|
|
15
|
+
(failed))))
|
|
16
|
+
|
|
17
|
+
(define (bind p)
|
|
18
|
+
(lambda (m matched failed k)
|
|
19
|
+
(p m (matched m) failed k)))
|
|
20
|
+
|
|
21
|
+
;; for this record
|
|
22
|
+
; (define-record Pair (fst snd))
|
|
23
|
+
|
|
24
|
+
;; this is what we need to generate
|
|
25
|
+
; (define (match-Pair p1 p2)
|
|
26
|
+
; (lambda (m matched failed k)
|
|
27
|
+
; (if (Pair? m)
|
|
28
|
+
; (p1 (Pair-fst m) matched failed (lambda (matched)
|
|
29
|
+
; (p2 (Pair-snd m) matched failed k)))
|
|
30
|
+
; (failed))))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
(define-syntax define-matcher
|
|
34
|
+
(syntax-rules ()
|
|
35
|
+
[(_ name pred ())
|
|
36
|
+
(define (name)
|
|
37
|
+
(lambda (sc matched failed k)
|
|
38
|
+
(if (pred sc) (k matched) (failed))))]
|
|
39
|
+
[(_ name pred ((p1 sel1) (p2 sel2) ...))
|
|
40
|
+
(define (name p1 p2 ...)
|
|
41
|
+
(lambda (m matched failed k)
|
|
42
|
+
;; has correct tag?
|
|
43
|
+
(if (pred m)
|
|
44
|
+
(match-fields m matched failed k ([p1 sel1] [p2 sel2] ...))
|
|
45
|
+
(failed))))]))
|
|
46
|
+
|
|
47
|
+
(define-syntax match-fields
|
|
48
|
+
(syntax-rules ()
|
|
49
|
+
[(_ m matched failed k ()) (k matched)]
|
|
50
|
+
[(_ m matched failed k ([p1 sel1] [p2 sel2] ...))
|
|
51
|
+
(p1 (sel1 m) matched failed (lambda (matched)
|
|
52
|
+
(match-fields m matched failed k ([p2 sel2] ...))))]))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
; forces the pattern match
|
|
56
|
+
(define-syntax pattern-match
|
|
57
|
+
(syntax-rules ()
|
|
58
|
+
[(_ m ()) (raise "no patterns provided")]
|
|
59
|
+
[(_ m ([p1 k1] [p2 k2]...))
|
|
60
|
+
(p1 m k1 (lambda () (pattern-match m ([p2 k2] ...))) done)]))
|
|
61
|
+
|
|
62
|
+
;; Examples
|
|
63
|
+
|
|
64
|
+
; (define-matcher match-Pair2 Pair? ([p1 Pair-fst] [p2 Pair-snd]))
|
|
65
|
+
|
|
66
|
+
; (define (match sc p matched)
|
|
67
|
+
; (p sc matched abort done))
|
|
68
|
+
|
|
69
|
+
; (display (match (make-Pair 1 2)
|
|
70
|
+
; (match-Pair2 any any)
|
|
71
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
72
|
+
|
|
73
|
+
; (display (match 3
|
|
74
|
+
; (match-Pair2 any any)
|
|
75
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
76
|
+
|
|
77
|
+
; (display (match (make-Pair 1 2)
|
|
78
|
+
; (match-Pair2 any (match-Pair2 ignore any))
|
|
79
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
80
|
+
|
|
81
|
+
; (display (match (make-Pair 1 (make-Pair 2 3))
|
|
82
|
+
; (match-Pair2 any (match-Pair2 ignore any))
|
|
83
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
84
|
+
|
|
85
|
+
; (display (match (make-Pair (make-Pair 1 2) (make-Pair 3 4))
|
|
86
|
+
; (match-Pair (match-Pair ignore any) (match-Pair ignore any))
|
|
87
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
88
|
+
|
|
89
|
+
; (display (match (make-Pair (make-Pair 1 2) (make-Pair 10 15))
|
|
90
|
+
; (match-Pair2 (match-Pair2 any ignore) (match-Pair2 ignore any))
|
|
91
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
92
|
+
|
|
93
|
+
; (display (match (make-Pair (make-Pair 1 2) (make-Pair 10 15))
|
|
94
|
+
; (match-Pair2 (match-Pair2 any ignore) (match-Pair2 ignore any))
|
|
95
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))))
|
|
96
|
+
|
|
97
|
+
; (display (pattern-match (make-Pair 1 2)
|
|
98
|
+
; ([(match-Pair2 (match-Pair2 any ignore) (match-Pair2 ignore any))
|
|
99
|
+
; (lambda (x) (lambda (y) (lambda () (+ x y))))]
|
|
100
|
+
; [any (lambda (x) (lambda () (Pair-snd x)))])))
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
(define (show_impl obj)
|
|
2
|
+
(cond
|
|
3
|
+
[(number? obj) (show-number obj)]
|
|
4
|
+
[(string? obj) obj]
|
|
5
|
+
[(boolean? obj) (if obj "true" "false")]
|
|
6
|
+
; [(record? obj)
|
|
7
|
+
; (let* ([rtd (record-rtd obj)]
|
|
8
|
+
; [name (symbol->string (record-type-name rtd))])
|
|
9
|
+
; ;; how can we show the fields?
|
|
10
|
+
; (string-append name))]
|
|
11
|
+
[(list? obj) (map show_impl obj)]
|
|
12
|
+
[(record? obj) (show-record obj)]
|
|
13
|
+
[else (generic-show obj)]))
|
|
14
|
+
|
|
15
|
+
(define (generic-show obj)
|
|
16
|
+
(define out (open-output-string))
|
|
17
|
+
(write obj out)
|
|
18
|
+
(get-output-string out))
|
|
19
|
+
|
|
20
|
+
; conform with the JS way of printing numbers
|
|
21
|
+
(define (show-number n)
|
|
22
|
+
(if (integer? n) (number->string (exact n)) (number->string n)))
|
|
23
|
+
|
|
24
|
+
; here we use eval to find the show function defined with the record...
|
|
25
|
+
; (define (show-record rec)
|
|
26
|
+
; (let* ([rtd (record-rtd rec)]
|
|
27
|
+
; [showName (string-append "show" (generic-show (record-type-name rtd)))]
|
|
28
|
+
; [showFun (eval (string->symbol showName))])
|
|
29
|
+
; (showFun rec)))
|
|
30
|
+
|
|
31
|
+
; we needed to add a unique id to the types in order to prevent duplicate definitions
|
|
32
|
+
; now for printing, we need to strip the unique id (starting with $) again.
|
|
33
|
+
(define (strip-type-name tpe)
|
|
34
|
+
(define out "")
|
|
35
|
+
(define found #f)
|
|
36
|
+
(for-each
|
|
37
|
+
(lambda (el)
|
|
38
|
+
(if (char=? el #\$) (set! found #t) #f)
|
|
39
|
+
(if found #f (set! out (string-append out (string el)))))
|
|
40
|
+
(string->list tpe))
|
|
41
|
+
out)
|
|
42
|
+
|
|
43
|
+
(define (show-record rec)
|
|
44
|
+
(let* ([rtd (record-rtd rec)]
|
|
45
|
+
[unique-tpe (generic-show (record-type-name rtd))]
|
|
46
|
+
[tpe (strip-type-name unique-tpe)]
|
|
47
|
+
[fields (record-type-field-names rtd)]
|
|
48
|
+
[n (vector-length fields)])
|
|
49
|
+
(define out (string-append tpe "("))
|
|
50
|
+
(do ([i 0 (+ i 1)])
|
|
51
|
+
((= i n))
|
|
52
|
+
(set! out (string-append out (show_impl ((record-accessor rtd i) rec))))
|
|
53
|
+
(if (< i (- n 1)) (set! out (string-append out ", "))))
|
|
54
|
+
(set! out (string-append out ")"))
|
|
55
|
+
out))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
(define (println_impl obj)
|
|
60
|
+
(display (show_impl obj))
|
|
61
|
+
(newline))
|
|
62
|
+
|
|
63
|
+
(define (equal_impl obj1 obj2)
|
|
64
|
+
(equal? obj1 obj2))
|
|
65
|
+
|
|
66
|
+
(define-syntax thunk
|
|
67
|
+
(syntax-rules ()
|
|
68
|
+
[(_ e ...) (lambda () e ...)]))
|
|
69
|
+
|
|
70
|
+
;; Benchmarking utils
|
|
71
|
+
|
|
72
|
+
; time in milliseconds
|
|
73
|
+
(define (timed block)
|
|
74
|
+
(let ([before (current-time)])
|
|
75
|
+
(block)
|
|
76
|
+
(let ([after (current-time)])
|
|
77
|
+
(seconds (time-difference after before)))))
|
|
78
|
+
|
|
79
|
+
(define (seconds diff)
|
|
80
|
+
(+ (time-second diff) (/ (time-nanosecond diff) 1000000000.0)))
|
|
81
|
+
|
|
82
|
+
(define (measure block warmup iterations)
|
|
83
|
+
(define (run n)
|
|
84
|
+
(if (<= n 0)
|
|
85
|
+
'()
|
|
86
|
+
(begin
|
|
87
|
+
(collect)
|
|
88
|
+
(cons (timed block) (run (- n 1))))))
|
|
89
|
+
(begin
|
|
90
|
+
(run warmup)
|
|
91
|
+
(run iterations)))
|
|
92
|
+
|
|
93
|
+
(define (hole)
|
|
94
|
+
(raise
|
|
95
|
+
(condition
|
|
96
|
+
(make-error)
|
|
97
|
+
(make-message-condition "not implemented"))))
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module immutable/cslist
|
|
2
|
+
|
|
3
|
+
import immutable/list
|
|
4
|
+
|
|
5
|
+
// a chez scheme cons list
|
|
6
|
+
extern type CSList[A]
|
|
7
|
+
extern pure def cons[A](el: A, rest: CSList[A]): CSList[A] =
|
|
8
|
+
"(cons ${el} ${rest})"
|
|
9
|
+
|
|
10
|
+
extern pure def nil[A](): CSList[A] =
|
|
11
|
+
"(list)"
|
|
12
|
+
|
|
13
|
+
extern pure def isEmpty[A](l: CSList[A]): Boolean =
|
|
14
|
+
"(null? ${l})"
|
|
15
|
+
|
|
16
|
+
// unsafe!
|
|
17
|
+
extern pure def head[A](l: CSList[A]): A =
|
|
18
|
+
"(car ${l})"
|
|
19
|
+
|
|
20
|
+
// unsafe!
|
|
21
|
+
extern pure def tail[A](l: CSList[A]): CSList[A] =
|
|
22
|
+
"(cdr ${l})"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def toChez[A](l: List[A]): CSList[A] = l match {
|
|
26
|
+
case Nil() => nil()
|
|
27
|
+
case Cons(a, rest) => cons(a, rest.toChez)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def fromChez[A](l: CSList[A]): List[A] =
|
|
31
|
+
if (l.isEmpty) Nil() else Cons(l.head, l.tail.fromChez)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module immutable/dequeue
|
|
2
|
+
|
|
3
|
+
import immutable/list
|
|
4
|
+
import immutable/option
|
|
5
|
+
|
|
6
|
+
// An implementation of a functional dequeue, using Okasaki's
|
|
7
|
+
// bankers dequeue implementation.
|
|
8
|
+
//
|
|
9
|
+
// Translation from the Haskell implementation:
|
|
10
|
+
// https://hackage.haskell.org/package/dequeue-0.1.12/docs/src/Data-Dequeue.html#Dequeue
|
|
11
|
+
record Dequeue[R](front: List[R], frontSize: Int, rear: List[R], rearSize: Int)
|
|
12
|
+
|
|
13
|
+
def emptyQueue[R](): Dequeue[R] = Dequeue(Nil(), 0, Nil(), 0)
|
|
14
|
+
|
|
15
|
+
def isEmpty[R](dq: Dequeue[R]): Boolean = dq match {
|
|
16
|
+
case Dequeue(f, fs, r, rs) => (fs == 0) && (rs == 0)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def size[R](dq: Dequeue[R]): Int = dq match {
|
|
20
|
+
case Dequeue(f, fs, r, rs) => fs + rs
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def first[R](dq: Dequeue[R]): Option[R] = dq match {
|
|
24
|
+
case Dequeue(f, fs, r, rs) =>
|
|
25
|
+
if ((fs == 0) && (rs == 1)) { r.headOption }
|
|
26
|
+
else { f.headOption }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def last[R](dq: Dequeue[R]): Option[R] = dq match {
|
|
30
|
+
case Dequeue(f, fs, r, rs) =>
|
|
31
|
+
if ((fs == 1) && (rs == 0)) { f.headOption }
|
|
32
|
+
else { r.headOption }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
def check[R](dq: Dequeue[R]): Dequeue[R] = dq match {
|
|
36
|
+
case Dequeue(f, fs, r, rs) =>
|
|
37
|
+
val c = 4;
|
|
38
|
+
val size1 = (fs + rs) / 2;
|
|
39
|
+
val size2 = (fs + rs) - size1;
|
|
40
|
+
|
|
41
|
+
if (fs > c * rs + 1) {
|
|
42
|
+
val front = f.take(size1);
|
|
43
|
+
val rear = r.append(f.drop(size1).reverse);
|
|
44
|
+
Dequeue(front, size1, rear, size2)
|
|
45
|
+
} else if (rs > c * fs + 1) {
|
|
46
|
+
val front = f.append(r.drop(size1).reverse);
|
|
47
|
+
val rear = r.take(size1);
|
|
48
|
+
Dequeue(front, size2, rear, size1)
|
|
49
|
+
} else {
|
|
50
|
+
dq
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
def pushFront[R](dq: Dequeue[R], el: R): Dequeue[R] = dq match {
|
|
55
|
+
case Dequeue(f, fs, r, rs) => Dequeue(Cons(el, f), fs + 1, r, rs).check
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
def popFront[R](dq: Dequeue[R]): Option[(R, Dequeue[R])] = dq match {
|
|
59
|
+
case Dequeue(Nil(), fs, Cons(x, Nil()), rs) =>
|
|
60
|
+
Some((x, emptyQueue()))
|
|
61
|
+
case Dequeue(Nil(), fs, r, rs) =>
|
|
62
|
+
None()
|
|
63
|
+
case Dequeue(Cons(x, rest), fs, r, rs) =>
|
|
64
|
+
Some((x, Dequeue(rest, fs - 1, r, rs).check))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
def pushBack[R](dq: Dequeue[R], el: R): Dequeue[R] = dq match {
|
|
68
|
+
case Dequeue(f, fs, r, rs) => Dequeue(f, fs, Cons(el, r), rs + 1).check
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
def popBack[R](dq: Dequeue[R]): Option[(R, Dequeue[R])] = dq match {
|
|
72
|
+
case Dequeue(Cons(x, Nil()), fs, Nil(), rs) =>
|
|
73
|
+
Some((x, emptyQueue()))
|
|
74
|
+
case Dequeue(f, fs, Nil(), rs) =>
|
|
75
|
+
None()
|
|
76
|
+
case Dequeue(f, fs, Cons(x, rest), rs) =>
|
|
77
|
+
Some((x, Dequeue(f, fs, rest, rs - 1).check))
|
|
78
|
+
}
|