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.
Files changed (167) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +113 -0
  3. package/bin/zuzu +17 -0
  4. package/bin/zuzu-build-browser-bundle +57 -0
  5. package/bin/zuzu-generate-browser-stdlib +584 -0
  6. package/bin/zuzu-js +23 -0
  7. package/bin/zuzu-js-compile +152 -0
  8. package/bin/zuzu-js-electron +19 -0
  9. package/dist/zuzu-browser-worker.js +45574 -0
  10. package/dist/zuzu-browser.js +45362 -0
  11. package/lib/browser-bundle-entry.js +160 -0
  12. package/lib/browser-gui-renderer.js +387 -0
  13. package/lib/browser-runtime.js +167 -0
  14. package/lib/browser-worker-entry.js +413 -0
  15. package/lib/browser-ztests/runner.html +103 -0
  16. package/lib/browser-ztests/runner.js +369 -0
  17. package/lib/cli.js +350 -0
  18. package/lib/collections.js +367 -0
  19. package/lib/compiler.js +303 -0
  20. package/lib/electron/launcher.js +70 -0
  21. package/lib/electron/main.js +956 -0
  22. package/lib/electron/preload.js +80 -0
  23. package/lib/electron/renderer.html +122 -0
  24. package/lib/electron/renderer.js +24 -0
  25. package/lib/execution-metadata.js +18 -0
  26. package/lib/gui/dom-renderer.js +778 -0
  27. package/lib/host/browser-host.js +278 -0
  28. package/lib/host/capabilities.js +47 -0
  29. package/lib/host/electron-host.js +15 -0
  30. package/lib/host/node-host.js +74 -0
  31. package/lib/paths.js +150 -0
  32. package/lib/runtime-entrypoints.js +60 -0
  33. package/lib/runtime-helpers.js +886 -0
  34. package/lib/runtime.js +3529 -0
  35. package/lib/tap.js +37 -0
  36. package/lib/transpiler-new/ast.js +23 -0
  37. package/lib/transpiler-new/codegen.js +2455 -0
  38. package/lib/transpiler-new/errors.js +28 -0
  39. package/lib/transpiler-new/index.js +26 -0
  40. package/lib/transpiler-new/lexer.js +834 -0
  41. package/lib/transpiler-new/parser.js +2332 -0
  42. package/lib/transpiler-new/validate-bindings.js +326 -0
  43. package/lib/transpiler-utils.js +95 -0
  44. package/lib/transpiler.js +33 -0
  45. package/lib/zuzu.js +53 -0
  46. package/modules/javascript.js +193 -0
  47. package/modules/std/archive.js +603 -0
  48. package/modules/std/clib.js +338 -0
  49. package/modules/std/data/csv.js +1331 -0
  50. package/modules/std/data/json.js +531 -0
  51. package/modules/std/data/xml.js +441 -0
  52. package/modules/std/data/yaml.js +256 -0
  53. package/modules/std/db-worker.js +250 -0
  54. package/modules/std/db.js +664 -0
  55. package/modules/std/digest/_hash.js +443 -0
  56. package/modules/std/digest/md5.js +26 -0
  57. package/modules/std/digest/sha.js +72 -0
  58. package/modules/std/eval.js +10 -0
  59. package/modules/std/gui/objects.js +1519 -0
  60. package/modules/std/internals.js +571 -0
  61. package/modules/std/io/socks-worker.js +318 -0
  62. package/modules/std/io/socks.js +186 -0
  63. package/modules/std/io.js +475 -0
  64. package/modules/std/marshal/cbor.js +463 -0
  65. package/modules/std/marshal/graph.js +1624 -0
  66. package/modules/std/marshal.js +87 -0
  67. package/modules/std/math/bignum.js +91 -0
  68. package/modules/std/math.js +79 -0
  69. package/modules/std/net/dns.js +306 -0
  70. package/modules/std/net/http.js +820 -0
  71. package/modules/std/net/smtp.js +943 -0
  72. package/modules/std/net/url.js +109 -0
  73. package/modules/std/proc.js +602 -0
  74. package/modules/std/secure.js +3724 -0
  75. package/modules/std/string/base64.js +138 -0
  76. package/modules/std/string.js +299 -0
  77. package/modules/std/task.js +914 -0
  78. package/modules/std/time.js +579 -0
  79. package/modules/std/tui.js +188 -0
  80. package/modules/std/worker-thread.js +246 -0
  81. package/modules/std/worker.js +790 -0
  82. package/package.json +67 -0
  83. package/stdlib/modules/javascript.zzm +99 -0
  84. package/stdlib/modules/perl.zzm +105 -0
  85. package/stdlib/modules/std/archive.zzm +132 -0
  86. package/stdlib/modules/std/cache/lru.zzm +174 -0
  87. package/stdlib/modules/std/clib.zzm +112 -0
  88. package/stdlib/modules/std/colour.zzm +220 -0
  89. package/stdlib/modules/std/config.zzm +818 -0
  90. package/stdlib/modules/std/data/cbor.zzm +497 -0
  91. package/stdlib/modules/std/data/csv.zzm +285 -0
  92. package/stdlib/modules/std/data/ini.zzm +472 -0
  93. package/stdlib/modules/std/data/json/schema/core.zzm +573 -0
  94. package/stdlib/modules/std/data/json/schema/format.zzm +581 -0
  95. package/stdlib/modules/std/data/json/schema/model.zzm +255 -0
  96. package/stdlib/modules/std/data/json/schema/output.zzm +272 -0
  97. package/stdlib/modules/std/data/json/schema/relative_pointer.zzm +299 -0
  98. package/stdlib/modules/std/data/json/schema/validation.zzm +1503 -0
  99. package/stdlib/modules/std/data/json/schema.zzm +306 -0
  100. package/stdlib/modules/std/data/json.zzm +102 -0
  101. package/stdlib/modules/std/data/kdl/json.zzm +460 -0
  102. package/stdlib/modules/std/data/kdl/xml.zzm +387 -0
  103. package/stdlib/modules/std/data/kdl.zzm +1631 -0
  104. package/stdlib/modules/std/data/toml.zzm +756 -0
  105. package/stdlib/modules/std/data/toon.zzm +1017 -0
  106. package/stdlib/modules/std/data/xml/escape.zzm +156 -0
  107. package/stdlib/modules/std/data/xml.zzm +276 -0
  108. package/stdlib/modules/std/data/yaml.zzm +94 -0
  109. package/stdlib/modules/std/db.zzm +173 -0
  110. package/stdlib/modules/std/defer.zzm +75 -0
  111. package/stdlib/modules/std/digest/crc32.zzm +196 -0
  112. package/stdlib/modules/std/digest/md5.zzm +54 -0
  113. package/stdlib/modules/std/digest/sha.zzm +83 -0
  114. package/stdlib/modules/std/dump.zzm +317 -0
  115. package/stdlib/modules/std/eval.zzm +63 -0
  116. package/stdlib/modules/std/getopt.zzm +432 -0
  117. package/stdlib/modules/std/gui/dialogue.zzm +592 -0
  118. package/stdlib/modules/std/gui/objects.zzm +123 -0
  119. package/stdlib/modules/std/gui.zzm +1914 -0
  120. package/stdlib/modules/std/internals.zzm +139 -0
  121. package/stdlib/modules/std/io/socks.zzm +139 -0
  122. package/stdlib/modules/std/io.zzm +157 -0
  123. package/stdlib/modules/std/lingua/en.zzm +347 -0
  124. package/stdlib/modules/std/log.zzm +169 -0
  125. package/stdlib/modules/std/mail.zzm +2726 -0
  126. package/stdlib/modules/std/marshal.zzm +138 -0
  127. package/stdlib/modules/std/math/bignum.zzm +98 -0
  128. package/stdlib/modules/std/math/range.zzm +116 -0
  129. package/stdlib/modules/std/math/roman.zzm +156 -0
  130. package/stdlib/modules/std/math.zzm +141 -0
  131. package/stdlib/modules/std/net/dns.zzm +93 -0
  132. package/stdlib/modules/std/net/http.zzm +278 -0
  133. package/stdlib/modules/std/net/smtp.zzm +257 -0
  134. package/stdlib/modules/std/net/url.zzm +69 -0
  135. package/stdlib/modules/std/path/jsonpointer.zzm +526 -0
  136. package/stdlib/modules/std/path/kdl.zzm +1003 -0
  137. package/stdlib/modules/std/path/simple.zzm +520 -0
  138. package/stdlib/modules/std/path/z/context.zzm +147 -0
  139. package/stdlib/modules/std/path/z/evaluate.zzm +549 -0
  140. package/stdlib/modules/std/path/z/functions.zzm +874 -0
  141. package/stdlib/modules/std/path/z/lexer.zzm +490 -0
  142. package/stdlib/modules/std/path/z/node.zzm +1455 -0
  143. package/stdlib/modules/std/path/z/operators.zzm +445 -0
  144. package/stdlib/modules/std/path/z/parser.zzm +359 -0
  145. package/stdlib/modules/std/path/z.zzm +403 -0
  146. package/stdlib/modules/std/path/zz/functions.zzm +828 -0
  147. package/stdlib/modules/std/path/zz/operators.zzm +1036 -0
  148. package/stdlib/modules/std/path/zz.zzm +100 -0
  149. package/stdlib/modules/std/proc.zzm +155 -0
  150. package/stdlib/modules/std/result.zzm +149 -0
  151. package/stdlib/modules/std/secure.zzm +606 -0
  152. package/stdlib/modules/std/string/base64.zzm +66 -0
  153. package/stdlib/modules/std/string/quoted_printable.zzm +485 -0
  154. package/stdlib/modules/std/string.zzm +179 -0
  155. package/stdlib/modules/std/task.zzm +221 -0
  156. package/stdlib/modules/std/template/z.zzm +531 -0
  157. package/stdlib/modules/std/template/zz.zzm +62 -0
  158. package/stdlib/modules/std/time.zzm +188 -0
  159. package/stdlib/modules/std/tui.zzm +89 -0
  160. package/stdlib/modules/std/uuid.zzm +223 -0
  161. package/stdlib/modules/std/web/session.zzm +388 -0
  162. package/stdlib/modules/std/web/static.zzm +329 -0
  163. package/stdlib/modules/std/web.zzm +1942 -0
  164. package/stdlib/modules/std/worker.zzm +202 -0
  165. package/stdlib/modules/std/zuzuzoo.zzm +3960 -0
  166. package/stdlib/modules/test/more.zzm +528 -0
  167. package/stdlib/modules/test/parser.zzm +209 -0
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "zuzu-js",
3
+ "version": "0.1.0",
4
+ "description": "JavaScript runtime, compiler, and browser bundle for ZuzuScript.",
5
+ "main": "lib/zuzu.js",
6
+ "bin": {
7
+ "zuzu": "bin/zuzu",
8
+ "zuzu-js": "bin/zuzu-js",
9
+ "zuzu-js-compile": "bin/zuzu-js-compile",
10
+ "zuzu-js-electron": "bin/zuzu-js-electron"
11
+ },
12
+ "files": [
13
+ "bin/",
14
+ "dist/zuzu-browser.js",
15
+ "dist/zuzu-browser-worker.js",
16
+ "lib/",
17
+ "modules/",
18
+ "stdlib/modules/"
19
+ ],
20
+ "directories": {
21
+ "example": "examples",
22
+ "lib": "lib",
23
+ "test": "test"
24
+ },
25
+ "scripts": {
26
+ "electron:demo": "electron bin/zuzu-js-electron docs/examples/09_gui_dialogue_demo.zzs",
27
+ "test": "node test/cli.js && node test/argument-spread.js && node test/default-operator.js && node test/declaration-unpacking.js && node test/collection-copy.js && node test/std-marshal-cbor.js && node test/std-marshal-data-graph.js && node test/std-marshal-user-object.js && node test/std-marshal-code-table.js && node test/async-parity.js && node test/browser-stdlib-generator.js && node test/browser-gui.js && node test/electron-gui.js && node test/electron-renderer.js && node test/electron-packaging.js",
28
+ "test:electron": "node test/electron-gui.js && node test/electron-renderer.js && node test/electron-packaging.js"
29
+ },
30
+ "keywords": [
31
+ "zuzu",
32
+ "zuzuscript",
33
+ "language",
34
+ "runtime",
35
+ "compiler"
36
+ ],
37
+ "author": "",
38
+ "license": "Artistic-1.0 OR GPL-2.0-or-later",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+ssh://git@github.com/zuzuscript/zuzu-js.git"
42
+ },
43
+ "bugs": {
44
+ "url": "https://github.com/zuzuscript/zuzu-js/issues"
45
+ },
46
+ "homepage": "https://zuzulang.org/",
47
+ "engines": {
48
+ "node": ">=16"
49
+ },
50
+ "dependencies": {
51
+ "@xmldom/xmldom": "^0.9.10",
52
+ "adm-zip": "^0.5.17",
53
+ "better-sqlite3": "^11.10.0",
54
+ "cbor-x": "^1.6.4",
55
+ "cborg": "^5.1.1",
56
+ "compressjs": "^1.0.3",
57
+ "js-yaml": "^4.1.1",
58
+ "koffi": "^2.16.1",
59
+ "mysql2": "^3.22.3",
60
+ "node-forge": "^1.4.0",
61
+ "pg": "^8.20.0",
62
+ "xpath": "^0.0.34"
63
+ },
64
+ "devDependencies": {
65
+ "electron": "^41.3.0"
66
+ }
67
+ }
@@ -0,0 +1,99 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ javascript - Evaluate JavaScript from ZuzuScript.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from javascript import JS, JSResult;
10
+
11
+ let r := JS.eval("[ 7, 8, 9 ]");
12
+ assert( r instanceof JSResult );
13
+
14
+ let j := r.toJSON();
15
+
16
+ let r2 := r.eval(" this[1] ");
17
+ assert( r2 instanceof JSResult );
18
+
19
+ let n;
20
+ n := r2.value() if r2.isSafe();
21
+
22
+ =head1 IMPLEMENTATION SUPPORT
23
+
24
+ This module is supported by zuzu-js on Node, Electron, and Browser. It
25
+ is not supported by zuzu.pl or zuzu-rust.
26
+
27
+ =head1 DESCRIPTION
28
+
29
+ This runtime-supported module is only implemented by C<zuzu-js>.
30
+
31
+ C<JS.eval(String code)> evaluates JavaScript and returns C<JSResult>.
32
+
33
+ C<JSResult.eval(String code)> evaluates more JavaScript with the wrapped
34
+ value bound to C<this>, again returning C<JSResult>.
35
+
36
+ C<JSResult.isSafe()> reports whether C<value()> can convert the wrapped
37
+ JavaScript value into a native Zuzu value.
38
+
39
+ C<JSResult.value()> returns the converted Zuzu value for safe results.
40
+
41
+ C<JSResult.toJSON()> serializes the wrapped JavaScript value as JSON.
42
+
43
+ =head1 EXPORTS
44
+
45
+ =head2 Classes
46
+
47
+ =over
48
+
49
+ =item C<JS>
50
+
51
+ Runtime-supported JavaScript bridge class.
52
+
53
+ =over
54
+
55
+ =item C<< JS.eval(String code) >>
56
+
57
+ Parameters: C<code> is JavaScript source text. Returns: C<JSResult>.
58
+ Evaluates C<code> in the host JavaScript runtime.
59
+
60
+ =back
61
+
62
+ =item C<JSResult>
63
+
64
+ Wrapper for a JavaScript value returned by C<JS.eval()> or
65
+ C<JSResult.eval()>.
66
+
67
+ =over
68
+
69
+ =item C<< result.eval(String code) >>
70
+
71
+ Parameters: C<code> is JavaScript source text. Returns: C<JSResult>.
72
+ Evaluates C<code> with the wrapped JavaScript value bound to C<this>.
73
+
74
+ =item C<< result.isSafe() >>
75
+
76
+ Parameters: none. Returns: C<Boolean>. Returns true when C<value()> can
77
+ convert the wrapped JavaScript value into a native ZuzuScript value.
78
+
79
+ =item C<< result.value() >>
80
+
81
+ Parameters: none. Returns: value. Converts and returns the wrapped
82
+ JavaScript value when C<isSafe()> is true.
83
+
84
+ =item C<< result.toJSON() >>
85
+
86
+ Parameters: none. Returns: C<String>. Serializes the wrapped JavaScript
87
+ value as JSON text.
88
+
89
+ =back
90
+
91
+ =back
92
+
93
+ =head1 COPYRIGHT AND LICENCE
94
+
95
+ B<< javascript >> is copyright Toby Inkster.
96
+
97
+ It is free software; you may redistribute it and/or modify it under
98
+ the terms of either the Artistic License 1.0 or the GNU General Public
99
+ License version 2.
@@ -0,0 +1,105 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ perl - Evaluate Perl code from ZuzuScript.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from perl import Perl, PerlResult;
10
+
11
+ let r := Perl.eval("[ 7, 8, 9 ]");
12
+ assert( r instanceof PerlResult );
13
+
14
+ let j := r.toJSON();
15
+
16
+ let r2 := r.eval(" $_->[1] ");
17
+ assert( r2 instanceof PerlResult );
18
+
19
+ let n;
20
+ n := r2.value() if r2.isSafe();
21
+
22
+ =head1 IMPLEMENTATION SUPPORT
23
+
24
+ This module is supported by zuzu.pl. It is not supported by zuzu-rust or
25
+ zuzu-js.
26
+
27
+ =head1 DESCRIPTION
28
+
29
+ This builtin module bridges to the host Perl interpreter.
30
+
31
+ C<Perl.version()> returns the current Perl version string.
32
+
33
+ C<Perl.eval(String code)> evaluates Perl in scalar context and
34
+ returns C<PerlResult>.
35
+
36
+ C<PerlResult> wraps the underlying Perl value. Use C<isSafe()> to
37
+ check whether C<value()> can convert it into a native Zuzu value.
38
+
39
+ C<toJSON()> attempts to encode the wrapped value as JSON text.
40
+
41
+ C<eval(String code)> evaluates more Perl with the wrapped value in
42
+ C<$_>, again returning C<PerlResult>.
43
+
44
+ =head1 EXPORTS
45
+
46
+ =head2 Classes
47
+
48
+ =over
49
+
50
+ =item C<Perl>
51
+
52
+ Runtime-supported Perl bridge class.
53
+
54
+ =over
55
+
56
+ =item C<< Perl.version() >>
57
+
58
+ Parameters: none. Returns: C<String>. Returns the host Perl interpreter
59
+ version.
60
+
61
+ =item C<< Perl.eval(String code) >>
62
+
63
+ Parameters: C<code> is Perl source text. Returns: C<PerlResult>.
64
+ Evaluates C<code> in scalar context in the host Perl interpreter.
65
+
66
+ =back
67
+
68
+ =item C<PerlResult>
69
+
70
+ Wrapper for a Perl value returned by C<Perl.eval()> or
71
+ C<PerlResult.eval()>.
72
+
73
+ =over
74
+
75
+ =item C<< result.eval(String code) >>
76
+
77
+ Parameters: C<code> is Perl source text. Returns: C<PerlResult>.
78
+ Evaluates C<code> with the wrapped Perl value available in C<$_>.
79
+
80
+ =item C<< result.isSafe() >>
81
+
82
+ Parameters: none. Returns: C<Boolean>. Returns true when C<value()> can
83
+ convert the wrapped Perl value into a native ZuzuScript value.
84
+
85
+ =item C<< result.value() >>
86
+
87
+ Parameters: none. Returns: value. Converts and returns the wrapped Perl
88
+ value when C<isSafe()> is true.
89
+
90
+ =item C<< result.toJSON() >>
91
+
92
+ Parameters: none. Returns: C<String>. Serializes the wrapped Perl value
93
+ as JSON text.
94
+
95
+ =back
96
+
97
+ =back
98
+
99
+ =head1 COPYRIGHT AND LICENCE
100
+
101
+ B<< perl >> is copyright Toby Inkster.
102
+
103
+ It is free software; you may redistribute it and/or modify it under
104
+ the terms of either the Artistic License 1.0 or the GNU General Public
105
+ License version 2.
@@ -0,0 +1,132 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/archive - Small archive and compression helpers.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/archive import Archive;
10
+ from std/io import Path;
11
+
12
+ let archive := {
13
+ entries: [
14
+ { path: "hello.txt", data: to_binary( "Hello\n" ) },
15
+ { path: "nested/world.txt", data: to_binary( "World\n" ) },
16
+ ],
17
+ };
18
+
19
+ let bytes := Archive.encode( archive, "tar.gz" );
20
+ let roundtrip := Archive.decode(bytes);
21
+
22
+ let path := Path.tempdir().child("hello.zip");
23
+ Archive.dump( path, archive );
24
+ let loaded := Archive.load(path);
25
+
26
+ =head1 IMPLEMENTATION SUPPORT
27
+
28
+ This module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and
29
+ Electron. It is not supported by zuzu-js in the browser.
30
+
31
+ =head1 DESCRIPTION
32
+
33
+ This module provides a small, runtime-supported archive API centred on
34
+ one exported class, C<Archive>.
35
+
36
+ =head1 EXPORTS
37
+
38
+ =head2 Classes
39
+
40
+ =over
41
+
42
+ =item C<Archive>
43
+
44
+ Runtime-supported archive namespace class.
45
+
46
+ =over
47
+
48
+ =item C<< Archive.decode(BinaryString bytes, String format?) >>
49
+
50
+ Parameters: C<bytes> is archive or compressed data and C<format> is an
51
+ optional format name. Returns: C<Dict>. Decodes C<bytes> into an archive
52
+ value.
53
+
54
+ =item C<< Archive.encode(Dict archive, String format?) >>
55
+
56
+ Parameters: C<archive> is an archive value and C<format> is an optional
57
+ format name. Returns: C<BinaryString>. Encodes C<archive> into archive
58
+ or compressed data.
59
+
60
+ =item C<< Archive.load(Path path, String format?) >>
61
+
62
+ Parameters: C<path> is a C<std/io> C<Path> and C<format> is an optional
63
+ format name. Returns: C<Dict>. Reads and decodes an archive file.
64
+
65
+ =item C<< Archive.dump(Path path, Dict archive, String format?) >>
66
+
67
+ Parameters: C<path> is a C<std/io> C<Path>, C<archive> is an archive
68
+ value, and C<format> is an optional format name. Returns: C<null>.
69
+ Encodes and writes an archive file.
70
+
71
+ =back
72
+
73
+ =back
74
+
75
+ Archive values use this shape:
76
+
77
+ {
78
+ format: "zip",
79
+ entries: [
80
+ { path: "hello.txt", data: BinaryString },
81
+ { path: "nested/world.txt", data: BinaryString },
82
+ ],
83
+ }
84
+
85
+ Only regular file payloads are preserved in this API. Directory
86
+ entries and extended archive metadata are ignored so the interface
87
+ remains practical to port to other backends later.
88
+
89
+ When constructing archives for C<encode> or C<dump>, each entry may
90
+ provide either:
91
+
92
+ =over
93
+
94
+ =item * C<data> as a C<BinaryString>
95
+
96
+ =item * C<data_from> as a C<std/io::Path>
97
+
98
+ =back
99
+
100
+ For single-stream compression formats such as C<gz> and C<bz2>,
101
+ C<entries> contains exactly one file entry.
102
+
103
+ =head1 SUPPORTED FORMATS
104
+
105
+ Host runtimes may support:
106
+
107
+ =over
108
+
109
+ =item * C<zip>
110
+
111
+ =item * C<tar>
112
+
113
+ =item * C<tar.gz> and C<tgz>
114
+
115
+ =item * C<tar.bz2> and C<tbz2>
116
+
117
+ =item * C<gz>
118
+
119
+ =item * C<bz2>
120
+
121
+ =back
122
+
123
+ This module is intended for host runtimes with archive and compression
124
+ support. Browser runtimes should not be assumed to support it.
125
+
126
+ =head1 COPYRIGHT AND LICENCE
127
+
128
+ B<< std/archive >> is copyright Toby Inkster.
129
+
130
+ It is free software; you may redistribute it and/or modify it under
131
+ the terms of either the Artistic License 1.0 or the GNU General Public
132
+ License version 2.
@@ -0,0 +1,174 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/cache/lru - Pure ZuzuScript in-memory LRU cache.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/cache/lru import Cache;
10
+
11
+ let cache := new Cache( capacity: 20 );
12
+
13
+ let item := cache.get( "item-key", function ( item_key ) {
14
+ # Called only on cache miss.
15
+ return calculate_some_expensive_value( item_key );
16
+ } );
17
+
18
+ cache.empty();
19
+
20
+ =head1 IMPLEMENTATION SUPPORT
21
+
22
+ This module is supported by all implementations of ZuzuScript.
23
+
24
+ =head1 DESCRIPTION
25
+
26
+ This module provides a tiny in-memory least-recently-used (LRU)
27
+ cache written in pure ZuzuScript.
28
+
29
+ Keys are stored in an internal C<Dict>, and are assumed to be
30
+ strings. Values may be any ZuzuScript value.
31
+
32
+ =head1 EXPORTS
33
+
34
+ =head2 Classes
35
+
36
+ =over
37
+
38
+ =item C<< Cache({ capacity?: Number }) >>
39
+
40
+ Construct a cache with a maximum number of entries.
41
+ Returns: C<Cache>. Defaults to C<128>.
42
+
43
+ =item C<< cache.get(String item_key, Function producer) >>
44
+
45
+ Parameters: C<item_key> is a string key and C<producer> is a function
46
+ called on cache miss. Returns: value. Returns the cached value or stores
47
+ and returns C<producer(item_key)>.
48
+
49
+ =item C<< cache.peek(String item_key, fallback?) >>
50
+
51
+ Parameters: C<item_key> is a string key and C<fallback> is optional.
52
+ Returns: value. Returns the cached value without changing recency, or
53
+ C<fallback>/C<null> on a miss.
54
+
55
+ =item C<< cache.set(String item_key, value) >>
56
+
57
+ Parameters: C<item_key> is a string key and C<value> is any value.
58
+ Returns: value. Stores C<value> and marks it as recently used.
59
+
60
+ =item C<< cache.has(String item_key) >>
61
+
62
+ Parameters: C<item_key> is a string key. Returns: C<Boolean>. Returns
63
+ true if the cache currently contains C<item_key>.
64
+
65
+ =item C<< cache.size() >>
66
+
67
+ Parameters: none. Returns: C<Number>. Returns the current number of
68
+ cached entries.
69
+
70
+ =item C<< cache.capacity() >>
71
+
72
+ Parameters: none. Returns: C<Number>. Returns the configured maximum
73
+ number of entries.
74
+
75
+ =item C<< cache.empty() >>
76
+
77
+ Parameters: none. Returns: C<null>. Removes all entries from the cache.
78
+
79
+ =back
80
+
81
+ =head1 COPYRIGHT AND LICENCE
82
+
83
+ B<< std/cache/lru >> is copyright Toby Inkster.
84
+
85
+ It is free software; you may redistribute it and/or modify it under
86
+ the terms of either the Artistic License 1.0 or the GNU General Public
87
+ License version 2.
88
+
89
+ =cut
90
+
91
+
92
+ class Cache {
93
+ let Number capacity := 128;
94
+ let Dict _items := {};
95
+ let Array _order := [];
96
+
97
+ method __build__ () {
98
+ die "Cache capacity must be greater than zero" if capacity <= 0;
99
+ }
100
+
101
+ method _drop_key_from_order ( String item_key ) {
102
+ let kept := [];
103
+ let i := 0;
104
+ while ( i < _order.length() ) {
105
+ let key := _order[i];
106
+ if ( key ≢ item_key ) {
107
+ kept.push(key);
108
+ }
109
+ i++;
110
+ }
111
+ _order := kept;
112
+ }
113
+
114
+ method _touch ( String item_key ) {
115
+ self._drop_key_from_order(item_key);
116
+ _order.push(item_key);
117
+ }
118
+
119
+ method _evict_if_needed () {
120
+ while ( _order.length() > capacity ) {
121
+ let oldest := _order.shift();
122
+ if ( _items.exists(oldest) ) {
123
+ _items.remove(oldest);
124
+ }
125
+ }
126
+ }
127
+
128
+ method set ( String item_key, value ) {
129
+ _items.set( item_key, value );
130
+ self._touch(item_key);
131
+ self._evict_if_needed();
132
+ return value;
133
+ }
134
+
135
+ method get ( String item_key, producer ) {
136
+ if ( _items.exists(item_key) ) {
137
+ self._touch(item_key);
138
+ return _items.get(item_key);
139
+ }
140
+
141
+ die "Cache.get expects a producer Function" if not( producer instanceof Function );
142
+
143
+ let value := producer(item_key);
144
+ self.set( item_key, value );
145
+ return value;
146
+ }
147
+
148
+ method peek ( String item_key, fallback? ) {
149
+ if ( _items.exists(item_key) ) {
150
+ self._touch(item_key);
151
+ return _items.get(item_key);
152
+ }
153
+
154
+ return fallback;
155
+ }
156
+
157
+ method has ( String item_key ) {
158
+ return _items.exists(item_key);
159
+ }
160
+
161
+ method size () {
162
+ return _items.length();
163
+ }
164
+
165
+ method capacity () {
166
+ return capacity;
167
+ }
168
+
169
+ method empty () {
170
+ _items.clear();
171
+ _order.clear();
172
+ return self;
173
+ }
174
+ }
@@ -0,0 +1,112 @@
1
+ =encoding utf8
2
+
3
+ =head1 NAME
4
+
5
+ std/clib - Dynamic C library loading and scalar FFI calls.
6
+
7
+ =head1 SYNOPSIS
8
+
9
+ from std/clib import CLib;
10
+
11
+ let lib := CLib.open("stdlib/test-fixtures/example_clib/libgreet.so");
12
+ let greet := lib.func(
13
+ "greet",
14
+ [],
15
+ {
16
+ type: "binary",
17
+ terminated_by: "nul",
18
+ free: "greet_free"
19
+ }
20
+ );
21
+
22
+ say to_string(greet.call());
23
+
24
+ =head1 IMPLEMENTATION SUPPORT
25
+
26
+ This module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and
27
+ Electron. It is not supported by zuzu-js in the browser.
28
+
29
+ =head1 DESCRIPTION
30
+
31
+ This runtime-supported module loads C dynamic libraries and calls
32
+ exported C functions through explicitly declared signatures.
33
+
34
+ The first implementation supports C<null>, booleans, 64-bit integers,
35
+ 64-bit floats, and C<BinaryString> byte buffers. Other data types are
36
+ out of scope.
37
+
38
+ The runtime copies returned binary data before returning it to
39
+ ZuzuScript. If a return descriptor includes C<free>, that symbol is
40
+ called after the copy so libraries can return owned memory safely.
41
+
42
+ On Unix-like systems, dynamic libraries usually use C<.so> on Linux and
43
+ C<.dylib> on macOS. Windows libraries usually use C<.dll>. Exact
44
+ availability depends on the host runtime. Browser runtimes reject this
45
+ module as unsupported.
46
+
47
+ =head1 EXPORTS
48
+
49
+ =head2 Classes
50
+
51
+ =over
52
+
53
+ =item C<CLib>
54
+
55
+ Static methods:
56
+
57
+ =over
58
+
59
+ =item C<< CLib.open(String path) >>
60
+
61
+ Parameters: C<path> is a dynamic library path. Returns: C<CLibrary>.
62
+ Loads a dynamic library.
63
+
64
+ =back
65
+
66
+ =item C<CLibrary>
67
+
68
+ Methods:
69
+
70
+ =over
71
+
72
+ =item C<< func(String name, Array params, return_type, options?) >>
73
+
74
+ Parameters: C<name> is a symbol name, C<params> describes parameter
75
+ types, C<return_type> describes the return type, and C<options> is
76
+ optional. Returns: C<CFunction>. Looks up a symbol and returns a
77
+ callable C function wrapper.
78
+
79
+ =item C<< has_symbol(String name) >>
80
+
81
+ Parameters: C<name> is a symbol name. Returns: C<Boolean>. Returns
82
+ whether the loaded library exports the named symbol.
83
+
84
+ =item C<close()>
85
+
86
+ Parameters: none. Returns: C<null>. Invalidates the library and
87
+ functions created from it.
88
+
89
+ =back
90
+
91
+ =item C<CFunction>
92
+
93
+ Methods:
94
+
95
+ =over
96
+
97
+ =item C<call(...)>
98
+
99
+ Parameters: arguments must match the declared C signature. Returns:
100
+ value. Calls the C function using the declared signature.
101
+
102
+ =back
103
+
104
+ =back
105
+
106
+ =head1 COPYRIGHT AND LICENCE
107
+
108
+ B<< std/clib >> is copyright Toby Inkster.
109
+
110
+ It is free software; you may redistribute it and/or modify it under
111
+ the terms of either the Artistic License 1.0 or the GNU General Public
112
+ License version 2.