substrate-lang 0.9.3 → 0.9.4

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 (136) hide show
  1. package/build/compiler/binary.cdd2ffb408dd@0+0.wasm +0 -0
  2. package/build/compiler/checker.2b0ea87ed311@0+0.wasm +0 -0
  3. package/build/compiler/compile.da85f9bc4478@0+0.wasm +0 -0
  4. package/build/compiler/{core.fc3dab9d1846@0+0.wasm → core.0410ffbdc488@0+0.wasm} +0 -0
  5. package/build/compiler/expander.80707e1666d6@0+0.wasm +0 -0
  6. package/build/compiler/{fs.563034be70c3@0+0.wasm → fs.5017b627cbd2@0+0.wasm} +0 -0
  7. package/build/compiler/{leb128.748b1c37277a@0+0.wasm → leb128.ba77430f659f@0+0.wasm} +0 -0
  8. package/build/compiler/{link.11b643d35670@0+0.wasm → link.be6e641afa93@0+0.wasm} +0 -0
  9. package/build/compiler/{macros.4083601c00db@0+0.wasm → macros.b695763c0ca3@0+0.wasm} +0 -0
  10. package/build/compiler/{main.ed62cce43000@0+0.wasm → main.cbbdf42e34c2@0+0.wasm} +0 -0
  11. package/build/compiler/{ops.b361e858d8e1@0+0.wasm → ops.324f0a665fab@0+0.wasm} +0 -0
  12. package/build/compiler/{path.dcc4712bcc7b@0+0.wasm → path.1b5fd988b6f3@0+0.wasm} +0 -0
  13. package/build/compiler/program +21 -21
  14. package/build/compiler/prune.29dde307bdee@0+0.wasm +0 -0
  15. package/build/compiler/{reader.b535e61f99f4@0+0.wasm → reader.d256e69e09e2@0+0.wasm} +0 -0
  16. package/build/compiler/{roots.6d2942578055@0+0.wasm → roots.e366210c01d6@0+0.wasm} +0 -0
  17. package/build/compiler/{running.d73f7826cb74@0+0.wasm → running.b99787c2d180@0+0.wasm} +0 -0
  18. package/build/compiler/serialize.a12536bbbe9a@0+0.wasm +0 -0
  19. package/build/compiler/{sha256.5fc9d60f8bb2@0+0.wasm → sha256.f6c742932dde@0+0.wasm} +0 -0
  20. package/build/compiler/{substrate.4c780d6dd6d4@0+0.wasm → substrate.728c690187f2@0+0.wasm} +0 -0
  21. package/build/compiler/syntax.fadc832db29f@0+0.wasm +0 -0
  22. package/build/compiler/{writer.806bc85aa684@0+0.wasm → writer.550227768eb9@0+0.wasm} +0 -0
  23. package/build/sub/{base64.8fba03e1be0a@0+0.wasm → base64.454b045156d2@0+0.wasm} +0 -0
  24. package/build/sub/build.115aeefc15e8@0+0.wasm +0 -0
  25. package/build/sub/{chromium.e4db7d29897c@0+0.wasm → chromium.fc0bfea0fbe6@0+0.wasm} +0 -0
  26. package/build/sub/{common.91ddee6b7a67@0+0.wasm → common.997c21b0b8cf@0+0.wasm} +0 -0
  27. package/build/sub/deflate.3138a38325a1@0+0.wasm +0 -0
  28. package/build/sub/{doc.0b48bbac404b@0+0.wasm → doc.e3f9a998cd91@0+0.wasm} +0 -0
  29. package/build/sub/{doc.566f9861828e@0+0.wasm → doc.f18ad14060e9@0+0.wasm} +0 -0
  30. package/build/sub/env.861d55fff974@0+0.wasm +0 -0
  31. package/build/sub/events.2c981f6f1ec7@0+0.wasm +0 -0
  32. package/build/sub/{fetch.5d2f427c995e@0+0.wasm → fetch.b0ce8f8b3da8@0+0.wasm} +0 -0
  33. package/build/sub/fetch.d62aa5fc9623@0+0.wasm +0 -0
  34. package/build/sub/{files.30e55182c5df@0+0.wasm → files.1706cc0941c0@0+0.wasm} +0 -0
  35. package/build/sub/{fs.563034be70c3@0+0.wasm → fs.5017b627cbd2@0+0.wasm} +0 -0
  36. package/build/sub/{git.48aefa1644be@0+0.wasm → git.1c5791236e35@0+0.wasm} +0 -0
  37. package/build/sub/{grants.5bf25700d47c@0+0.wasm → grants.cd99dff2854e@0+0.wasm} +0 -0
  38. package/build/sub/{gzip.69588e97c35a@0+0.wasm → gzip.9ebea150f218@0+0.wasm} +0 -0
  39. package/build/sub/hash.ba8330dad9ff@0+0.wasm +0 -0
  40. package/build/sub/{html.20baa1dc7ca6@0+0.wasm → html.0b0362932a75@0+0.wasm} +0 -0
  41. package/build/sub/{html.c1671a102b4d@0+0.wasm → html.3b3c8d7d9971@0+0.wasm} +0 -0
  42. package/build/sub/{inflate.8899e0933792@0+0.wasm → inflate.3cfa17586072@0+0.wasm} +0 -0
  43. package/build/sub/{json.f15a29d99d8d@0+0.wasm → json.af2e0ae20084@0+0.wasm} +0 -0
  44. package/build/sub/manifest.6e014ac19e5d@0+0.wasm +0 -0
  45. package/build/sub/map.e582eae03ec2@0+0.wasm +0 -0
  46. package/build/sub/{pack.55992e8cc09c@0+0.wasm → pack.4295e4f5bdbd@0+0.wasm} +0 -0
  47. package/build/sub/{path.dcc4712bcc7b@0+0.wasm → path.1b5fd988b6f3@0+0.wasm} +0 -0
  48. package/build/sub/path.de22f6659534@0+0.wasm +0 -0
  49. package/build/sub/process.ca10ac0b8a62@0+0.wasm +0 -0
  50. package/build/sub/program +48 -48
  51. package/build/sub/read.279fafcda508@0+0.wasm +0 -0
  52. package/build/sub/{reader.b535e61f99f4@0+0.wasm → reader.d256e69e09e2@0+0.wasm} +0 -0
  53. package/build/sub/{root.9b713ec588c1@0+0.wasm → root.02141d04d568@0+0.wasm} +0 -0
  54. package/build/sub/{roots.6d2942578055@0+0.wasm → roots.e366210c01d6@0+0.wasm} +0 -0
  55. package/build/sub/{sha256.5fc9d60f8bb2@0+0.wasm → sha256.f6c742932dde@0+0.wasm} +0 -0
  56. package/build/sub/{sha512.b988b9dc6114@0+0.wasm → sha512.9fee24e95460@0+0.wasm} +0 -0
  57. package/build/sub/site.76aa8286c257@0+0.wasm +0 -0
  58. package/build/sub/{site.7c6d8c7747af@0+0.wasm → site.e6e415bc3170@0+0.wasm} +0 -0
  59. package/build/sub/{store.d4e845ff24ac@0+0.wasm → store.c48db3345968@0+0.wasm} +0 -0
  60. package/build/sub/{stream.4c07247477f7@0+0.wasm → stream.27fd2fe858e1@0+0.wasm} +0 -0
  61. package/build/sub/{sub.b57e17b6876b@0+0.wasm → sub.c0fb7310de12@0+0.wasm} +0 -0
  62. package/build/sub/{substrate.4c780d6dd6d4@0+0.wasm → substrate.728c690187f2@0+0.wasm} +0 -0
  63. package/build/sub/{syntax.9857f6784d63@0+0.wasm → syntax.fadc832db29f@0+0.wasm} +0 -0
  64. package/build/sub/tar.692c0e8827cd@0+0.wasm +0 -0
  65. package/build/sub/{test.0d9c079bb309@0+0.wasm → test.1fd2ff8123bf@0+0.wasm} +0 -0
  66. package/build/sub/{text.4ab70ac35b5a@0+0.wasm → text.8ff142d72fd7@0+0.wasm} +0 -0
  67. package/build/sub/{timer.3809bb17a7a1@0+0.wasm → timer.d3454726b3bf@0+0.wasm} +0 -0
  68. package/build/sub/{upgrade.18a5aa0dae89@0+0.wasm → upgrade.2a9219e6a45d@0+0.wasm} +0 -0
  69. package/build/sub/{utf8.524c475ecd40@0+0.wasm → utf8.e82afeb9e953@0+0.wasm} +0 -0
  70. package/build/sub/worker.ea1e11f8f5e2@0+0.wasm +0 -0
  71. package/build/sub/writer.550227768eb9@0+0.wasm +0 -0
  72. package/package.json +1 -1
  73. package/std/archive/tar.sub +14 -21
  74. package/std/compress/deflate.sub +10 -12
  75. package/std/encoding/json.sub +44 -65
  76. package/std/encoding/wire.sub +6 -8
  77. package/std/http/checks.sub +3 -3
  78. package/std/http/conditional.sub +2 -4
  79. package/std/http/cookie.sub +5 -7
  80. package/std/http/form.sub +7 -10
  81. package/std/http/http.sub +17 -24
  82. package/std/http/multipart.sub +5 -5
  83. package/std/http/route.sub +9 -9
  84. package/std/http/server.sub +7 -12
  85. package/std/http/session.sub +1 -4
  86. package/std/http/sse-client.sub +9 -14
  87. package/std/http/url.sub +10 -10
  88. package/std/http/websocket.sub +2 -5
  89. package/std/meta/type-info.sub +10 -10
  90. package/std/package/hash.sub +1 -1
  91. package/std/package/manifest.sub +14 -15
  92. package/std/package/map.sub +4 -8
  93. package/std/package/path.sub +1 -4
  94. package/std/package/read.sub +3 -8
  95. package/std/package/site.sub +5 -5
  96. package/std/test/compare.sub +9 -10
  97. package/std/test/page.sub +1 -1
  98. package/std/test/run.sub +1 -1
  99. package/std/test/test.sub +24 -17
  100. package/substrate/VERSION +1 -1
  101. package/substrate/compiler/binary.sub +5 -14
  102. package/substrate/compiler/checker.sub +204 -19
  103. package/substrate/compiler/compile.sub +8 -8
  104. package/substrate/compiler/expander.sub +21 -29
  105. package/substrate/compiler/link.sub +2 -2
  106. package/substrate/compiler/ops.sub +1 -1
  107. package/substrate/compiler/prune.sub +12 -17
  108. package/substrate/compiler/roots.sub +3 -2
  109. package/substrate/compiler/serialize.sub +1 -1
  110. package/substrate/compiler/substrate.sub +8 -13
  111. package/substrate/compiler/syntax.sub +8 -21
  112. package/substrate/host/fs.sub +8 -11
  113. package/substrate/host/grants.sub +25 -26
  114. package/substrate/host/node/process.sub +5 -6
  115. package/build/compiler/binary.3823f89ce414@0+0.wasm +0 -0
  116. package/build/compiler/checker.592d37dcbec9@0+0.wasm +0 -0
  117. package/build/compiler/compile.86a2b03b0c9b@0+0.wasm +0 -0
  118. package/build/compiler/expander.689d326e5a1b@0+0.wasm +0 -0
  119. package/build/compiler/prune.d4a3f9834095@0+0.wasm +0 -0
  120. package/build/compiler/serialize.b2196de75bc8@0+0.wasm +0 -0
  121. package/build/compiler/syntax.9857f6784d63@0+0.wasm +0 -0
  122. package/build/sub/build.84ac996eda63@0+0.wasm +0 -0
  123. package/build/sub/deflate.fc8075e3aed1@0+0.wasm +0 -0
  124. package/build/sub/env.f051f8166526@0+0.wasm +0 -0
  125. package/build/sub/events.f952172735e0@0+0.wasm +0 -0
  126. package/build/sub/fetch.097f1cc9502d@0+0.wasm +0 -0
  127. package/build/sub/hash.3f0d118da63f@0+0.wasm +0 -0
  128. package/build/sub/manifest.cf7471880377@0+0.wasm +0 -0
  129. package/build/sub/map.dc516eec27ff@0+0.wasm +0 -0
  130. package/build/sub/path.b7a8e1cf3aaa@0+0.wasm +0 -0
  131. package/build/sub/process.aea2c88cb7a0@0+0.wasm +0 -0
  132. package/build/sub/read.cd1e693f4fb4@0+0.wasm +0 -0
  133. package/build/sub/site.81548474c323@0+0.wasm +0 -0
  134. package/build/sub/tar.e482cf873cfc@0+0.wasm +0 -0
  135. package/build/sub/worker.f1190de21b21@0+0.wasm +0 -0
  136. package/build/sub/writer.806bc85aa684@0+0.wasm +0 -0
