Commit | Line | Data |
---|---|---|
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 | |
ab29f6bd A |
5 | <xsl:function name="env:noReplEnv"> |
6 | <xsl:param name="env"/> | |
7 | <xsl:sequence select="map {'outer': $env('outer'), 'isReplEnv': false(), 'data': $env('data') }"/> | |
8 | </xsl:function> | |
9 | ||
b10698ec A |
10 | <xsl:function name="env:set"> |
11 | <xsl:param name="env"/> | |
12 | <xsl:param name="name"/> | |
13 | <xsl:param name="value"/> | |
ab29f6bd | 14 | <xsl:sequence select="if ($env('isReplEnv')) then map { 'outer': $env('outer'), 'replEnv': env:set($env('replEnv'), $name, $value), 'isReplEnv': true(), 'data': $env('data') } else map { 'outer': $env('outer'), 'replEnv': $env('replEnv'), 'isReplEnv': false(), 'data': map:put($env('data'), $name, $value => serialize(map{})) }"/> |
b10698ec A |
15 | </xsl:function> |
16 | ||
17 | <xsl:function name="env:find"> | |
18 | <xsl:param name="env"/> | |
19 | <xsl:param name="name"/> | |
ab29f6bd | 20 | <xsl:sequence select="if (empty($env)) then () else if (map:contains($env('data'), $name)) then $env else (env:find($env('outer'), $name), env:find($env('replEnv'), $name))[1]"/> |
b10698ec A |
21 | </xsl:function> |
22 | ||
23 | <xsl:function name="env:get"> | |
24 | <xsl:param name="env"/> | |
25 | <xsl:param name="name"/> | |
26 | <xsl:variable name="value" select="let $venv := env:find($env, $name) return if (empty($venv)) then () else $venv('data')($name)"></xsl:variable> | |
27 | <xsl:choose> | |
28 | <xsl:when test="empty($value)"><xsl:message terminate="yes">Symbol <xsl:value-of select="$name" /> not found</xsl:message></xsl:when> | |
29 | <xsl:otherwise><xsl:sequence select="parse-xml($value)"/></xsl:otherwise> | |
30 | </xsl:choose> | |
31 | </xsl:function> | |
32 | ||
33 | <xsl:function name="env:base" as="xs:string"> | |
34 | <xsl:variable name="plus"><malval kind="function" name="+"></malval></xsl:variable> | |
35 | <xsl:variable name="minus"><malval kind="function" name="-"></malval></xsl:variable> | |
36 | <xsl:variable name="mult"><malval kind="function" name="*"></malval></xsl:variable> | |
37 | <xsl:variable name="div"><malval kind="function" name="/"></malval></xsl:variable> | |
ab29f6bd A |
38 | <xsl:sequence select="env:serialise(env:set(env:set(env:set(env:set(map{'outer':(), 'data':map{}, 'isReplEnv': false()}, '+', $plus), '-', $minus), '*', $mult), '/', $div))"/> |
39 | </xsl:function> | |
40 | ||
41 | <xsl:function name="env:swap-replEnv"> | |
42 | <xsl:param name="env"></xsl:param> | |
43 | <xsl:param name="toRepl"></xsl:param> | |
44 | <xsl:sequence select="if (not(empty($toRepl))) then map:put($env, 'replEnv', $toRepl) else $env"/> | |
45 | </xsl:function> | |
46 | ||
47 | <xsl:function name="env:replEnv"> | |
48 | <xsl:param name="env"/> | |
49 | <xsl:sequence select="$env('replEnv')"/> | |
50 | </xsl:function> | |
51 | ||
52 | <xsl:function name="env:toReplEnv"> | |
53 | <xsl:param name="env"/> | |
54 | <xsl:variable name='renv' select="map{'outer':(), 'data': map{}, 'replEnv': map{'data':env:dump($env), 'outer':(), 'isReplEnv': false()}, 'isReplEnv': true()}"/> | |
55 | <xsl:sequence select="$renv"/> | |
b10698ec A |
56 | </xsl:function> |
57 | ||
342a5b36 | 58 | <xsl:function name="env:empty"> |
ab29f6bd | 59 | <xsl:sequence select="map{'outer':(), 'data':map{}, 'isReplEnv': false()}"/> |
342a5b36 A |
60 | </xsl:function> |
61 | ||
b10698ec A |
62 | <xsl:function name="env:serialise"> |
63 | <xsl:param name="env"/> | |
64 | <xsl:sequence select="serialize($env, map {'method': 'json'})"/> | |
65 | </xsl:function> | |
66 | ||
67 | <xsl:function name="env:close"> | |
68 | <xsl:param name="env"/> | |
ab29f6bd | 69 | <xsl:sequence select="map{'outer': env:noReplEnv($env), 'data': map{}, 'isReplEnv': false(), 'replEnv': $env('replEnv')}"/> |
b10698ec A |
70 | </xsl:function> |
71 | ||
342a5b36 A |
72 | <xsl:function name="env:close-with-binds"> |
73 | <xsl:param name="env"/> | |
74 | <xsl:param name="binds" /> | |
75 | <xsl:param name="exprs" /> | |
76 | ||
ab29f6bd | 77 | <xsl:variable name="new-env" select="map {'outer': env:noReplEnv($env), 'replEnv': $env('replEnv'), 'data': map{}, 'isReplEnv': false()}"/> |
342a5b36 A |
78 | <xsl:sequence select="$new-env => env:bind-all($binds, $exprs)"/> |
79 | </xsl:function> | |
80 | ||
81 | <xsl:function name="env:dump"> | |
82 | <xsl:param name="env"/> | |
83 | <xsl:sequence select="if (not(empty($env))) then map:merge(($env('data'), env:dump($env('outer')))) else map{}"/> | |
84 | </xsl:function> | |
85 | ||
86 | <xsl:function name="env:merge"> | |
87 | <xsl:param name="env" /> | |
88 | <xsl:param name="second" /> | |
89 | ||
90 | <xsl:variable name="env-items" select="env:dump($env)"></xsl:variable> | |
91 | <xsl:variable name="second-items" select="env:dump($second)"></xsl:variable> | |
ab29f6bd | 92 | <xsl:variable name="new-env" select="if (empty($env)) then $second else if (empty($second)) then $env else map {'outer': $env('outer'), 'data': map:merge(($env-items, $second-items)), 'isReplEnv': false(), 'replEnv': env:merge($second('replEnv'), $env('replEnv'))}"></xsl:variable> |
342a5b36 A |
93 | <xsl:sequence select="$new-env"/> |
94 | </xsl:function> | |
95 | ||
96 | <xsl:function name="env:hier"> | |
97 | <xsl:param name="env"/> | |
98 | <xsl:param name="over"/> | |
ab29f6bd A |
99 | <xsl:variable name="newEnv" select="env:merge($over, $env)"></xsl:variable> |
100 | <xsl:sequence select="map{'outer': env:noReplEnv($newEnv), 'data': map{}, 'isReplEnv': false(), 'replEnv': $newEnv('replEnv')}"/> | |
342a5b36 A |
101 | </xsl:function> |
102 | ||
103 | <xsl:function name="env:bind-all"> | |
104 | <xsl:param name="env"/> | |
105 | <xsl:param name="binds"/> | |
106 | <xsl:param name="exprs"/> | |
107 | <xsl:choose> | |
108 | <xsl:when test="exists($binds) and exists($exprs)"> | |
109 | <xsl:choose> | |
110 | <xsl:when test="string(head($binds)) = '&'"> | |
111 | <xsl:variable name="listExprs"> | |
112 | <malval kind="list"> | |
113 | <lvalue> | |
114 | <xsl:sequence select="$exprs"/> | |
115 | </lvalue> | |
116 | </malval> | |
117 | </xsl:variable> | |
118 | <xsl:sequence select="$env => env:set(string($binds[2]), $listExprs)"/> | |
119 | </xsl:when> | |
120 | <xsl:otherwise> | |
121 | <xsl:variable name="new-env" select="$env => env:set(string(head($binds)), head($exprs))"></xsl:variable> | |
122 | <xsl:sequence select="$new-env => env:bind-all(tail($binds), tail($exprs))"/> | |
123 | </xsl:otherwise> | |
124 | </xsl:choose> | |
125 | </xsl:when> | |
126 | <xsl:when test="exists($binds)"> | |
127 | <xsl:choose> | |
128 | <xsl:when test="string(head($binds)) = '&'"> | |
129 | <xsl:variable name="listExprs"> | |
130 | <malval kind="list"> | |
131 | <lvalue> | |
132 | </lvalue> | |
133 | </malval> | |
134 | </xsl:variable> | |
135 | <xsl:sequence select="$env => env:set(string($binds[2]), $listExprs)"/> | |
136 | </xsl:when> | |
137 | <xsl:otherwise> | |
138 | <xsl:variable name="Exprs"> | |
139 | <malval kind="nil"> | |
140 | </malval> | |
141 | </xsl:variable> | |
142 | <xsl:variable name="new-env" select="$env => env:set(string(head($binds)), $Exprs)"></xsl:variable> | |
143 | <xsl:sequence select="$new-env => env:bind-all(tail($binds), $exprs)"/> | |
144 | </xsl:otherwise> | |
145 | </xsl:choose> | |
146 | </xsl:when> | |
147 | <xsl:otherwise> | |
148 | <xsl:sequence select="$env"/> | |
149 | </xsl:otherwise> | |
150 | </xsl:choose> | |
151 | </xsl:function> | |
152 | ||
b10698ec A |
153 | <xsl:function name="env:deserialise"> |
154 | <xsl:param name="env"/> | |
155 | <xsl:sequence select="parse-json($env)"/> | |
156 | </xsl:function> | |
157 | ||
342a5b36 | 158 | </xsl:stylesheet> |