Commit | Line | Data |
---|---|---|
e4882d7d A |
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <!-- Step 6: File --> | |
3 | <!-- input document must be in the following format --> | |
4 | <!-- | |
5 | <mal> | |
6 | <stdin>...stdin text...</stdin> | |
7 | <stdout> ... ignored, omitted ... </stdout> | |
8 | <state> contains env and atoms </state> | |
9 | </mal> | |
10 | --> | |
11 | <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:env="ENV" xmlns:core="CORE" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:map="http://www.w3.org/2005/xpath-functions/map" version="3.0" exclude-result-prefixes="fn xs map env core"> | |
12 | <xsl:import href="reader.xslt"/> | |
13 | <xsl:import href="printer.xslt"/> | |
14 | <xsl:import href="env.xslt"/> | |
15 | <xsl:import href="core.xslt"/> | |
16 | <xsl:output method="xml" encoding="utf-8" indent="yes"/> | |
17 | <xsl:template match="mal" name="rep"> | |
fd99084c | 18 | <xsl:param name="display" select="false()" /> |
e4882d7d A |
19 | <xsl:choose> |
20 | <xsl:when test="string(state/env/@data) = ''"> | |
21 | <xsl:variable name="argv"> | |
22 | <malval kind="list"> | |
23 | <lvalue> | |
24 | <xsl:for-each select="argv/arg/text()"> | |
25 | <malval kind="string" value="{.}"/> | |
26 | </xsl:for-each> | |
27 | </lvalue> | |
28 | </malval> | |
29 | </xsl:variable> | |
30 | <xsl:variable name="vstate"> | |
31 | <mal> | |
32 | <state> | |
33 | <env data="{env:serialise(env:empty() => env:bind-all(core:ns()/@name, core:ns()) => env:set('*ARGV*', $argv) => env:toReplEnv())}"/> | |
34 | <atoms/> | |
35 | </state> | |
36 | <stdin>(do (def! not (fn* (a) (if a false true))) (def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) "\nnil)"))))))</stdin> | |
37 | </mal> | |
38 | </xsl:variable> | |
39 | <xsl:variable name="new-state"> | |
40 | <xsl:for-each select="$vstate/mal"> | |
41 | <xsl:call-template name="rep"/> | |
42 | </xsl:for-each> | |
43 | </xsl:variable> | |
44 | <xsl:variable name="state-v"> | |
45 | <xsl:sequence select="$new-state/mal/state"/> | |
46 | <xsl:sequence select="stdin"/> | |
47 | </xsl:variable> | |
48 | <xsl:for-each select="$state-v"> | |
fd99084c A |
49 | <xsl:call-template name="rep"> |
50 | <xsl:with-param name="display" select="$display"/> | |
51 | </xsl:call-template> | |
e4882d7d A |
52 | </xsl:for-each> |
53 | </xsl:when> | |
54 | <xsl:otherwise> | |
55 | <mal> | |
56 | <xsl:variable name="env" as="map(*)"> | |
57 | <xsl:sequence select="env:deserialise(state/env/@data)"/> | |
58 | </xsl:variable> | |
59 | <xsl:sequence select="stdin"/> | |
60 | <xsl:variable name="_read"> | |
61 | <xsl:call-template name="READ"/> | |
62 | </xsl:variable> | |
63 | <xsl:variable name="_eval"> | |
64 | <xsl:for-each select="$_read"> | |
65 | <xsl:call-template name="EVAL"> | |
66 | <xsl:with-param name="env" select="$env"/> | |
67 | </xsl:call-template> | |
68 | </xsl:for-each> | |
69 | </xsl:variable> | |
70 | <xsl:for-each select="$_eval"> | |
fd99084c | 71 | <xsl:variable name="_print"> |
e4882d7d A |
72 | <xsl:variable name="data"> |
73 | <xsl:sequence select="data/value"/> | |
74 | <xsl:sequence select="atoms"/> | |
75 | </xsl:variable> | |
76 | <xsl:for-each select="$data"> | |
77 | <xsl:call-template name="PRINT"/> | |
78 | </xsl:for-each> | |
fd99084c A |
79 | </xsl:variable> |
80 | <xsl:if test="$display"> | |
81 | <xsl:message> | |
82 | <request kind="display" value="{$_print}"/> | |
83 | </xsl:message> | |
84 | </xsl:if> | |
e4882d7d A |
85 | <state> |
86 | <env data="{env/@data}"/> | |
87 | <xsl:sequence select="atoms"/> | |
88 | </state> | |
89 | </xsl:for-each> | |
90 | </mal> | |
91 | </xsl:otherwise> | |
92 | </xsl:choose> | |
93 | </xsl:template> | |
94 | <xsl:template name="PRINT"> | |
95 | <xsl:variable name="str"> | |
96 | <xsl:call-template name="malprinter-pr_str"> | |
97 | <xsl:with-param name="readably" select="true()"/> | |
98 | </xsl:call-template> | |
99 | </xsl:variable> | |
100 | <xsl:value-of select="$str"/> | |
101 | </xsl:template> | |
102 | <xsl:template name="eval_ast"> | |
103 | <xsl:param name="env"/> | |
104 | <xsl:param name="atoms"/> | |
105 | <xsl:choose> | |
106 | <xsl:when test="value/malval/@kind = 'symbol'"> | |
107 | <xsl:variable name="val"> | |
108 | <xsl:sequence select="env:get($env, value/malval/@value)"/> | |
109 | </xsl:variable> | |
110 | <value> | |
111 | <xsl:sequence select="$val"/> | |
112 | </value> | |
113 | </xsl:when> | |
114 | <xsl:when test="value/malval/@kind = 'list' or value/malval/@kind = 'vector' or value/malval/@kind = 'hash'"> | |
115 | <xsl:variable name="myctx"> | |
116 | <xsl:iterate select="value/malval/lvalue/malval"> | |
117 | <xsl:param name="atoms" select="$atoms"/> | |
118 | <xsl:param name="xctx" select="()"/> | |
119 | <xsl:on-completion> | |
120 | <xsl:sequence select="$xctx/value/malval"/> | |
121 | <xsl:sequence select="$atoms"/> | |
122 | </xsl:on-completion> | |
123 | <xsl:variable name="ctx"> | |
124 | <value> | |
125 | <xsl:sequence select="."/> | |
126 | </value> | |
127 | <xsl:sequence select="$atoms"/> | |
128 | </xsl:variable> | |
129 | <xsl:variable name="xctxy"> | |
130 | <xsl:for-each select="$ctx"> | |
131 | <xsl:variable name="val"> | |
132 | <xsl:call-template name="EVAL"> | |
133 | <xsl:with-param name="env" select="$env"/> | |
134 | <xsl:with-param name="encode-env" select="false()"/> | |
135 | </xsl:call-template> | |
136 | </xsl:variable> | |
137 | <xsl:sequence select="$val/data/value"/> | |
138 | <xsl:sequence select="$val/atoms"/> | |
139 | </xsl:for-each> | |
140 | </xsl:variable> | |
141 | <xsl:next-iteration> | |
142 | <xsl:with-param name="atoms" select="$xctxy/atoms"/> | |
143 | <xsl:with-param name="xctx" select="$xctx, $xctxy"/> | |
144 | </xsl:next-iteration> | |
145 | </xsl:iterate> | |
146 | </xsl:variable> | |
147 | <value> | |
148 | <malval kind="{value/malval/@kind}"> | |
149 | <lvalue> | |
150 | <xsl:sequence select="$myctx/malval"/> | |
151 | </lvalue> | |
152 | </malval> | |
153 | </value> | |
154 | <xsl:sequence select="$myctx/atoms"/> | |
155 | </xsl:when> | |
156 | <xsl:otherwise> | |
157 | <xsl:sequence select="."/> | |
158 | <xsl:sequence select="$atoms"/> | |
159 | </xsl:otherwise> | |
160 | </xsl:choose> | |
161 | </xsl:template> | |
162 | <!-- uapply[env, fn, args] --> | |
163 | <xsl:template name="uapply"> | |
164 | <xsl:param name="func"/> | |
165 | <xsl:param name="args"/> | |
166 | <xsl:param name="env"/> | |
167 | <xsl:variable name="nenv" select="$env => env:hier(env:deserialise($func/malval/env/@data)) => env:close-with-binds($func/malval/binds/malval/@value, $args/value/malval/lvalue/malval)"/> | |
168 | <xsl:variable name="body"> | |
169 | <value> | |
170 | <xsl:sequence select="$func/malval/body/malval"/> | |
171 | </value> | |
172 | <xsl:sequence select="atoms"/> | |
173 | </xsl:variable> | |
174 | <xsl:variable name="result"> | |
175 | <xsl:for-each select="$body"> | |
176 | <xsl:call-template name="EVAL"> | |
177 | <xsl:with-param name="env" select="$nenv"/> | |
178 | </xsl:call-template> | |
179 | </xsl:for-each> | |
180 | </xsl:variable> | |
181 | <xsl:sequence select="$result/data/value"/> | |
182 | <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($result/env/@data) => env:replEnv()))}"/> | |
183 | <xsl:sequence select="$result/atoms"/> | |
184 | </xsl:template> | |
185 | <xsl:template name="EVAL"> | |
186 | <xsl:param name="env"/> | |
187 | <xsl:param name="encode-env" select="true()"/> | |
188 | <xsl:variable name="atoms" select="atoms"/> | |
189 | <xsl:variable name="data"> | |
190 | <xsl:choose> | |
191 | <xsl:when test="value/malval/@kind = 'list'"> | |
192 | <xsl:choose> | |
193 | <xsl:when test="count(value/malval/lvalue/malval) = 0"> | |
194 | <xsl:sequence select="."/> | |
195 | <xsl:if test="$encode-env"> | |
196 | <env data="{env:serialise($env)}"/> | |
197 | </xsl:if> | |
198 | <xsl:sequence select="$atoms"/> | |
199 | </xsl:when> | |
200 | <xsl:otherwise> | |
201 | <xsl:choose> | |
80e3d5eb A |
202 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] |
203 | return $fn/@kind = 'symbol' and | |
204 | $fn/@value = 'def!'"> | |
e4882d7d A |
205 | <xsl:variable name="name"> |
206 | <xsl:value-of select="value/malval/lvalue/malval[2]/@value"/> | |
207 | </xsl:variable> | |
208 | <xsl:variable name="xvalue"> | |
209 | <value> | |
210 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
211 | </value> | |
212 | <xsl:sequence select="$atoms"/> | |
213 | </xsl:variable> | |
214 | <xsl:variable name="value"> | |
215 | <xsl:for-each select="$xvalue"> | |
216 | <xsl:call-template name="EVAL"> | |
217 | <xsl:with-param name="env" select="$env"/> | |
218 | <xsl:with-param name="encode-env" select="false()"/> | |
219 | </xsl:call-template> | |
220 | </xsl:for-each> | |
221 | </xsl:variable> | |
222 | <xsl:sequence select="$value/data/value"/> | |
223 | <xsl:if test="$encode-env"> | |
224 | <env data="{env:serialise(env:set($env, $name, $value/data/value/malval))}"/> | |
225 | </xsl:if> | |
226 | <xsl:sequence select="$value/atoms"/> | |
227 | </xsl:when> | |
80e3d5eb A |
228 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] |
229 | return $fn/@kind = 'symbol' and | |
230 | $fn/@value = 'let*'"> | |
e4882d7d A |
231 | <xsl:variable name="xvalue"> |
232 | <value> | |
233 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
234 | </value> | |
235 | <xsl:sequence select="$atoms"/> | |
236 | </xsl:variable> | |
237 | <xsl:iterate select="fn:group_consec(value/malval/lvalue/malval[2]/lvalue/malval)"> | |
238 | <xsl:param name="new_env" select="env:close($env)"/> | |
239 | <xsl:param name="new_atoms" select="$atoms"/> | |
240 | <xsl:on-completion> | |
241 | <xsl:variable name="xvalue"> | |
242 | <xsl:sequence select="$xvalue/value"/> | |
243 | <xsl:sequence select="$new_atoms"/> | |
244 | </xsl:variable> | |
245 | <xsl:variable name="value"> | |
246 | <xsl:for-each select="$xvalue"> | |
247 | <xsl:call-template name="EVAL"> | |
248 | <xsl:with-param name="env" select="$new_env"/> | |
249 | <xsl:with-param name="encode-env" select="$encode-env"/> | |
250 | </xsl:call-template> | |
251 | </xsl:for-each> | |
252 | </xsl:variable> | |
253 | <xsl:sequence select="$value/data/value"/> | |
254 | <xsl:if test="$encode-env"> | |
255 | <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($value/env/@data) => env:replEnv()))}"/> | |
256 | </xsl:if> | |
257 | <xsl:sequence select="$value/atoms"/> | |
258 | </xsl:on-completion> | |
259 | <xsl:variable name="name"> | |
260 | <xsl:value-of select="node()[name() = 'first']/malval/@value"/> | |
261 | </xsl:variable> | |
262 | <xsl:variable name="xvalue"> | |
263 | <value> | |
264 | <xsl:sequence select="node()[name() = 'second']/malval"/> | |
265 | </value> | |
266 | <xsl:sequence select="$new_atoms"/> | |
267 | </xsl:variable> | |
268 | <xsl:variable name="value"> | |
269 | <xsl:for-each select="$xvalue"> | |
270 | <xsl:call-template name="EVAL"> | |
271 | <xsl:with-param name="env" select="$new_env"/> | |
272 | <xsl:with-param name="encode-env" select="false()"/> | |
273 | </xsl:call-template> | |
274 | </xsl:for-each> | |
275 | </xsl:variable> | |
276 | <xsl:next-iteration> | |
277 | <xsl:with-param name="new_env" select="env:set($new_env, $name, $value/data/value/malval)"/> | |
278 | <xsl:with-param name="new_atoms" select="$value/atoms"/> | |
279 | </xsl:next-iteration> | |
280 | </xsl:iterate> | |
281 | </xsl:when> | |
80e3d5eb A |
282 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] |
283 | return $fn/@kind = 'symbol' and | |
284 | $fn/@value = 'do'"> | |
e4882d7d A |
285 | <xsl:iterate select="value/malval/lvalue/malval[position() > 1]"> |
286 | <xsl:param name="new_env" select="$env"/> | |
287 | <xsl:param name="atoms" select="$atoms"/> | |
288 | <xsl:param name="previous_res" select="()"/> | |
289 | <xsl:on-completion> | |
290 | <xsl:sequence select="$previous_res"/> | |
291 | <xsl:if test="$encode-env"> | |
292 | <env data="{env:serialise($new_env)}"/> | |
293 | </xsl:if> | |
294 | <xsl:sequence select="$atoms"/> | |
295 | </xsl:on-completion> | |
296 | <xsl:variable name="xvalue"> | |
297 | <value> | |
298 | <xsl:sequence select="."/> | |
299 | </value> | |
300 | <xsl:sequence select="$atoms"/> | |
301 | </xsl:variable> | |
302 | <xsl:variable name="value"> | |
303 | <xsl:for-each select="$xvalue"> | |
304 | <xsl:call-template name="EVAL"> | |
305 | <xsl:with-param name="env" select="$new_env"/> | |
306 | </xsl:call-template> | |
307 | </xsl:for-each> | |
308 | </xsl:variable> | |
309 | <xsl:next-iteration> | |
310 | <xsl:with-param name="new_env" select="env:deserialise($value/env/@data)"/> | |
311 | <xsl:with-param name="previous_res" select="$value/data/value"/> | |
312 | <xsl:with-param name="atoms" select="$value/atoms"/> | |
313 | </xsl:next-iteration> | |
314 | </xsl:iterate> | |
315 | </xsl:when> | |
80e3d5eb A |
316 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] |
317 | return $fn/@kind = 'symbol' and | |
318 | $fn/@value = 'if'"> | |
e4882d7d A |
319 | <xsl:variable name="cond"> |
320 | <xsl:for-each select="value/malval/lvalue/malval[2]"> | |
321 | <xsl:variable name="context"> | |
322 | <value> | |
323 | <xsl:sequence select="."/> | |
324 | </value> | |
325 | <xsl:sequence select="$atoms"/> | |
326 | </xsl:variable> | |
327 | <xsl:for-each select="$context"> | |
328 | <xsl:call-template name="EVAL"> | |
329 | <xsl:with-param name="env" select="$env"/> | |
330 | <xsl:with-param name="encode-env" select="false()"/> | |
331 | </xsl:call-template> | |
332 | </xsl:for-each> | |
333 | </xsl:for-each> | |
334 | </xsl:variable> | |
335 | <xsl:variable name="ptrue"> | |
336 | <xsl:for-each select="value/malval/lvalue/malval[3]"> | |
337 | <value> | |
338 | <xsl:sequence select="."/> | |
339 | </value> | |
340 | <xsl:sequence select="$cond/atoms"/> | |
341 | </xsl:for-each> | |
342 | </xsl:variable> | |
343 | <xsl:variable name="pfalse"> | |
344 | <xsl:for-each select="value/malval/lvalue/malval[4]"> | |
345 | <value> | |
346 | <xsl:sequence select="."/> | |
347 | </value> | |
348 | <xsl:sequence select="$cond/atoms"/> | |
349 | </xsl:for-each> | |
350 | </xsl:variable> | |
351 | <xsl:variable name="xfalse"> | |
352 | <xsl:choose> | |
353 | <xsl:when test="empty($pfalse/value)"> | |
354 | <value> | |
355 | <malval kind="nil"/> | |
356 | </value> | |
357 | <xsl:sequence select="$cond/atoms"/> | |
358 | </xsl:when> | |
359 | <xsl:otherwise> | |
360 | <xsl:sequence select="$pfalse/value"/> | |
361 | <xsl:sequence select="$pfalse/atoms"/> | |
362 | </xsl:otherwise> | |
363 | </xsl:choose> | |
364 | </xsl:variable> | |
365 | <xsl:variable name="res"> | |
366 | <xsl:choose> | |
80e3d5eb A |
367 | <xsl:when test="let $kind := $cond/data/value/malval/@kind |
368 | return $kind = 'nil' or | |
369 | $kind = 'false'"> | |
e4882d7d A |
370 | <xsl:for-each select="$xfalse"> |
371 | <xsl:call-template name="EVAL"> | |
372 | <xsl:with-param name="env" select="$env"/> | |
373 | <xsl:with-param name="encode-env" select="$encode-env"/> | |
374 | </xsl:call-template> | |
375 | </xsl:for-each> | |
376 | </xsl:when> | |
377 | <xsl:otherwise> | |
378 | <xsl:for-each select="$ptrue"> | |
379 | <xsl:call-template name="EVAL"> | |
380 | <xsl:with-param name="env" select="$env"/> | |
381 | <xsl:with-param name="encode-env" select="$encode-env"/> | |
382 | </xsl:call-template> | |
383 | </xsl:for-each> | |
384 | </xsl:otherwise> | |
385 | </xsl:choose> | |
386 | </xsl:variable> | |
387 | <xsl:sequence select="$res/data/value"/> | |
388 | <xsl:if test="$encode-env"> | |
389 | <env data="{env:serialise($env)}"/> | |
390 | </xsl:if> | |
391 | <xsl:sequence select="$res/atoms"/> | |
392 | </xsl:when> | |
80e3d5eb A |
393 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] |
394 | return $fn/@kind = 'symbol' and | |
395 | $fn/@value = 'fn*'"> | |
e4882d7d A |
396 | <value> |
397 | <malval kind="userfunction"> | |
398 | <binds> | |
399 | <xsl:sequence select="value/malval/lvalue/malval[2]/lvalue/malval"/> | |
400 | </binds> | |
401 | <body> | |
402 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
403 | </body> | |
404 | <env data="{env:serialise(env:noReplEnv($env))}"/> | |
405 | <!-- capture current env --> | |
406 | </malval> | |
407 | </value> | |
408 | <xsl:if test="$encode-env"> | |
409 | <env data="{env:serialise($env)}"/> | |
410 | </xsl:if> | |
411 | <xsl:sequence select="$atoms"/> | |
412 | </xsl:when> | |
413 | <xsl:otherwise> | |
414 | <xsl:variable name="new_list"> | |
415 | <xsl:call-template name="eval_ast"> | |
416 | <xsl:with-param name="atoms" select="$atoms"/> | |
417 | <xsl:with-param name="env" select="$env"/> | |
418 | </xsl:call-template> | |
419 | </xsl:variable> | |
420 | <xsl:variable name="func"> | |
421 | <xsl:for-each select="$new_list"> | |
422 | <xsl:sequence select="value/malval/lvalue/malval[1]"/> | |
423 | </xsl:for-each> | |
424 | </xsl:variable> | |
425 | <xsl:variable name="args"> | |
426 | <xsl:for-each select="$new_list"> | |
427 | <value> | |
428 | <malval kind="list"> | |
429 | <lvalue> | |
430 | <xsl:for-each select="value/malval/lvalue/node()[position() != 1]"> | |
431 | <xsl:sequence select="."/> | |
432 | </xsl:for-each> | |
433 | </lvalue> | |
434 | </malval> | |
435 | </value> | |
436 | <xsl:sequence select="$new_list/atoms"/> | |
437 | </xsl:for-each> | |
438 | </xsl:variable> | |
439 | <xsl:variable name="resultv"> | |
440 | <xsl:choose> | |
441 | <xsl:when test="$func/malval/@kind = 'userfunction'"> | |
442 | <xsl:call-template name="uapply"> | |
443 | <xsl:with-param name="env" select="$env"/> | |
444 | <xsl:with-param name="func" select="$func"/> | |
445 | <xsl:with-param name="args" select="$args"/> | |
446 | </xsl:call-template> | |
447 | </xsl:when> | |
448 | <xsl:otherwise> | |
449 | <xsl:choose> | |
450 | <xsl:when test="$func/malval/@name = 'eval'"> | |
451 | <!-- needs access to env --> | |
452 | <xsl:variable name="venv" select="env:replEnv($env)"/> | |
453 | <xsl:variable name="form"> | |
454 | <value> | |
455 | <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/> | |
456 | </value> | |
457 | <xsl:sequence select="$atoms"/> | |
458 | </xsl:variable> | |
459 | <xsl:variable name="value"> | |
460 | <xsl:for-each select="$form"> | |
461 | <xsl:call-template name="EVAL"> | |
462 | <xsl:with-param name="env" select="$venv"/> | |
463 | <xsl:with-param name="encode-env" select="$encode-env"/> | |
464 | </xsl:call-template> | |
465 | </xsl:for-each> | |
466 | </xsl:variable> | |
467 | <xsl:sequence select="$value/data/value"/> | |
468 | <xsl:if test="$encode-env"> | |
469 | <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($value/env/@data)))}"/> | |
470 | </xsl:if> | |
471 | <xsl:sequence select="$value/atoms"/> | |
472 | </xsl:when> | |
473 | <xsl:when test="$func/malval/@name = 'atom'"> | |
474 | <!-- needs access to atoms --> | |
475 | <xsl:variable name="atom-ident" select="count($atoms/atom)"/> | |
476 | <value> | |
477 | <malval kind="atom" value="{$atom-ident}"/> | |
478 | </value> | |
479 | <atoms> | |
480 | <xsl:for-each select="$atoms/atom"> | |
481 | <xsl:sequence select="."/> | |
482 | </xsl:for-each> | |
483 | <atom identity="{$atom-ident}"> | |
484 | <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/> | |
485 | </atom> | |
486 | </atoms> | |
487 | </xsl:when> | |
488 | <xsl:when test="$func/malval/@name = 'deref'"> | |
489 | <!-- needs access to atoms --> | |
490 | <value> | |
491 | <xsl:sequence select="$atoms/atom[@identity = $args/value/malval/lvalue/malval[1]/@value]/malval"/> | |
492 | </value> | |
493 | <xsl:sequence select="$atoms"/> | |
494 | </xsl:when> | |
495 | <xsl:when test="$func/malval/@name = 'reset!'"> | |
496 | <!-- needs access to atoms --> | |
497 | <xsl:variable name="atom-ident" select="$args/value/malval/lvalue/malval[1]/@value"/> | |
498 | <xsl:variable name="newv" select="$args/value/malval/lvalue/malval[2]"/> | |
499 | <value> | |
500 | <xsl:sequence select="$newv"/> | |
501 | </value> | |
502 | <atoms> | |
503 | <xsl:for-each select="$atoms/atom[@identity != $atom-ident]"> | |
504 | <xsl:sequence select="."/> | |
505 | </xsl:for-each> | |
506 | <atom identity="{$atom-ident}"> | |
507 | <xsl:sequence select="$newv"/> | |
508 | </atom> | |
509 | </atoms> | |
510 | </xsl:when> | |
511 | <xsl:when test="$func/malval/@name = 'swap!'"> | |
512 | <!-- needs access to atoms --> | |
513 | <xsl:variable name="atom-ident" select="$args/value/malval/lvalue/malval[1]/@value"/> | |
514 | <xsl:variable name="atom-value" select="$atoms/atom[@identity = $atom-ident]/malval"/> | |
515 | <xsl:variable name="fn" select="$args/value/malval/lvalue/malval[2]"/> | |
516 | <xsl:variable name="newlist"> | |
517 | <value> | |
518 | <malval kind="list"> | |
519 | <lvalue> | |
520 | <xsl:sequence select="$fn"/> | |
521 | <xsl:sequence select="$atom-value"/> | |
522 | <xsl:sequence select="$args/value/malval/lvalue/malval[position() > 2]"/> | |
523 | </lvalue> | |
524 | </malval> | |
525 | </value> | |
526 | <xsl:sequence select="$atoms"/> | |
527 | </xsl:variable> | |
528 | <xsl:variable name="newv"> | |
529 | <xsl:for-each select="$newlist"> | |
530 | <xsl:call-template name="EVAL"> | |
531 | <xsl:with-param name="env" select="$env"/> | |
532 | <xsl:with-param name="encode-env" select="$encode-env"/> | |
533 | </xsl:call-template> | |
534 | </xsl:for-each> | |
535 | </xsl:variable> | |
536 | <xsl:sequence select="$newv/data/value"/> | |
537 | <atoms> | |
538 | <xsl:for-each select="$newv/atoms/atom[@identity != $atom-ident]"> | |
539 | <xsl:sequence select="."/> | |
540 | </xsl:for-each> | |
541 | <atom identity="{$atom-ident}"> | |
542 | <xsl:sequence select="$newv/data/value/malval"/> | |
543 | </atom> | |
544 | </atoms> | |
545 | <xsl:if test="$encode-env"> | |
546 | <xsl:sequence select="$newv/env"/> | |
547 | </xsl:if> | |
548 | </xsl:when> | |
549 | <xsl:otherwise> | |
550 | <xsl:call-template name="core-apply"> | |
551 | <xsl:with-param name="func" select="$func"/> | |
552 | <xsl:with-param name="args" select="$args"/> | |
553 | </xsl:call-template> | |
554 | <xsl:sequence select="$atoms"/> | |
555 | </xsl:otherwise> | |
556 | </xsl:choose> | |
557 | </xsl:otherwise> | |
558 | </xsl:choose> | |
559 | </xsl:variable> | |
560 | <xsl:for-each select="$resultv"> | |
561 | <xsl:choose> | |
562 | <xsl:when test="empty(env)"> | |
563 | <xsl:if test="$encode-env"> | |
564 | <env data="{env:serialise($env)}"/> | |
565 | </xsl:if> | |
566 | </xsl:when> | |
567 | <xsl:otherwise> | |
568 | <xsl:sequence select="env"/> | |
569 | </xsl:otherwise> | |
570 | </xsl:choose> | |
571 | <xsl:sequence select="atoms"/> | |
572 | <xsl:sequence select="value"/> | |
573 | </xsl:for-each> | |
574 | </xsl:otherwise> | |
575 | </xsl:choose> | |
576 | </xsl:otherwise> | |
577 | </xsl:choose> | |
578 | </xsl:when> | |
579 | <xsl:otherwise> | |
580 | <xsl:call-template name="eval_ast"> | |
581 | <xsl:with-param name="atoms" select="$atoms"/> | |
582 | <xsl:with-param name="env" select="$env"/> | |
583 | </xsl:call-template> | |
584 | <xsl:if test="$encode-env"> | |
585 | <env data="{env:serialise($env)}"/> | |
586 | </xsl:if> | |
587 | <!-- <xsl:sequence select="$atoms"/> --> | |
588 | </xsl:otherwise> | |
589 | </xsl:choose> | |
590 | </xsl:variable> | |
591 | <data> | |
592 | <xsl:sequence select="$data/value"/> | |
593 | </data> | |
594 | <xsl:if test="$encode-env"> | |
595 | <env data="{$data/env/@data}"/> | |
596 | </xsl:if> | |
597 | <xsl:sequence select="$data/atoms"/> | |
598 | </xsl:template> | |
599 | <xsl:template name="READ"> | |
600 | <xsl:variable name="context"> | |
601 | <str> | |
602 | <xsl:copy-of select="stdin/text()"/> | |
603 | </str> | |
604 | </xsl:variable> | |
605 | <xsl:variable name="form"> | |
606 | <xsl:sequence select="state/atoms"/> | |
607 | <xsl:for-each select="$context"> | |
608 | <xsl:call-template name="malreader-read_str"/> | |
609 | </xsl:for-each> | |
610 | </xsl:variable> | |
611 | <xsl:for-each select="$form"> | |
612 | <xsl:if test="error"> | |
613 | <xsl:value-of select="error(QName('MAL', 'Error'), string(error))"/> | |
614 | </xsl:if> | |
615 | <xsl:sequence select="."/> | |
616 | </xsl:for-each> | |
617 | </xsl:template> | |
618 | <xsl:function name="fn:group_consec"> | |
619 | <xsl:param name="nodes"/> | |
620 | <xsl:variable name="groups"> | |
621 | <xsl:for-each-group select="$nodes" group-by="position() mod 2"> | |
622 | <xsl:choose> | |
623 | <xsl:when test="position() = 1"> | |
624 | <first> | |
625 | <xsl:sequence select="current-group()"/> | |
626 | </first> | |
627 | </xsl:when> | |
628 | <xsl:otherwise> | |
629 | <second> | |
630 | <xsl:sequence select="current-group()"/> | |
631 | </second> | |
632 | </xsl:otherwise> | |
633 | </xsl:choose> | |
634 | </xsl:for-each-group> | |
635 | </xsl:variable> | |
636 | <xsl:iterate select="1 to count($groups/first/*)"> | |
637 | <element> | |
638 | <xsl:variable name="idx" select="number(.)"/> | |
639 | <first> | |
640 | <xsl:sequence select="$groups/first/node()[position() = $idx]"/> | |
641 | </first> | |
642 | <second> | |
643 | <xsl:sequence select="$groups/second/node()[position() = $idx]"/> | |
644 | </second> | |
645 | </element> | |
646 | </xsl:iterate> | |
647 | </xsl:function> | |
648 | </xsl:stylesheet> |