1 <?xml version="1.0" encoding="UTF-8"?>
2 <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:core="CORE" exclude-result-prefixes="core fn xsl">
3 <xsl:function name="core:ns">
5 <malval kind="function" name="+" />
6 <malval kind="function" name="-" />
7 <malval kind="function" name="*" />
8 <malval kind="function" name="/" />
9 <malval kind="function" name="prn"/>
10 <malval kind="function" name="pr-str"/>
11 <malval kind="function" name="str"/>
12 <malval kind="function" name="println"/>
13 <malval kind="function" name="list"/>
14 <malval kind="function" name="list?"/>
15 <malval kind="function" name="empty?"/>
16 <malval kind="function" name="count"/>
17 <malval kind="function" name="="/>
18 <malval kind="function" name="<"/>
19 <malval kind="function" name="<="/>
20 <malval kind="function" name=">"/>
21 <malval kind="function" name=">="/>
22 <malval kind="function" name="read-string"/>
23 <malval kind="function" name="slurp"/>
24 <malval kind="function" name="env??"/> <!-- defined in the step files -->
25 <malval kind="function" name="eval"/> <!-- defined in the step files -->
26 <malval kind="function" name="atom"/> <!-- defined in the step files -->
27 <malval kind="function" name="atom?"/>
28 <malval kind="function" name="deref"/> <!-- defined in the step files -->
29 <malval kind="function" name="swap!"/> <!-- defined in the step files -->
30 <malval kind="function" name="reset!"/> <!-- defined in the step files -->
34 <xsl:template name="core-apply">
35 <xsl:param name="func" />
36 <xsl:param name="args" />
38 <xsl:when test="$func/malval/@kind = 'function'">
40 <xsl:when test="$func/malval/@name = '+'">
41 <xsl:variable name="result" select="number($args/value/malval/lvalue/malval[1]/@value) + number($args/value/malval/lvalue/malval[2]/@value)"></xsl:variable>
42 <xsl:sequence select="core:makeMALType($result, 'number')"/>
44 <xsl:when test="$func/malval/@name = '-'">
45 <xsl:variable name="result" select="number($args/value/malval/lvalue/malval[1]/@value) - number($args/value/malval/lvalue/malval[2]/@value)"></xsl:variable>
46 <xsl:sequence select="core:makeMALType($result, 'number')"/>
48 <xsl:when test="$func/malval/@name = '*'">
49 <xsl:variable name="result" select="number($args/value/malval/lvalue/malval[1]/@value) * number($args/value/malval/lvalue/malval[2]/@value)"></xsl:variable>
50 <xsl:sequence select="core:makeMALType($result, 'number')"/>
52 <xsl:when test="$func/malval/@name = '/'">
53 <xsl:variable name="result" select="number($args/value/malval/lvalue/malval[1]/@value) div number($args/value/malval/lvalue/malval[2]/@value)"></xsl:variable>
54 <xsl:sequence select="core:makeMALType($result, 'number')"/>
56 <xsl:when test="$func/malval/@name = 'prn'">
57 <xsl:variable name="args" select="$args/value/malval/lvalue/malval" />
58 <xsl:variable name="sargs">
59 <xsl:for-each select="$args">
60 <xsl:variable name="arg">
62 <xsl:sequence select="."/>
66 <xsl:for-each select="$arg">
67 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="true()"/></xsl:call-template>
73 <xsl:sequence select="string-join($sargs/str, ' ')"/>
75 <xsl:sequence select="core:makeMALType((), 'nil')"/>
77 <xsl:when test="$func/malval/@name = 'pr-str'">
78 <xsl:variable name="args" select="$args/value/malval/lvalue/malval" />
79 <xsl:variable name="sargs">
80 <xsl:for-each select="$args">
81 <xsl:variable name="arg">
83 <xsl:sequence select="."/>
87 <xsl:for-each select="$arg">
88 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="true()"/></xsl:call-template>
93 <xsl:sequence select="core:makeMALType(string-join($sargs/str, ' '), 'string')"/>
95 <xsl:when test="$func/malval/@name = 'str'">
96 <xsl:variable name="args" select="$args/value/malval/lvalue/malval" />
97 <xsl:variable name="sargs">
98 <xsl:for-each select="$args">
99 <xsl:variable name="arg">
101 <xsl:sequence select="."/>
105 <xsl:for-each select="$arg">
106 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="false()"/></xsl:call-template>
111 <xsl:sequence select="core:makeMALType(string-join($sargs/str, ''), 'string')"/>
113 <xsl:when test="$func/malval/@name = 'println'">
114 <xsl:variable name="args" select="$args/value/malval/lvalue/malval" />
115 <xsl:variable name="sargs">
116 <xsl:for-each select="$args">
117 <xsl:variable name="arg">
119 <xsl:sequence select="."/>
123 <xsl:for-each select="$arg">
124 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="false()"/></xsl:call-template>
130 <xsl:sequence select="string-join($sargs/str, ' ')"/>
132 <xsl:sequence select="core:makeMALType((), 'nil')"/>
134 <xsl:when test="$func/malval/@name = 'list'">
135 <xsl:sequence select="$args"/>
137 <xsl:when test="$func/malval/@name = 'list?'">
138 <xsl:sequence select="core:makeMALType((), if ($args/value/malval/lvalue/malval[1]/@kind = 'list') then 'true' else 'false')"/>
140 <xsl:when test="$func/malval/@name = 'empty?'">
141 <xsl:sequence select="core:makeMALType((), if (count($args/value/malval/lvalue/malval[1]/lvalue/malval) = 0) then 'true' else 'false')"/>
143 <xsl:when test="$func/malval/@name = 'count'">
144 <xsl:sequence select="core:makeMALType(count($args/value/malval/lvalue/malval[1]/lvalue/malval), 'number')"/>
146 <xsl:when test="$func/malval/@name = '='">
147 <xsl:sequence select="core:makeMALType((), if (core:equal($args/value/malval/lvalue/malval[1], $args/value/malval/lvalue/malval[2])) then 'true' else 'false')"/>
149 <xsl:when test="$func/malval/@name = '<'">
150 <xsl:sequence select="core:makeMALType((), if (number($args/value/malval/lvalue/malval[1]/@value) lt number($args/value/malval/lvalue/malval[2]/@value)) then 'true' else 'false')"/>
152 <xsl:when test="$func/malval/@name = '<='">
153 <xsl:sequence select="core:makeMALType((), if (number($args/value/malval/lvalue/malval[1]/@value) le number($args/value/malval/lvalue/malval[2]/@value)) then 'true' else 'false')"/>
155 <xsl:when test="$func/malval/@name = '>'">
156 <xsl:sequence select="core:makeMALType((), if (number($args/value/malval/lvalue/malval[1]/@value) gt number($args/value/malval/lvalue/malval[2]/@value)) then 'true' else 'false')"/>
158 <xsl:when test="$func/malval/@name = '>='">
159 <xsl:sequence select="core:makeMALType((), if (number($args/value/malval/lvalue/malval[1]/@value) ge number($args/value/malval/lvalue/malval[2]/@value)) then 'true' else 'false')"/>
161 <xsl:when test="$func/malval/@name = 'read-string'">
162 <xsl:variable name="read-string-context">
164 <xsl:value-of select="$args/value/malval/lvalue/malval[1]/@value"></xsl:value-of>
167 <xsl:for-each select="$read-string-context">
168 <xsl:call-template name="malreader-read_str"></xsl:call-template>
171 <xsl:when test="$func/malval/@name = 'slurp'">
172 <xsl:sequence select="core:makeMALType(unparsed-text($args/value/malval/lvalue/malval[1]/@value), 'string')"/>
174 <xsl:when test="$func/malval/@name = 'atom?'">
175 <xsl:sequence select="core:makeMALType((), if ($args/value/malval/lvalue/malval[1]/@kind = 'atom') then 'true' else 'false')"/>
178 <xsl:message terminate="yes">Invalid function <xsl:sequence select="$func"/> </xsl:message>
182 <xsl:otherwise></xsl:otherwise>
186 <xsl:function name="core:makeMALType">
187 <xsl:param name="value" />
188 <xsl:param name="kind" />
190 <malval kind="{$kind}" value="{$value}"/>
194 <xsl:function name="core:all-equal">
195 <xsl:param name="seq"/>
196 <xsl:param name="left"/>
197 <xsl:param name="right"/>
199 <xsl:when test="empty($seq)">
200 <xsl:sequence select="true()"/>
204 <xsl:when test="core:list-equal($left, $right, head($seq))">
205 <xsl:sequence select="core:all-equal(tail($seq), $right, $left)"/>
208 <xsl:sequence select="false()"/>
215 <xsl:function name="core:equal">
216 <xsl:param name="left"/>
217 <xsl:param name="right"/>
220 <xsl:when test="$left/@kind = $right/@kind">
223 <xsl:when test="$left/@kind = 'list' or $left/@kind = 'vector' or $left/@kind = 'hash'">
226 <xsl:when test="count($left/lvalue/malval) = count($right/lvalue/malval)">
227 <xsl:sequence select="core:all-equal(1 to count($left/lvalue/malval), $left, $right)"/>
229 <!-- different counts -->
231 <xsl:sequence select="false()"/>
235 <!-- simple 'value' type -->
237 <xsl:sequence select="string($left/@value) = string($right/@value)"/>
241 <!-- different types -->
244 <xsl:when test="($left/@kind = 'list' and $right/@kind = 'vector') or ($left/@kind = 'vector' and $right/@kind = 'list')">
247 <xsl:when test="count($left/lvalue/malval) = count($right/lvalue/malval)">
248 <xsl:sequence select="core:all-equal(1 to count($left/lvalue/malval), $left, $right)"/>
250 <!-- different counts -->
252 <xsl:sequence select="false()"/>
257 <xsl:sequence select="false()"/>
264 <xsl:function name="core:list-equal">
265 <xsl:param name="l"/>
266 <xsl:param name="r"/>
267 <xsl:param name="v"/>
269 <xsl:sequence select="core:equal($l/lvalue/malval[$v], $r/lvalue/malval[$v])"/>