package/std/test/test.sub CHANGED
@@ -2,6 +2,9 @@
2
2
  ;; program, with the grants that substrate test gives every test plus those in its #:grants; #:grants can ask only for
3
3
  ;; what substrate test itself was given. A test ends once nothing it started is still pending, and #:output and
4
4
  ;; #:output-file check everything it printed.
5
+ ;;
6
+ ;; In #:grants, (toolchain) lets a test run the toolchain, as the helpers in run.sub do. That amounts to every grant,
7
+ ;; because the toolchain can be started with any grants.
5
8
  (require-unqualified host/fs)
6
9
  (require-unqualified host/events)
7
10
  (require-unqualified host/modules/clock)
@@ -11,20 +14,16 @@
11
14
  (require-unqualified host/node/env)
12
15
  (require-unqualified "compare.sub")
13
16
 
14
- (provide run-tests expect-output expect-output-file test-path scratch-directory
17
+ (provide run-tests expect-output expect-output-file test-path scratch-directory toolchain-host
15
18
  compare-output! compare-output-file!)
16
19
 
17
20
  ;; ---- the runner ----
18
21
 
19
22
  (struct entry [module string] [name string] [line u32] [skip string] [traps string]
20
23
  [grants (slice (slice string))] [output string] [output-file string] [run (fn ())]
21
- [outcome u32] [why string] [report buffer])
24
+ [outcome outcome] [why string] [report buffer])
22
25
 
