@effekt-lang/effekt 0.2.1 → 0.3.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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/bin/effekt +0 -0
  4. package/bin/effekt.sh +2 -0
  5. package/libraries/chez/THIRD-PARTY.txt +11 -0
  6. package/libraries/chez/callcc/datatype.ss +188 -0
  7. package/libraries/chez/callcc/effekt.ss +31 -0
  8. package/libraries/chez/callcc/seq.ss +44 -0
  9. package/libraries/chez/callcc/seq0.ss +69 -0
  10. package/libraries/chez/callcc/tail.ss +76 -0
  11. package/libraries/chez/callcc/tail0.ss +89 -0
  12. package/libraries/chez/common/effekt_primitives.ss +105 -0
  13. package/libraries/chez/common/immutable/cslist.effekt +37 -0
  14. package/libraries/chez/common/mutable/dict.effekt +28 -0
  15. package/libraries/chez/common/text/pregexp.scm +772 -0
  16. package/libraries/chez/common/text/regex.effekt +31 -0
  17. package/libraries/chez/lift/effekt.ss +118 -0
  18. package/libraries/chez/monadic/effekt.ss +84 -0
  19. package/libraries/chez/monadic/seq0.ss +76 -0
  20. package/libraries/common/args.effekt +95 -0
  21. package/libraries/common/array.effekt +225 -0
  22. package/libraries/common/bench.effekt +60 -0
  23. package/libraries/common/buffer.effekt +123 -0
  24. package/libraries/common/bytes.effekt +125 -0
  25. package/libraries/common/dequeue.effekt +92 -0
  26. package/libraries/common/effekt.effekt +764 -0
  27. package/libraries/common/exception.effekt +122 -0
  28. package/libraries/common/io/console.effekt +66 -0
  29. package/libraries/common/io/error.effekt +365 -0
  30. package/libraries/common/io/files.effekt +282 -0
  31. package/libraries/common/io/network.effekt +105 -0
  32. package/libraries/common/io/time.effekt +15 -0
  33. package/libraries/common/io.effekt +158 -0
  34. package/libraries/common/list.effekt +687 -0
  35. package/libraries/common/option.effekt +72 -0
  36. package/libraries/common/process.effekt +10 -0
  37. package/libraries/common/queue.effekt +140 -0
  38. package/libraries/common/ref.effekt +63 -0
  39. package/libraries/common/result.effekt +45 -0
  40. package/libraries/common/seq.effekt +914 -0
  41. package/libraries/common/string.effekt +395 -0
  42. package/libraries/common/test.effekt +98 -0
  43. package/libraries/js/effekt_builtins.js +57 -0
  44. package/libraries/js/effekt_runtime.js +385 -0
  45. package/libraries/js/io.js +143 -0
  46. package/libraries/js/mutable/map.effekt +31 -0
  47. package/libraries/js/text/regex.effekt +33 -0
  48. package/libraries/js/unsafe/cont.effekt +11 -0
  49. package/libraries/js/web/dom.effekt +45 -0
  50. package/libraries/llvm/array.c +53 -0
  51. package/libraries/llvm/buffer.c +286 -0
  52. package/libraries/llvm/forward-declare-c.ll +43 -0
  53. package/libraries/llvm/hole.c +11 -0
  54. package/libraries/llvm/io.c +566 -0
  55. package/libraries/llvm/io.ll +19 -0
  56. package/libraries/llvm/main.c +41 -0
  57. package/libraries/llvm/ref.c +45 -0
  58. package/libraries/llvm/rts.ll +761 -0
  59. package/libraries/llvm/sanity.c +16 -0
  60. package/libraries/llvm/types.c +43 -0
  61. package/libraries/ml/effekt.sml +65 -0
  62. package/libraries/ml/internal/mllist.effekt +9 -0
  63. package/libraries/ml/internal/mloption.effekt +18 -0
  64. package/libraries/ml/random.effekt +85 -0
  65. package/libraries/ml/text/regex.effekt +102 -0
  66. package/licenses/THIRD-PARTY.txt +21 -0
  67. package/licenses/apache-2.0 - license-2.0.txt +202 -0
  68. package/licenses/eclipse public license, version 2.0 - epl-2.0.html +61 -0
  69. package/licenses/kiama-license.txt +373 -0
  70. package/licenses/kiama-readme.txt +186 -0
  71. package/licenses/mit license - mit-license.html +1239 -0
  72. package/licenses/the apache software license, version 2.0 - license-2.0.txt +202 -0
  73. package/licenses/the bsd license - bsd-license.html +1237 -0
  74. package/licenses/the mit license - mit.html +1239 -0
  75. package/package.json +26 -18
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Jonathan Brachthäuser and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Ξ Effekt
2
+
3
+ Compared to other languages with effect handlers (and support for polymorphic effects) the Effekt language
4
+ aims to be significantly more lightweight in its concepts.
5
+
6
+
7
+ ## Disclaimer: Use at your own risk
8
+
9
+ **Effekt is a research-level language. We are actively working on it and the language (and everything else) is very likely to change.**
10
+
11
+ Also, Effekt comes with no warranty and there are (probably) many bugs -- If this does not discourage you, feel free to
12
+ play with it and give us your feedback :)
13
+
14
+ ## Installation
15
+
16
+ You need to have Java (>= 11) and Node (>= 12) and npm installed.
17
+
18
+ The recommended way of installing Effekt is by running:
19
+
20
+ ```
21
+ npm install -g https://github.com/effekt-lang/effekt/releases/latest/download/effekt.tgz
22
+ ```
23
+
24
+ Alternatively, you can download the `effekt.tgz` file from [another release](https://github.com/effekt-lang/effekt/releases) and then run
25
+
26
+ ```
27
+ npm install -g effekt.tgz
28
+ ```
29
+
30
+ This will make the `effekt` command globally available. You can start the Effekt REPL by entering:
31
+
32
+ ```
33
+ > effekt
34
+ ```
35
+
36
+ You can find more information about the Effekt language and how to use it on the website (<https://effekt-lang.org>).
package/bin/effekt ADDED
Binary file
package/bin/effekt.sh ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ java -jar "$(npm root -g)/@effekt-lang/effekt/bin/effekt" $@
@@ -0,0 +1,11 @@
1
+ The runtime of the callcc version builds on code by R. Kent Dybvig,
2
+ Simon L. Peyton Jones, and Amr Sabry, as presented in:
3
+
4
+ Dyvbig, R. K., Jones, S. P., & Sabry, A. (2007).
5
+ A monadic framework for delimited continuations.
6
+ Journal of Functional Programming, 17(6), 687-730.
7
+
8
+ The regular expression implementation is by Dorai Sitaram and
9
+ obtained from:
10
+
11
+ <https://github.com/ds26gte/pregexp/blob/master/pregexp.scm>
@@ -0,0 +1,188 @@
1
+ ;;; datatype.ss
2
+ ;;; Copyright (c) 2005, R. Kent Dybvig, Simon L. Peyton Jones, and Amr Sabry
3
+
4
+ ;;; Code for defining datatypes, based on record subtyping.
5
+
6
+ #|
7
+
8
+ Description
9
+ -----------
10
+
11
+ A define-datatype form creates a new datatype with zero or more variants,
12
+ each with its own set of fields. It produces definitions for a predicate,
13
+ constructors, and a case form.
14
+
15
+ Syntax:
16
+
17
+ <datatype definition> -> (define-datatype <datatype name> <variant>*)
18
+
19
+ <datatype name> -> identifier
20
+
21
+ <variant> -> (<variant name> <field name>*)
22
+ <variant name> -> identifier
23
+ <field name> -> identifier
24
+
25
+ Products:
26
+ The definition
27
+
28
+ (define-datatype dtname (vname vfield ...))
29
+
30
+ produces the following set of variable definitions:
31
+
32
+ dtname? a predicate true only of datatype instances
33
+ variant ... a set of constructors for the different variants
34
+ dtname-case a case construct for the datatype
35
+
36
+ Each constructor accepts one argument for each field of the variant.
37
+ The case construct has the following syntax:
38
+
39
+ (dtname-case <expression> <clause> ...)
40
+
41
+ where each <clause> is of the form:
42
+
43
+ [(<variant name> <field name>*) <expression>+]
44
+
45
+ except that the last must be an else clause of the form
46
+
47
+ [else <expression>+]
48
+
49
+ if any of the datatype's variants are not represented in the set of
50
+ clauses. The clauses may appear in any order and the field names
51
+ need not be the same as those given in the datatype definition.
52
+ (They are instead specified positionally.)
53
+
54
+ Example:
55
+
56
+ (case-sensitive #t)
57
+
58
+ (define-datatype AST
59
+ (Const datum)
60
+ (Ref var)
61
+ (If tst thn els)
62
+ (Fun fmls body)
63
+ (Call exp0 args))
64
+
65
+ (define (parse x)
66
+ (cond
67
+ [(symbol? x) (Ref x)]
68
+ [(pair? x)
69
+ (case (car x)
70
+ [(if) (If (parse (cadr x)) (parse (caddr x)) (parse (cadddr x)))]
71
+ [(fun) (Fun (cadr x) (parse (caddr x)))]
72
+ [else (Call (parse (car x)) (map parse (cdr x)))])]
73
+ [else (Const x)]))
74
+
75
+ (define (ev x r)
76
+ (AST-case x
77
+ [(Ref v) (cdr (assq v r))]
78
+ [(Const x) x]
79
+ [(If tst thn els) (ev (if (ev tst r) thn els) r)]
80
+ [(Fun fmls body)
81
+ (lambda args
82
+ (ev body (append (map cons fmls args) r)))]
83
+ [(Call proc actuals)
84
+ (apply (ev proc r) (map (lambda (x) (ev x r)) actuals))]))
85
+
86
+ (AST? (parse #'(fun (x) x)))
87
+
88
+ (define (run x) (ev (parse x) `((- . ,-) (* . ,*) (= . ,=))))
89
+
90
+ (run '((fun (f) (f f 10))
91
+ (fun (f x)
92
+ (if (= x 0)
93
+ 1
94
+ (* x (f f (- x 1))))))) ;=> 3628800
95
+
96
+ |#
97
+
98
+ (define-syntax define-datatype
99
+ (lambda (x)
100
+ (define construct-name
101
+ (lambda (template-identifier . args)
102
+ (datum->syntax-object
103
+ template-identifier
104
+ (string->symbol
105
+ (apply string-append
106
+ (map (lambda (x)
107
+ (if (string? x)
108
+ x
109
+ (symbol->string (syntax-object->datum x))))
110
+ args))))))
111
+ (define iota
112
+ (case-lambda
113
+ [(n) (iota 0 n)]
114
+ [(i n) (if (= n 0) '() (cons i (iota (+ i 1) (- n 1))))]))
115
+ (syntax-case x ()
116
+ [(_ dtname (vname field ...) ...)
117
+ (and (identifier? #'dtname) (andmap identifier? (syntax->list #'(vname ...))))
118
+ (with-syntax ([dtname? (construct-name #'dtname #'dtname "?")]
119
+ [dtname-case (construct-name #'dtname #'dtname "-case")]
120
+ [dtname-variant (construct-name #'dtname #'dtname "-variant")]
121
+ [((vname-field ...) ...)
122
+ (map (lambda (vname fields)
123
+ (map (lambda (field)
124
+ (construct-name #'dtname
125
+ vname "-" field))
126
+ fields))
127
+ (syntax->list #'(vname ...))
128
+ (map syntax->list (syntax->list #'((field ...) ...))))]
129
+ [(make-vname ...)
130
+ (map (lambda (x)
131
+ (construct-name #'dtname
132
+ "make-" x))
133
+ (syntax->list #'(vname ...)))]
134
+ [(i ...) (iota (length (syntax->list #'(vname ...))))])
135
+ #'(module (dtname? (dtname-case dtname-variant vname-field ... ...) vname ...)
136
+ (define-record dtname ((immutable variant)))
137
+ (module (make-vname vname-field ...)
138
+ (define-record vname dtname ((immutable field) ...) ()))
139
+ ...
140
+ (define-syntax dtname-case
141
+ (lambda (x)
142
+ (define make-clause
143
+ (lambda (x)
144
+ (syntax-case x (vname ...)
145
+ [(vname (field ...) e1 e2 (... ...))
146
+ #'((i) (let ([field (vname-field t)] ...)
147
+ e1 e2 (... ...)))]
148
+ ...)))
149
+ (syntax-case x (else)
150
+ [(__ e0
151
+ ((v fld (... ...)) e1 e2 (... ...))
152
+ (... ...)
153
+ (else e3 e4 (... ...)))
154
+ (with-syntax ([(clause (... ...))
155
+ (map make-clause
156
+ #'((v (fld (... ...)) e1 e2 (... ...))
157
+ (... ...)))])
158
+ #'(let ([t e0])
159
+ (case (dtname-variant t)
160
+ clause
161
+ (... ...)
162
+ (else e3 e4 (... ...)))))]
163
+ [(__ e0
164
+ ((v fld (... ...)) e1 e2 (... ...))
165
+ (... ...))
166
+ (let f ([ls1 (list #'vname ...)])
167
+ (or (null? ls1)
168
+ (and (let g ([ls2 (syntax->list #'(v (... ...)))])
169
+ (if (null? ls2)
170
+ (syntax-error x
171
+ (format "unhandled `~s' variant in"
172
+ (syntax-object->datum (car ls1))))
173
+ (or (literal-identifier=? (car ls1) (car ls2))
174
+ (g (cdr ls2)))))
175
+ (f (cdr ls1)))))
176
+ (with-syntax ([(clause (... ...))
177
+ (map make-clause
178
+ (syntax->list
179
+ #'((v (fld (... ...)) e1 e2 (... ...))
180
+ (... ...))))])
181
+ #'(let ([t e0])
182
+ (case (dtname-variant t)
183
+ clause
184
+ (... ...))))])))
185
+ (define vname
186
+ (lambda (field ...)
187
+ (make-vname i field ...)))
188
+ ...))])))
@@ -0,0 +1,31 @@
1
+
2
+ ; ;; EXAMPLE
3
+ ; ; (handle ([Fail_22 (Fail_109 () resume_120 (Nil_74))])
4
+ ; ; (let ((tmp86_121 ((Fail_109 Fail_22))))
5
+ ; ; (Cons_73 tmp86_121 (Nil_74))))
6
+ ; (define-syntax handle
7
+ ; (syntax-rules ()
8
+ ; [(_ ((cap1 (op1 (arg1 ...) k exp ...) ...) ...) body ...)
9
+ ; (let ([P (newPrompt)])
10
+ ; (pushPrompt P
11
+ ; (let ([cap1 (cap1 (define-effect-op P (arg1 ...) k exp ...) ...)] ...)
12
+ ; body ...)))]))
13
+
14
+ (define-syntax handle
15
+ (syntax-rules ()
16
+ [(_ ((cap1 (op1 (arg1 ...) k exp ...) ...) ...) body)
17
+ (let ([P (newPrompt)])
18
+ (pushPrompt P
19
+ (body (cap1 (define-effect-op P (arg1 ...) k exp ...) ...) ...)))]))
20
+
21
+ (define-syntax define-effect-op
22
+ (syntax-rules ()
23
+ [(_ P (arg1 ...) k exp ...)
24
+ (lambda (arg1 ...)
25
+ (shift0-at P k exp ...))]))
26
+
27
+ ; state(init) { cell => ... }
28
+ (define (state init body)
29
+ (with-region (lambda (arena) (body (fresh arena init)))))
30
+
31
+ (define call/cc/base call/cc)
@@ -0,0 +1,44 @@
1
+ ;;; seq.ss
2
+ ;;; Copyright (c) 2005, R. Kent Dybvig, Simon L. Peyton Jones, and Amr Sabry
3
+
4
+ ;;; sequence (Seq) datatype
5
+
6
+ (define-datatype Seq
7
+ (EmptyS)
8
+ (PushP p Seq)
9
+ ; Box -> BackupState -> Seq -> Seq
10
+ (PushState b s Seq)
11
+ (PushSeg k Seq))
12
+
13
+ (define (splitSeq p seq)
14
+ (Seq-case seq
15
+ [(EmptyS) (error 'splitSeq "prompt ~s not found on stack" p)]
16
+ [(PushP p* sk)
17
+ (if (not (eq? p p*))
18
+ (let-values ([(subk sk*) (splitSeq p sk)])
19
+ (values (PushP p* subk) sk*))
20
+ (values (EmptyS) sk))]
21
+ [(PushState b _ sk)
22
+ (let-values ([(subk sk*) (splitSeq p sk)])
23
+ (values (PushState b (unbox b) subk) sk*))]
24
+ [(PushSeg k sk)
25
+ (let-values ([(subk sk*) (splitSeq p sk)])
26
+ (values (PushSeg k subk) sk*))]))
27
+
28
+ (define (appendSeq seq_1 seq_2)
29
+ (Seq-case seq_1
30
+ [(EmptyS) seq_2]
31
+ [(PushP p subk) (PushP p (appendSeq subk seq_2))]
32
+ [(PushState b s subk)
33
+ (set-box! b s)
34
+ (PushState b #f (appendSeq subk seq_2))]
35
+ [(PushSeg k subk) (PushSeg k (appendSeq subk seq_2))]))
36
+
37
+ (define-syntax shift0-at
38
+ (syntax-rules ()
39
+ [(_ P id exp ...)
40
+ (withSubCont
41
+ P
42
+ (lambda (s)
43
+ (let ([id (lambda (v) (pushPrompt P (pushSubCont s v)))])
44
+ exp ...)))]))
@@ -0,0 +1,69 @@
1
+ ; [ [f1, f2, f3, f4| fields | prompt], [f1, f2, f3, f4| fields | prompt]... ]
2
+ (define-record Stack (
3
+ [immutable frames]
4
+ [immutable arena]
5
+ [immutable prompt]))
6
+
7
+ (define-record Substack (
8
+ [immutable frames]
9
+ [immutable arena]
10
+ [immutable field-backup]
11
+ [immutable prompt]))
12
+
13
+ ; MetaCont = (non-empty-list-of Stack)
14
+ ; SubCont = (non-empty-list-of Stack)
15
+
16
+
17
+ ; An Arena is a pointer to a list of cells
18
+ (define (make-arena) (box '()))
19
+
20
+ (define (fresh arena init)
21
+ (let* ([cell (box init)]
22
+ [cells (unbox arena)])
23
+ (set-box! arena (cons cell cells))
24
+ cell))
25
+
26
+ ; Backup = List<(Cell, Value)>
27
+
28
+ ; Arena -> Backup
29
+ (define (backup arena)
30
+ (let ([fields (unbox arena)])
31
+ (map (lambda (cell) (cons cell (unbox cell))) fields)))
32
+
33
+ ; Backup -> ()
34
+ (define (restore data)
35
+ (for-each (lambda (cell-data)
36
+ (set-box! (car cell-data) (cdr cell-data)))
37
+ data))
38
+
39
+ ; Prompt MetaCont -> SubCont, MetaCont
40
+ (define (splitSeq p seq)
41
+ (define (split sub s)
42
+ (if (null? s)
43
+ (error 'splitSeq "prompt ~s not found on stack" p)
44
+ (let* ([stack (car s)]
45
+ [frames (Stack-frames stack)]
46
+ [arena (Stack-arena stack)]
47
+ [prompt (Stack-prompt stack)]
48
+ [rest (cdr s)])
49
+ (define sub* (cons (make-Substack frames arena (backup arena) prompt) sub))
50
+ (if (not (eq? prompt p))
51
+ (split sub* rest)
52
+ (values sub* rest)))))
53
+ (split (list) seq))
54
+
55
+
56
+ (define (appendSeq subcont meta)
57
+ (if (null? subcont)
58
+ meta
59
+ (let* ([stack (car subcont)]
60
+ [frames (Substack-frames stack)]
61
+ [arena (Substack-arena stack)]
62
+ [fields (Substack-field-backup stack)]
63
+ [prompt (Substack-prompt stack)]
64
+ [_ (restore fields)]
65
+ [rest (cdr subcont)])
66
+ (appendSeq rest (cons (make-Stack frames arena prompt) meta)))))
67
+
68
+ ; (define ex (list (make-Stack '(1 2 3) (list (box 1)) 4) (make-Stack '(1 2 3) (list (box 2)) 3) (make-Stack '(1 2 3) (list (box 3)) 2) (make-Stack '(4 5 6) (list (box 4)) 1)))
69
+ ; (let-values ([(cont meta) (splitSeq 2 ex)]) (appendSeq cont meta))
@@ -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,105 @@
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
+ [(char? obj) (show-char obj)]
7
+ ; [(record? obj)
8
+ ; (let* ([rtd (record-rtd obj)]
9
+ ; [name (symbol->string (record-type-name rtd))])
10
+ ; ;; how can we show the fields?
11
+ ; (string-append name))]
12
+ [(list? obj) (map show_impl obj)]
13
+ [(record? obj) (show-record obj)]
14
+ [else (generic-show obj)]))
15
+
16
+ (define (generic-show obj)
17
+ (define out (open-output-string))
18
+ (write obj out)
19
+ (get-output-string out))
20
+
21
+ ; conform with the JS way of printing numbers
22
+ (define (show-number n)
23
+ (if (integer? n) (number->string (exact n)) (number->string n)))
24
+
25
+ (define (show-char c)
26
+ (string c))
27
+
28
+ ; here we use eval to find the show function defined with the record...
29
+ ; (define (show-record rec)
30
+ ; (let* ([rtd (record-rtd rec)]
31
+ ; [showName (string-append "show" (generic-show (record-type-name rtd)))]
32
+ ; [showFun (eval (string->symbol showName))])
33
+ ; (showFun rec)))
34
+
35
+ ; we needed to add a unique id to the types in order to prevent duplicate definitions
36
+ ; now for printing, we need to strip the unique id (starting with $) again.
37
+ (define (strip-type-name tpe)
38
+ (define out "")
39
+ (define found #f)
40
+ (for-each
41
+ (lambda (el)
42
+ (if (char=? el #\$) (set! found #t) #f)
43
+ (if found #f (set! out (string-append out (string el)))))
44
+ (string->list tpe))
45
+ out)
46
+
47
+ (define (show-record rec)
48
+ (let* ([rtd (record-rtd rec)]
49
+ [unique-tpe (generic-show (record-type-name rtd))]
50
+ [tpe (strip-type-name unique-tpe)]
51
+ [fields (record-type-field-names rtd)]
52
+ [n (vector-length fields)])
53
+ (define out (string-append tpe "("))
54
+ (do ([i 0 (+ i 1)])
55
+ ((= i n))
56
+ (set! out (string-append out (show_impl ((record-accessor rtd i) rec))))
57
+ (if (< i (- n 1)) (set! out (string-append out ", "))))
58
+ (set! out (string-append out ")"))
59
+ out))
60
+
61
+
62
+
63
+ (define (println_impl str)
64
+ (display str)
65
+ (newline))
66
+
67
+ (define (equal_impl obj1 obj2)
68
+ (equal? obj1 obj2))
69
+
70
+ (define-syntax thunk
71
+ (syntax-rules ()
72
+ [(_ e ...) (lambda () e ...)]))
73
+
74
+ ;; Benchmarking utils
75
+
76
+ ; time in milliseconds
77
+ (define (timed block)
78
+ (let ([before (current-time)])
79
+ (block)
80
+ (let ([after (current-time)])
81
+ (seconds (time-difference after before)))))
82
+
83
+ (define (seconds diff)
84
+ (+ (time-second diff) (/ (time-nanosecond diff) 1000000000.0)))
85
+
86
+ (define (timestamp)
87
+ (let ([t (current-time)])
88
+ (+ (* (time-second t) 1000000000) (time-nanosecond t))))
89
+
90
+ (define (measure block warmup iterations)
91
+ (define (run n)
92
+ (if (<= n 0)
93
+ '()
94
+ (begin
95
+ (collect)
96
+ (cons (timed block) (run (- n 1))))))
97
+ (begin
98
+ (run warmup)
99
+ (run iterations)))
100
+
101
+ (define (hole)
102
+ (raise
103
+ (condition
104
+ (make-error)
105
+ (make-message-condition "not implemented"))))