firefly-compiler 0.5.35 → 0.5.37

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 (225) hide show
  1. package/.hintrc +4 -4
  2. package/.vscode/settings.json +4 -4
  3. package/bin/Release.ff +157 -154
  4. package/bin/firefly.mjs +1 -1
  5. package/compiler/Builder.ff +275 -277
  6. package/compiler/Compiler.ff +234 -233
  7. package/compiler/Dependencies.ff +186 -187
  8. package/compiler/DependencyLock.ff +17 -17
  9. package/compiler/Deriver.ff +23 -31
  10. package/compiler/Dictionaries.ff +1 -1
  11. package/compiler/Inference.ff +43 -20
  12. package/compiler/JsEmitter.ff +1437 -1282
  13. package/compiler/LspHook.ff +202 -202
  14. package/compiler/Main.ff +25 -24
  15. package/compiler/ModuleCache.ff +178 -178
  16. package/compiler/Parser.ff +36 -109
  17. package/compiler/Resolver.ff +5 -8
  18. package/compiler/Substitution.ff +1 -1
  19. package/compiler/Syntax.ff +1 -16
  20. package/compiler/Token.ff +9 -0
  21. package/compiler/Tokenizer.ff +4 -0
  22. package/compiler/Workspace.ff +88 -88
  23. package/core/.firefly/include/package.json +5 -5
  24. package/core/.firefly/package.ff +2 -2
  25. package/core/Any.ff +26 -30
  26. package/core/Array.ff +298 -265
  27. package/core/Atomic.ff +63 -64
  28. package/core/Box.ff +7 -7
  29. package/core/BrowserSystem.ff +40 -40
  30. package/core/Buffer.ff +185 -152
  31. package/core/BuildSystem.ff +156 -148
  32. package/core/Channel.ff +95 -92
  33. package/core/Char.ff +3 -2
  34. package/core/Core.ff +16 -23
  35. package/core/Crypto.ff +94 -96
  36. package/core/Equal.ff +41 -36
  37. package/core/Error.ff +15 -10
  38. package/core/FileHandle.ff +45 -37
  39. package/core/Float.ff +176 -200
  40. package/core/HttpClient.ff +142 -148
  41. package/core/Instant.ff +6 -8
  42. package/core/Int.ff +40 -24
  43. package/core/IntMap.ff +61 -39
  44. package/core/Js.ff +305 -0
  45. package/core/JsSystem.ff +135 -114
  46. package/core/JsValue.ff +303 -159
  47. package/core/Json.ff +423 -443
  48. package/core/List.ff +482 -486
  49. package/core/Lock.ff +108 -144
  50. package/core/Log.ff +25 -14
  51. package/core/NodeSystem.ff +198 -191
  52. package/core/Ordering.ff +160 -161
  53. package/core/Path.ff +377 -409
  54. package/core/Queue.ff +90 -0
  55. package/core/Random.ff +140 -134
  56. package/core/RbMap.ff +216 -216
  57. package/core/Serializable.ff +16 -13
  58. package/core/Show.ff +44 -43
  59. package/core/SourceLocation.ff +68 -68
  60. package/core/Stream.ff +1 -1
  61. package/core/String.ff +224 -202
  62. package/core/StringMap.ff +58 -36
  63. package/core/Task.ff +165 -149
  64. package/experimental/benchmarks/ListGrab.ff +23 -23
  65. package/experimental/benchmarks/ListGrab.java +55 -55
  66. package/experimental/benchmarks/Pyrotek45.ff +30 -30
  67. package/experimental/benchmarks/Pyrotek45.java +64 -64
  68. package/experimental/bidirectional/Bidi.ff +88 -88
  69. package/experimental/lines/Main.ff +40 -0
  70. package/experimental/random/Index.ff +53 -53
  71. package/experimental/random/Process.ff +120 -120
  72. package/experimental/random/RunLength.ff +65 -65
  73. package/experimental/random/Scrape.ff +51 -51
  74. package/experimental/random/Symbols.ff +73 -73
  75. package/experimental/random/Tensor.ff +52 -52
  76. package/experimental/random/Units.ff +36 -36
  77. package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
  78. package/experimental/s3/S3TestPut.ff +16 -16
  79. package/experimental/tests/TestJson.ff +26 -26
  80. package/firefly.sh +0 -0
  81. package/fireflysite/.firefly/package.ff +4 -4
  82. package/fireflysite/CommunityOverview.ff +20 -20
  83. package/fireflysite/CountingButtonDemo.ff +58 -58
  84. package/fireflysite/DocumentParser.ff +325 -331
  85. package/fireflysite/ExamplesOverview.ff +40 -40
  86. package/fireflysite/FrontPage.ff +344 -344
  87. package/fireflysite/GettingStarted.ff +45 -45
  88. package/fireflysite/Guide.ff +456 -456
  89. package/fireflysite/Main.ff +163 -152
  90. package/fireflysite/MatchingPasswordsDemo.ff +82 -82
  91. package/fireflysite/PackagesOverview.ff +49 -49
  92. package/fireflysite/PostgresqlDemo.ff +34 -34
  93. package/fireflysite/ReferenceAll.ff +18 -18
  94. package/fireflysite/ReferenceIntroduction.ff +11 -11
  95. package/fireflysite/Styles.ff +567 -567
  96. package/fireflysite/Test.ff +121 -62
  97. package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -209
  98. package/fireflysite/assets/markdown/reference/EmittedJavascript.md +65 -65
  99. package/fireflysite/assets/markdown/reference/Exceptions.md +101 -101
  100. package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +364 -364
  101. package/fireflysite/assets/markdown/reference/JavascriptInterop.md +235 -172
  102. package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -162
  103. package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -48
  104. package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -224
  105. package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -86
  106. package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -99
  107. package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -100
  108. package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -184
  109. package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -136
  110. package/fireflysite/assets/markdown/scratch/Toc.md +40 -40
  111. package/lsp/.firefly/package.ff +1 -1
  112. package/lsp/CompletionHandler.ff +827 -827
  113. package/lsp/Handler.ff +714 -714
  114. package/lsp/HoverHandler.ff +79 -79
  115. package/lsp/LanguageServer.ff +272 -272
  116. package/lsp/SignatureHelpHandler.ff +55 -55
  117. package/lsp/SymbolHandler.ff +181 -181
  118. package/lsp/TestReferences.ff +17 -17
  119. package/lsp/TestReferencesCase.ff +7 -7
  120. package/lsp/stderr.txt +1 -1
  121. package/lsp/stdout.txt +34 -34
  122. package/lux/.firefly/package.ff +1 -1
  123. package/lux/Css.ff +648 -648
  124. package/lux/CssTest.ff +48 -48
  125. package/lux/Lux.ff +608 -617
  126. package/lux/LuxEvent.ff +79 -116
  127. package/lux/Main.ff +123 -123
  128. package/lux/Main2.ff +143 -143
  129. package/lux/TestDry.ff +28 -28
  130. package/output/js/ff/compiler/Builder.mjs +72 -71
  131. package/output/js/ff/compiler/Compiler.mjs +19 -13
  132. package/output/js/ff/compiler/Dependencies.mjs +8 -7
  133. package/output/js/ff/compiler/DependencyLock.mjs +6 -4
  134. package/output/js/ff/compiler/Deriver.mjs +26 -24
  135. package/output/js/ff/compiler/Dictionaries.mjs +14 -18
  136. package/output/js/ff/compiler/Environment.mjs +6 -4
  137. package/output/js/ff/compiler/Inference.mjs +238 -164
  138. package/output/js/ff/compiler/JsEmitter.mjs +1160 -350
  139. package/output/js/ff/compiler/JsImporter.mjs +20 -18
  140. package/output/js/ff/compiler/LspHook.mjs +12 -10
  141. package/output/js/ff/compiler/Main.mjs +61 -41
  142. package/output/js/ff/compiler/ModuleCache.mjs +10 -8
  143. package/output/js/ff/compiler/Parser.mjs +153 -669
  144. package/output/js/ff/compiler/Patterns.mjs +12 -10
  145. package/output/js/ff/compiler/Resolver.mjs +52 -78
  146. package/output/js/ff/compiler/Substitution.mjs +12 -16
  147. package/output/js/ff/compiler/Syntax.mjs +50 -341
  148. package/output/js/ff/compiler/Token.mjs +126 -4
  149. package/output/js/ff/compiler/Tokenizer.mjs +62 -52
  150. package/output/js/ff/compiler/Unification.mjs +74 -90
  151. package/output/js/ff/compiler/Wildcards.mjs +4 -2
  152. package/output/js/ff/compiler/Workspace.mjs +26 -20
  153. package/output/js/ff/core/Any.mjs +20 -20
  154. package/output/js/ff/core/Array.mjs +268 -175
  155. package/output/js/ff/core/AssetSystem.mjs +8 -6
  156. package/output/js/ff/core/Atomic.mjs +84 -52
  157. package/output/js/ff/core/Bool.mjs +6 -4
  158. package/output/js/ff/core/BrowserSystem.mjs +38 -29
  159. package/output/js/ff/core/Buffer.mjs +285 -133
  160. package/output/js/ff/core/BuildSystem.mjs +36 -56
  161. package/output/js/ff/core/Channel.mjs +250 -97
  162. package/output/js/ff/core/Char.mjs +5 -3
  163. package/output/js/ff/core/Core.mjs +28 -34
  164. package/output/js/ff/core/Crypto.mjs +30 -52
  165. package/output/js/ff/core/Duration.mjs +4 -2
  166. package/output/js/ff/core/Equal.mjs +14 -12
  167. package/output/js/ff/core/Error.mjs +17 -11
  168. package/output/js/ff/core/FileHandle.mjs +76 -38
  169. package/output/js/ff/core/Float.mjs +92 -160
  170. package/output/js/ff/core/HttpClient.mjs +208 -76
  171. package/output/js/ff/core/Instant.mjs +8 -10
  172. package/output/js/ff/core/Int.mjs +36 -26
  173. package/output/js/ff/core/IntMap.mjs +79 -33
  174. package/output/js/ff/core/Js.mjs +751 -0
  175. package/output/js/ff/core/JsSystem.mjs +54 -60
  176. package/output/js/ff/core/JsValue.mjs +294 -143
  177. package/output/js/ff/core/Json.mjs +443 -253
  178. package/output/js/ff/core/List.mjs +262 -214
  179. package/output/js/ff/core/Lock.mjs +156 -125
  180. package/output/js/ff/core/Log.mjs +20 -10
  181. package/output/js/ff/core/Map.mjs +10 -8
  182. package/output/js/ff/core/NodeSystem.mjs +189 -123
  183. package/output/js/ff/core/Nothing.mjs +4 -2
  184. package/output/js/ff/core/Option.mjs +40 -38
  185. package/output/js/ff/core/Ordering.mjs +26 -20
  186. package/output/js/ff/core/Pair.mjs +4 -2
  187. package/output/js/ff/core/Path.mjs +517 -315
  188. package/output/js/ff/core/Queue.mjs +306 -0
  189. package/output/js/ff/core/Random.mjs +141 -77
  190. package/output/js/ff/core/RbMap.mjs +36 -34
  191. package/output/js/ff/core/Serializable.mjs +44 -28
  192. package/output/js/ff/core/Set.mjs +6 -4
  193. package/output/js/ff/core/Show.mjs +8 -6
  194. package/output/js/ff/core/SourceLocation.mjs +4 -2
  195. package/output/js/ff/core/Stream.mjs +30 -50
  196. package/output/js/ff/core/String.mjs +263 -172
  197. package/output/js/ff/core/StringMap.mjs +77 -31
  198. package/output/js/ff/core/Task.mjs +91 -76
  199. package/output/js/ff/core/Try.mjs +20 -18
  200. package/output/js/ff/core/Unit.mjs +4 -2
  201. package/package.json +1 -1
  202. package/postgresql/Pg.ff +53 -59
  203. package/rpc/.firefly/package.ff +1 -1
  204. package/rpc/Rpc.ff +70 -70
  205. package/s3/.firefly/package.ff +1 -1
  206. package/s3/S3.ff +92 -94
  207. package/vscode/LICENSE.txt +21 -21
  208. package/vscode/Prepublish.ff +15 -15
  209. package/vscode/README.md +16 -16
  210. package/vscode/client/package-lock.json +544 -544
  211. package/vscode/client/package.json +22 -22
  212. package/vscode/client/src/extension.ts +104 -104
  213. package/vscode/icons/firefly-icon.svg +10 -10
  214. package/vscode/language-configuration.json +61 -61
  215. package/vscode/package-lock.json +3623 -3623
  216. package/vscode/package.json +1 -1
  217. package/vscode/snippets.json +241 -241
  218. package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
  219. package/webserver/.firefly/include/package.json +5 -5
  220. package/webserver/.firefly/package.ff +2 -2
  221. package/webserver/WebServer.ff +647 -685
  222. package/websocket/.firefly/package.ff +1 -1
  223. package/websocket/WebSocket.ff +100 -131
  224. package/core/UnsafeJs.ff +0 -42
  225. package/output/js/ff/core/UnsafeJs.mjs +0 -191