23
- (const waiting u32 0)
24
- (const unrun u32 1)
25
- (const passing u32 2)
26
- (const failing u32 3)
27
- (const skipping u32 4)
26
+ (enum outcome waiting unrun passing failing skipping)
28
27
 
29
28
  (define entries (ptr entry) 0)
30
29
  (define entry-count u32 0)
@@ -53,12 +52,9 @@
53
52
  ;; Copies the clauses to the heap, since most tests start after main has returned.
54
53
  (define (kept-clauses [clauses (slice (slice string))]) -> (slice (slice string))
55
54
  (when (== (-> clauses length) 0) (return clauses))
56
- (let ([out (cast (ptr (slice string)) (malloc (* (-> clauses length) (sizeof (slice string)))))])
57
- (for ([i u32 0]) (< i (-> clauses length)) (+= i 1)
58
- (let* ([c (@ clauses i)] [items (cast (ptr string) (malloc (* (-> c length) (sizeof string))))])
59
- (for ([j u32 0]) (< j (-> c length)) (+= j 1) (set! (@ items j) (@ c j)))
60
- (set! (@ out i) (slice items (-> c length)))))
61
- (slice out (-> clauses length))))
55
+ (let ([out (new 0 (slice string) (-> clauses length))])
56
+ (for ([i u32 0]) (< i (-> clauses length)) (+= i 1) (set! (@ out i) (copy 0 (@ clauses i))))
57
+ out))
62
58
 
63
59
  (define system string "")
64
60
 
@@ -129,6 +125,13 @@
129
125
  ;; The test's own scratch directory, which is empty when the test starts.
130
126
  (define (scratch-directory) -> string (setting "SUBSTRATE_SCRATCH"))
131
127
 
