impl step4, fix string parsing
[jackhill/mal.git] / xslt / env.xslt
CommitLineData
b10698ec 1<?xml version="1.0" encoding="UTF-8"?>
342a5b36 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:xs="http://www.w3.org/2001/XMLSchema" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:env="ENV">
b10698ec 3 <!-- since I can not, for the life of me, figure out how to (de-)serialise maps from/to xml, we're gonna be storing the env as a json string -->
342a5b36 4
b10698ec
A
5 <xsl:function name="env:set">
6 <xsl:param name="env"/>
7 <xsl:param name="name"/>
8 <xsl:param name="value"/>
342a5b36 9 <xsl:sequence select="map { 'outer': $env('outer'), 'data': map:put(map:merge($env('data')), $name, $value => serialize(map{})) }"/>
b10698ec
A
10 </xsl:function>
11
12 <xsl:function name="env:find">
13 <xsl:param name="env"/>
14 <xsl:param name="name"/>
15 <xsl:sequence select="if (empty($env)) then () else if (map:contains($env('data'), $name)) then $env else env:find($env('outer'), $name)"/>
16 </xsl:function>
17
18 <xsl:function name="env:get">
19 <xsl:param name="env"/>
20 <xsl:param name="name"/>
21 <xsl:variable name="value" select="let $venv := env:find($env, $name) return if (empty($venv)) then () else $venv('data')($name)"></xsl:variable>
22 <xsl:choose>
23 <xsl:when test="empty($value)"><xsl:message terminate="yes">Symbol <xsl:value-of select="$name" /> not found</xsl:message></xsl:when>
24 <xsl:otherwise><xsl:sequence select="parse-xml($value)"/></xsl:otherwise>
25 </xsl:choose>
26 </xsl:function>
27
28 <xsl:function name="env:base" as="xs:string">
29 <xsl:variable name="plus"><malval kind="function" name="+"></malval></xsl:variable>
30 <xsl:variable name="minus"><malval kind="function" name="-"></malval></xsl:variable>
31 <xsl:variable name="mult"><malval kind="function" name="*"></malval></xsl:variable>
32 <xsl:variable name="div"><malval kind="function" name="/"></malval></xsl:variable>
33 <xsl:sequence select="env:serialise(env:set(env:set(env:set(env:set(map{'outer':(), 'data':map{}}, '+', $plus), '-', $minus), '*', $mult), '/', $div))"/>
34 </xsl:function>
35
342a5b36
A
36 <xsl:function name="env:empty">
37 <xsl:sequence select="map{'outer':(), 'data':map{}}"/>
38 </xsl:function>
39
b10698ec
A
40 <xsl:function name="env:serialise">
41 <xsl:param name="env"/>
42 <xsl:sequence select="serialize($env, map {'method': 'json'})"/>
43 </xsl:function>
44
45 <xsl:function name="env:close">
46 <xsl:param name="env"/>
47 <xsl:sequence select="map {'outer': $env, 'data': map{}}"/>
48 </xsl:function>
49
342a5b36
A
50 <xsl:function name="env:close-with-binds">
51 <xsl:param name="env"/>
52 <xsl:param name="binds" />
53 <xsl:param name="exprs" />
54
55 <xsl:variable name="new-env" select="map {'outer': $env, 'data': map{}}"/>
56 <xsl:sequence select="$new-env => env:bind-all($binds, $exprs)"/>
57 </xsl:function>
58
59 <xsl:function name="env:dump">
60 <xsl:param name="env"/>
61 <xsl:sequence select="if (not(empty($env))) then map:merge(($env('data'), env:dump($env('outer')))) else map{}"/>
62 </xsl:function>
63
64 <xsl:function name="env:merge">
65 <xsl:param name="env" />
66 <xsl:param name="second" />
67
68 <xsl:variable name="env-items" select="env:dump($env)"></xsl:variable>
69 <xsl:variable name="second-items" select="env:dump($second)"></xsl:variable>
70 <xsl:variable name="new-env" select="map {'outer': (), 'data': map:merge(($env-items, $second-items))}"></xsl:variable>
71 <xsl:sequence select="$new-env"/>
72 </xsl:function>
73
74 <xsl:function name="env:hier">
75 <xsl:param name="env"/>
76 <xsl:param name="over"/>
77 <xsl:sequence select="map{'outer': env:merge($over, $env), 'data': map{}}"/>
78 </xsl:function>
79
80 <xsl:function name="env:bind-all">
81 <xsl:param name="env"/>
82 <xsl:param name="binds"/>
83 <xsl:param name="exprs"/>
84 <xsl:choose>
85 <xsl:when test="exists($binds) and exists($exprs)">
86 <xsl:choose>
87 <xsl:when test="string(head($binds)) = '&#38;'">
88 <xsl:variable name="listExprs">
89 <malval kind="list">
90 <lvalue>
91 <xsl:sequence select="$exprs"/>
92 </lvalue>
93 </malval>
94 </xsl:variable>
95 <xsl:sequence select="$env => env:set(string($binds[2]), $listExprs)"/>
96 </xsl:when>
97 <xsl:otherwise>
98 <xsl:variable name="new-env" select="$env => env:set(string(head($binds)), head($exprs))"></xsl:variable>
99 <xsl:sequence select="$new-env => env:bind-all(tail($binds), tail($exprs))"/>
100 </xsl:otherwise>
101 </xsl:choose>
102 </xsl:when>
103 <xsl:when test="exists($binds)">
104 <xsl:choose>
105 <xsl:when test="string(head($binds)) = '&#38;'">
106 <xsl:variable name="listExprs">
107 <malval kind="list">
108 <lvalue>
109 </lvalue>
110 </malval>
111 </xsl:variable>
112 <xsl:sequence select="$env => env:set(string($binds[2]), $listExprs)"/>
113 </xsl:when>
114 <xsl:otherwise>
115 <xsl:variable name="Exprs">
116 <malval kind="nil">
117 </malval>
118 </xsl:variable>
119 <xsl:variable name="new-env" select="$env => env:set(string(head($binds)), $Exprs)"></xsl:variable>
120 <xsl:sequence select="$new-env => env:bind-all(tail($binds), $exprs)"/>
121 </xsl:otherwise>
122 </xsl:choose>
123 </xsl:when>
124 <xsl:otherwise>
125 <xsl:sequence select="$env"/>
126 </xsl:otherwise>
127 </xsl:choose>
128 </xsl:function>
129
b10698ec
A
130 <xsl:function name="env:deserialise">
131 <xsl:param name="env"/>
132 <xsl:sequence select="parse-json($env)"/>
133 </xsl:function>
134
342a5b36 135</xsl:stylesheet>