1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Step 8: Macros -->
3 <!-- input document must be in the following format -->
6 <stdin>...stdin text...</stdin>
7 <stdout> ... ignored, omitted ... </stdout>
8 <state> contains env and atoms </state>
13 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" exclude-result-prefixes="fn xs map env core">
14 <xsl:import href="reader.xslt" />
15 <xsl:import href="printer.xslt" />
16 <xsl:import href="env.xslt" />
17 <xsl:import href="core.xslt" />
19 <xsl:output method='xml' encoding='utf-8' indent='yes'/>
20 <xsl:template match="mal" name="rep">
22 <xsl:when test="string(state/env/@data) = ''">
23 <xsl:variable name="argv">
26 <xsl:for-each select="argv/arg/text()">
27 <malval kind="string" value="{.}" />
32 <xsl:variable name="vstate">
35 <env data="{env:serialise(env:empty() => env:bind-all(core:ns()/@name, core:ns()) => env:set('*ARGV*', $argv) => env:toReplEnv())}"></env>
38 <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))))))))</stdin>
41 <xsl:variable name="new-state">
42 <xsl:for-each select="$vstate/mal">
43 <xsl:call-template name="rep"></xsl:call-template>
46 <xsl:variable name="state-v">
47 <xsl:sequence select="$new-state/mal/state"/>
48 <xsl:sequence select="stdin"/>
50 <xsl:for-each select="$state-v">
51 <xsl:call-template name="rep"></xsl:call-template>
56 <xsl:variable name="env" as="map(*)">
57 <xsl:sequence select="env:deserialise(state/env/@data)"/>
59 <xsl:sequence select="stdin"/>
60 <xsl:variable name="_read">
61 <xsl:call-template name="READ" />
63 <xsl:variable name="_eval">
64 <xsl:for-each select="$_read">
65 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
68 <xsl:for-each select="$_eval">
70 <xsl:variable name="data">
71 <xsl:sequence select="data/value"/>
72 <xsl:sequence select="atoms[1]"/>
74 <xsl:for-each select="$data">
75 <xsl:call-template name="PRINT"></xsl:call-template>
79 <env data="{env/@data}"/>
80 <xsl:sequence select="atoms[1]"/>
88 <xsl:template name="PRINT">
89 <xsl:variable name="str">
90 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="true()"/></xsl:call-template>
92 <xsl:value-of select="$str" />
95 <xsl:template name="eval_ast">
96 <xsl:param name="env" />
98 <xsl:when test="value/malval/@kind = 'symbol'">
99 <xsl:variable name="val">
100 <xsl:sequence select="env:get($env, value/malval/@value)" />
103 <xsl:sequence select="$val"/>
106 <xsl:when test="value/malval/@kind = 'list'">
110 <xsl:for-each select="value/malval/lvalue/malval">
111 <xsl:variable name="ctx">
113 <xsl:sequence select="."/>
116 <xsl:variable name="xctx">
117 <xsl:for-each select="$ctx">
118 <xsl:variable name="val">
119 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
121 <xsl:sequence select="$val/data/value"/>
124 <xsl:sequence select="$xctx/value/malval"/>
130 <xsl:when test="value/malval/@kind = 'vector'">
132 <malval kind="vector">
134 <xsl:for-each select="value/malval/lvalue/malval">
135 <xsl:variable name="ctx">
137 <xsl:sequence select="."/>
140 <xsl:variable name="xctx">
141 <xsl:for-each select="$ctx">
142 <xsl:variable name="val">
143 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
145 <xsl:sequence select="$val/data/value"/>
148 <xsl:sequence select="$xctx/value/malval"/>
154 <xsl:when test="value/malval/@kind = 'hash'">
158 <xsl:for-each select="value/malval/lvalue/malval">
159 <xsl:variable name="ctx">
161 <xsl:sequence select="."/>
164 <xsl:variable name="xctx">
165 <xsl:for-each select="$ctx">
166 <xsl:variable name="val">
167 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
169 <xsl:sequence select="$val/data/value"/>
172 <xsl:sequence select="$xctx/value/malval"/>
179 <xsl:sequence select="." />
184 <!-- uapply[env, fn, args] -->
185 <xsl:template name="uapply">
186 <xsl:param name="func" />
187 <xsl:param name="args" />
188 <xsl:param name="env" />
190 <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)" />
191 <xsl:variable name="body">
193 <xsl:sequence select="$func/malval/body/malval"/>
195 <xsl:sequence select="atoms[1]"/>
197 <xsl:variable name="result">
198 <xsl:for-each select="$body">
199 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$nenv"/></xsl:call-template>
202 <xsl:sequence select="$result/data/value"/>
203 <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($result/env/@data) => env:replEnv()))}" />
204 <xsl:sequence select="$result/atoms[1]"/>
207 <xsl:template name="quasiquote">
208 <xsl:param name="ast" />
209 <xsl:variable name="result">
211 <xsl:when test="fn:is-pair($ast)">
213 <xsl:when test="let $fst := $ast/lvalue/malval[1] return $fst/@kind = 'symbol' and $fst/@value = 'unquote'">
214 <xsl:sequence select="$ast/lvalue/malval[2]"/>
216 <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')">
219 <malval kind="symbol" value="concat"/>
220 <xsl:sequence select="$ast/lvalue/malval[1]/lvalue/malval[2]"/>
221 <xsl:variable name="rest" select="$ast/lvalue/malval[position() > 1]"/>
222 <xsl:variable name="rest-">
225 <xsl:sequence select="$rest"/>
229 <xsl:call-template name="quasiquote"><xsl:with-param name="ast" select="$rest-"/></xsl:call-template>
236 <malval kind="symbol" value="cons"/>
237 <xsl:variable name="first" select="$ast/lvalue/malval[1]"/>
238 <xsl:variable name="rest" select="$ast/lvalue/malval[position() > 1]"/>
239 <xsl:variable name="rest-">
242 <xsl:sequence select="$rest"/>
246 <xsl:call-template name="quasiquote"><xsl:with-param name="ast" select="$first"/></xsl:call-template>
247 <xsl:call-template name="quasiquote"><xsl:with-param name="ast" select="$rest-/malval"/></xsl:call-template>
256 <malval kind="symbol" value="quote"/>
257 <xsl:sequence select="$ast"/>
263 <xsl:sequence select="$result"/>
266 <xsl:template name="macroexpand">
267 <xsl:param name="ast" />
268 <xsl:param name="env" />
270 <xsl:when test="fn:is-macro-call($ast, $env)">
271 <xsl:variable name="fn" select="env:get($env, $ast/lvalue/malval[1]/@value)"></xsl:variable>
272 <xsl:variable name="args">
276 <xsl:sequence select="$ast/lvalue/malval[position() > 1]"/>
281 <xsl:variable name="new">
282 <xsl:call-template name="uapply"><xsl:with-param name="func" select="$fn"/><xsl:with-param name="args" select="$args"/><xsl:with-param name="env" select="$env"/></xsl:call-template>
284 <xsl:call-template name="macroexpand"><xsl:with-param name="ast" select="$new/value/malval"/><xsl:with-param name="env" select="$env"/></xsl:call-template>
288 <xsl:sequence select="$ast"/>
290 <xsl:sequence select="atoms[1]"/>
291 <env data="{$env => env:serialise()}" />
296 <xsl:template name="EVAL">
297 <xsl:param name="env" />
298 <xsl:variable name="atoms" select="atoms[1]"></xsl:variable>
299 <xsl:variable name="data">
301 <xsl:when test="value/malval/@kind = 'list'">
303 <xsl:when test="count(value/malval/lvalue/malval) = 0">
304 <xsl:sequence select="."/>
305 <env data="{env:serialise($env)}" />
306 <xsl:sequence select="$atoms"/>
309 <xsl:variable name="mexp">
310 <xsl:call-template name="macroexpand"><xsl:with-param name="ast" select="value/malval"/><xsl:with-param name="env" select="$env"/></xsl:call-template>
312 <xsl:for-each select="$mexp">
314 <xsl:when test="value/malval/@kind != 'list'">
315 <xsl:variable name="ctx">
316 <xsl:sequence select="value"/>
318 <xsl:for-each select="$ctx">
319 <xsl:call-template name="eval_ast"><xsl:with-param name="env" select="$env"/></xsl:call-template>
320 <env data="{env:serialise($env)}"/>
321 <xsl:sequence select="$atoms"/>
324 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'def!'">
325 <xsl:variable name="name">
326 <xsl:value-of select="value/malval/lvalue/malval[2]/@value"/>
328 <xsl:variable name="xvalue">
330 <xsl:sequence select="value/malval/lvalue/malval[3]"/>
332 <xsl:sequence select="$atoms"/>
334 <xsl:variable name="value">
335 <xsl:for-each select="$xvalue">
336 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
339 <xsl:sequence select="$value/data/value"/>
340 <env data="{env:serialise(env:set($env, $name, $value/data/value/malval))}"/>
341 <xsl:sequence select="$value/atoms[1]"/>
343 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'defmacro!'">
344 <xsl:variable name="name">
345 <xsl:value-of select="value/malval/lvalue/malval[2]/@value"/>
347 <xsl:variable name="xvalue">
349 <xsl:sequence select="value/malval/lvalue/malval[3]"/>
351 <xsl:sequence select="$atoms"/>
353 <xsl:variable name="value">
354 <xsl:for-each select="$xvalue">
355 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
358 <xsl:variable name="resv">
360 <malval kind="{$value/data/value/malval/@kind}" value="{$value/data/value/malval/@value}">
361 <xsl:sequence select="$value/data/value/malval/*[name() != 'is_macro']" />
362 <is_macro>true</is_macro>
366 <xsl:sequence select="$resv"/>
367 <env data="{env:serialise(env:set($env, $name, $resv/value/malval))}"/>
368 <xsl:sequence select="$resv/atoms[1]"/>
370 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'let*'">
371 <xsl:variable name="xvalue">
373 <xsl:sequence select="value/malval/lvalue/malval[3]"/>
375 <xsl:sequence select="$atoms"/>
378 <xsl:iterate select="fn:group_consec(value/malval/lvalue/malval[2]/lvalue/malval)">
379 <xsl:param name="new_env" select="env:close($env)"/>
380 <xsl:param name="new_atoms" select="$atoms"/>
383 <xsl:variable name="xvalue">
384 <xsl:sequence select="$xvalue/value"/>
385 <xsl:sequence select="$new_atoms"/>
387 <xsl:variable name="value">
388 <xsl:for-each select="$xvalue">
389 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$new_env"/></xsl:call-template>
392 <xsl:sequence select="$value/data/value"></xsl:sequence>
393 <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($value/env/@data) => env:replEnv()))}" />
395 <xsl:sequence select="$value/atoms[1]"/>
398 <xsl:variable name="name">
399 <xsl:value-of select="node()[name() = 'first']/malval/@value"/>
402 <xsl:variable name="xvalue">
404 <xsl:sequence select="node()[name() = 'second']/malval"/>
406 <xsl:sequence select="$new_atoms"/>
409 <xsl:variable name="value">
410 <xsl:for-each select="$xvalue">
411 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$new_env"/></xsl:call-template>
416 <xsl:with-param name="new_env" select="env:set($new_env, $name, $value/data/value/malval)"/>
417 <xsl:with-param name="new_atoms" select="$value/atoms[1]"/>
418 </xsl:next-iteration>
421 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'do'">
422 <xsl:iterate select="value/malval/lvalue/malval[position() > 1]">
423 <xsl:param name="new_env" select="$env"/>
424 <xsl:param name="atoms" select="$atoms"/>
425 <xsl:param name="previous_res" select="()"/>
427 <xsl:sequence select="$previous_res"/>
428 <env data="{env:serialise($new_env)}" />
429 <xsl:sequence select="$atoms"/>
431 <xsl:variable name="xvalue">
433 <xsl:sequence select="."/>
435 <xsl:sequence select="$atoms"/>
437 <xsl:variable name="value">
438 <xsl:for-each select="$xvalue">
439 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$new_env"/></xsl:call-template>
443 <xsl:with-param name="new_env" select="env:deserialise($value/env/@data)"/>
444 <xsl:with-param name="previous_res" select="$value/data/value"/>
445 <xsl:with-param name="atoms" select="$value/atoms[1]"/>
446 </xsl:next-iteration>
449 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'if'">
450 <xsl:variable name="cond">
451 <xsl:for-each select="value/malval/lvalue/malval[2]">
452 <xsl:variable name="context">
454 <xsl:sequence select="."/>
456 <xsl:sequence select="$atoms"/>
458 <xsl:for-each select="$context">
459 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
463 <xsl:variable name="ptrue">
464 <xsl:for-each select="value/malval/lvalue/malval[3]">
466 <xsl:sequence select="."/>
468 <xsl:sequence select="$cond/atoms[1]"/>
471 <xsl:variable name="pfalse">
472 <xsl:for-each select="value/malval/lvalue/malval[4]">
474 <xsl:sequence select="."/>
476 <xsl:sequence select="$cond/atoms[1]"/>
479 <xsl:variable name="xfalse">
481 <xsl:when test="empty($pfalse/value)">
483 <malval kind='nil' />
485 <xsl:sequence select="$cond/atoms[1]"/>
488 <xsl:sequence select="$pfalse/value"/>
489 <xsl:sequence select="$pfalse/atoms[1]"/>
493 <xsl:variable name="res">
495 <xsl:when test="let $kind := $cond/data/value/malval/@kind return $kind = 'nil' or $kind = 'false'">
496 <xsl:for-each select="$xfalse">
497 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
501 <xsl:for-each select="$ptrue">
502 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
507 <xsl:sequence select="$res/data/value"/>
508 <env data="{env:serialise($env)}" />
509 <xsl:sequence select="$res/atoms[1]"/>
511 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'fn*'">
513 <malval kind="userfunction">
514 <is_macro>false</is_macro>
516 <xsl:sequence select="value/malval/lvalue/malval[2]/lvalue/malval" />
519 <xsl:sequence select="value/malval/lvalue/malval[3]"/>
521 <env data="{env:serialise(env:noReplEnv($env))}"/> <!-- capture current env -->
524 <env data="{env:serialise($env)}" />
525 <xsl:sequence select="$atoms"/>
527 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'quote'">
529 <xsl:sequence select="value/malval/lvalue/malval[2]" />
531 <env data="{env:serialise($env)}" />
532 <xsl:sequence select="$atoms"/>
534 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'quasiquote'">
535 <xsl:variable name="exp">
537 <xsl:call-template name="quasiquote"><xsl:with-param name="ast" select="value/malval/lvalue/malval[2]"/></xsl:call-template>
539 <xsl:sequence select="$atoms"/>
541 <xsl:variable name="res">
542 <xsl:for-each select="$exp">
543 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
546 <xsl:sequence select="$res/data/value"/>
547 <xsl:sequence select="$res/env"/>
548 <xsl:sequence select="$res/atoms[1]"/>
550 <xsl:when test="let $fn := value/malval/lvalue/malval[1] return $fn/@kind = 'symbol' and $fn/@value = 'macroexpand'">
551 <xsl:variable name="exp">
552 <xsl:call-template name="macroexpand"><xsl:with-param name="ast" select="value/malval/lvalue/malval[2]"/><xsl:with-param name="env" select="$env"/></xsl:call-template>
553 <xsl:sequence select="$atoms"/>
555 <xsl:sequence select="$exp/value"/>
556 <env data="{env:serialise($env)}" />
557 <xsl:sequence select="$atoms"/>
560 <xsl:variable name="new_list">
561 <xsl:call-template name="eval_ast"><xsl:with-param name="env" select="$env"/></xsl:call-template>
563 <xsl:variable name="func">
564 <xsl:for-each select="$new_list">
565 <xsl:sequence select="value/malval/lvalue/malval[1]"/>
568 <xsl:variable name="args">
569 <xsl:for-each select="$new_list">
573 <xsl:for-each select="value/malval/lvalue/node()[position() != 1]">
574 <xsl:sequence select="."/>
579 <xsl:sequence select="$atoms"/>
582 <xsl:variable name="resultv">
584 <xsl:when test="$func/malval/@kind = 'userfunction'">
585 <xsl:call-template name="uapply"><xsl:with-param name="env" select="$env"/><xsl:with-param name="func" select="$func"/><xsl:with-param name="args" select="$args"/></xsl:call-template>
589 <xsl:when test="$func/malval/@name = 'env??'"> <!-- needs access to env -->
590 <xsl:variable name="nev" select="env:dump($env)"></xsl:variable>
591 <xsl:variable name="value">
592 <malval kind="string" value="{$env => serialize(map{'method':'json'})}"/>
595 <xsl:sequence select="$value"/>
597 <env data="{env:serialise($env)}"/>
598 <xsl:sequence select="$value/atoms[1]"/>
600 <xsl:when test="$func/malval/@name = 'eval'"> <!-- needs access to env -->
601 <xsl:variable name="venv" select="env:replEnv($env)"></xsl:variable>
602 <xsl:variable name="form">
604 <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/>
606 <xsl:sequence select="$atoms"/>
608 <xsl:variable name="value">
609 <xsl:for-each select="$form">
610 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$venv"/></xsl:call-template>
613 <xsl:sequence select="$value/data/value"/>
614 <env data="{env:serialise(env:swap-replEnv($env, env:deserialise($value/env/@data)))}"/>
615 <xsl:sequence select="$value/atoms[1]"/>
617 <xsl:when test="$func/malval/@name = 'atom'"> <!-- needs access to atoms -->
618 <xsl:variable name="atom-ident" select="current-dateTime()"></xsl:variable>
620 <malval kind="atom" value="{$atom-ident}"/>
623 <xsl:for-each select="$atoms/atom">
624 <xsl:sequence select="."/>
626 <atom identity="{$atom-ident}">
627 <xsl:sequence select="$args/value/malval/lvalue/malval[1]"/>
631 <xsl:when test="$func/malval/@name = 'deref'"> <!-- needs access to atoms -->
633 <xsl:sequence select="$atoms/atom[@identity = $args/value/malval/lvalue/malval[1]/@value]/malval"/>
635 <xsl:sequence select="$atoms"/>
637 <xsl:when test="$func/malval/@name = 'reset!'"> <!-- needs access to atoms -->
638 <xsl:variable name="atom-ident" select="$args/value/malval/lvalue/malval[1]/@value"></xsl:variable>
639 <xsl:variable name="newv" select="$args/value/malval/lvalue/malval[2]"></xsl:variable>
641 <xsl:sequence select="$newv"/>
644 <xsl:for-each select="$atoms/atom[@identity != $atom-ident]">
645 <xsl:sequence select="."/>
647 <atom identity="{$atom-ident}">
648 <xsl:sequence select="$newv"/>
652 <xsl:when test="$func/malval/@name = 'swap!'"> <!-- needs access to atoms -->
653 <xsl:variable name="atom-ident" select="$args/value/malval/lvalue/malval[1]/@value"></xsl:variable>
654 <xsl:variable name="atom-value" select="$atoms/atom[@identity = $atom-ident]/malval"></xsl:variable>
655 <xsl:variable name="fn" select="$args/value/malval/lvalue/malval[2]"></xsl:variable>
656 <xsl:variable name="newlist">
660 <xsl:sequence select="$fn"/>
661 <xsl:sequence select="$atom-value"/>
662 <xsl:sequence select="$args/value/malval/lvalue/malval[position() > 2]"/>
666 <xsl:sequence select="$atoms"/>
668 <xsl:variable name="newv">
669 <xsl:for-each select="$newlist">
670 <xsl:call-template name="EVAL"><xsl:with-param name="env" select="$env"/></xsl:call-template>
673 <xsl:sequence select="$newv/data/value"/>
675 <xsl:for-each select="$newv/atoms[1]/atom[@identity != $atom-ident]">
676 <xsl:sequence select="."/>
678 <atom identity="{$atom-ident}">
679 <xsl:sequence select="$newv/data/value/malval"/>
682 <xsl:sequence select="$newv/env"/>
685 <xsl:call-template name="core-apply"><xsl:with-param name="func" select="$func"/><xsl:with-param name="args" select="$args"/></xsl:call-template>
686 <xsl:sequence select="$atoms"/>
692 <xsl:for-each select="$resultv">
694 <xsl:when test="empty(env)">
695 <env data="{env:serialise($env)}" />
698 <xsl:sequence select="env"/>
701 <xsl:sequence select="atoms[1]"/>
702 <xsl:sequence select="value"/>
711 <xsl:call-template name="eval_ast"><xsl:with-param name="env" select="$env"/></xsl:call-template>
712 <env data="{env:serialise($env)}" />
713 <xsl:sequence select="$atoms"/>
717 <data><xsl:sequence select="$data/value"/></data>
718 <env data="{$data/env/@data}" />
719 <xsl:sequence select="$data/atoms[1]"/>
722 <xsl:template name="READ">
723 <xsl:variable name="context">
725 <xsl:copy-of select="stdin/text()" />
728 <xsl:variable name="form">
729 <xsl:sequence select="state/atoms[1]"/>
730 <xsl:for-each select="$context">
731 <xsl:call-template name="malreader-read_str"></xsl:call-template>
734 <xsl:for-each select="$form">
735 <xsl:if test="error">
736 <xsl:message terminate="yes">
737 <xsl:value-of select="error" />
740 <xsl:sequence select="." />
744 <xsl:function name="fn:group_consec">
745 <xsl:param name="nodes" />
746 <xsl:variable name="groups">
747 <xsl:for-each-group select="$nodes" group-by="position() mod 2">
749 <xsl:when test="position() = 1">
751 <xsl:sequence select="current-group()"/>
756 <xsl:sequence select="current-group()"/>
760 </xsl:for-each-group>
762 <xsl:iterate select="1 to count($groups/first/*)">
764 <xsl:variable name="idx" select="number(.)"></xsl:variable>
765 <first><xsl:sequence select="$groups/first/node()[position() = $idx]"/></first>
766 <second><xsl:sequence select="$groups/second/node()[position() = $idx]"/></second>
771 <xsl:function name="fn:is-pair">
772 <xsl:param name="list"/>
773 <xsl:sequence select="($list/@kind = 'list' or $list/@kind = 'vector') and count($list/lvalue/malval) != 0"/>
776 <xsl:function name="fn:is-macro-call">
777 <xsl:param name="ast"/>
778 <xsl:param name="env"/>
779 <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')"/>
780 <xsl:sequence select="$res"/>