128
+ ;; The toolchain's host, which (toolchain) in #:grants lets a test run.
129
+ (define (toolchain-host) -> string
130
+ (let ([b (make-buffer)])
131
+ (buffer-add-string! (& b) (setting "SUBSTRATE_TOOLCHAIN"))
132
+ (buffer-add-string! (& b) "/host/subhost.mjs")
133
+ (buffer-string (& b))))
134
+
132
135
  (define (selected? [e (ptr entry)]) -> bool
133
136
  (let ([any #f] [i u32 0])
134
137
  (while (< i (-> arguments length))
@@ -164,7 +167,7 @@
164
167
  (set! run-scratch (setting "SUBSTRATE_SCRATCH"))
165
168
  (set! started (clock-monotonic))
166
169
  (let ([n (if capturing at-once 1)])
167
- (set! slots (cast (ptr slot) (calloc n (sizeof slot))))
170
+ (set! slots (-> (new 0 slot n) items))
168
171
  (for ([i u32 0]) (< i n) (+= i 1) (slot-go! (& (@ slots i)))))
169
172
  (reported!))
170
173
 
@@ -216,9 +219,13 @@
216
219
  (grants-allow! (& (-> o grants)) grant-read scratch)
217
220
  (grants-allow! (& (-> o grants)) grant-write scratch)
218
221
  (for ([i u32 0]) (< i (-> e grants length)) (+= i 1)
219
- (let ([c (@ (-> e grants) i)] [items (make-buffer)])
220
- (for ([j u32 1]) (< j (-> c length)) (+= j 1) (pushed! (& items) (scratch-placed (@ c j) scratch)))
221
- (unless (grants-add! (& (-> o grants)) (@ c 0) (strings-in (& items)) (& why))
222
+ (let ([c (@ (-> e grants) i)] [items (make-buffer)] [kind (@ (@ (-> e grants) i) 0)])
223
+ (if (and (== kind "toolchain") (== (-> c length) 1))
224
+ (begin
225
+ (set! kind "run")
226
+ (pushed! (& items) (toolchain-host)))
227
+ (for ([j u32 1]) (< j (-> c length)) (+= j 1) (pushed! (& items) (scratch-placed (@ c j) scratch))))
228
+ (unless (grants-add! (& (-> o grants)) kind (strings-in (& items)) (& why))
222
229
  (failed! e why "")
223
230
  (return #f))))
224
231
  (set! (-> s entry) e)
package/substrate/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.3
1
+ 0.9.4
@@ -70,7 +70,7 @@
70
70
  [current (ptr srcloc)] [start (ptr srcloc)] [started bool] [else-pending bool])
71
71
 
72
72
  (define (new-asm) -> (ptr asm)
73
- (let ([a (cast (ptr asm) (arena-alloc (current-arena) (sizeof asm)))])
73
+ (let ([a (new (current-arena) asm)])
74
74
  (set! (-> a out) (make-buffer))
75
75
  (set! (-> a relocs) 0)
76
76
  (set! (-> a locations) 0)
@@ -86,7 +86,7 @@
86
86
  (struct cell-record [self datum] [value datum])
87
87
 
88
88
  (define (cell [v datum]) -> datum
89
- (let ([c (cast (ptr cell-record) (arena-alloc (current-arena) (sizeof cell-record)))])
89
+ (let ([c (new (current-arena) cell-record)])
90
90
  (set! (-> c self) (make-record-in (current-arena) cell-kind c))
91
91
  (set! (-> c value) v)
92
92
  (-> c self)))
@@ -96,23 +96,14 @@
96
96
  (define (set-cell-value! [c datum] [v datum]) (set! (-> (cast (ptr cell-record) (record-pointer c)) value) v))
97
97
 
98
98
  (define (reloc! [a (ptr asm)] [kind datum] [key datum])
99
- (let ([r (cast (ptr reloc) (arena-alloc (current-arena) (sizeof reloc)))])
100
- (set! (-> r offset) (asm-size a))
101
- (set! (-> r kind) kind)
102
- (set! (-> r key) key)
103
- (set! (-> r next) (-> a relocs))
104
- (set! (-> a relocs) r)))
99
+ (set! (-> a relocs) (new (current-arena) (reloc #:offset (asm-size a) #:kind kind #:key key #:next (-> a relocs)))))
105
100
 
106
101
  ;; ---- source locations ----
107
102
 
108
103
  (define code-locations (ptr code-location) 0)
109
104
 
110
105
  (define (new-location [offset u32] [loc (ptr srcloc)] [next (ptr code-location)]) -> (ptr code-location)
111
- (let ([l (cast (ptr code-location) (arena-alloc (current-arena) (sizeof code-location)))])
112
- (set! (-> l offset) offset)
113
- (set! (-> l loc) loc)
114
- (set! (-> l next) next)
115
- l))
106
+ (new (current-arena) (code-location #:offset offset #:loc loc #:next next)))
116
107
 
117
108
  (define (same-location? [a (ptr srcloc)] [b (ptr srcloc)]) -> bool
118
109
  (or (== a b)
@@ -283,7 +274,7 @@
283
274
 
284
275
  (define (link-body [a (ptr asm)] [b (ptr asm)] [resolve (closure (datum datum) -> datum)]) -> datum
285
276
  (let ([q (make-buffer)] [notes (ptr code-location) 0]
286
- [l (cast (ptr linked) (arena-alloc (current-arena) (sizeof linked)))])
277
+ [l (new (current-arena) linked)])
287
278
  (set! notes (link-segment! (& q) a resolve notes))
288
279
  (when (!= b 0)
289
280
  (when (-> b started) (set! notes (new-location (-> q length) (-> b start) notes)))
@@ -111,7 +111,7 @@
111
111
  (let ([s (cast (ptr checking) (@ states))])
112
112
  (while (and (!= s 0) (!= (-> s phase) phase)) (set! s (-> s next)))
113
113
  (when (== s 0)
114
- (set! s (cast (ptr checking) (arena-alloc (current-arena) (sizeof checking))))
114
+ (set! s (new (current-arena) checking))
115
115
  (set! (-> s phase) phase)
116
116
  (set! (-> s counter) 0)
117
117
  (set! (-> s instances) (make-table))
@@ -138,6 +138,7 @@
138
138
  [('struct) (aggregate-type s 'struct)]
139
139
  [('union) (aggregate-type s 'union)]
140
140
  [('variant) (substrate-variant s)]
141
+ [('enum) (substrate-enum s)]
141
142
  [('substrate-struct-check) (substrate-struct-check s)]
142
143
  [('exception) (substrate-exception s)]
143
144
  [('typedef) (substrate-typedef s)]
@@ -145,7 +146,7 @@
145
146
  [('#%module-begin) (substrate-module-begin s)]
146
147
  [('forms) (forms-form s)]
147
148
  [('#%top-interaction) (syntax-match s [(_ e) (at s (syn `(#%checked interaction ,e)))])]
148
- [('make-cell 'new) (data-form kind s)]
149
+ [('make-cell) (data-form s)]
149
150
  [('test) (substrate-test s)]
150
151
  [('expect) (substrate-expect s)]
151
152
  [('expect-equal) (substrate-expect-equal s)]
@@ -169,7 +170,7 @@
169
170
  (struct code-record [self datum] [code datum])
170
171
 
171
172
  (define (code-box [c datum]) -> datum
172
- (let ([b (cast (ptr code-record) (arena-alloc (current-arena) (sizeof code-record)))])
173
+ (let ([b (new (current-arena) code-record)])
173
174
  (set! (-> b self) (make-record code-kind b))
174
175
  (set! (-> b code) c)
175
176
  (-> b self)))
@@ -223,6 +224,7 @@
223
224
  (define (closure-type? [t datum]) -> bool (and (pair? t) (== (car t) 'closure)))
224
225
  (define (array-type? [t datum]) -> bool (and (pair? t) (== (car t) 'array)))
225
226
  (define (struct-type? [t datum]) -> bool (and (pair? t) (== (car t) 'struct)))
227
+ (define (enum-type? [t datum]) -> bool (and (pair? t) (== (car t) 'enum)))
226
228
  (define (aggregate? [t datum]) -> bool (or (array-type? t) (struct-type? t)))
227
229
  (define (slice-type? [t datum]) -> bool (and (pair? t) (== (car t) 'slice)))
228
230
  ;; A string or a slice: a pointer and a length in one i64, the pointer below.
@@ -255,6 +257,7 @@
255
257
  [(struct-type? t)
256
258
  (let ([name (if full (cadr t) (caddr t))])
257
259
  (if (pair? (cdddr t)) (cons name (for/list ([u (cadddr t)]) (shown-as u full))) name))]
260
+ [(enum-type? t) (if full (cadr t) (caddr t))]
258
261
  [(and (pair? t) (== (car t) 'tvar)) (cadr t)]
259
262
  [(values-type? t) (cons 'values (for/list ([u (cdr t)]) (shown-as u full)))]
260
263
  [(== t 'none) 'void]
@@ -312,6 +315,7 @@
312
315
  `(struct ,(identifier-name h) ,(cadr v) ,(for/list ([t a]) (kept! (complete! (parse-type t) t) t)))))
313
316
 
314
317
  (define (parameters-of [v datum]) -> datum (if (> (length v) 4) (list-ref v 4) nil))
318
+ (define (numbers-of [v datum]) -> datum (if (> (length v) 5) (list-ref v 5) 0))
315
319
 
316
320
  ;; A type's compile-time value: (substrate-struct name (field ...) kind (parameter ...)) or
317
321
  ;; (substrate-typedef type).
@@ -325,6 +329,8 @@
325
329
  (let* ([l (syntax->list v)]
326
330
  [t datum (syntax-match (if (!= l 0) l nil)
327
331
  [('substrate-struct n fs k (p ...)) `(substrate-struct ,(syntax-e n) ,fs ,(syntax-e k) ,(for/list ([q p]) (syntax-e q)))]
332
+ [('substrate-struct n fs k (p ...) (x ...))
333
+ `(substrate-struct ,(syntax-e n) ,fs ,(syntax-e k) ,(for/list ([q p]) (syntax-e q)) ,(for/list ([y x]) (syntax-e y)))]
328
334
  [('substrate-typedef t) `(substrate-typedef ,(syntax->datum t))]
329
335
  [_ 0])])
330
336
  (when (!= t 0) (hash-set! (-> state types) (cast u64 v) (cast u32 t)))
@@ -335,6 +341,7 @@
335
341
  (when (== v 0) (substrate-error x "~a is not a type" `(,(syntax-e x))))
336
342
  (cond [(== (car v) 'substrate-typedef) (cadr v)]
337
343
  [(pair? (parameters-of v)) (substrate-error x "~a takes types: write (~a type ...)" `(,(syntax-e x) ,(syntax-e x)))]
344
+ [(!= (numbers-of v) 0) `(enum ,(identifier-name x) ,(cadr v))]
338
345
  [else `(struct ,(identifier-name x) ,(cadr v))])))
339
346
 
340
347
  (define (type-syntax? [s datum]) -> bool
@@ -349,7 +356,7 @@
349
356
  [_ #f]))
350
357
 
351
358
  (define (scalar! [t datum] [where datum]) -> datum
352
- (unless (or (arithmetic? t) (address-type? t) (== t 'exnref) (== t 'bool) (view-type? t) (and (pair? t) (== (car t) 'tvar)))
359
+ (unless (or (arithmetic? t) (address-type? t) (== t 'exnref) (== t 'bool) (view-type? t) (enum-type? t) (and (pair? t) (== (car t) 'tvar)))
353
360
  (substrate-error where "expected a number or pointer type, not ~s" `(,(shown t))))
354
361
  t)
355
362
 
@@ -397,7 +404,7 @@
397
404
  [saved type-arguments] [l datum 0])
398
405
  (datum-put! (-> state layouts) (cdr t) 'laying-out)
399
406
  (set! type-arguments (for/list ([p (parameters-of v)] [a (if (pair? (cdddr t)) (cadddr t) nil)]) (cons p a)))
400
- (set! l (try (if (== (cadddr v) 'variant)
407
+ (set! l (try (if (memq (cadddr v) '(variant enum))
401
408
  (variant-layout items)
402
409
  (let ([r (lay-out items (== (cadddr v) 'union))])
403
410
  `(,(fixnum (round-up (fixnum-value (car r)) (fixnum-value (cadr r)))) ,(cadr r) ,(caddr r))))
@@ -791,6 +798,12 @@
791
798
  [('lambda) (lambda-shape s)]
792
799
  [('match) (match-shape s)]
793
800
  [('try) (try-shape s)]
801
+ [('new)
802
+ (unless (or (== n 3) (== n 4)) (substrate-error s "expected (new arena type), (new arena type count) or (new arena value)" nil))
803
+ (use `(,(cadr l) ,(if (or (== n 4) (type-syntax? (caddr l))) (piece 'type 0 (caddr l)) (caddr l)) ,@(cdddr l)))]
804
+ [('copy)
805
+ (unless (== n 3) (substrate-error s "expected (copy arena items)" nil))
806
+ (use (exprs-in 0 (cdr l)))]
794
807
  [else 0])))
795
808
 
796
809
  ;; A binding is [x type value], [x value], [(x ...) value] or [(x ...) (type ...) value], or [x type]
@@ -1307,6 +1320,8 @@
1307
1320
  (cons 'lit (caddr (field-of ty (piece-at m 2)))))]
1308
1321
  [('inst) (check-inst s m)]
1309
1322
  [('#%datum) (literal s (syntax-e (piece-at m 1)))]
1323
+ [('new) (check-new m env)]
1324
+ [('copy) (check-copy m env)]
1310
1325
  [else (check-marked s fenv (mark-arguments m) env hint)]))))
1311
1326
 
1312
1327
  (define (mark-arguments [m datum]) -> datum (if (== (car m) 'group) (pieces-from m 1) nil))
@@ -1318,7 +1333,10 @@
1318
1333
  (check-generic-call s g args env hint)
1319
1334
  (syntax-match g [(f . _) (substrate-error s "~a is generic: give its types, (inst ~a type ...)" `(,(syntax-e f) ,(syntax-e f)))]))]
1320
1335
  [('#%substrate-construct v i n)
1321
- (let ([t (construct-type s v i args env hint)]) (cons t (construct s t i n args env (temp t))))]))
1336
+ (let ([t (construct-type s v i args env hint)])
1337
+ (if (enum-type? t)
1338
+ (begin (case-fields s t (syntax-e i) n args) (cons t (enum-constant t (syntax-e i))))
1339
+ (cons t (construct s t i n args env (temp t)))))]))
1322
1340
 
1323
1341
  (define (check-inst [s datum] [m datum]) -> datum
1324
1342
  (let* ([f (piece-at m 1)] [h (expand-head f)])
@@ -1544,6 +1562,7 @@
1544
1562
  (define (let-value [zero bool] [r datum] [t datum] [x datum] [init datum] [stored bool]) -> datum
1545
1563
  (cond [(not zero) (convert r t init stored)]
1546
1564
  [(view-type? t) (const-code 'i64 (fixnum 0))]
1565
+ [(enum-type? t) (i32-const 0)]
1547
1566
  [else (constant (fixnum 0) t x)]))
1548
1567
 
1549
1568
  (define (let-put [r datum] [dst datum] [t datum] [init datum] [env datum]) -> datum
@@ -1695,7 +1714,7 @@
1695
1714
  (case (car p)
1696
1715
  [('call) (cadr (cadddr p))]
1697
1716
  [('array) (array-of-type (cadr p) (caddr p))]
1698
- [else (if (null? (parameters-of (type-binding (cadr p)))) (named-type (cadr p)) 0)])))
1717
+ [else (if (null? (parameters-of (type-binding (cadr p)))) (let ([t (named-type (cadr p))]) (if (enum-type? t) 0 t)) 0)])))
1699
1718
 
1700
1719
  (define (temp [t datum]) -> datum (address (frame-place t (frame-slot! t)) 0))
1701
1720
 
@@ -1928,16 +1947,18 @@
1928
1947
  (if (== (car n) 'group)
1929
1948
  `(,(piece-at n 0) (,(cdr (pieces-of n)) ,body ,(cadr c)))
1930
1949
  `(,(piece-syntax n) (#f ,body ,(cadr c))))))]
1931
- [p (struct-base v env)] [t (car p)] [a (fresh-key!)] [tag (fresh-key!)] [nullable (pointer-base? p)]
1950
+ [p (match-base v env)] [t (car p)] [a (fresh-key!)] [tag (fresh-key!)] [nullable (pointer-base? p)]
1932
1951
  [pairs (for/list ([x cs]) (cons (car x) (cadr x)))]
1933
1952
  [nulls (for/list ([nc pairs] #:when (null-clause? (car nc))) nc)]
1934
1953
  [cases (for/list ([nc pairs] #:when (not (null-clause? (car nc)))) nc)])
1935
- (unless (variant-type? t) (substrate-error v "match takes a variant, or a pointer to one, not ~s" `(,(shown t))))
1954
+ (unless (or (variant-type? t) (enum-type? t)) (substrate-error v "match takes a variant, or a pointer to one, not ~s" `(,(shown t))))
1936
1955
  (when (and (pair? nulls) (not nullable))
1937
1956
  (substrate-error (car (car nulls)) "this match takes a variant, not a pointer to one, which is never 0" nil))
1938
1957
  (when (and (pair? nulls) (pair? (cdr nulls))) (substrate-error (car (cadr nulls)) "0 is matched twice" nil))
1939
- (match-arms e p t a tag nullable nulls (for/list ([c cases]) (car c)) (for/list ([c cases]) (cdr c)) nil
1940
- (numbers-below (length (cases-of t))) env hint)))
1958
+ (if (enum-type? t)
1959
+ (enum-match e p t a tag nulls cases env hint)
1960
+ (match-arms e p t a tag nullable nulls (for/list ([c cases]) (car c)) (for/list ([c cases]) (cdr c)) nil
1961
+ (numbers-below (length (cases-of t))) env hint))))
1941
1962
 
1942
1963
  (define (match-arms [e datum] [p datum] [t datum] [a datum] [tag datum] [nullable bool] [nulls datum] [names datum]
1943
1964
  [clauses datum] [arms datum] [left datum] [env datum] [hint datum]) -> datum
@@ -2334,7 +2355,7 @@
2334
2355
  [(float-type? t) (prim-code (op-name t 'convert_i32_u) `(,c))]
2335
2356
  [else (substrate-error where "expected ~s, got bool" `(,(shown t)))])]
2336
2357
  [(or (struct-type? t) (struct-type? from) (closure-type? t) (closure-type? from) (values-type? t) (values-type? from)
2337
- (view-type? t) (view-type? from))
2358
+ (view-type? t) (view-type? from) (enum-type? t) (enum-type? from))
2338
2359
  (unless (equal? from t) (substrate-error where "expected ~s, got ~s" (shown-apart t from)))
2339
2360
  c]
2340
2361
  [(address-type? t)
@@ -2390,6 +2411,13 @@
2390
2411
  (cons to (cdr r))]
2391
2412
  [else (substrate-error x "cannot cast ~s to ~s" `(,(shown from) ,(shown to)))])]
2392
2413
  [(view-type? from) (substrate-error x "cannot cast ~s to ~s" `(,(shown from) ,(shown to)))]
2414
+ [(enum-type? to)
2415
+ (cond [(equal? from to) (cons to (cdr r))]
2416
+ [(integer-type? (as-number from)) (cons to (convert r 'i32 x #f))]
2417
+ [else (substrate-error x "cannot cast ~s to ~s" `(,(shown from) ,(shown to)))])]
2418
+ [(enum-type? from)
2419
+ (unless (integer-type? to) (substrate-error x "cannot cast ~s to ~s" `(,(shown from) ,(shown to))))
2420
+ (cons (promoted to) (numeric (cdr r) 'i32 to #t))]
2393
2421
  [(address-type? to)
2394
2422
  (cond [(== from 'lit) (cons to (const-code 'i32 (cdr r)))]
2395
2423
  [(or (address-type? from) (memq from '(i32 u32))) (cons to (cdr r))]
@@ -2438,6 +2466,9 @@
2438
2466
  (let ([t (cond [(address-type? ta) ta]
2439
2467
  [(address-type? tb) tb]
2440
2468
  [(and (arithmetic? ta) (arithmetic? tb)) (common ta tb)]
2469
+ [(and (enum-type? ta) (equal? ta tb)) ta]
2470
+ [(or (enum-type? ta) (enum-type? tb))
2471
+ (substrate-error e "~a compares two values of the same enum, not ~s and ~s" `(,o ,(shown ta) ,(shown tb)))]
2441
2472
  [else (substrate-error e "~a compares numbers, pointers or strings, not ~s and ~s" `(,o ,(shown ta) ,(shown tb)))])])
2442
2473
  (cons 'bool (prim-code (instruction o t) `(,(convert a t e #f) ,(convert b t e #f)))))]
2443
2474
  [(and (arithmetic? ta) (arithmetic? tb))
@@ -2709,6 +2740,7 @@
2709
2740
  [(== t 'f32) (call-of 'print-float `(,(prim-code 'f64.promote_f32 `(,(cdr r))) ,(i32-const 1)))]
2710
2741
  [(equal? t (datum-type)) `(call ,(syntax-function-of 'print-datum (-> state phase)) (,(cdr r) ,(i32-const display)))]
2711
2742
  [(address-type? t) (call-of 'print-integer `(,(prim-code 'i64.extend_i32_u `(,(cdr r))) ,(i32-const 0)))]
2743
+ [(enum-type? t) (printed-enum r t)]
2712
2744
  [(and (struct-type? t) (variant-type? t)) (printed-variant r t a display)]
2713
2745
  [(and (struct-type? t) (== (type-kind t) 'struct)) (printed-struct r t a display)]
2714
2746
  [else (seq `(,(as-void r) ,(text-printed (format "#<~s>" `(,(shown t))))))])))
@@ -2779,13 +2811,10 @@
2779
2811
 
2780
2812
  (define (src [d datum]) -> datum (datum->syntax here d 0))
2781
2813
 
2782
- (define (data-form [kind datum] [s datum]) -> datum
2783
- (case kind
2784
- [('make-cell)
2785
- (syntax-match s
2786
- [(_ c) (at s (src `(let ([p (cell-bytes ,(cell-size c))]) (set! (@ p) ,c) p)))]
2787
- [(_ a c) (at s (src `(let ([p (cast datum (arena-alloc ,a ,(cell-size c)))]) (set! (@ p) ,c) p)))])]
2788
- [else (syntax-match s [(_ a t) (at s (src `(cast (ptr ,t) (arena-alloc ,a (sizeof ,t)))))])]))
2814
+ (define (data-form [s datum]) -> datum
2815
+ (syntax-match s
2816
+ [(_ c) (at s (src `(let ([p (cell-bytes ,(cell-size c))]) (set! (@ p) ,c) p)))]
2817
+ [(_ a c) (at s (src `(let ([p (cast datum (arena-alloc ,a ,(cell-size c)))]) (set! (@ p) ,c) p)))]))
2789
2818
 
2790
2819
  ;; A cell is a tag and its case's fields.
2791
2820
  (define (cell-size [c datum]) -> datum
@@ -2793,3 +2822,159 @@
2793
2822
  (fixnum 4)
2794
2823
  (let ([fields (cdr (assq (syntax-e (car (syntax->list c))) (cases-of (cadr (datum-type)))))])
2795
2824
  (fixnum (if (null? fields) 4 (let ([f (last fields)]) (+ (fixnum-value (caddr f)) (size-of (cadr f)))))))))
2825
+
2826
+ (define (check-new [m datum] [env datum]) -> datum
2827
+ (if (== (piece-role (list-ref (pieces-of m) 2)) 'type) (new-zeroed m env) (new-value m env)))
2828
+
2829
+ (define (new-value [m datum] [env datum]) -> datum
2830
+ (let* ([s (piece-at m 1)] [x (piece-at m 2)] [arena (expect s (arena-pointer) env #f)] [h (expand-in x env)]
2831
+ [pr (producer-with h x)] [produced (production-type pr)]
2832
+ [r (if (!= produced 0)
2833
+ 0
2834
+ (let ([c (check-with h x env 0)]) (if (== (car c) 'slit) (cons 'string (string-code (cdr c))) (settle c 0 x))))]
2835
+ [t (kept! (complete! (if (!= produced 0) produced (car r)) x) x)] [a (fresh-key!)] [p (fresh-key!)])
2836
+ (cons `(ptr ,t)
2837
+ `(let ((,a i32 ,arena a))
2838
+ (let ((,p i32 ,(allocation-from s (lref a) (i32-const (size-of t))) p))
2839
+ ,(seq `(,(cond [(!= produced 0) (as-void (constructed (lref p) pr produced x t env))]
2840
+ [(aggregate? t) (as-void (copied-into (lref p) r t x))]
2841
+ [else (store t (lref p) 0 (convert r t x #f))])
2842
+ ,(lref p))))))))
2843
+
2844
+ (define (new-zeroed [m datum] [env datum]) -> datum
2845
+ (let* ([u (piece-at m 2)] [t (kept! (complete! (parse-type u) u) u)] [size (size-of t)] [s (piece-at m 1)]
2846
+ [arena (expect s (arena-pointer) env #f)] [a (fresh-key!)] [p (fresh-key!)])
2847
+ (if (null? (cdddr (pieces-of m)))
2848
+ (cons `(ptr ,t)
2849
+ `(let ((,a i32 ,arena a))
2850
+ (let ((,p i32 ,(allocation-from s (lref a) (i32-const size)) p))
2851
+ ,(seq `(,(zero-bytes (lref p) size) ,(lref p))))))
2852
+ (let ([n (fresh-key!)])
2853
+ (cons `(slice ,t)
2854
+ `(let ((,a i32 ,arena a) (,n i32 ,(expect (piece-at m 3) 'u32 env #f) n))
2855
+ (let ((,p i32 ,(allocation-from s (lref a) (allocation-size (lref n) size)) p))
2856
+ ,(seq `(,(prim-code 'memory.fill `(,(lref p) ,(i32-const 0) ,(items-size (lref n) size)))
2857
+ ,(view-code (lref p) (lref n)))))))))))
2858
+
2859
+ (define (check-copy [m datum] [env datum]) -> datum
2860
+ (let* ([s (piece-at m 1)] [arena (expect s (arena-pointer) env #f)] [x (piece-at m 2)] [c (check x env 0)]
2861
+ [r (if (== (car c) 'slit) (cons 'string (string-code (cdr c))) (settle c 0 x))] [t (car r)])
2862
+ (unless (view-type? t) (substrate-error x "copy takes a string or a slice, not ~s" `(,(shown t))))
2863
+ (let ([size (size-of (complete! (view-items t) x))] [a (fresh-key!)] [v (fresh-key!)] [n (fresh-key!)] [p (fresh-key!)])
2864
+ (cons t `(let ((,a i32 ,arena a) (,v i64 ,(cdr r) v))
2865
+ (let ((,n i32 ,(view-length (lref v)) n))
2866
+ (let ((,p i32 ,(allocation-from s (lref a) (allocation-size (lref n) size)) p))
2867
+ ,(seq `(,(prim-code 'memory.copy `(,(lref p) ,(view-pointer (lref v)) ,(items-size (lref n) size)))
2868
+ ,(view-code (lref p) (lref n)))))))))))
2869
+
2870
+ (define (arena-pointer) -> datum `(ptr ,(named-type (datum->syntax here 'arena 0))))
2871
+
2872
+ (define (allocation-from [s datum] [a datum] [size datum]) -> datum
2873
+ (cond [(zero? (syntax-e s)) (call-of 'malloc `(,size))]
2874
+ [(syntax-match s [('& _) #t] [_ #f]) (call-of 'arena-alloc `(,a ,size))]
2875
+ [else
2876
+ (let ([n (fresh-key!)])
2877
+ `(let ((,n i32 ,size n))
2878
+ (if ,(prim-code 'i32.eqz `(,a)) ,(call-of 'malloc `(,(lref n))) ,(call-of 'arena-alloc `(,a ,(lref n))))))]))
2879
+
2880
+ (define (items-size [n datum] [size i32]) -> datum (if (== size 1) n (prim-code 'i32.mul `(,n ,(i32-const size)))))
2881
+
2882
+ ;; Past the limit, a size that malloc refuses.
2883
+ (define (allocation-size [n datum] [size i32]) -> datum
2884
+ (if (== size 0)
2885
+ (i32-const 0)
2886
+ `(select ,(i32-const 2147483584) ,(items-size n size) ,(prim-code 'i32.gt_u `(,n ,(i32-const (/ 2147483584 size)))))))
2887
+
2888
+ ;; ---- enums ----
2889
+
2890
+ (define (substrate-enum [s datum]) -> datum
2891
+ (syntax-match s
2892
+ [(_ (? identifier? name) c ...) (if (null? c) (substrate-error s "expected (enum name case ...)" nil) (enum-form name c))]
2893
+ [_ (substrate-error s "expected (enum name case ...)" nil)]))
2894
+
2895
+ (define (enum-form [name datum] [cs datum]) -> datum
2896
+ (let* ([names (for/list ([c cs])
2897
+ (syntax-match c
2898
+ [(? identifier? n) n]
2899
+ [((? identifier? n) k) (unless (integer? (syntax-e k)) (substrate-error k "expected a number" nil)) n]
2900
+ [_ (substrate-error c "expected a case or [case number]" nil)]))]
2901
+ [given (for/list ([c cs]) (syntax-match c [(_ k) k] [_ 0]))])
2902
+ (distinct! names '"case")
2903
+ (syn `(begin (define-syntax ,name (quote-syntax (substrate-struct ,name (,@(for/list ([n names]) `(,n))) enum () ,(case-numbers cs given))))
2904
+ ,@(for/list ([n names] [i (numbers-below (length names))])
2905
+ `(define-syntax ,n (quote-syntax (#%form mark (#%substrate-construct ,name ,i ,n)))))))))
2906
+
2907
+ (define (case-numbers [cs datum] [given datum]) -> datum
2908
+ (let ([next i64 0] [out nil])
2909
+ (while (pair? cs)
2910
+ (let* ([k (car given)] [n (if (== k 0) next (integer-value (syntax-e k)))] [d (make-integer n)])
2911
+ (when (or (< n -2147483648) (> n 2147483647)) (substrate-error (car cs) "a case's number is a 32-bit integer" nil))
2912
+ (when (member d out) (substrate-error (car cs) "two cases have the number ~a" `(,d)))
2913
+ (set! out (cons d out))
2914
+ (set! next (+ n 1)))
2915
+ (set! cs (cdr cs))
2916
+ (set! given (cdr given)))
2917
+ (reverse out)))
2918
+
2919
+ (define (enum-numbers [t datum]) -> datum (numbers-of (type-value (syntax-local-value (name-identifier (cadr t))))))
2920
+
2921
+ (define (enum-constant [t datum] [i datum]) -> datum (const-code 'i32 (list-ref (enum-numbers t) (fixnum-value i))))
2922
+
2923
+ (define (match-base [s datum] [env datum]) -> datum
2924
+ (let* ([h (expand-head s)] [p (if (place-head? h) (place-with h s env) 0)])
2925
+ (if (and (!= p 0) (or (struct-type? (car p)) (view-type? (car p))))
2926
+ p
2927
+ (let ([r (if (!= p 0) (read-place p s) (check-with h s env 0))])
2928
+ (cond [(enum-type? (car r)) `(,(car r) local ,(cdr r))]
2929
+ [(and (pointer? (car r)) (enum-type? (cadr (car r)))) `(,(cadr (car r)) memory ,(cdr r) 0 pointer)]
2930
+ [else (based r s)])))))
2931
+
2932
+ (define (enum-match [e datum] [p datum] [t datum] [a datum] [k datum] [nulls datum] [clauses datum] [env datum] [hint datum])
2933
+ -> datum
2934
+ (let ([left (numbers-below (length (cases-of t)))] [arms nil] [default datum 0] [numbers (enum-numbers t)]
2935
+ [null-arm (if (pair? nulls) (check-sequence (cadddr (car nulls)) (caddr (car nulls)) env hint) 0)])
2936
+ (for/each ([c clauses])
2937
+ (let* ([n (car c)] [x (cadr c)] [cl (cadddr c)] [i (if (== (syntax-e n) '_) 0 (case-index n t))])
2938
+ (when (null? left) (substrate-error cl "this clause can never match" nil))
2939
+ (when (and (!= i 0) (not (member i left))) (substrate-error n "~a is matched twice" `(,(syntax-e n))))
2940
+ (when (pair? x) (substrate-error cl "~a has ~a field~a, not ~a" `(,(syntax-e n) ,(fixnum 0) ,(plural 0) ,(fixnum (length x)))))
2941
+ (let ([r (check-sequence cl (caddr c) env hint)])
2942
+ (if (== i 0)
2943
+ (begin
2944
+ (set! default (cons r cl))
2945
+ (set! left nil))
2946
+ (begin
2947
+ (set! arms (cons `(,(list-ref numbers (fixnum-value i)) ,r ,cl) arms))
2948
+ (set! left (for/list ([j left] #:when (not (equal? j i))) j)))))))
2949
+ (when (and (pair? left) (== default 0))
2950
+ (substrate-error e "this match does not cover ~a" `(,(joined (for/list ([i left]) (car (list-ref (cases-of t) (fixnum-value i))))))))
2951
+ (let* ([arms (reverse arms)]
2952
+ [j (for/fold ([ty (if (!= default 0) (car (car default)) (if (!= null-arm 0) (car null-arm) 'none))]) ([x arms])
2953
+ (join ty (car (cadr x))))]
2954
+ [j (if (!= null-arm 0) (join j (car null-arm)) j)]
2955
+ [ty (if (and (== j 'void) (!= hint 0) (!= hint 'void)) hint (promoted (settled-for j hint)))]
2956
+ [chain `(let ((,k i32 ,(if (== (cadr p) 'local) (caddr p) (load t (lref a) (fixnum-value (cadddr p)))) tag))
2957
+ ,(enum-chain arms default ty k))])
2958
+ (cons ty (cond [(== (cadr p) 'local) chain]
2959
+ [(!= null-arm 0)
2960
+ `(let ((,a i32 ,(caddr p) a))
2961
+ (if ,(prim-code 'i32.eqz `(,(lref a))) ,(as null-arm ty (cadddr (car nulls))) ,chain))]
2962
+ [else `(let ((,a i32 ,(caddr p) a)) ,chain)])))))
2963
+
2964
+ (define (enum-chain [arms datum] [default datum] [ty datum] [k datum]) -> datum
2965
+ (if (null? arms)
2966
+ (if (!= default 0) (as (car default) ty (cdr default)) '(unreachable))
2967
+ `(if ,(prim-code 'i32.eq `(,(lref k) ,(const-code 'i32 (car (car arms)))))
2968
+ ,(as (cadr (car arms)) ty (caddr (car arms)))
2969
+ ,(enum-chain (cdr arms) default ty k))))
2970
+
2971
+ (define (printed-enum [r datum] [t datum]) -> datum
2972
+ (let ([k (fresh-key!)])
2973
+ `(let ((,k i32 ,(cdr r) k)) ,(enum-printed k (for/list ([c (cases-of t)]) (car c)) (enum-numbers t)))))
2974
+
2975
+ (define (enum-printed [k datum] [names datum] [numbers datum]) -> datum
2976
+ (if (null? names)
2977
+ (call-of 'print-integer `(,(prim-code 'i64.extend_i32_s `(,(lref k))) ,(i32-const 1)))
2978
+ `(if ,(prim-code 'i32.eq `(,(lref k) ,(const-code 'i32 (car numbers))))
2979
+ ,(text-printed (format "~a" `(,(car names))))
2980
+ ,(enum-printed k (cdr names) (cdr numbers)))))
@@ -111,7 +111,7 @@
111
111
  ;; ---- per-function state ----
112
112
 
113
113
  (define (new-fctx [params datum] [results datum]) -> (ptr fctx)
114
- (let ([fc (cast (ptr fctx) (arena-alloc (current-arena) (sizeof fctx)))])
114
+ (let ([fc (new (current-arena) fctx)])
115
115
  (set! (-> fc locals) (make-table))
116
116
  (set! (-> fc extra) nil)
117
117
  (set! (-> fc next) 0)
@@ -147,7 +147,7 @@
147
147
  (define compiling datum 0)
148
148
 
149
149
  (define (push-label [key datum] [kind datum] [type datum] [next (ptr label)]) -> (ptr label)
150
- (let ([l (cast (ptr label) (arena-alloc (current-arena) (sizeof label)))])
150
+ (let ([l (new (current-arena) label)])
151
151
  (set! (-> l key) key)
152
152
  (set! (-> l kind) kind)
153
153
  (set! (-> l type) type)
@@ -177,7 +177,7 @@
177
177
  (define (synth-of [d datum]) -> (ptr synth) (cast (ptr synth) (record-pointer d)))
178
178
 
179
179
  (define (new-mstate [self datum]) -> (ptr mstate)
180
- (let ([ms (cast (ptr mstate) (arena-alloc (current-arena) (sizeof mstate)))])
180
+ (let ([ms (new (current-arena) mstate)])
181
181
  (set! (-> ms self) self)
182
182
  (set! (-> ms func-imports) nil)
183
183
  (set! (-> ms global-imports) nil)
@@ -240,7 +240,7 @@
240
240
  (set! (-> ms table-loc) current-loc)))
241
241
 
242
242
  (define (new-synth! [ms (ptr mstate)] [kind datum] [info datum]) -> datum
243
- (let ([s (cast (ptr synth) (arena-alloc (current-arena) (sizeof synth)))])
243
+ (let ([s (new (current-arena) synth)])
244
244
  (set! (-> s self) (make-record-in (current-arena) synth-kind s))
245
245
  (set! (-> s kind) kind)
246
246
  (set! (-> s info) info)
@@ -626,7 +626,7 @@
626
626
 
627
627
  (define (compile-function [ms (ptr mstate)] [info datum] [params datum] [body datum]) -> (ptr compiled)
628
628
  (let ([fc (new-fctx params (func-info-results info))]
629
- [cf (cast (ptr compiled) (arena-alloc (current-arena) (sizeof compiled)))])
629
+ [cf (new (current-arena) compiled)])
630
630
  (set! (-> ms fname) (func-info-name info))
631
631
  (set! compiling (func-info-name info))
632
632
  (set! current-loc 0)
@@ -757,7 +757,7 @@
757
757
  (set-tag-info-export! (cadr f) (export-name! ms (tag-info-name (cadr f)))))
758
758
  tag-forms)
759
759
  (set! constants (constant-inits ms global-forms))
760
- (set! last (cast (ptr compiled) (arena-alloc (current-arena) (sizeof compiled))))
760
+ (set! last (new (current-arena) compiled))
761
761
  (set! (-> last next) 0)
762
762
  (set! first last)
763
763
  (for-each (lambda ([f datum])
@@ -814,7 +814,7 @@
814
814
  (define (table-functions! [ms (ptr mstate)] [last (ptr compiled)] [segment i64]) -> (ptr compiled)
815
815
  (let ([ts (reverse (-> ms tables))])
816
816
  (while (pair? ts)
817
- (let ([t (car ts)] [a (new-asm)] [cf (cast (ptr compiled) (arena-alloc (current-arena) (sizeof compiled)))])
817
+ (let ([t (car ts)] [a (new-asm)] [cf (new (current-arena) compiled)])
818
818
  (instr! a `(i32.const ,(caddr t)))
819
819
  (instr! a `(call ,(list-ref t 4)))
820
820
  (instr! a `(global.set ,(car t)))
@@ -973,7 +973,7 @@
973
973
  (define (link-module [ms (ptr mstate)] [compiled (ptr compiled)] [start-fc (ptr fctx)] [setup (ptr asm)]
974
974
  [literal-segment datum] [global-forms datum] [tag-forms datum] [memory-form datum]
975
975
  [table-form datum] [constants (ptr hash-table)]) -> datum
976
- (let* ([lk (cast (ptr linker) (arena-alloc (current-arena) (sizeof linker)))]
976
+ (let* ([lk (new (current-arena) linker)]
977
977
  [has-start (or (> (asm-size setup) 0) (> (asm-size (-> start-fc asm)) 0))]
978
978
  [func-imports (reverse (-> ms func-imports))]
979
979
  [global-imports (reverse (-> ms global-imports))]