zuzu-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.md +113 -0
- package/bin/zuzu +17 -0
- package/bin/zuzu-build-browser-bundle +57 -0
- package/bin/zuzu-generate-browser-stdlib +584 -0
- package/bin/zuzu-js +23 -0
- package/bin/zuzu-js-compile +152 -0
- package/bin/zuzu-js-electron +19 -0
- package/dist/zuzu-browser-worker.js +45574 -0
- package/dist/zuzu-browser.js +45362 -0
- package/lib/browser-bundle-entry.js +160 -0
- package/lib/browser-gui-renderer.js +387 -0
- package/lib/browser-runtime.js +167 -0
- package/lib/browser-worker-entry.js +413 -0
- package/lib/browser-ztests/runner.html +103 -0
- package/lib/browser-ztests/runner.js +369 -0
- package/lib/cli.js +350 -0
- package/lib/collections.js +367 -0
- package/lib/compiler.js +303 -0
- package/lib/electron/launcher.js +70 -0
- package/lib/electron/main.js +956 -0
- package/lib/electron/preload.js +80 -0
- package/lib/electron/renderer.html +122 -0
- package/lib/electron/renderer.js +24 -0
- package/lib/execution-metadata.js +18 -0
- package/lib/gui/dom-renderer.js +778 -0
- package/lib/host/browser-host.js +278 -0
- package/lib/host/capabilities.js +47 -0
- package/lib/host/electron-host.js +15 -0
- package/lib/host/node-host.js +74 -0
- package/lib/paths.js +150 -0
- package/lib/runtime-entrypoints.js +60 -0
- package/lib/runtime-helpers.js +886 -0
- package/lib/runtime.js +3529 -0
- package/lib/tap.js +37 -0
- package/lib/transpiler-new/ast.js +23 -0
- package/lib/transpiler-new/codegen.js +2455 -0
- package/lib/transpiler-new/errors.js +28 -0
- package/lib/transpiler-new/index.js +26 -0
- package/lib/transpiler-new/lexer.js +834 -0
- package/lib/transpiler-new/parser.js +2332 -0
- package/lib/transpiler-new/validate-bindings.js +326 -0
- package/lib/transpiler-utils.js +95 -0
- package/lib/transpiler.js +33 -0
- package/lib/zuzu.js +53 -0
- package/modules/javascript.js +193 -0
- package/modules/std/archive.js +603 -0
- package/modules/std/clib.js +338 -0
- package/modules/std/data/csv.js +1331 -0
- package/modules/std/data/json.js +531 -0
- package/modules/std/data/xml.js +441 -0
- package/modules/std/data/yaml.js +256 -0
- package/modules/std/db-worker.js +250 -0
- package/modules/std/db.js +664 -0
- package/modules/std/digest/_hash.js +443 -0
- package/modules/std/digest/md5.js +26 -0
- package/modules/std/digest/sha.js +72 -0
- package/modules/std/eval.js +10 -0
- package/modules/std/gui/objects.js +1519 -0
- package/modules/std/internals.js +571 -0
- package/modules/std/io/socks-worker.js +318 -0
- package/modules/std/io/socks.js +186 -0
- package/modules/std/io.js +475 -0
- package/modules/std/marshal/cbor.js +463 -0
- package/modules/std/marshal/graph.js +1624 -0
- package/modules/std/marshal.js +87 -0
- package/modules/std/math/bignum.js +91 -0
- package/modules/std/math.js +79 -0
- package/modules/std/net/dns.js +306 -0
- package/modules/std/net/http.js +820 -0
- package/modules/std/net/smtp.js +943 -0
- package/modules/std/net/url.js +109 -0
- package/modules/std/proc.js +602 -0
- package/modules/std/secure.js +3724 -0
- package/modules/std/string/base64.js +138 -0
- package/modules/std/string.js +299 -0
- package/modules/std/task.js +914 -0
- package/modules/std/time.js +579 -0
- package/modules/std/tui.js +188 -0
- package/modules/std/worker-thread.js +246 -0
- package/modules/std/worker.js +790 -0
- package/package.json +67 -0
- package/stdlib/modules/javascript.zzm +99 -0
- package/stdlib/modules/perl.zzm +105 -0
- package/stdlib/modules/std/archive.zzm +132 -0
- package/stdlib/modules/std/cache/lru.zzm +174 -0
- package/stdlib/modules/std/clib.zzm +112 -0
- package/stdlib/modules/std/colour.zzm +220 -0
- package/stdlib/modules/std/config.zzm +818 -0
- package/stdlib/modules/std/data/cbor.zzm +497 -0
- package/stdlib/modules/std/data/csv.zzm +285 -0
- package/stdlib/modules/std/data/ini.zzm +472 -0
- package/stdlib/modules/std/data/json/schema/core.zzm +573 -0
- package/stdlib/modules/std/data/json/schema/format.zzm +581 -0
- package/stdlib/modules/std/data/json/schema/model.zzm +255 -0
- package/stdlib/modules/std/data/json/schema/output.zzm +272 -0
- package/stdlib/modules/std/data/json/schema/relative_pointer.zzm +299 -0
- package/stdlib/modules/std/data/json/schema/validation.zzm +1503 -0
- package/stdlib/modules/std/data/json/schema.zzm +306 -0
- package/stdlib/modules/std/data/json.zzm +102 -0
- package/stdlib/modules/std/data/kdl/json.zzm +460 -0
- package/stdlib/modules/std/data/kdl/xml.zzm +387 -0
- package/stdlib/modules/std/data/kdl.zzm +1631 -0
- package/stdlib/modules/std/data/toml.zzm +756 -0
- package/stdlib/modules/std/data/toon.zzm +1017 -0
- package/stdlib/modules/std/data/xml/escape.zzm +156 -0
- package/stdlib/modules/std/data/xml.zzm +276 -0
- package/stdlib/modules/std/data/yaml.zzm +94 -0
- package/stdlib/modules/std/db.zzm +173 -0
- package/stdlib/modules/std/defer.zzm +75 -0
- package/stdlib/modules/std/digest/crc32.zzm +196 -0
- package/stdlib/modules/std/digest/md5.zzm +54 -0
- package/stdlib/modules/std/digest/sha.zzm +83 -0
- package/stdlib/modules/std/dump.zzm +317 -0
- package/stdlib/modules/std/eval.zzm +63 -0
- package/stdlib/modules/std/getopt.zzm +432 -0
- package/stdlib/modules/std/gui/dialogue.zzm +592 -0
- package/stdlib/modules/std/gui/objects.zzm +123 -0
- package/stdlib/modules/std/gui.zzm +1914 -0
- package/stdlib/modules/std/internals.zzm +139 -0
- package/stdlib/modules/std/io/socks.zzm +139 -0
- package/stdlib/modules/std/io.zzm +157 -0
- package/stdlib/modules/std/lingua/en.zzm +347 -0
- package/stdlib/modules/std/log.zzm +169 -0
- package/stdlib/modules/std/mail.zzm +2726 -0
- package/stdlib/modules/std/marshal.zzm +138 -0
- package/stdlib/modules/std/math/bignum.zzm +98 -0
- package/stdlib/modules/std/math/range.zzm +116 -0
- package/stdlib/modules/std/math/roman.zzm +156 -0
- package/stdlib/modules/std/math.zzm +141 -0
- package/stdlib/modules/std/net/dns.zzm +93 -0
- package/stdlib/modules/std/net/http.zzm +278 -0
- package/stdlib/modules/std/net/smtp.zzm +257 -0
- package/stdlib/modules/std/net/url.zzm +69 -0
- package/stdlib/modules/std/path/jsonpointer.zzm +526 -0
- package/stdlib/modules/std/path/kdl.zzm +1003 -0
- package/stdlib/modules/std/path/simple.zzm +520 -0
- package/stdlib/modules/std/path/z/context.zzm +147 -0
- package/stdlib/modules/std/path/z/evaluate.zzm +549 -0
- package/stdlib/modules/std/path/z/functions.zzm +874 -0
- package/stdlib/modules/std/path/z/lexer.zzm +490 -0
- package/stdlib/modules/std/path/z/node.zzm +1455 -0
- package/stdlib/modules/std/path/z/operators.zzm +445 -0
- package/stdlib/modules/std/path/z/parser.zzm +359 -0
- package/stdlib/modules/std/path/z.zzm +403 -0
- package/stdlib/modules/std/path/zz/functions.zzm +828 -0
- package/stdlib/modules/std/path/zz/operators.zzm +1036 -0
- package/stdlib/modules/std/path/zz.zzm +100 -0
- package/stdlib/modules/std/proc.zzm +155 -0
- package/stdlib/modules/std/result.zzm +149 -0
- package/stdlib/modules/std/secure.zzm +606 -0
- package/stdlib/modules/std/string/base64.zzm +66 -0
- package/stdlib/modules/std/string/quoted_printable.zzm +485 -0
- package/stdlib/modules/std/string.zzm +179 -0
- package/stdlib/modules/std/task.zzm +221 -0
- package/stdlib/modules/std/template/z.zzm +531 -0
- package/stdlib/modules/std/template/zz.zzm +62 -0
- package/stdlib/modules/std/time.zzm +188 -0
- package/stdlib/modules/std/tui.zzm +89 -0
- package/stdlib/modules/std/uuid.zzm +223 -0
- package/stdlib/modules/std/web/session.zzm +388 -0
- package/stdlib/modules/std/web/static.zzm +329 -0
- package/stdlib/modules/std/web.zzm +1942 -0
- package/stdlib/modules/std/worker.zzm +202 -0
- package/stdlib/modules/std/zuzuzoo.zzm +3960 -0
- package/stdlib/modules/test/more.zzm +528 -0
- package/stdlib/modules/test/parser.zzm +209 -0
|
@@ -0,0 +1,874 @@
|
|
|
1
|
+
=encoding utf8
|
|
2
|
+
|
|
3
|
+
=head1 NAME
|
|
4
|
+
|
|
5
|
+
std/path/z/functions - Function definitions for ZPath.
|
|
6
|
+
|
|
7
|
+
=head1 IMPLEMENTATION SUPPORT
|
|
8
|
+
|
|
9
|
+
This module is supported by all implementations of ZuzuScript.
|
|
10
|
+
|
|
11
|
+
=head1 DESCRIPTION
|
|
12
|
+
|
|
13
|
+
This module defines the function objects and standard function table used
|
|
14
|
+
by C<std/path/z>.
|
|
15
|
+
|
|
16
|
+
=head1 EXPORTS
|
|
17
|
+
|
|
18
|
+
=head2 Classes
|
|
19
|
+
|
|
20
|
+
=over
|
|
21
|
+
|
|
22
|
+
=item C<< Func({ spelling: String, f: Function }) >>
|
|
23
|
+
|
|
24
|
+
Constructs a ZPath function definition. Returns: C<Func>.
|
|
25
|
+
|
|
26
|
+
=over
|
|
27
|
+
|
|
28
|
+
=item C<< func.has_name(n) >>
|
|
29
|
+
|
|
30
|
+
Parameters: C<n> is a function name. Returns: C<Boolean>. Returns true
|
|
31
|
+
when C<n> matches the function spelling.
|
|
32
|
+
|
|
33
|
+
=back
|
|
34
|
+
|
|
35
|
+
=back
|
|
36
|
+
|
|
37
|
+
=head2 Functions
|
|
38
|
+
|
|
39
|
+
=over
|
|
40
|
+
|
|
41
|
+
=item C<< replace(haystack, needle, replacement) >>
|
|
42
|
+
|
|
43
|
+
Parameters: C<haystack> is source text, C<needle> is a pattern, and
|
|
44
|
+
C<replacement> is replacement text. Returns: C<String>. Performs ZPath
|
|
45
|
+
replacement with capture substitutions.
|
|
46
|
+
|
|
47
|
+
=item C<< mk_single_number_function(String name, Function impl) >>
|
|
48
|
+
|
|
49
|
+
Parameters: C<name> is a ZPath function name and C<impl> maps one
|
|
50
|
+
number. Returns: C<Function>. Builds a function wrapper for per-node
|
|
51
|
+
numeric functions.
|
|
52
|
+
|
|
53
|
+
=item C<< mk_aggregate_number_function(String name, Function impl) >>
|
|
54
|
+
|
|
55
|
+
Parameters: C<name> is a ZPath function name and C<impl> maps an array
|
|
56
|
+
of numbers. Returns: C<Function>. Builds a function wrapper for
|
|
57
|
+
aggregate numeric functions.
|
|
58
|
+
|
|
59
|
+
=item C<< mk_single_string_function(String name, Function impl) >>
|
|
60
|
+
|
|
61
|
+
Parameters: C<name> is a ZPath function name and C<impl> maps one
|
|
62
|
+
string. Returns: C<Function>. Builds a function wrapper for per-node
|
|
63
|
+
string functions.
|
|
64
|
+
|
|
65
|
+
=item C<< mk_match_function() >>
|
|
66
|
+
|
|
67
|
+
Parameters: none. Returns: C<Function>. Builds the standard ZPath
|
|
68
|
+
C<match> function implementation.
|
|
69
|
+
|
|
70
|
+
=back
|
|
71
|
+
|
|
72
|
+
=head2 Constants
|
|
73
|
+
|
|
74
|
+
=over
|
|
75
|
+
|
|
76
|
+
=item C<STANDARD_FUNCTIONS>
|
|
77
|
+
|
|
78
|
+
Type: C<Array>. Standard ZPath function definitions.
|
|
79
|
+
|
|
80
|
+
=back
|
|
81
|
+
|
|
82
|
+
=head1 COPYRIGHT AND LICENCE
|
|
83
|
+
|
|
84
|
+
B<< std/path/z/functions >> is copyright Toby Inkster.
|
|
85
|
+
|
|
86
|
+
It is free software; you may redistribute it and/or modify it under
|
|
87
|
+
the terms of either the Artistic License 1.0 or the GNU General Public
|
|
88
|
+
License version 2.
|
|
89
|
+
|
|
90
|
+
=cut
|
|
91
|
+
|
|
92
|
+
from std/path/z/node import KDLNodeNode, KDLValueNode, Node, XmlNodeNode;
|
|
93
|
+
from std/path/z/operators import EvalHelpers;
|
|
94
|
+
from std/data/xml/escape import escape_xml, unescape_xml;
|
|
95
|
+
from std/string import index, rindex, search, sprint, substr, join;
|
|
96
|
+
from std/math import Math;
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class Func with EvalHelpers {
|
|
100
|
+
let String spelling with get;
|
|
101
|
+
let Function f;
|
|
102
|
+
|
|
103
|
+
method has_name ( n ) {
|
|
104
|
+
return true if self.get_spelling eq n;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function replace ( haystack, needle, replacement ) {
|
|
110
|
+
let copy := haystack;
|
|
111
|
+
|
|
112
|
+
if ( replacement ~ /\$[0-9]/ ) {
|
|
113
|
+
let r := replacement;
|
|
114
|
+
copy ~= needle → do {
|
|
115
|
+
let matches := m;
|
|
116
|
+
r ~= /\$([0-9]+)/g → matches[ m[1] ];
|
|
117
|
+
r;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
copy ~= needle → replacement;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return copy;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function mk_single_number_function ( String name, Function impl ) {
|
|
128
|
+
return function ( funk, ev, ast, ctx, args ) {
|
|
129
|
+
let nodes := [];
|
|
130
|
+
for ( let a in args ) {
|
|
131
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
132
|
+
for ( let n in got ) {
|
|
133
|
+
nodes.push( n );
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
nodes := ctx.nodeset;
|
|
138
|
+
}
|
|
139
|
+
return nodes
|
|
140
|
+
.map( fn x → x.number_value )
|
|
141
|
+
.grep( fn x → x instanceof Number )
|
|
142
|
+
.map( fn x → funk.wrap_for_array( impl(x) ) );
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function mk_aggregate_number_function ( String name, Function impl ) {
|
|
147
|
+
return function ( funk, ev, ast, ctx, args ) {
|
|
148
|
+
let nodes := [];
|
|
149
|
+
for ( let a in args ) {
|
|
150
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
151
|
+
for ( let n in got ) {
|
|
152
|
+
nodes.push( n );
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
nodes := ctx.nodeset;
|
|
157
|
+
}
|
|
158
|
+
const nums := nodes
|
|
159
|
+
.map( fn x → x.number_value )
|
|
160
|
+
.grep( fn x → x instanceof Number );
|
|
161
|
+
return funk.wrap( impl( nums ) );
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function mk_single_string_function ( String name, Function impl ) {
|
|
166
|
+
return function ( funk, ev, ast, ctx, args ) {
|
|
167
|
+
let nodes := [];
|
|
168
|
+
for ( let a in args ) {
|
|
169
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
170
|
+
for ( let n in got ) {
|
|
171
|
+
nodes.push( n );
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
nodes := ctx.nodeset;
|
|
176
|
+
}
|
|
177
|
+
return nodes
|
|
178
|
+
.map( fn x → x.string_value )
|
|
179
|
+
.grep( fn x → x instanceof String )
|
|
180
|
+
.map( fn x → funk.wrap_for_array( impl(x) ) );
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function mk_match_function () {
|
|
185
|
+
return function ( funk, ev, ast, ctx, args ) {
|
|
186
|
+
let nodes := [];
|
|
187
|
+
let re;
|
|
188
|
+
|
|
189
|
+
if ( args.empty ) {
|
|
190
|
+
die "Not enough arguments for match()";
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
re := try {
|
|
194
|
+
ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
|
|
195
|
+
} catch {
|
|
196
|
+
"";
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
for ( let a in args[1:] ) {
|
|
201
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
202
|
+
for ( let n in got ) {
|
|
203
|
+
nodes.push( n );
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
nodes := ctx.nodeset;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return nodes
|
|
211
|
+
.map( fn x → x.string_value )
|
|
212
|
+
.grep( fn x → x instanceof String )
|
|
213
|
+
.map( fn x → funk.wrap_for_array( ( x ~ re ) ? true : false ) );
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const STANDARD_FUNCTIONS := [
|
|
218
|
+
new Func(
|
|
219
|
+
spelling: "true",
|
|
220
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
221
|
+
die "Too many arguments for true()" unless args.empty;
|
|
222
|
+
return funk.wrap( true );
|
|
223
|
+
},
|
|
224
|
+
),
|
|
225
|
+
|
|
226
|
+
new Func(
|
|
227
|
+
spelling: "false",
|
|
228
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
229
|
+
die "Too many arguments for false()" unless args.empty;
|
|
230
|
+
return funk.wrap( false );
|
|
231
|
+
},
|
|
232
|
+
),
|
|
233
|
+
|
|
234
|
+
new Func(
|
|
235
|
+
spelling: "null",
|
|
236
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
237
|
+
die "Too many arguments for null()" unless args.empty;
|
|
238
|
+
return funk.wrap( null );
|
|
239
|
+
},
|
|
240
|
+
),
|
|
241
|
+
|
|
242
|
+
new Func(
|
|
243
|
+
spelling: "die",
|
|
244
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
245
|
+
die "Called 'die' function in zpath";
|
|
246
|
+
},
|
|
247
|
+
),
|
|
248
|
+
|
|
249
|
+
new Func(
|
|
250
|
+
spelling: "count",
|
|
251
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
252
|
+
let n := 0;
|
|
253
|
+
for ( let a in args ) {
|
|
254
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
255
|
+
n += got.length;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
const cur := ctx.parentset ?: ctx.nodeset;
|
|
259
|
+
n := cur.length;
|
|
260
|
+
}
|
|
261
|
+
return funk.wrap( n );
|
|
262
|
+
},
|
|
263
|
+
),
|
|
264
|
+
|
|
265
|
+
new Func(
|
|
266
|
+
spelling: "index",
|
|
267
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
268
|
+
if ( args.length = 0 ) {
|
|
269
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
270
|
+
return funk.wrap( cur ? cur.ix : null );
|
|
271
|
+
}
|
|
272
|
+
else if ( args.length = 1 ) {
|
|
273
|
+
const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
|
|
274
|
+
return got.map( fn x → funk.wrap_for_array(x.ix) );
|
|
275
|
+
}
|
|
276
|
+
die "Too many arguments for index()";
|
|
277
|
+
},
|
|
278
|
+
),
|
|
279
|
+
|
|
280
|
+
new Func(
|
|
281
|
+
spelling: "key",
|
|
282
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
283
|
+
if ( args.length = 0 ) {
|
|
284
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
285
|
+
return funk.wrap( cur ? cur.key : null );
|
|
286
|
+
}
|
|
287
|
+
else if ( args.length = 1 ) {
|
|
288
|
+
const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
|
|
289
|
+
return got.map(
|
|
290
|
+
fn x → funk.wrap_for_array(
|
|
291
|
+
x ≡ null ? null : x.key
|
|
292
|
+
)
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
die "Too many arguments for key()";
|
|
296
|
+
},
|
|
297
|
+
),
|
|
298
|
+
|
|
299
|
+
new Func(
|
|
300
|
+
spelling: "type",
|
|
301
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
302
|
+
if ( args.length = 0 ) {
|
|
303
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
304
|
+
return funk.wrap( cur ? cur.type : "undefined" );
|
|
305
|
+
}
|
|
306
|
+
else if ( args.length = 1 ) {
|
|
307
|
+
const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) ).get( 0, null );
|
|
308
|
+
return funk.wrap( got ? got.type : "undefined" );
|
|
309
|
+
}
|
|
310
|
+
die "Too many arguments for type()";
|
|
311
|
+
},
|
|
312
|
+
),
|
|
313
|
+
|
|
314
|
+
new Func(
|
|
315
|
+
spelling: "union",
|
|
316
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
317
|
+
let out := [];
|
|
318
|
+
for ( let arg in args ) {
|
|
319
|
+
const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
|
|
320
|
+
for ( let n in got ) {
|
|
321
|
+
out.push( n );
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return ev.dedup_nodes( out );
|
|
325
|
+
},
|
|
326
|
+
),
|
|
327
|
+
|
|
328
|
+
new Func(
|
|
329
|
+
spelling: "intersection",
|
|
330
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
331
|
+
return [] if args.empty;
|
|
332
|
+
|
|
333
|
+
let out := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
|
|
334
|
+
out := ev.dedup_nodes( out );
|
|
335
|
+
|
|
336
|
+
let i := 1;
|
|
337
|
+
while ( i < args.length() ) {
|
|
338
|
+
let got := ev.eval_expr( args[i], ev.nested_ctx( ctx ) );
|
|
339
|
+
got := ev.dedup_nodes( got );
|
|
340
|
+
|
|
341
|
+
let seen := {};
|
|
342
|
+
for ( let n in got ) {
|
|
343
|
+
let key := n.id();
|
|
344
|
+
if ( key ≡ null ) {
|
|
345
|
+
key := "anon:" _ ( "" _ n.raw() );
|
|
346
|
+
}
|
|
347
|
+
seen.set( key, true );
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
let next_out := [];
|
|
351
|
+
for ( let n in out ) {
|
|
352
|
+
let key := n.id();
|
|
353
|
+
if ( key ≡ null ) {
|
|
354
|
+
key := "anon:" _ ( "" _ n.raw() );
|
|
355
|
+
}
|
|
356
|
+
if ( seen.exists(key) ) {
|
|
357
|
+
next_out.push(n);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
out := next_out;
|
|
362
|
+
last if out.empty;
|
|
363
|
+
i++;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return ev.dedup_nodes( out );
|
|
367
|
+
},
|
|
368
|
+
),
|
|
369
|
+
|
|
370
|
+
new Func(
|
|
371
|
+
spelling: "is-first",
|
|
372
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
373
|
+
if ( args.length = 0 ) {
|
|
374
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
375
|
+
return [] unless cur and cur.parent;
|
|
376
|
+
return funk.wrap( cur.ix = 0 );
|
|
377
|
+
}
|
|
378
|
+
die "Too many arguments for is-first()";
|
|
379
|
+
},
|
|
380
|
+
),
|
|
381
|
+
|
|
382
|
+
new Func(
|
|
383
|
+
spelling: "is-last",
|
|
384
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
385
|
+
if ( args.length = 0 ) {
|
|
386
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
387
|
+
return [] unless cur and cur.parent and cur.ix ≢ null;
|
|
388
|
+
const siblings := cur.parent.children
|
|
389
|
+
.grep( fn kid → kid.key ≡ cur.key );
|
|
390
|
+
return [] if siblings.empty;
|
|
391
|
+
let pos := 0;
|
|
392
|
+
while ( pos < siblings.length ) {
|
|
393
|
+
const kid := siblings[pos];
|
|
394
|
+
last if kid.id() ≡ cur.id();
|
|
395
|
+
pos++;
|
|
396
|
+
}
|
|
397
|
+
return [] if pos ≥ siblings.length;
|
|
398
|
+
return funk.wrap( pos = siblings.length - 1 );
|
|
399
|
+
}
|
|
400
|
+
die "Too many arguments for is-last()";
|
|
401
|
+
},
|
|
402
|
+
),
|
|
403
|
+
|
|
404
|
+
new Func(
|
|
405
|
+
spelling: "next",
|
|
406
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
407
|
+
if ( args.length = 0 ) {
|
|
408
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
409
|
+
return [ cur.next_sibling ];
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
let out := [];
|
|
413
|
+
for ( let arg in args ) {
|
|
414
|
+
const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
|
|
415
|
+
for ( let n in got ) {
|
|
416
|
+
out.push( n.next_sibling );
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return out;
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
),
|
|
423
|
+
|
|
424
|
+
new Func(
|
|
425
|
+
spelling: "prev",
|
|
426
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
427
|
+
if ( args.length = 0 ) {
|
|
428
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
429
|
+
return [ cur.prev_sibling ];
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
let out := [];
|
|
433
|
+
for ( let arg in args ) {
|
|
434
|
+
const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
|
|
435
|
+
for ( let n in got ) {
|
|
436
|
+
out.push( n.prev_sibling );
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return out;
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
),
|
|
443
|
+
|
|
444
|
+
new Func(
|
|
445
|
+
spelling: "string",
|
|
446
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
447
|
+
if ( args.length = 0 ) {
|
|
448
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
449
|
+
return [] unless cur;
|
|
450
|
+
return funk.wrap( cur.string_value );
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
let out := [];
|
|
454
|
+
for ( let arg in args ) {
|
|
455
|
+
const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
|
|
456
|
+
for ( let n in got ) {
|
|
457
|
+
out.push( n );
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return out.map( fn x → funk.wrap_for_array( x.string_value ) );
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
),
|
|
464
|
+
|
|
465
|
+
new Func(
|
|
466
|
+
spelling: "number",
|
|
467
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
468
|
+
if ( args.length = 0 ) {
|
|
469
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
470
|
+
return [] unless cur;
|
|
471
|
+
return funk.wrap( cur.number_value );
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
let out := [];
|
|
475
|
+
for ( let arg in args ) {
|
|
476
|
+
const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
|
|
477
|
+
for ( let n in got ) {
|
|
478
|
+
out.push( n );
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return out.map( fn x → funk.wrap_for_array( x.number_value ) );
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
),
|
|
485
|
+
|
|
486
|
+
new Func(
|
|
487
|
+
spelling: "value",
|
|
488
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
489
|
+
if ( args.length = 0 ) {
|
|
490
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
491
|
+
return [] unless cur;
|
|
492
|
+
return funk.wrap( cur.primitive_value );
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
let out := [];
|
|
496
|
+
for ( let arg in args ) {
|
|
497
|
+
const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
|
|
498
|
+
for ( let n in got ) {
|
|
499
|
+
out.push( n );
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return out.map( fn x → funk.wrap_for_array( x.primitive_value ) );
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
),
|
|
506
|
+
|
|
507
|
+
new Func(
|
|
508
|
+
spelling: "ceil",
|
|
509
|
+
f: mk_single_number_function( "ceil", fn n → ceil n ),
|
|
510
|
+
),
|
|
511
|
+
|
|
512
|
+
new Func(
|
|
513
|
+
spelling: "floor",
|
|
514
|
+
f: mk_single_number_function( "floor", fn n → floor n ),
|
|
515
|
+
),
|
|
516
|
+
|
|
517
|
+
new Func(
|
|
518
|
+
spelling: "round",
|
|
519
|
+
f: mk_single_number_function( "round", fn n → round n ),
|
|
520
|
+
),
|
|
521
|
+
|
|
522
|
+
new Func(
|
|
523
|
+
spelling: "sum",
|
|
524
|
+
f: mk_aggregate_number_function( "sum", fn nums → Math.sum(nums) ),
|
|
525
|
+
),
|
|
526
|
+
|
|
527
|
+
new Func(
|
|
528
|
+
spelling: "min",
|
|
529
|
+
f: mk_aggregate_number_function( "min", fn nums → Math.min(nums) ),
|
|
530
|
+
),
|
|
531
|
+
|
|
532
|
+
new Func(
|
|
533
|
+
spelling: "max",
|
|
534
|
+
f: mk_aggregate_number_function( "max", fn nums → Math.max(nums) ),
|
|
535
|
+
),
|
|
536
|
+
|
|
537
|
+
new Func(
|
|
538
|
+
spelling: "escape",
|
|
539
|
+
f: mk_single_string_function( "escape", fn s → escape_xml(s) ),
|
|
540
|
+
),
|
|
541
|
+
|
|
542
|
+
new Func(
|
|
543
|
+
spelling: "unescape",
|
|
544
|
+
f: mk_single_string_function( "unescape", fn s → unescape_xml(s) ),
|
|
545
|
+
),
|
|
546
|
+
|
|
547
|
+
new Func(
|
|
548
|
+
spelling: "upper-case",
|
|
549
|
+
f: mk_single_string_function( "upper-case", fn s → uc s ),
|
|
550
|
+
),
|
|
551
|
+
|
|
552
|
+
new Func(
|
|
553
|
+
spelling: "lower-case",
|
|
554
|
+
f: mk_single_string_function( "lower-case", fn s → lc s ),
|
|
555
|
+
),
|
|
556
|
+
|
|
557
|
+
new Func(
|
|
558
|
+
spelling: "index-of",
|
|
559
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
560
|
+
let nodes := [];
|
|
561
|
+
let search;
|
|
562
|
+
|
|
563
|
+
if ( args.empty ) {
|
|
564
|
+
die "Not enough arguments for index-of()";
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
search := try {
|
|
568
|
+
ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
|
|
569
|
+
} catch {
|
|
570
|
+
"";
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
for ( let a in args[1:] ) {
|
|
575
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
576
|
+
for ( let n in got ) {
|
|
577
|
+
nodes.push( n );
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
nodes := ctx.nodeset;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return nodes
|
|
585
|
+
.map( fn x → x.string_value )
|
|
586
|
+
.grep( fn x → x instanceof String )
|
|
587
|
+
.map( fn x → funk.wrap_for_array( index(x, search) ) );
|
|
588
|
+
}
|
|
589
|
+
),
|
|
590
|
+
|
|
591
|
+
new Func(
|
|
592
|
+
spelling: "last-index-of",
|
|
593
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
594
|
+
let nodes := [];
|
|
595
|
+
let search;
|
|
596
|
+
|
|
597
|
+
if ( args.empty ) {
|
|
598
|
+
die "Not enough arguments for last-index-of()";
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
search := try {
|
|
602
|
+
ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
|
|
603
|
+
} catch {
|
|
604
|
+
"";
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
for ( let a in args[1:] ) {
|
|
609
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
610
|
+
for ( let n in got ) {
|
|
611
|
+
nodes.push( n );
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
nodes := ctx.nodeset;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return nodes
|
|
619
|
+
.map( fn x → x.string_value )
|
|
620
|
+
.grep( fn x → x instanceof String )
|
|
621
|
+
.map( fn x → funk.wrap_for_array( rindex(x, search) ) );
|
|
622
|
+
}
|
|
623
|
+
),
|
|
624
|
+
|
|
625
|
+
new Func(
|
|
626
|
+
spelling: "substring",
|
|
627
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
628
|
+
|
|
629
|
+
let nodes := [];
|
|
630
|
+
let start;
|
|
631
|
+
let len;
|
|
632
|
+
|
|
633
|
+
if ( args.length < 2 ) {
|
|
634
|
+
die "Not enough arguments for substring()";
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
start := try {
|
|
638
|
+
ev.eval_expr( args[-2], ev.nested_ctx( ctx ) )[0].number_value;
|
|
639
|
+
} catch {
|
|
640
|
+
0;
|
|
641
|
+
};
|
|
642
|
+
len := try {
|
|
643
|
+
ev.eval_expr( args[-1], ev.nested_ctx( ctx ) )[0].number_value;
|
|
644
|
+
} catch {
|
|
645
|
+
0;
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
for ( let a in args[0:-2] ) {
|
|
650
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
651
|
+
for ( let n in got ) {
|
|
652
|
+
nodes.push( n );
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
nodes := ctx.nodeset;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
return nodes
|
|
660
|
+
.map( fn x → x.string_value )
|
|
661
|
+
.grep( fn x → x instanceof String )
|
|
662
|
+
.map( fn x → funk.wrap_for_array( substr(x, start, len) ) );
|
|
663
|
+
}
|
|
664
|
+
),
|
|
665
|
+
|
|
666
|
+
new Func(
|
|
667
|
+
spelling: "format",
|
|
668
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
669
|
+
let nodes := [];
|
|
670
|
+
let fmt;
|
|
671
|
+
|
|
672
|
+
if ( args.empty ) {
|
|
673
|
+
die "Not enough arguments for format()";
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
fmt := try {
|
|
677
|
+
ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
|
|
678
|
+
} catch {
|
|
679
|
+
"";
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
for ( let a in args[1:] ) {
|
|
684
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
685
|
+
for ( let n in got ) {
|
|
686
|
+
nodes.push( n );
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
nodes := ctx.nodeset;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
return nodes
|
|
694
|
+
.map( fn x → x.string_value )
|
|
695
|
+
.grep( fn x → x instanceof String )
|
|
696
|
+
.map( fn x → funk.wrap_for_array( sprint(fmt, x) ) );
|
|
697
|
+
}
|
|
698
|
+
),
|
|
699
|
+
|
|
700
|
+
new Func(
|
|
701
|
+
spelling: "string-length",
|
|
702
|
+
f: mk_single_string_function( "string-length", fn s → length s ),
|
|
703
|
+
),
|
|
704
|
+
|
|
705
|
+
new Func(
|
|
706
|
+
spelling: "match",
|
|
707
|
+
f: mk_match_function(),
|
|
708
|
+
),
|
|
709
|
+
|
|
710
|
+
new Func(
|
|
711
|
+
spelling: "matches",
|
|
712
|
+
f: mk_match_function(),
|
|
713
|
+
),
|
|
714
|
+
|
|
715
|
+
new Func(
|
|
716
|
+
spelling: "replace",
|
|
717
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
718
|
+
let nodes := [];
|
|
719
|
+
let pattern;
|
|
720
|
+
let replacement;
|
|
721
|
+
|
|
722
|
+
if ( args.length < 2 ) {
|
|
723
|
+
die "Not enough arguments for replace()";
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
pattern := try {
|
|
727
|
+
ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
|
|
728
|
+
} catch {
|
|
729
|
+
"";
|
|
730
|
+
};
|
|
731
|
+
replacement := try {
|
|
732
|
+
ev.eval_expr( args[1], ev.nested_ctx( ctx ) )[0].string_value;
|
|
733
|
+
} catch {
|
|
734
|
+
"";
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
for ( let a in args[2:] ) {
|
|
739
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
740
|
+
for ( let n in got ) {
|
|
741
|
+
nodes.push( n );
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
else {
|
|
745
|
+
nodes := ctx.nodeset;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
return nodes
|
|
749
|
+
.map( fn x → x.string_value )
|
|
750
|
+
.grep( fn x → x instanceof String )
|
|
751
|
+
.map( fn x → funk.wrap_for_array( replace( x, pattern, replacement ) ) );
|
|
752
|
+
}
|
|
753
|
+
),
|
|
754
|
+
|
|
755
|
+
new Func(
|
|
756
|
+
spelling: "join",
|
|
757
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
758
|
+
let nodes := [];
|
|
759
|
+
let joiner;
|
|
760
|
+
|
|
761
|
+
if ( args.empty ) {
|
|
762
|
+
die "Not enough arguments for format()";
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
joiner := try {
|
|
766
|
+
ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
|
|
767
|
+
} catch {
|
|
768
|
+
"";
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
for ( let a in args[1:] ) {
|
|
773
|
+
const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
|
|
774
|
+
for ( let n in got ) {
|
|
775
|
+
nodes.push( n );
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
nodes := ctx.nodeset;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const strings := nodes
|
|
783
|
+
.map( fn x → x.string_value )
|
|
784
|
+
.grep( fn x → x instanceof String );
|
|
785
|
+
return funk.wrap( join( joiner, strings ) );
|
|
786
|
+
}
|
|
787
|
+
),
|
|
788
|
+
|
|
789
|
+
new Func(
|
|
790
|
+
spelling: "url",
|
|
791
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
792
|
+
if ( args.length = 0 ) {
|
|
793
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
794
|
+
return [] unless cur;
|
|
795
|
+
return funk.wrap( cur instanceof XmlNodeNode ? cur.raw.namespaceURI() : null );
|
|
796
|
+
}
|
|
797
|
+
else if ( args.length = 1 ) {
|
|
798
|
+
const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
|
|
799
|
+
return got.map(
|
|
800
|
+
fn x → funk.wrap_for_array(
|
|
801
|
+
x instanceof XmlNodeNode ? x.raw.namespaceURI() : null
|
|
802
|
+
)
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
die "Too many arguments for url()";
|
|
806
|
+
},
|
|
807
|
+
),
|
|
808
|
+
|
|
809
|
+
new Func(
|
|
810
|
+
spelling: "local-name",
|
|
811
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
812
|
+
if ( args.length = 0 ) {
|
|
813
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
814
|
+
return [] unless cur;
|
|
815
|
+
return funk.wrap(
|
|
816
|
+
cur instanceof XmlNodeNode ? cur.raw.localName()
|
|
817
|
+
: cur instanceof KDLNodeNode ? cur.name()
|
|
818
|
+
: null
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
else if ( args.length = 1 ) {
|
|
822
|
+
const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
|
|
823
|
+
return got.map(
|
|
824
|
+
fn x → funk.wrap_for_array(
|
|
825
|
+
x instanceof XmlNodeNode ? x.raw.localName()
|
|
826
|
+
: x instanceof KDLNodeNode ? x.name()
|
|
827
|
+
: null
|
|
828
|
+
)
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
die "Too many arguments for local-name()";
|
|
832
|
+
},
|
|
833
|
+
),
|
|
834
|
+
|
|
835
|
+
new Func(
|
|
836
|
+
spelling: "tag",
|
|
837
|
+
f: function ( funk, ev, ast, ctx, args ) {
|
|
838
|
+
if ( args.length = 0 ) {
|
|
839
|
+
const cur := ctx.nodeset.get( 0, null );
|
|
840
|
+
return [] unless cur;
|
|
841
|
+
if ( cur instanceof KDLNodeNode ) {
|
|
842
|
+
let ann := cur.raw().type_annotation();
|
|
843
|
+
return funk.wrap( ann ≡ null ? null : "" _ ann );
|
|
844
|
+
}
|
|
845
|
+
if ( cur instanceof KDLValueNode ) {
|
|
846
|
+
let ann := cur.raw().type_annotation();
|
|
847
|
+
return funk.wrap( ann ≡ null ? null : "" _ ann );
|
|
848
|
+
}
|
|
849
|
+
return funk.wrap( cur.has_tagged ? cur.tagged{tag} : null );
|
|
850
|
+
}
|
|
851
|
+
else if ( args.length = 1 ) {
|
|
852
|
+
const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
|
|
853
|
+
return got.map(
|
|
854
|
+
fn x → funk.wrap_for_array(
|
|
855
|
+
x instanceof KDLNodeNode
|
|
856
|
+
? (
|
|
857
|
+
x.raw().type_annotation() ≡ null
|
|
858
|
+
? null
|
|
859
|
+
: "" _ x.raw().type_annotation()
|
|
860
|
+
)
|
|
861
|
+
: x instanceof KDLValueNode
|
|
862
|
+
? (
|
|
863
|
+
x.raw().type_annotation() ≡ null
|
|
864
|
+
? null
|
|
865
|
+
: "" _ x.raw().type_annotation()
|
|
866
|
+
)
|
|
867
|
+
: x can has_tagged ? x.tagged{tag} : null
|
|
868
|
+
)
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
die "Too many arguments for tag()";
|
|
872
|
+
},
|
|
873
|
+
),
|
|
874
|
+
];
|