package/core/Queue.ff ADDED
@@ -0,0 +1,90 @@
1
+ class Queue[T](items: IntMap[T], mutable nextKey: Int)
2
+ newtype QueueKey(key: Int)
3
+
4
+ new[T](): Queue[T] {
5
+ Queue(IntMap.new(), 0)
6
+ }
7
+
8
+ extend self[T]: Queue[T] {
9
+
10
+ push(item: T): QueueKey {
11
+ self.nextKey += 1
12
+ self.items.set(self.nextKey, item)
13
+ QueueKey(self.nextKey)
14
+ }
15
+
16
+ pop(): Option[T] {
17
+ if(self.items.size() == 0) {None} else:
18
+ let key = self.items!->keys()->next()->value?
19
+ let value = self.items.get(key)
20
+ self.items.remove(key)
21
+ value
22
+ }
23
+
24
+ first(): Option[T] {
25
+ if(self.items.size() == 0) {None} else:
26
+ let key = self.items!->keys()->next()->value?
27
+ let value = self.items.get(key)
28
+ value
29
+ }
30
+
31
+ remove(key: QueueKey): Bool {
32
+ self.items.remove(key.key)
33
+ }
34
+
35
+ has(key: QueueKey): Bool {
36
+ self.items.has(key.key)
37
+ }
38
+
39
+ clear(): Unit {
40
+ self.items.clear()
41
+ }
42
+
43
+ size(): Int {
44
+ self.items.size()
45
+ }
46
+
47
+ isEmpty(): Bool {
48
+ self.size() == 0
49
+ }
50
+
51
+ each(body: (QueueKey, T) => Unit): Unit {
52
+ self.items.each {k, v => body(QueueKey(k), v)}
53
+ }
54
+
55
+ eachWhile(body: (QueueKey, T) => Bool): Unit {
56
+ self.items.eachWhile {k, v => body(QueueKey(k), v)}
57
+ }
58
+
59
+ toArray(): Array[T] {
60
+ let array = Array.new()
61
+ self.each {_, v => array.push(v)}
62
+ array
63
+ }
64
+
65
+ toList(): List[T] {
66
+ self.toArray().drain()
67
+ }
68
+
69
+ toStream(): Stream[T] {
70
+ self.toList().toStream()
71
+ }
72
+
73
+ keys(): List[QueueKey] {
74
+ let array = Array.new()
75
+ self.items.each {k, _ => array.push(QueueKey(k))}
76
+ array.drain()
77
+ }
78
+
79
+ values(): List[T] {
80
+ let array = Array.new()
81
+ self.items.each {_, v => array.push(v)}
82
+ array.drain()
83
+ }
84
+
85
+ copy(): Queue[T] {
86
+ Queue(self.items.copy(), self.nextKey)
87
+ }
88
+
89
+ }
90
+
package/core/Random.ff CHANGED
@@ -1,134 +1,140 @@
1
- class Random {}
2
-
3
- // Using Alea PRNG by Johannes Baagøe <baagoe@baagoe.com>, 2010
4
- // Typical use: Random.seedInstant(system.task().now())
5
-
6
- newFromInt(seed: Int): Random {
7
- newFromFloat(seed.toFloat())
8
- }
9
-
10
- newFromFloat(seed: Float): Random {
11
- let buffer = Buffer.new(8)
12
- buffer.setFloat64(0, seed)
13
- newFromBuffer(buffer)
14
- }
15
-
16
- newFromInstant(seed: Instant): Random {
17
- newFromFloat(seed.since1970.seconds)
18
- }
19
-
20
- newFromBuffer(buffer: Buffer): Random
21
- target js sync """
22
- var n = 0xefc8249d;
23
- function mash(data) {
24
- for(var i = 0; i < data.byteLength; i++) {
25
- n += data.getUint8(i);
26
- var h = 0.02519603282416938 * n;
27
- n = h >>> 0;
28
- h -= n;
29
- h *= n;
30
- n = h >>> 0;
31
- h -= n;
32
- n += h * 0x100000000; // 2^32
33
- }
34
- return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
35
- }
36
- var space = new DataView(new Uint8Array([32]).buffer);
37
- var r = {
38
- s0: mash(space),
39
- s1: mash(space),
40
- s2: mash(space),
41
- c: 1,
42
- spareGauss: NaN
43
- };
44
- r.s0 -= mash(buffer_);
45
- if(r.s0 < 0) r.s0 += 1;
46
- r.s1 -= mash(buffer_);
47
- if(r.s1 < 0) r.s1 += 1;
48
- r.s2 -= mash(buffer_);
49
- if(r.s2 < 0) r.s2 += 1;
50
- return r;
51
- """
52
-
53
- extend self: Random {
54
-
55
- copy(): Random
56
- target js sync """
57
- return {...self_};
58
- """
59
-
60
- nextInt(from: Int, until: Int): Int
61
- target js sync """
62
- return Random_nextFloat(self_, from_, until_) | 0;
63
- """
64
-
65
- nextFloat(from: Float, until: Float): Float
66
- target js sync """
67
- var t = 2091639 * self_.s0 + self_.c * 2.3283064365386963e-10; // 2^-32
68
- self_.s0 = self_.s1;
69
- self_.s1 = self_.s2;
70
- var uniform = self_.s2 = t - (self_.c = t | 0);
71
- return from_ + uniform * (until_ - from_);
72
- """
73
-
74
- nextBool(): Bool {
75
- self.nextInt(0, 2) == 0
76
- }
77
-
78
- nextBytes(buffer: Buffer, start: Int, stop: Int): Unit {
79
- start.until(stop).each {i =>
80
- buffer.setUint8(i, self.nextInt(0, 256))
81
- }
82
- }
83
-
84
- nextGauss(mean: Float, standardDeviation: Float): Float
85
- target js sync """
86
- if(!isNaN(self_.spareGauss)) {
87
- const result = self_.spareGauss * standardDeviation_ + mean_;
88
- self_.spareGauss = NaN;
89
- return result;
90
- } else {
91
- let u = 0.5, v = 0.5, s = 0.5;
92
- do {
93
- u = Random_nextFloat(self_, 0.0, 1.0) * 2 - 1;
94
- v = Random_nextFloat(self_, 0.0, 1.0) * 2 - 1;
95
- s = u * u + v * v;
96
- } while(s >= 1 || s == 0);
97
- s = Math.sqrt(-2.0 * Math.log(s) / s);
98
- self_.spareGauss = v * s;
99
- return mean_ + standardDeviation_ * u * s;
100
- }
101
- """
102
-
103
- shuffleArray[T](array: Array[T]): Unit {
104
- 0.until(array.size() - 1).each {i =>
105
- let j = self.nextInt(0, array.size() - i) + i
106
- let value = array.grab(i)
107
- array.set(i, array.grab(j))
108
- array.set(j, value)
109
- }
110
- }
111
-
112
- shuffleList[T](list: List[T]): List[T] {
113
- let array = list.toArray()
114
- self.shuffleArray(list.toArray())
115
- array.drain()
116
- }
117
-
118
- sampleArray[T](count: Int, array: Array[T], body: T => Unit): Unit {
119
- self.shuffleList(array.toList()).takeFirst(count).each {body(_)}
120
- }
121
-
122
- sampleList[T](count: Int, list: List[T]): List[T] {
123
- self.shuffleList(list).takeFirst(count)
124
- }
125
-
126
- grabArray[T](array: Array[T]): T {
127
- array.grab(self.nextInt(0, array.size()))
128
- }
129
-
130
- grabList[T](list: List[T]): T {
131
- list.grab(self.nextInt(0, list.size()))
132
- }
133
-
134
- }
1
+ class Random(
2
+ mutable s0: Float
3
+ mutable s1: Float
4
+ mutable s2: Float
5
+ mutable c: Float
6
+ mutable spareGauss: Float
7
+ )
8
+
9
+ // Using Alea PRNG by Johannes Baagøe <baagoe@baagoe.com>, 2010
10
+ // Typical use: Random.seedInstant(system.task().now())
11
+
12
+ newFromInt(seed: Int): Random {
13
+ newFromFloat(seed.toFloat())
14
+ }
15
+
16
+ newFromFloat(seed: Float): Random {
17
+ let buffer = Buffer.new(8)
18
+ buffer.setFloat64(0, seed)
19
+ newFromBuffer(buffer)
20
+ }
21
+
22
+ newFromInstant(seed: Instant): Random {
23
+ newFromFloat(seed.since1970.seconds)
24
+ }
25
+
26
+ newFromBuffer(buffer: Buffer): Random {
27
+ mutable n: Float = (0xefc8249d).toFloat()
28
+ function mash(data: Buffer): Float {
29
+ 0.until(data.size()).each {i =>
30
+ n += data.grabUint8(i).toFloat()
31
+ mutable h = 0.02519603282416938 * n
32
+ n = Js.binaryOperator(">>>", h, 0)?
33
+ h -= n
34
+ h *= n
35
+ n = Js.binaryOperator(">>>", h, 0)?
36
+ h -=n
37
+ n += h * 0x100000000 // 2^32
38
+ }
39
+ Js.binaryOperator(">>>", n, 0)? * 2.3283064365386963e-10
40
+ }
41
+ let space: Buffer = Js->DataView->(Js->Uint8Array->([32])->buffer)?
42
+ let r = Random(
43
+ s0 = mash(space)
44
+ s1 = mash(space)
45
+ s2 = mash(space)
46
+ c = 1.0
47
+ spareGauss = Float.nan()
48
+ )
49
+ r.s0 -= mash(buffer)
50
+ if(r.s0 < 0.0) {r.s0 += 1.0}
51
+ r.s1 -= mash(buffer);
52
+ if(r.s1 < 0.0) {r.s1 +=1.0}
53
+ r.s2 -= mash(buffer);
54
+ if(r.s2 < 0.0) {r.s2 += 1.0}
55
+ r
56
+ }
57
+
58
+ extend self: Random {
59
+
60
+ copy(): Random {
61
+ self.Random()
62
+ }
63
+
64
+ nextInt(from: Int, until: Int): Int {
65
+ Js.binaryOperator("|", self.nextFloat(from.toFloat(), until.toFloat())!, 0)?
66
+ }
67
+
68
+ nextFloat(from: Float, until: Float): Float {
69
+ let t = 2091639 * self.s0 + self.c * 2.3283064365386963e-10
70
+ self.s0 = self.s1;
71
+ self.s1 = self.s2;
72
+ self.c = Js.binaryOperator("|", t, 0)?
73
+ let uniform = t - self.c
74
+ self.s2 = uniform
75
+ from + uniform * (until - from)
76
+ }
77
+
78
+ nextBool(): Bool {
79
+ self.nextInt(0, 2) == 0
80
+ }
81
+
82
+ nextBytes(buffer: Buffer, start: Int, stop: Int): Unit {
83
+ start.until(stop).each {i =>
84
+ buffer.setUint8(i, self.nextInt(0, 256))
85
+ }
86
+ }
87
+
88
+ nextGauss(mean: Float, standardDeviation: Float): Float {
89
+ if(!self.spareGauss.isNan()) {
90
+ let result = self.spareGauss * standardDeviation + mean
91
+ self.spareGauss = Float.nan()
92
+ result
93
+ } else {
94
+ mutable u = 0.5
95
+ mutable v = 0.5
96
+ mutable s = 0.5
97
+ doWhile {
98
+ u = self.nextFloat(0.0, 1.0) * 2 - 1
99
+ v = self.nextFloat(0.0, 1.0) * 2 - 1
100
+ s = u * u + v * v
101
+ s >= 1.0 || s == 0.0
102
+ }
103
+ s = (-2.0 * s.ln() / s).sqrt()
104
+ self.spareGauss = v * s
105
+ mean + standardDeviation * u * s
106
+ }
107
+ }
108
+
109
+ shuffleArray[T](array: Array[T]): Unit {
110
+ 0.until(array.size() - 1).each {i =>
111
+ let j = self.nextInt(0, array.size() - i) + i
112
+ let value = array.grab(i)
113
+ array.set(i, array.grab(j))
114
+ array.set(j, value)
115
+ }
116
+ }
117
+
118
+ shuffleList[T](list: List[T]): List[T] {
119
+ let array = list.toArray()
120
+ self.shuffleArray(list.toArray())
121
+ array.drain()
122
+ }
123
+
124
+ sampleArray[T](count: Int, array: Array[T], body: T => Unit): Unit {
125
+ self.shuffleList(array.toList()).takeFirst(count).each {body(_)}
126
+ }
127
+
128
+ sampleList[T](count: Int, list: List[T]): List[T] {
129
+ self.shuffleList(list).takeFirst(count)
130
+ }
131
+
132
+ grabArray[T](array: Array[T]): T {
133
+ array.grab(self.nextInt(0, array.size()))
134
+ }
135
+
136
+ grabList[T](list: List[T]): T {
137
+ list.grab(self.nextInt(0, list.size()))
138
+ }
139
+
140
+ }