Commit | Line | Data |
---|---|---|
d4798a57 A |
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <!-- Step A: MAL --> | |
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> | |
d4798a57 A |
9 | </mal> |
10 | --> | |
1c2f45cf A |
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" xmlns:err="http://www.w3.org/2005/xqt-errors" xmlns:MAL="MAL" version="3.0" exclude-result-prefixes="fn xs map env core err MAL"> |
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"> | |
18 | <xsl:choose> | |
19 | <xsl:when test="string(state/env/@data) = ''"> | |
20 | <xsl:variable name="argv"> | |
21 | <malval kind="list"> | |
22 | <lvalue> | |
23 | <xsl:for-each select="argv/arg/text()"> | |
24 | <malval kind="string" value="{.}"/> | |
25 | </xsl:for-each> | |
26 | </lvalue> | |
27 | </malval> | |
28 | </xsl:variable> | |
29 | <xsl:variable name="vstate"> | |
30 | <mal> | |
31 | <state> | |
32 | <env data="{env:serialise(env:empty() => env:bind-all(core:ns()/@name, core:ns()) => env:set('*ARGV*', $argv) => env:toReplEnv())}"/> | |
33 | <atoms/> | |
34 | </state> | |
35 | <stdin>(do (def! not (fn* (a) (if a false true))) (def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) "\nnil)"))))) (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw "odd number of forms to cond")) (cons 'cond (rest (rest xs))))))) (def! *host-language* "XSLT"))</stdin> | |
36 | </mal> | |
37 | </xsl:variable> | |
38 | <xsl:variable name="new-state"> | |
39 | <xsl:for-each select="$vstate/mal"> | |
40 | <xsl:call-template name="rep"/> | |
41 | </xsl:for-each> | |
42 | </xsl:variable> | |
43 | <xsl:variable name="state-v"> | |
44 | <xsl:sequence select="$new-state/mal/state"/> | |
45 | <xsl:sequence select="stdin"/> | |
46 | </xsl:variable> | |
47 | <xsl:for-each select="$state-v"> | |
48 | <xsl:call-template name="rep"/> | |
49 | </xsl:for-each> | |
50 | </xsl:when> | |
51 | <xsl:otherwise> | |
52 | <mal> | |
53 | <xsl:variable name="env" as="map(*)"> | |
54 | <xsl:sequence select="env:deserialise(state/env/@data)"/> | |
d4798a57 | 55 | </xsl:variable> |
1c2f45cf A |
56 | <xsl:sequence select="stdin"/> |
57 | <xsl:variable name="_read"> | |
58 | <xsl:call-template name="READ"/> | |
d4798a57 | 59 | </xsl:variable> |
1c2f45cf A |
60 | <xsl:variable name="_eval"> |
61 | <xsl:for-each select="$_read"> | |
62 | <xsl:call-template name="EVAL"> | |
63 | <xsl:with-param name="env" select="$env"/> | |
64 | </xsl:call-template> | |
d4798a57 A |
65 | </xsl:for-each> |
66 | </xsl:variable> | |
1c2f45cf A |
67 | <xsl:for-each select="$_eval"> |
68 | <stdout> | |
69 | <xsl:variable name="data"> | |
70 | <xsl:sequence select="data/value"/> | |
71 | <xsl:sequence select="atoms[1]"/> | |
72 | </xsl:variable> | |
73 | <xsl:for-each select="$data"> | |
74 | <xsl:call-template name="PRINT"/> | |
75 | </xsl:for-each> | |
76 | </stdout> | |
77 | <state> | |
78 | <env data="{env/@data}"/> | |
79 | <xsl:sequence select="atoms[1]"/> | |
80 | </state> | |
d4798a57 | 81 | </xsl:for-each> |
1c2f45cf A |
82 | </mal> |
83 | </xsl:otherwise> | |
84 | </xsl:choose> | |
85 | </xsl:template> | |
86 | <xsl:template name="PRINT"> | |
87 | <xsl:variable name="str"> | |
88 | <xsl:call-template name="malprinter-pr_str"> | |
89 | <xsl:with-param name="readably" select="true()"/> | |
90 | </xsl:call-template> | |
91 | </xsl:variable> | |
92 | <xsl:value-of select="$str"/> | |
93 | </xsl:template> | |
94 | <xsl:template name="eval_ast"> | |
95 | <xsl:param name="env"/> | |
96 | <xsl:param name="atoms"/> | |
97 | <xsl:choose> | |
98 | <xsl:when test="value/malval/@kind = 'symbol'"> | |
99 | <xsl:variable name="val"> | |
100 | <xsl:sequence select="env:get($env, value/malval/@value)"/> | |
101 | </xsl:variable> | |
102 | <value> | |
103 | <xsl:sequence select="$val"/> | |
104 | </value> | |
105 | </xsl:when> | |
106 | <xsl:when test="value/malval/@kind = 'list' or value/malval/@kind = 'vector' or value/malval/@kind = 'hash'"> | |
107 | <xsl:variable name="myctx"> | |
108 | <xsl:iterate select="value/malval/lvalue/malval"> | |
109 | <xsl:param name="atoms" select="$atoms"/> | |
110 | <xsl:param name="xctx" select="()"/> | |
111 | <xsl:on-completion> | |
112 | <xsl:sequence select="$xctx/value/malval"/> | |
113 | <xsl:sequence select="$atoms"/> | |
114 | </xsl:on-completion> | |
115 | <xsl:variable name="ctx"> | |
116 | <value> | |
117 | <xsl:sequence select="."/> | |
118 | </value> | |
119 | <xsl:sequence select="$atoms"/> | |
d4798a57 | 120 | </xsl:variable> |
1c2f45cf A |
121 | <xsl:variable name="xctxy"> |
122 | <xsl:for-each select="$ctx"> | |
123 | <xsl:variable name="val"> | |
124 | <xsl:call-template name="EVAL"> | |
125 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 126 | <xsl:with-param name="encode-env" select="false()"/> |
1c2f45cf A |
127 | </xsl:call-template> |
128 | </xsl:variable> | |
129 | <xsl:sequence select="$val/data/value"/> | |
130 | <xsl:sequence select="$val/atoms"/> | |
d4798a57 A |
131 | </xsl:for-each> |
132 | </xsl:variable> | |
1c2f45cf A |
133 | <xsl:next-iteration> |
134 | <xsl:with-param name="atoms" select="$xctxy/atoms"/> | |
135 | <xsl:with-param name="xctx" select="$xctx, $xctxy"/> | |
136 | </xsl:next-iteration> | |
137 | </xsl:iterate> | |
138 | </xsl:variable> | |
139 | <value> | |
140 | <malval kind="{value/malval/@kind}"> | |
141 | <lvalue> | |
142 | <xsl:sequence select="$myctx/malval"/> | |
143 | </lvalue> | |
144 | </malval> | |
145 | </value> | |
146 | <xsl:sequence select="$myctx/atoms"/> | |
147 | </xsl:when> | |
148 | <xsl:otherwise> | |
149 | <xsl:sequence select="."/> | |
150 | <xsl:sequence select="$atoms"/> | |
151 | </xsl:otherwise> | |
152 | </xsl:choose> | |
153 | </xsl:template> | |
154 | <xsl:template name="call-function"> | |
155 | <xsl:param name="func"/> | |
156 | <xsl:param name="args"/> | |
157 | <xsl:param name="env"/> | |
158 | <xsl:variable name="atoms" select="atoms"/> | |
159 | <xsl:variable name="res"> | |
d4798a57 | 160 | <xsl:choose> |
1c2f45cf A |
161 | <xsl:when test="$func/malval/@kind = 'userfunction'"> |
162 | <xsl:call-template name="uapply"> | |
163 | <xsl:with-param name="func" select="$func"/> | |
164 | <xsl:with-param name="args" select="$args"/> | |
165 | <xsl:with-param name="env" select="$env"/> | |
166 | </xsl:call-template> | |
d4798a57 | 167 | </xsl:when> |
1c2f45cf A |
168 | <xsl:otherwise> |
169 | <xsl:choose> | |
170 | <xsl:when test="$func/malval/@name = 'env??'"> | |
171 | <!-- needs access to env --> | |
172 | <xsl:variable name="nev" select="env:dump($env)"/> | |
173 | <xsl:variable name="value"> | |
174 | <malval kind="string" value="{$env => serialize(map{'method':'json'})}"/> | |
175 | </xsl:variable> | |
176 | <value> | |
177 | <xsl:sequence select="$value"/> | |
178 | </value> | |
179 | <env data="{env:serialise($env)}"/> | |
180 | <xsl:sequence select="$value/atoms[1]"/> | |
181 | </xsl:when> | |
182 | <xsl:when test="$func/malval/@name = 'eval'"> | |
183 | <!-- needs access to env --> | |
184 | <xsl:variable name="venv" select="env:replEnv($env) => env:wrapReplEnv()"/> | |
185 | <xsl:variable name="form"> | |
0365ac12 | 186 | <value> |
1c2f45cf | 187 | <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/> |
0365ac12 A |
188 | </value> |
189 | <xsl:sequence select="$atoms"/> | |
190 | </xsl:variable> | |
1c2f45cf A |
191 | <xsl:variable name="value"> |
192 | <xsl:for-each select="$form"> | |
193 | <xsl:call-template name="EVAL"> | |
194 | <xsl:with-param name="env" select="$venv"/> | |
195 | </xsl:call-template> | |
d4798a57 | 196 | </xsl:for-each> |
0365ac12 | 197 | </xsl:variable> |
1c2f45cf A |
198 | <xsl:sequence select="$value/data/value"/> |
199 | <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($value/env/@data) => env:collapseReplEnv()))}"/> | |
200 | <xsl:sequence select="$value/atoms[1]"/> | |
201 | </xsl:when> | |
202 | <xsl:when test="$func/malval/@name = 'atom'"> | |
203 | <!-- needs access to atoms --> | |
204 | <xsl:variable name="atom-ident" select="count($atoms/atom)"/> | |
205 | <value> | |
206 | <malval kind="atom" value="{$atom-ident}"/> | |
207 | </value> | |
208 | <atoms> | |
209 | <xsl:for-each select="$atoms/atom"> | |
210 | <xsl:sequence select="."/> | |
211 | </xsl:for-each> | |
212 | <atom identity="{$atom-ident}"> | |
213 | <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/> | |
214 | </atom> | |
215 | </atoms> | |
216 | </xsl:when> | |
217 | <xsl:when test="$func/malval/@name = 'deref'"> | |
218 | <!-- needs access to atoms --> | |
219 | <value> | |
220 | <xsl:sequence select="$atoms/atom[@identity = $args/value/malval/lvalue/malval[1]/@value]/malval"/> | |
221 | </value> | |
222 | <xsl:sequence select="$atoms"/> | |
223 | </xsl:when> | |
224 | <xsl:when test="$func/malval/@name = 'reset!'"> | |
225 | <!-- needs access to atoms --> | |
226 | <xsl:variable name="atom-ident" select="$args/value/malval/lvalue/malval[1]/@value"/> | |
227 | <xsl:variable name="newv" select="$args/value/malval/lvalue/malval[2]"/> | |
228 | <value> | |
229 | <xsl:sequence select="$newv"/> | |
230 | </value> | |
231 | <atoms> | |
232 | <xsl:for-each select="$atoms/atom[@identity != $atom-ident]"> | |
233 | <xsl:sequence select="."/> | |
234 | </xsl:for-each> | |
235 | <atom identity="{$atom-ident}"> | |
236 | <xsl:sequence select="$newv"/> | |
237 | </atom> | |
238 | </atoms> | |
239 | </xsl:when> | |
240 | <xsl:when test="$func/malval/@name = 'swap!'"> | |
241 | <!-- needs access to atoms --> | |
242 | <xsl:variable name="atom-ident" select="$args/value/malval/lvalue/malval[1]/@value"/> | |
243 | <xsl:variable name="atom-value" select="$atoms/atom[@identity = $atom-ident]/malval"/> | |
244 | <xsl:variable name="fn"> | |
245 | <xsl:sequence select="$args/value/malval/lvalue/malval[2]"/> | |
246 | </xsl:variable> | |
247 | <xsl:variable name="cargs"> | |
64eb1e7d | 248 | <value> |
1c2f45cf A |
249 | <malval kind="list"> |
250 | <lvalue> | |
251 | <xsl:sequence select="$atom-value"/> | |
252 | <xsl:sequence select="$args/value/malval/lvalue/malval[position() > 2]"/> | |
253 | </lvalue> | |
254 | </malval> | |
64eb1e7d | 255 | </value> |
1c2f45cf A |
256 | </xsl:variable> |
257 | <xsl:variable name="newv"> | |
258 | <xsl:call-template name="call-function"> | |
259 | <xsl:with-param name="func" select="$fn"/> | |
260 | <xsl:with-param name="args" select="$cargs"/> | |
261 | <xsl:with-param name="env" select="$env"/> | |
262 | </xsl:call-template> | |
263 | </xsl:variable> | |
264 | <xsl:sequence select="$newv/value"/> | |
265 | <atoms> | |
266 | <xsl:for-each select="$newv/atoms[1]/atom[@identity != $atom-ident]"> | |
267 | <xsl:sequence select="."/> | |
268 | </xsl:for-each> | |
269 | <atom identity="{$atom-ident}"> | |
270 | <xsl:sequence select="$newv/value/malval"/> | |
271 | </atom> | |
272 | </atoms> | |
273 | <xsl:sequence select="$newv/env"/> | |
274 | </xsl:when> | |
275 | <xsl:when test="$func/malval/@name = 'apply'"> | |
276 | <!-- needs access to env --> | |
277 | <!-- (apply F A... T) -> (F A... T...) --> | |
278 | <xsl:variable name="fun"> | |
279 | <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/> | |
280 | </xsl:variable> | |
281 | <xsl:variable name="args"> | |
64eb1e7d | 282 | <value> |
1c2f45cf A |
283 | <malval kind="list"> |
284 | <lvalue> | |
285 | <xsl:variable name="argc" select="count($args/value/malval/lvalue/malval)"/> | |
286 | <xsl:sequence select="$args/value/malval/lvalue/malval[position() gt 1 and position() lt $argc]"/> | |
287 | <xsl:sequence select="$args/value/malval/lvalue/malval[$argc]/lvalue/malval"/> | |
288 | </lvalue> | |
289 | </malval> | |
64eb1e7d | 290 | </value> |
1c2f45cf A |
291 | </xsl:variable> |
292 | <xsl:variable name="ctx"> | |
293 | <xsl:sequence select="./*"/> | |
64eb1e7d | 294 | <xsl:sequence select="$atoms"/> |
1c2f45cf A |
295 | </xsl:variable> |
296 | <xsl:variable name="res"> | |
297 | <xsl:for-each select="$ctx"> | |
298 | <xsl:call-template name="call-function"> | |
299 | <xsl:with-param name="func" select="$fun"/> | |
300 | <xsl:with-param name="args" select="$args"/> | |
301 | <xsl:with-param name="env" select="$env"/> | |
302 | </xsl:call-template> | |
303 | </xsl:for-each> | |
304 | </xsl:variable> | |
305 | <xsl:sequence select="$res/value"/> | |
306 | <xsl:sequence select="$res/env"/> | |
307 | <xsl:sequence select="$res/atoms[1]"/> | |
308 | </xsl:when> | |
309 | <xsl:when test="$func/malval/@name = 'map'"> | |
310 | <!-- needs access to env --> | |
311 | <!-- (map F T) -> (list (F Tx)...) --> | |
312 | <xsl:variable name="func"> | |
313 | <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/> | |
314 | </xsl:variable> | |
315 | <xsl:iterate select="$args/value/malval/lvalue/malval[2]/lvalue/malval"> | |
316 | <xsl:param name="xenv" select="$env"/> | |
317 | <xsl:param name="atoms" select="$atoms"/> | |
318 | <xsl:param name="value" select="()"/> | |
319 | <xsl:on-completion> | |
64eb1e7d A |
320 | <value> |
321 | <malval kind="list"> | |
322 | <lvalue> | |
1c2f45cf | 323 | <xsl:sequence select="$value"/> |
64eb1e7d A |
324 | </lvalue> |
325 | </malval> | |
326 | </value> | |
1c2f45cf A |
327 | <env data="{$env => env:serialise()}"/> |
328 | <xsl:sequence select="$atoms"/> | |
329 | </xsl:on-completion> | |
64eb1e7d A |
330 | <xsl:variable name="args"> |
331 | <value> | |
332 | <malval kind="list"> | |
333 | <lvalue> | |
1c2f45cf | 334 | <xsl:sequence select="."/> |
64eb1e7d A |
335 | </lvalue> |
336 | </malval> | |
337 | </value> | |
338 | </xsl:variable> | |
339 | <xsl:variable name="ctx"> | |
340 | <xsl:sequence select="./*"/> | |
341 | <xsl:sequence select="$atoms"/> | |
342 | </xsl:variable> | |
64eb1e7d A |
343 | <xsl:variable name="res"> |
344 | <xsl:for-each select="$ctx"> | |
1c2f45cf A |
345 | <xsl:call-template name="call-function"> |
346 | <xsl:with-param name="func" select="$func"/> | |
347 | <xsl:with-param name="args" select="$args"/> | |
348 | <xsl:with-param name="env" select="$xenv"/> | |
349 | </xsl:call-template> | |
64eb1e7d A |
350 | </xsl:for-each> |
351 | </xsl:variable> | |
1c2f45cf A |
352 | <xsl:next-iteration> |
353 | <xsl:with-param name="xenv" select="env:deserialise($res/env/@data)"/> | |
354 | <xsl:with-param name="atoms" select="$res/atoms[1]"/> | |
355 | <xsl:with-param name="value" select="$value, $res/value/malval"/> | |
356 | </xsl:next-iteration> | |
357 | </xsl:iterate> | |
358 | </xsl:when> | |
359 | <xsl:when test="$func/malval/@name = 'readline'"> | |
360 | <!-- requires interaction with harness --> | |
361 | <xsl:message> | |
362 | <request kind="readline" value="{$args/value/malval/lvalue/malval[1]/@value}"/> | |
363 | </xsl:message> | |
364 | <xsl:variable name="str" select="unparsed-text('xsl_input-string')"/> | |
365 | <xsl:sequence select="core:makeMALType($str, if (string-length($str) = 0) then 'nil' else 'string')"/> | |
366 | <xsl:sequence select="env"/> | |
367 | <xsl:sequence select="$atoms"/> | |
368 | </xsl:when> | |
369 | <xsl:otherwise> | |
370 | <xsl:variable name="ctx"> | |
64eb1e7d | 371 | <xsl:sequence select="$atoms"/> |
1c2f45cf A |
372 | </xsl:variable> |
373 | <xsl:for-each select="$ctx"> | |
374 | <xsl:call-template name="core-apply"> | |
375 | <xsl:with-param name="func" select="$func"/> | |
376 | <xsl:with-param name="args" select="$args"/> | |
377 | </xsl:call-template> | |
378 | </xsl:for-each> | |
379 | <xsl:sequence select="$atoms"/> | |
380 | </xsl:otherwise> | |
381 | </xsl:choose> | |
d4798a57 A |
382 | </xsl:otherwise> |
383 | </xsl:choose> | |
1c2f45cf A |
384 | </xsl:variable> |
385 | <xsl:sequence select="$res/value"/> | |
386 | <xsl:choose> | |
387 | <xsl:when test="$res/atoms"> | |
388 | <xsl:sequence select="$res/atoms[1]"/> | |
389 | </xsl:when> | |
390 | <xsl:otherwise> | |
391 | <xsl:sequence select="atoms"/> | |
392 | </xsl:otherwise> | |
393 | </xsl:choose> | |
394 | <xsl:choose> | |
395 | <xsl:when test="$res/env"> | |
396 | <xsl:sequence select="$res/env"/> | |
397 | </xsl:when> | |
398 | <xsl:otherwise> | |
399 | <env data="{$env => env:serialise()}"/> | |
400 | </xsl:otherwise> | |
401 | </xsl:choose> | |
402 | </xsl:template> | |
403 | <!-- uapply[env, fn, args] --> | |
404 | <xsl:template name="uapply"> | |
405 | <xsl:param name="func"/> | |
406 | <xsl:param name="args"/> | |
407 | <xsl:param name="env"/> | |
408 | <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)"/> | |
409 | <xsl:variable name="body"> | |
410 | <value> | |
411 | <xsl:sequence select="$func/malval/body/malval"/> | |
412 | </value> | |
413 | <xsl:sequence select="atoms[1]"/> | |
414 | </xsl:variable> | |
415 | <xsl:variable name="result"> | |
416 | <xsl:for-each select="$body"> | |
417 | <xsl:call-template name="EVAL"> | |
418 | <xsl:with-param name="env" select="$nenv"/> | |
419 | </xsl:call-template> | |
420 | </xsl:for-each> | |
421 | </xsl:variable> | |
422 | <xsl:sequence select="$result/data/value"/> | |
423 | <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($result/env/@data) => env:replEnv()))}"/> | |
424 | <xsl:sequence select="$result/atoms[1]"/> | |
425 | </xsl:template> | |
426 | <xsl:template name="quasiquote"> | |
427 | <xsl:param name="ast"/> | |
428 | <xsl:variable name="result"> | |
d4798a57 | 429 | <xsl:choose> |
1c2f45cf A |
430 | <xsl:when test="fn:is-pair($ast)"> |
431 | <xsl:choose> | |
432 | <xsl:when test="let $fst := $ast/lvalue/malval[1] return $fst/@kind = 'symbol' and $fst/@value = 'unquote'"> | |
433 | <xsl:sequence select="$ast/lvalue/malval[2]"/> | |
434 | </xsl:when> | |
435 | <xsl:when test="let $fst := $ast/lvalue/malval[1] return fn:is-pair($fst) and (let $fstfst := $fst/lvalue/malval[1] return $fstfst/@kind = 'symbol' and $fstfst/@value = 'splice-unquote')"> | |
d4798a57 A |
436 | <malval kind="list"> |
437 | <lvalue> | |
1c2f45cf A |
438 | <malval kind="symbol" value="concat"/> |
439 | <xsl:sequence select="$ast/lvalue/malval[1]/lvalue/malval[2]"/> | |
440 | <xsl:variable name="rest" select="$ast/lvalue/malval[position() > 1]"/> | |
441 | <xsl:variable name="rest-"> | |
442 | <malval kind="list"> | |
443 | <lvalue> | |
444 | <xsl:sequence select="$rest"/> | |
445 | </lvalue> | |
446 | </malval> | |
447 | </xsl:variable> | |
448 | <xsl:call-template name="quasiquote"> | |
449 | <xsl:with-param name="ast" select="$rest-"/> | |
450 | </xsl:call-template> | |
d4798a57 A |
451 | </lvalue> |
452 | </malval> | |
1c2f45cf A |
453 | </xsl:when> |
454 | <xsl:otherwise> | |
455 | <malval kind="list"> | |
456 | <lvalue> | |
457 | <malval kind="symbol" value="cons"/> | |
458 | <xsl:variable name="first" select="$ast/lvalue/malval[1]"/> | |
459 | <xsl:variable name="rest" select="$ast/lvalue/malval[position() > 1]"/> | |
460 | <xsl:variable name="rest-"> | |
461 | <malval kind="list"> | |
462 | <lvalue> | |
463 | <xsl:sequence select="$rest"/> | |
464 | </lvalue> | |
465 | </malval> | |
466 | </xsl:variable> | |
467 | <xsl:call-template name="quasiquote"> | |
468 | <xsl:with-param name="ast" select="$first"/> | |
469 | </xsl:call-template> | |
470 | <xsl:call-template name="quasiquote"> | |
471 | <xsl:with-param name="ast" select="$rest-/malval"/> | |
472 | </xsl:call-template> | |
473 | </lvalue> | |
474 | </malval> | |
475 | </xsl:otherwise> | |
476 | </xsl:choose> | |
d4798a57 A |
477 | </xsl:when> |
478 | <xsl:otherwise> | |
1c2f45cf A |
479 | <malval kind="list"> |
480 | <lvalue> | |
481 | <malval kind="symbol" value="quote"/> | |
482 | <xsl:sequence select="$ast"/> | |
483 | </lvalue> | |
484 | </malval> | |
d4798a57 A |
485 | </xsl:otherwise> |
486 | </xsl:choose> | |
1c2f45cf A |
487 | </xsl:variable> |
488 | <xsl:sequence select="$result"/> | |
489 | </xsl:template> | |
490 | <xsl:template name="macroexpand"> | |
491 | <xsl:param name="ast"/> | |
492 | <xsl:param name="env"/> | |
a1252d40 | 493 | <xsl:param name="encode-env"/> |
1c2f45cf A |
494 | <xsl:choose> |
495 | <xsl:when test="fn:is-macro-call($ast, $env)"> | |
496 | <xsl:variable name="fn" select="env:get($env, $ast/lvalue/malval[1]/@value)"/> | |
497 | <xsl:variable name="args"> | |
498 | <value> | |
499 | <malval kind="list"> | |
500 | <lvalue> | |
501 | <xsl:sequence select="$ast/lvalue/malval[position() > 1]"/> | |
502 | </lvalue> | |
503 | </malval> | |
504 | </value> | |
505 | </xsl:variable> | |
506 | <xsl:variable name="new"> | |
507 | <xsl:call-template name="uapply"> | |
508 | <xsl:with-param name="func" select="$fn"/> | |
509 | <xsl:with-param name="args" select="$args"/> | |
510 | <xsl:with-param name="env" select="$env"/> | |
511 | </xsl:call-template> | |
512 | </xsl:variable> | |
513 | <xsl:call-template name="macroexpand"> | |
514 | <xsl:with-param name="ast" select="$new/value/malval"/> | |
515 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 516 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf A |
517 | </xsl:call-template> |
518 | </xsl:when> | |
519 | <xsl:otherwise> | |
520 | <value> | |
521 | <xsl:sequence select="$ast"/> | |
522 | </value> | |
523 | <xsl:sequence select="atoms[1]"/> | |
a1252d40 A |
524 | <xsl:if test="$encode-env"> |
525 | <env data="{$env => env:serialise()}"/> | |
526 | </xsl:if> | |
1c2f45cf A |
527 | </xsl:otherwise> |
528 | </xsl:choose> | |
529 | </xsl:template> | |
530 | <xsl:template name="EVAL"> | |
531 | <xsl:param name="env"/> | |
a1252d40 | 532 | <xsl:param name="encode-env" select="true()"/> |
1c2f45cf | 533 | <!-- <xsl:message> |
d4798a57 | 534 | |
0365ac12 | 535 | EVALUATE <xsl:sequence select="core:pr-str(value/malval)/value/text()"/> IN (<xsl:sequence select="empty(atoms)"/>) ATOMS <xsl:sequence select="fn:pretty(atoms)"/> |
d4798a57 | 536 | |
309b36ee | 537 | </xsl:message> --> |
1c2f45cf A |
538 | <xsl:variable name="atoms" select="atoms[1]"/> |
539 | <xsl:variable name="data"> | |
540 | <xsl:choose> | |
541 | <xsl:when test="value/malval/@kind = 'list'"> | |
542 | <xsl:choose> | |
543 | <xsl:when test="count(value/malval/lvalue/malval) = 0"> | |
544 | <xsl:sequence select="."/> | |
a1252d40 A |
545 | <xsl:if test="$encode-env"> |
546 | <env data="{env:serialise($env)}"/> | |
547 | </xsl:if> | |
1c2f45cf A |
548 | <xsl:sequence select="$atoms"/> |
549 | </xsl:when> | |
550 | <xsl:otherwise> | |
551 | <xsl:variable name="mexp"> | |
552 | <xsl:call-template name="macroexpand"> | |
553 | <xsl:with-param name="ast" select="value/malval"/> | |
554 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 555 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf A |
556 | </xsl:call-template> |
557 | </xsl:variable> | |
558 | <xsl:for-each select="$mexp"> | |
559 | <xsl:choose> | |
560 | <xsl:when test="value/malval/@kind != 'list'"> | |
561 | <xsl:variable name="ctx"> | |
562 | <xsl:sequence select="value"/> | |
563 | </xsl:variable> | |
564 | <xsl:for-each select="$ctx"> | |
565 | <xsl:call-template name="eval_ast"> | |
566 | <xsl:with-param name="atoms" select="$atoms"/> | |
567 | <xsl:with-param name="env" select="$env"/> | |
568 | </xsl:call-template> | |
a1252d40 A |
569 | <xsl:if test="$encode-env"> |
570 | <env data="{env:serialise($env)}"/> | |
571 | </xsl:if> | |
1c2f45cf A |
572 | <!-- <xsl:sequence select="$atoms"/> --> |
573 | </xsl:for-each> | |
574 | </xsl:when> | |
575 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'def!'"> | |
576 | <xsl:variable name="name"> | |
577 | <xsl:value-of select="value/malval/lvalue/malval[2]/@value"/> | |
578 | </xsl:variable> | |
579 | <xsl:variable name="xvalue"> | |
580 | <value> | |
581 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
582 | </value> | |
583 | <xsl:sequence select="$atoms"/> | |
584 | </xsl:variable> | |
585 | <xsl:variable name="value"> | |
586 | <xsl:for-each select="$xvalue"> | |
587 | <xsl:call-template name="EVAL"> | |
588 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 589 | <xsl:with-param name="encode-env" select="false()"/> |
1c2f45cf | 590 | </xsl:call-template> |
d4798a57 | 591 | </xsl:for-each> |
1c2f45cf A |
592 | </xsl:variable> |
593 | <xsl:sequence select="$value/data/value"/> | |
a1252d40 A |
594 | <xsl:if test="$encode-env"> |
595 | <env data="{env:serialise(env:set($env, $name, $value/data/value/malval))}"/> | |
596 | </xsl:if> | |
1c2f45cf A |
597 | <xsl:sequence select="$value/atoms[1]"/> |
598 | </xsl:when> | |
599 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'defmacro!'"> | |
600 | <xsl:variable name="name"> | |
601 | <xsl:value-of select="value/malval/lvalue/malval[2]/@value"/> | |
602 | </xsl:variable> | |
603 | <xsl:variable name="xvalue"> | |
604 | <value> | |
605 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
606 | </value> | |
607 | <xsl:sequence select="$atoms"/> | |
608 | </xsl:variable> | |
609 | <xsl:variable name="value"> | |
610 | <xsl:for-each select="$xvalue"> | |
611 | <xsl:call-template name="EVAL"> | |
612 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 613 | <xsl:with-param name="encode-env" select="false()"/> |
1c2f45cf A |
614 | </xsl:call-template> |
615 | </xsl:for-each> | |
616 | </xsl:variable> | |
617 | <xsl:variable name="resv"> | |
618 | <value> | |
619 | <malval kind="{$value/data/value/malval/@kind}" value="{$value/data/value/malval/@value}"> | |
620 | <xsl:sequence select="$value/data/value/malval/*[name() != 'is_macro']"/> | |
621 | <is_macro>true</is_macro> | |
622 | </malval> | |
623 | </value> | |
624 | </xsl:variable> | |
625 | <xsl:sequence select="$resv"/> | |
a1252d40 A |
626 | <xsl:if test="$encode-env"> |
627 | <env data="{env:serialise(env:set($env, $name, $resv/value/malval))}"/> | |
628 | </xsl:if> | |
1c2f45cf A |
629 | <xsl:sequence select="$value/atoms[1]"/> |
630 | </xsl:when> | |
631 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'let*'"> | |
632 | <xsl:variable name="xvalue"> | |
633 | <value> | |
634 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
635 | </value> | |
636 | <xsl:sequence select="$atoms"/> | |
637 | </xsl:variable> | |
638 | <xsl:iterate select="fn:group_consec(value/malval/lvalue/malval[2]/lvalue/malval)"> | |
639 | <xsl:param name="new_env" select="env:close($env)"/> | |
640 | <xsl:param name="new_atoms" select="$atoms"/> | |
641 | <xsl:on-completion> | |
642 | <xsl:variable name="xvalue"> | |
643 | <xsl:sequence select="$xvalue/value"/> | |
644 | <xsl:sequence select="$new_atoms"/> | |
645 | </xsl:variable> | |
646 | <xsl:variable name="value"> | |
647 | <xsl:for-each select="$xvalue"> | |
648 | <xsl:call-template name="EVAL"> | |
649 | <xsl:with-param name="env" select="$new_env"/> | |
a1252d40 | 650 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf A |
651 | </xsl:call-template> |
652 | </xsl:for-each> | |
653 | </xsl:variable> | |
654 | <xsl:sequence select="$value/data/value"/> | |
a1252d40 A |
655 | <xsl:if test="$encode-env"> |
656 | <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($value/env/@data) => env:replEnv()))}"/> | |
657 | </xsl:if> | |
1c2f45cf A |
658 | <xsl:sequence select="$value/atoms[1]"/> |
659 | </xsl:on-completion> | |
d4798a57 | 660 | <xsl:variable name="name"> |
1c2f45cf | 661 | <xsl:value-of select="node()[name() = 'first']/malval/@value"/> |
d4798a57 A |
662 | </xsl:variable> |
663 | <xsl:variable name="xvalue"> | |
664 | <value> | |
1c2f45cf | 665 | <xsl:sequence select="node()[name() = 'second']/malval"/> |
d4798a57 | 666 | </value> |
1c2f45cf | 667 | <xsl:sequence select="$new_atoms"/> |
d4798a57 A |
668 | </xsl:variable> |
669 | <xsl:variable name="value"> | |
670 | <xsl:for-each select="$xvalue"> | |
1c2f45cf A |
671 | <xsl:call-template name="EVAL"> |
672 | <xsl:with-param name="env" select="$new_env"/> | |
a1252d40 | 673 | <xsl:with-param name="encode-env" select="false()"/> |
1c2f45cf | 674 | </xsl:call-template> |
d4798a57 A |
675 | </xsl:for-each> |
676 | </xsl:variable> | |
1c2f45cf A |
677 | <xsl:next-iteration> |
678 | <xsl:with-param name="new_env" select="env:set($new_env, $name, $value/data/value/malval)"/> | |
679 | <xsl:with-param name="new_atoms" select="$value/atoms[1]"/> | |
680 | </xsl:next-iteration> | |
681 | </xsl:iterate> | |
682 | </xsl:when> | |
683 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'do'"> | |
684 | <xsl:iterate select="value/malval/lvalue/malval[position() > 1]"> | |
685 | <xsl:param name="new_env" select="$env"/> | |
686 | <xsl:param name="atoms" select="$atoms"/> | |
687 | <xsl:param name="previous_res" select="()"/> | |
688 | <xsl:on-completion> | |
689 | <xsl:sequence select="$previous_res"/> | |
a1252d40 A |
690 | <xsl:if test="$encode-env"> |
691 | <env data="{env:serialise($new_env)}"/> | |
692 | </xsl:if> | |
1c2f45cf A |
693 | <xsl:sequence select="$atoms"/> |
694 | </xsl:on-completion> | |
d4798a57 A |
695 | <xsl:variable name="xvalue"> |
696 | <value> | |
1c2f45cf | 697 | <xsl:sequence select="."/> |
d4798a57 A |
698 | </value> |
699 | <xsl:sequence select="$atoms"/> | |
700 | </xsl:variable> | |
701 | <xsl:variable name="value"> | |
702 | <xsl:for-each select="$xvalue"> | |
1c2f45cf A |
703 | <xsl:call-template name="EVAL"> |
704 | <xsl:with-param name="env" select="$new_env"/> | |
705 | </xsl:call-template> | |
d4798a57 A |
706 | </xsl:for-each> |
707 | </xsl:variable> | |
1c2f45cf A |
708 | <xsl:next-iteration> |
709 | <xsl:with-param name="new_env" select="env:deserialise($value/env/@data)"/> | |
710 | <xsl:with-param name="previous_res" select="$value/data/value"/> | |
711 | <xsl:with-param name="atoms" select="$value/atoms[1]"/> | |
712 | </xsl:next-iteration> | |
713 | </xsl:iterate> | |
714 | </xsl:when> | |
715 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'if'"> | |
716 | <xsl:variable name="cond"> | |
717 | <xsl:for-each select="value/malval/lvalue/malval[2]"> | |
718 | <xsl:variable name="context"> | |
719 | <value> | |
720 | <xsl:sequence select="."/> | |
721 | </value> | |
722 | <xsl:sequence select="$atoms"/> | |
723 | </xsl:variable> | |
724 | <xsl:for-each select="$context"> | |
725 | <xsl:call-template name="EVAL"> | |
726 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 727 | <xsl:with-param name="encode-env" select="false()"/> |
1c2f45cf A |
728 | </xsl:call-template> |
729 | </xsl:for-each> | |
730 | </xsl:for-each> | |
731 | </xsl:variable> | |
732 | <xsl:variable name="ptrue"> | |
733 | <xsl:for-each select="value/malval/lvalue/malval[3]"> | |
d4798a57 | 734 | <value> |
1c2f45cf | 735 | <xsl:sequence select="."/> |
d4798a57 | 736 | </value> |
1c2f45cf A |
737 | <xsl:sequence select="$cond/atoms[1]"/> |
738 | </xsl:for-each> | |
739 | </xsl:variable> | |
740 | <xsl:variable name="pfalse"> | |
741 | <xsl:for-each select="value/malval/lvalue/malval[4]"> | |
742 | <value> | |
743 | <xsl:sequence select="."/> | |
744 | </value> | |
745 | <xsl:sequence select="$cond/atoms[1]"/> | |
746 | </xsl:for-each> | |
747 | </xsl:variable> | |
748 | <xsl:variable name="xfalse"> | |
749 | <xsl:choose> | |
750 | <xsl:when test="empty($pfalse/value)"> | |
d4798a57 | 751 | <value> |
1c2f45cf | 752 | <malval kind="nil"/> |
d4798a57 | 753 | </value> |
1c2f45cf A |
754 | <xsl:sequence select="$cond/atoms[1]"/> |
755 | </xsl:when> | |
756 | <xsl:otherwise> | |
757 | <xsl:sequence select="$pfalse/value"/> | |
758 | <xsl:sequence select="$pfalse/atoms[1]"/> | |
759 | </xsl:otherwise> | |
760 | </xsl:choose> | |
761 | </xsl:variable> | |
762 | <xsl:variable name="res"> | |
763 | <xsl:choose> | |
764 | <xsl:when test="let $kind := $cond/data/value/malval/@kind return $kind = 'nil' or $kind = 'false'"> | |
765 | <xsl:for-each select="$xfalse"> | |
766 | <xsl:call-template name="EVAL"> | |
767 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 768 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf | 769 | </xsl:call-template> |
d4798a57 | 770 | </xsl:for-each> |
1c2f45cf A |
771 | </xsl:when> |
772 | <xsl:otherwise> | |
773 | <xsl:for-each select="$ptrue"> | |
774 | <xsl:call-template name="EVAL"> | |
775 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 776 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf A |
777 | </xsl:call-template> |
778 | </xsl:for-each> | |
779 | </xsl:otherwise> | |
780 | </xsl:choose> | |
781 | </xsl:variable> | |
782 | <xsl:sequence select="$res/data/value"/> | |
a1252d40 A |
783 | <xsl:if test="$encode-env"> |
784 | <xsl:sequence select="$res/env"/> | |
785 | </xsl:if> | |
1c2f45cf A |
786 | <xsl:sequence select="$res/atoms[1]"/> |
787 | </xsl:when> | |
788 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'fn*'"> | |
789 | <value> | |
790 | <malval kind="userfunction"> | |
791 | <is_macro>false</is_macro> | |
792 | <binds> | |
793 | <xsl:sequence select="value/malval/lvalue/malval[2]/lvalue/malval"/> | |
794 | </binds> | |
795 | <body> | |
796 | <xsl:sequence select="value/malval/lvalue/malval[3]"/> | |
797 | </body> | |
798 | <env data="{env:serialise(env:noReplEnv($env))}"/> | |
799 | <!-- capture current env --> | |
800 | </malval> | |
801 | </value> | |
a1252d40 A |
802 | <xsl:if test="$encode-env"> |
803 | <env data="{env:serialise($env)}"/> | |
804 | </xsl:if> | |
1c2f45cf A |
805 | <xsl:sequence select="$atoms"/> |
806 | </xsl:when> | |
807 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'quote'"> | |
808 | <value> | |
809 | <xsl:sequence select="value/malval/lvalue/malval[2]"/> | |
810 | </value> | |
a1252d40 A |
811 | <xsl:if test="$encode-env"> |
812 | <env data="{env:serialise($env)}"/> | |
813 | </xsl:if> | |
1c2f45cf A |
814 | <xsl:sequence select="$atoms"/> |
815 | </xsl:when> | |
816 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'quasiquote'"> | |
817 | <xsl:variable name="exp"> | |
818 | <value> | |
819 | <xsl:call-template name="quasiquote"> | |
820 | <xsl:with-param name="ast" select="value/malval/lvalue/malval[2]"/> | |
821 | </xsl:call-template> | |
822 | </value> | |
823 | <xsl:sequence select="$atoms"/> | |
824 | </xsl:variable> | |
825 | <xsl:variable name="res"> | |
826 | <xsl:for-each select="$exp"> | |
827 | <xsl:call-template name="EVAL"> | |
828 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 829 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf A |
830 | </xsl:call-template> |
831 | </xsl:for-each> | |
832 | </xsl:variable> | |
833 | <xsl:sequence select="$res/data/value"/> | |
a1252d40 A |
834 | <xsl:if test="$encode-env"> |
835 | <xsl:sequence select="$res/env"/> | |
836 | </xsl:if> | |
1c2f45cf A |
837 | <xsl:sequence select="$res/atoms[1]"/> |
838 | </xsl:when> | |
839 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'macroexpand'"> | |
840 | <xsl:variable name="exp"> | |
841 | <xsl:call-template name="macroexpand"> | |
842 | <xsl:with-param name="ast" select="value/malval/lvalue/malval[2]"/> | |
843 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 844 | <xsl:with-param name="encode-env" select="false()"/> |
1c2f45cf A |
845 | </xsl:call-template> |
846 | <xsl:sequence select="$atoms"/> | |
847 | </xsl:variable> | |
848 | <xsl:sequence select="$exp/value"/> | |
a1252d40 A |
849 | <xsl:if test="$encode-env"> |
850 | <env data="{env:serialise($env)}"/> | |
851 | </xsl:if> | |
1c2f45cf A |
852 | <xsl:sequence select="$atoms"/> |
853 | </xsl:when> | |
854 | <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'try*'"> | |
855 | <xsl:variable name="tryv"> | |
856 | <xsl:try> | |
d4798a57 A |
857 | <xsl:variable name="xvalue"> |
858 | <value> | |
1c2f45cf | 859 | <xsl:sequence select="value/malval/lvalue/malval[2]"/> |
d4798a57 A |
860 | </value> |
861 | <xsl:sequence select="$atoms"/> | |
862 | </xsl:variable> | |
863 | <xsl:variable name="value"> | |
864 | <xsl:for-each select="$xvalue"> | |
1c2f45cf A |
865 | <xsl:call-template name="EVAL"> |
866 | <xsl:with-param name="env" select="$env"/> | |
a1252d40 | 867 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf | 868 | </xsl:call-template> |
d4798a57 A |
869 | </xsl:for-each> |
870 | </xsl:variable> | |
1c2f45cf | 871 | <xsl:sequence select="$value/data/value"/> |
a1252d40 A |
872 | <xsl:if test="$encode-env"> |
873 | <xsl:sequence select="$value/env"/> | |
874 | </xsl:if> | |
1c2f45cf A |
875 | <xsl:sequence select="$value/atoms[1]"/> |
876 | <xsl:catch errors="*"> | |
877 | <xsl:variable name="catchv-name" select="value/malval/lvalue/malval[3]/lvalue/malval[2]/@value"/> | |
878 | <xsl:variable name="catchv"> | |
d4798a57 | 879 | <value> |
1c2f45cf | 880 | <xsl:sequence select="value/malval/lvalue/malval[3]/lvalue/malval[3]"/> |
d4798a57 | 881 | </value> |
d4798a57 | 882 | </xsl:variable> |
1c2f45cf A |
883 | <xsl:if test="empty($catchv/value/malval)"> |
884 | <xsl:value-of select="error($err:code, $err:description, $err:value)"/> | |
885 | </xsl:if> | |
886 | <xsl:variable name="newenv" select="env:close($env) => env:set($catchv-name, $err:value)"/> | |
d4798a57 | 887 | <xsl:variable name="value"> |
1c2f45cf A |
888 | <xsl:for-each select="$catchv"> |
889 | <xsl:call-template name="EVAL"> | |
890 | <xsl:with-param name="env" select="$newenv"/> | |
a1252d40 | 891 | <xsl:with-param name="encode-env" select="$encode-env"/> |
1c2f45cf | 892 | </xsl:call-template> |
d4798a57 A |
893 | </xsl:for-each> |
894 | </xsl:variable> | |
895 | <xsl:sequence select="$value/data/value"/> | |
a1252d40 A |
896 | <xsl:if test="$encode-env"> |
897 | <xsl:sequence select="$value/env"/> | |
898 | <!-- leaks the bound name, ouch --> | |
899 | </xsl:if> | |
d4798a57 | 900 | <xsl:sequence select="$value/atoms[1]"/> |
1c2f45cf A |
901 | </xsl:catch> |
902 | </xsl:try> | |
903 | </xsl:variable> | |
904 | <xsl:sequence select="$tryv"/> | |
905 | </xsl:when> | |
906 | <xsl:otherwise> | |
907 | <xsl:variable name="new_list"> | |
908 | <xsl:call-template name="eval_ast"> | |
909 | <xsl:with-param name="atoms" select="$atoms"/> | |
910 | <xsl:with-param name="env" select="$env"/> | |
911 | </xsl:call-template> | |
912 | </xsl:variable> | |
913 | <xsl:variable name="func"> | |
914 | <xsl:for-each select="$new_list"> | |
915 | <xsl:sequence select="value/malval/lvalue/malval[1]"/> | |
d4798a57 | 916 | </xsl:for-each> |
1c2f45cf A |
917 | </xsl:variable> |
918 | <xsl:variable name="args"> | |
919 | <xsl:for-each select="$new_list"> | |
920 | <value> | |
921 | <malval kind="list"> | |
922 | <lvalue> | |
923 | <xsl:sequence select="value/malval/lvalue/node()[position() != 1]"/> | |
924 | </lvalue> | |
925 | </malval> | |
926 | </value> | |
927 | </xsl:for-each> | |
928 | </xsl:variable> | |
929 | <xsl:variable name="ctx"> | |
930 | <xsl:sequence select="$new_list/atoms"/> | |
931 | </xsl:variable> | |
932 | <xsl:variable name="resultv"> | |
933 | <xsl:for-each select="$ctx"> | |
934 | <xsl:call-template name="call-function"> | |
935 | <xsl:with-param name="env" select="$env"/> | |
936 | <xsl:with-param name="func" select="$func"/> | |
937 | <xsl:with-param name="args" select="$args"/> | |
938 | </xsl:call-template> | |
939 | </xsl:for-each> | |
940 | </xsl:variable> | |
941 | <xsl:for-each select="$resultv"> | |
942 | <xsl:choose> | |
943 | <xsl:when test="empty(env)"> | |
a1252d40 A |
944 | <xsl:if test="$encode-env"> |
945 | <env data="{env:serialise($env)}"/> | |
946 | </xsl:if> | |
1c2f45cf A |
947 | </xsl:when> |
948 | <xsl:otherwise> | |
a1252d40 A |
949 | <xsl:if test="$encode-env"> |
950 | <xsl:sequence select="env"/> | |
951 | </xsl:if> | |
1c2f45cf A |
952 | </xsl:otherwise> |
953 | </xsl:choose> | |
954 | <xsl:sequence select="atoms[1]"/> | |
955 | <xsl:sequence select="value"/> | |
956 | </xsl:for-each> | |
957 | </xsl:otherwise> | |
958 | </xsl:choose> | |
959 | </xsl:for-each> | |
960 | </xsl:otherwise> | |
961 | </xsl:choose> | |
962 | </xsl:when> | |
963 | <xsl:otherwise> | |
964 | <xsl:call-template name="eval_ast"> | |
965 | <xsl:with-param name="atoms" select="$atoms"/> | |
966 | <xsl:with-param name="env" select="$env"/> | |
967 | </xsl:call-template> | |
a1252d40 A |
968 | <xsl:if test="$encode-env"> |
969 | <env data="{env:serialise($env)}"/> | |
970 | </xsl:if> | |
1c2f45cf A |
971 | <!-- <xsl:sequence select="$atoms"/> --> |
972 | </xsl:otherwise> | |
973 | </xsl:choose> | |
974 | </xsl:variable> | |
975 | <xsl:variable name="new-atoms" select="($data/atoms[1], $atoms)[1]"/> | |
976 | <!-- <xsl:message> | |
977 | EVALUATED (<xsl:sequence select="empty($data/atoms)"/>) <xsl:sequence select="core:pr-str(value/malval)/value/text()"/> TO <xsl:sequence select="core:pr-str($data/value/malval)/value/text()"/> WITH ATOMS <xsl:sequence select="fn:pretty($new-atoms)"/> | |
978 | </xsl:message> --> | |
979 | <data> | |
980 | <xsl:sequence select="$data/value"/> | |
981 | </data> | |
a1252d40 A |
982 | <xsl:if test="$encode-env"> |
983 | <env data="{$data/env/@data}"/> | |
984 | </xsl:if> | |
1c2f45cf A |
985 | <xsl:sequence select="$new-atoms"/> |
986 | </xsl:template> | |
987 | <xsl:template name="READ"> | |
988 | <xsl:variable name="context"> | |
989 | <str> | |
990 | <xsl:copy-of select="stdin/text()"/> | |
991 | </str> | |
992 | </xsl:variable> | |
993 | <xsl:variable name="form"> | |
994 | <xsl:sequence select="state/atoms[1]"/> | |
995 | <xsl:for-each select="$context"> | |
996 | <xsl:call-template name="malreader-read_str"/> | |
997 | </xsl:for-each> | |
998 | </xsl:variable> | |
999 | <xsl:for-each select="$form"> | |
1000 | <xsl:if test="error"> | |
1001 | <xsl:value-of select="error(QName('MAL', 'Error'), string(error))"/> | |
1002 | </xsl:if> | |
1003 | <xsl:sequence select="."/> | |
1004 | </xsl:for-each> | |
1005 | </xsl:template> | |
1006 | <xsl:function name="fn:group_consec"> | |
1007 | <xsl:param name="nodes"/> | |
1008 | <xsl:variable name="groups"> | |
1009 | <xsl:for-each-group select="$nodes" group-by="position() mod 2"> | |
1010 | <xsl:choose> | |
1011 | <xsl:when test="position() = 1"> | |
1012 | <first> | |
1013 | <xsl:sequence select="current-group()"/> | |
1014 | </first> | |
d4798a57 A |
1015 | </xsl:when> |
1016 | <xsl:otherwise> | |
1c2f45cf A |
1017 | <second> |
1018 | <xsl:sequence select="current-group()"/> | |
1019 | </second> | |
d4798a57 A |
1020 | </xsl:otherwise> |
1021 | </xsl:choose> | |
1c2f45cf A |
1022 | </xsl:for-each-group> |
1023 | </xsl:variable> | |
1024 | <xsl:iterate select="1 to count($groups/first/*)"> | |
1025 | <element> | |
1026 | <xsl:variable name="idx" select="number(.)"/> | |
1027 | <first> | |
1028 | <xsl:sequence select="$groups/first/node()[position() = $idx]"/> | |
1029 | </first> | |
1030 | <second> | |
1031 | <xsl:sequence select="$groups/second/node()[position() = $idx]"/> | |
1032 | </second> | |
1033 | </element> | |
1034 | </xsl:iterate> | |
1035 | </xsl:function> | |
1036 | <xsl:function name="fn:is-pair"> | |
1037 | <xsl:param name="list"/> | |
1038 | <xsl:sequence select="($list/@kind = 'list' or $list/@kind = 'vector') and count($list/lvalue/malval) != 0"/> | |
1039 | </xsl:function> | |
1040 | <xsl:function name="fn:is-macro-call"> | |
1041 | <xsl:param name="ast"/> | |
1042 | <xsl:param name="env"/> | |
1043 | <xsl:variable name="res" select="$ast/@kind = 'list' and $ast/lvalue/malval[1]/@kind = 'symbol' and (let $fn := env:get-noerror($env, $ast/lvalue/malval[1]/@value) return not(empty($fn)) and $fn/malval/is_macro/text() = 'true')"/> | |
1044 | <xsl:sequence select="$res"/> | |
1045 | </xsl:function> | |
1046 | <xsl:function name="fn:pretty"> | |
1047 | <xsl:param name="atoms"/> | |
1048 | <xsl:sequence select="$atoms/atom/concat('(', @identity, ': ', malval/@kind, ' ', core:pr-str(malval), ')')"/> | |
1049 | </xsl:function> | |
d4798a57 | 1050 | </xsl:stylesheet> |