@magnusopera/fscript 0.77.1 → 0.78.1

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 (85) hide show
  1. package/dist/FScript.Language/Ast.js +2 -2
  2. package/dist/FScript.Language/BuiltinFunctions.js +68 -67
  3. package/dist/FScript.Language/BuiltinSignatures.js +7 -7
  4. package/dist/FScript.Language/BuiltinTypes.js +3 -3
  5. package/dist/FScript.Language/Error.js +2 -2
  6. package/dist/FScript.Language/Eval.js +305 -213
  7. package/dist/FScript.Language/IncludeResolver.js +97 -79
  8. package/dist/FScript.Language/Interactive.js +149 -0
  9. package/dist/FScript.Language/Lexer.js +77 -77
  10. package/dist/FScript.Language/Parser.js +274 -272
  11. package/dist/FScript.Language/Pretty.js +4 -4
  12. package/dist/FScript.Language/Span.js +2 -2
  13. package/dist/FScript.Language/Token.js +59 -2
  14. package/dist/FScript.Language/TypeInfer.js +452 -348
  15. package/dist/FScript.Language/Types.js +22 -10
  16. package/dist/FScript.Language/Value.js +3 -2
  17. package/dist/Library.js +91 -79
  18. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Array.js +36 -35
  19. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Async.js +52 -23
  20. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/AsyncBuilder.js +23 -2
  21. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/BigInt.js +33 -32
  22. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/BitConverter.js +2 -2
  23. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/CHANGELOG.md +80 -1
  24. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Date.js +8 -15
  25. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/DateOffset.js +8 -17
  26. package/dist/fable_modules/fable-library-js.5.13.0/Directory.js +11 -0
  27. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Double.js +8 -2
  28. package/dist/fable_modules/fable-library-js.5.13.0/Environment.js +3 -0
  29. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Event.js +10 -1
  30. package/dist/fable_modules/fable-library-js.5.13.0/File.js +27 -0
  31. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/List.js +35 -21
  32. package/dist/fable_modules/fable-library-js.5.13.0/Long.js +38 -0
  33. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/MailboxProcessor.js +11 -5
  34. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Map.js +8 -4
  35. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/MutableMap.js +2 -2
  36. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/MutableSet.js +1 -1
  37. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Observable.js +5 -3
  38. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Option.js +1 -18
  39. package/dist/fable_modules/fable-library-js.5.13.0/Path.js +31 -0
  40. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Reflection.js +13 -3
  41. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/RegExp.js +53 -24
  42. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Seq.js +109 -22
  43. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Set.js +16 -3
  44. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/String.js +28 -1
  45. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/System.js +15 -9
  46. package/dist/fable_modules/fable-library-js.5.13.0/Task.js +27 -0
  47. package/dist/fable_modules/fable-library-js.5.13.0/TaskBuilder.js +72 -0
  48. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Types.js +12 -12
  49. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Util.js +15 -3
  50. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/package.json +1 -1
  51. package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/quotation.js +25 -8
  52. package/dist/fable_modules/project_cracked.json +1 -1
  53. package/package.json +1 -1
  54. package/dist/fable_modules/fable-library-js.5.2.0/Long.js +0 -47
  55. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Boolean.js +0 -0
  56. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Char.js +0 -0
  57. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Choice.js +0 -0
  58. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/CollectionUtil.js +0 -0
  59. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/ConditionalWeakTable.js +0 -0
  60. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/DateOnly.js +0 -0
  61. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Decimal.js +0 -0
  62. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Encoding.js +0 -0
  63. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/FSharp.Collections.js +0 -0
  64. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/FSharp.Core.CompilerServices.js +0 -0
  65. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/FSharp.Core.js +0 -0
  66. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Global.js +0 -0
  67. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Guid.js +0 -0
  68. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Int32.js +0 -0
  69. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/MapUtil.js +0 -0
  70. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Native.js +0 -0
  71. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Numeric.js +0 -0
  72. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/README.md +0 -0
  73. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Random.js +0 -0
  74. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Range.js +0 -0
  75. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Result.js +0 -0
  76. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Seq2.js +0 -0
  77. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/System.Collections.Generic.js +0 -0
  78. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/System.Text.js +0 -0
  79. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/TimeOnly.js +0 -0
  80. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/TimeSpan.js +0 -0
  81. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Timer.js +0 -0
  82. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Unicode.13.0.0.js +0 -0
  83. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/Uri.js +0 -0
  84. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/big.d.ts +0 -0
  85. /package/dist/fable_modules/{fable-library-js.5.2.0 → fable-library-js.5.13.0}/lib/big.js +0 -0
@@ -1,7 +1,7 @@
1
1
  import { disposeSafe, getEnumerator, copyToArray, defaultOf, Exception } from "./Util.js";
2
2
  import { Helpers_allocateArrayFromCons } from "./Native.js";
3
3
  import { setItem as setItem_1, item as item_2 } from "./Array.js";
4
- import { value as value_2, map as map_1, defaultArg, some } from "./Option.js";
4
+ import { value as value_2, defaultArg, some } from "./Option.js";
5
5
  import { min as min_1, max as max_1 } from "./Double.js";
6
6
  import { SR_notEnoughElements, SR_inputMustBeNonNegative, SR_inputSequenceEmpty, SR_Arg_ArgumentOutOfRangeException, SR_indexOutOfBounds } from "./Global.js";
7
7
  import { Operators_IsNull } from "./FSharp.Core.js";
@@ -37,7 +37,7 @@ export function getSubArray(array, start, count) {
37
37
  }
38
38
  export function last(array) {
39
39
  if (array.length === 0) {
40
- throw new Exception("The input array was empty\\nParameter name: array");
40
+ throw new Exception("The input array was empty (Parameter \'array\')");
41
41
  }
42
42
  return item_2(array.length - 1, array);
43
43
  }
@@ -183,8 +183,9 @@ export function where(predicate, array) {
183
183
  return array.filter(predicate);
184
184
  }
185
185
  export function indexOf(array, item_1, start, count, eq) {
186
+ let option_1 = undefined;
186
187
  const start_1 = defaultArg(start, 0) | 0;
187
- const end$0027 = defaultArg(map_1((c) => ((start_1 + c) | 0), count), array.length) | 0;
188
+ const end$0027 = defaultArg((option_1 = count, (option_1 != null) ? (start_1 + value_2(option_1)) : undefined), array.length) | 0;
188
189
  const loop = (i_mut) => {
189
190
  loop: while (true) {
190
191
  const i = i_mut;
@@ -216,7 +217,7 @@ export function singleton(value, cons) {
216
217
  }
217
218
  export function initialize(count, initializer, cons) {
218
219
  if (count < 0) {
219
- throw new Exception("The input must be non-negative\\nParameter name: count");
220
+ throw new Exception("The input must be non-negative (Parameter \'count\')");
220
221
  }
221
222
  const result = Helpers_allocateArrayFromCons(cons, count);
222
223
  for (let i = 0; i <= (count - 1); i++) {
@@ -239,7 +240,7 @@ export function pairwise(array) {
239
240
  }
240
241
  export function replicate(count, initial, cons) {
241
242
  if (count < 0) {
242
- throw new Exception("The input must be non-negative\\nParameter name: count");
243
+ throw new Exception("The input must be non-negative (Parameter \'count\')");
243
244
  }
244
245
  const result = Helpers_allocateArrayFromCons(cons, count);
245
246
  for (let i = 0; i <= (result.length - 1); i++) {
@@ -275,7 +276,7 @@ export function scanBack(folder, array, state, cons) {
275
276
  }
276
277
  export function skip(count, array, cons) {
277
278
  if (count > array.length) {
278
- throw new Exception("count is greater than array length\\nParameter name: count");
279
+ throw new Exception("count is greater than array length (Parameter \'count\')");
279
280
  }
280
281
  if (count === array.length) {
281
282
  return Helpers_allocateArrayFromCons(cons, 0);
@@ -300,10 +301,10 @@ export function skipWhile(predicate, array, cons) {
300
301
  }
301
302
  export function take(count, array, cons) {
302
303
  if (count < 0) {
303
- throw new Exception("The input must be non-negative\\nParameter name: count");
304
+ throw new Exception("The input must be non-negative (Parameter \'count\')");
304
305
  }
305
306
  if (count > array.length) {
306
- throw new Exception("count is greater than array length\\nParameter name: count");
307
+ throw new Exception("count is greater than array length (Parameter \'count\')");
307
308
  }
308
309
  if (count === 0) {
309
310
  return Helpers_allocateArrayFromCons(cons, 0);
@@ -761,7 +762,7 @@ export function zip3(array1, array2, array3) {
761
762
  }
762
763
  export function chunkBySize(chunkSize, array) {
763
764
  if (chunkSize < 1) {
764
- throw new Exception("The input must be positive.\\nParameter name: size");
765
+ throw new Exception("The input must be positive. (Parameter \'size\')");
765
766
  }
766
767
  const result = [];
767
768
  if (array.length > 0) {
@@ -777,7 +778,7 @@ export function chunkBySize(chunkSize, array) {
777
778
  }
778
779
  export function splitAt(index, array) {
779
780
  if ((index < 0) ? true : (index > array.length)) {
780
- throw new Exception((SR_indexOutOfBounds + "\\nParameter name: ") + "index");
781
+ throw new Exception(SR_indexOutOfBounds + " (Parameter \'index\')");
781
782
  }
782
783
  return [array.slice(0, (0 + index)), array.slice(index)];
783
784
  }
@@ -886,9 +887,9 @@ export function exactlyOne(array) {
886
887
  case 1:
887
888
  return item_2(0, array);
888
889
  case 0:
889
- throw new Exception("The input sequence was empty\\nParameter name: array");
890
+ throw new Exception("The input sequence was empty (Parameter \'array\')");
890
891
  default:
891
- throw new Exception("Input array too long\\nParameter name: array");
892
+ throw new Exception("Input array too long (Parameter \'array\')");
892
893
  }
893
894
  }
894
895
  export function tryExactlyOne(array) {
@@ -901,7 +902,7 @@ export function tryExactlyOne(array) {
901
902
  }
902
903
  export function head(array) {
903
904
  if (array.length === 0) {
904
- throw new Exception("The input array was empty\\nParameter name: array");
905
+ throw new Exception("The input array was empty (Parameter \'array\')");
905
906
  }
906
907
  else {
907
908
  return item_2(0, array);
@@ -917,13 +918,13 @@ export function tryHead(array) {
917
918
  }
918
919
  export function tail(array) {
919
920
  if (array.length === 0) {
920
- throw new Exception("Not enough elements\\nParameter name: array");
921
+ throw new Exception("Not enough elements (Parameter \'array\')");
921
922
  }
922
923
  return array.slice(1);
923
924
  }
924
925
  export function item(index, array) {
925
926
  if ((index < 0) ? true : (index >= array.length)) {
926
- throw new Exception("Index was outside the bounds of the array.\\nParameter name: index");
927
+ throw new Exception("Index was outside the bounds of the array. (Parameter \'index\')");
927
928
  }
928
929
  else {
929
930
  return array[index];
@@ -931,7 +932,7 @@ export function item(index, array) {
931
932
  }
932
933
  export function setItem(array, index, value) {
933
934
  if ((index < 0) ? true : (index >= array.length)) {
934
- throw new Exception("Index was outside the bounds of the array.\\nParameter name: index");
935
+ throw new Exception("Index was outside the bounds of the array. (Parameter \'index\')");
935
936
  }
936
937
  else {
937
938
  array[index] = value;
@@ -1069,7 +1070,7 @@ export function min(xs, comparer) {
1069
1070
  }
1070
1071
  export function average(array, averager) {
1071
1072
  if (array.length === 0) {
1072
- throw new Exception("The input array was empty\\nParameter name: array");
1073
+ throw new Exception("The input array was empty (Parameter \'array\')");
1073
1074
  }
1074
1075
  let total = averager.GetZero();
1075
1076
  for (let i = 0; i <= (array.length - 1); i++) {
@@ -1079,7 +1080,7 @@ export function average(array, averager) {
1079
1080
  }
1080
1081
  export function averageBy(projection, array, averager) {
1081
1082
  if (array.length === 0) {
1082
- throw new Exception("The input array was empty\\nParameter name: array");
1083
+ throw new Exception("The input array was empty (Parameter \'array\')");
1083
1084
  }
1084
1085
  let total = averager.GetZero();
1085
1086
  for (let i = 0; i <= (array.length - 1); i++) {
@@ -1101,7 +1102,7 @@ export function windowed(windowSize, source) {
1101
1102
  }
1102
1103
  export function splitInto(chunks, array) {
1103
1104
  if (chunks < 1) {
1104
- throw new Exception("The input must be positive.\\nParameter name: chunks");
1105
+ throw new Exception("The input must be positive. (Parameter \'chunks\')");
1105
1106
  }
1106
1107
  const result = [];
1107
1108
  if (array.length > 0) {
@@ -1143,7 +1144,7 @@ export function transpose(arrays, cons) {
1143
1144
  export function insertAt(index, y, xs, cons) {
1144
1145
  const len = xs.length | 0;
1145
1146
  if ((index < 0) ? true : (index > len)) {
1146
- throw new Exception((SR_indexOutOfBounds + "\\nParameter name: ") + "index");
1147
+ throw new Exception(SR_indexOutOfBounds + " (Parameter \'index\')");
1147
1148
  }
1148
1149
  const target = Helpers_allocateArrayFromCons(cons, len + 1);
1149
1150
  for (let i = 0; i <= (index - 1); i++) {
@@ -1158,7 +1159,7 @@ export function insertAt(index, y, xs, cons) {
1158
1159
  export function insertManyAt(index, ys, xs, cons) {
1159
1160
  const len = xs.length | 0;
1160
1161
  if ((index < 0) ? true : (index > len)) {
1161
- throw new Exception((SR_indexOutOfBounds + "\\nParameter name: ") + "index");
1162
+ throw new Exception(SR_indexOutOfBounds + " (Parameter \'index\')");
1162
1163
  }
1163
1164
  const ys_1 = Array.from(ys);
1164
1165
  const len2 = ys_1.length | 0;
@@ -1179,7 +1180,7 @@ export function randomShuffleInPlaceBy(randomizer, xs) {
1179
1180
  for (let i = len - 1; i >= 1; i--) {
1180
1181
  const r = randomizer();
1181
1182
  if ((r < 0) ? true : (r >= 1)) {
1182
- throw new Exception((SR_Arg_ArgumentOutOfRangeException + "\\nParameter name: ") + "randomizer");
1183
+ throw new Exception(SR_Arg_ArgumentOutOfRangeException + " (Parameter \'randomizer\')");
1183
1184
  }
1184
1185
  const j = ~~(r * (i + 1)) | 0;
1185
1186
  const tmp = item_2(i, xs);
@@ -1206,12 +1207,12 @@ export function randomShuffle(xs) {
1206
1207
  }
1207
1208
  export function randomChoiceBy(randomizer, xs) {
1208
1209
  if (isEmpty(xs)) {
1209
- throw new Exception((SR_inputSequenceEmpty + "\\nParameter name: ") + "source");
1210
+ throw new Exception(SR_inputSequenceEmpty + " (Parameter \'source\')");
1210
1211
  }
1211
1212
  const len = xs.length | 0;
1212
1213
  const r = randomizer();
1213
1214
  if ((r < 0) ? true : (r >= 1)) {
1214
- throw new Exception((SR_Arg_ArgumentOutOfRangeException + "\\nParameter name: ") + "randomizer");
1215
+ throw new Exception(SR_Arg_ArgumentOutOfRangeException + " (Parameter \'randomizer\')");
1215
1216
  }
1216
1217
  return item_2(~~(r * len), xs);
1217
1218
  }
@@ -1223,16 +1224,16 @@ export function randomChoice(xs) {
1223
1224
  }
1224
1225
  export function randomChoicesBy(randomizer, count, xs, cons) {
1225
1226
  if (count < 0) {
1226
- throw new Exception((SR_inputMustBeNonNegative + "\\nParameter name: ") + "count");
1227
+ throw new Exception(SR_inputMustBeNonNegative + " (Parameter \'count\')");
1227
1228
  }
1228
1229
  if ((count > 0) && isEmpty(xs)) {
1229
- throw new Exception((SR_inputSequenceEmpty + "\\nParameter name: ") + "source");
1230
+ throw new Exception(SR_inputSequenceEmpty + " (Parameter \'source\')");
1230
1231
  }
1231
1232
  const len = xs.length | 0;
1232
1233
  return initialize(count, (_arg) => {
1233
1234
  const r = randomizer();
1234
1235
  if ((r < 0) ? true : (r >= 1)) {
1235
- throw new Exception((SR_Arg_ArgumentOutOfRangeException + "\\nParameter name: ") + "randomizer");
1236
+ throw new Exception(SR_Arg_ArgumentOutOfRangeException + " (Parameter \'randomizer\')");
1236
1237
  }
1237
1238
  return item_2(~~(r * len), xs);
1238
1239
  }, cons);
@@ -1245,20 +1246,20 @@ export function randomChoices(count, xs, cons) {
1245
1246
  }
1246
1247
  export function randomSampleBy(randomizer, count, xs) {
1247
1248
  if (count < 0) {
1248
- throw new Exception((SR_inputMustBeNonNegative + "\\nParameter name: ") + "count");
1249
+ throw new Exception(SR_inputMustBeNonNegative + " (Parameter \'count\')");
1249
1250
  }
1250
1251
  const arr = copy(xs);
1251
1252
  const len = arr.length | 0;
1252
1253
  if ((len === 0) && (count > 0)) {
1253
- throw new Exception((SR_inputSequenceEmpty + "\\nParameter name: ") + "source");
1254
+ throw new Exception(SR_inputSequenceEmpty + " (Parameter \'source\')");
1254
1255
  }
1255
1256
  if (count > len) {
1256
- throw new Exception((SR_notEnoughElements + "\\nParameter name: ") + "count");
1257
+ throw new Exception(SR_notEnoughElements + " (Parameter \'count\')");
1257
1258
  }
1258
1259
  for (let i = 0; i <= (count - 1); i++) {
1259
1260
  const r = randomizer();
1260
1261
  if ((r < 0) ? true : (r >= 1)) {
1261
- throw new Exception((SR_Arg_ArgumentOutOfRangeException + "\\nParameter name: ") + "randomizer");
1262
+ throw new Exception(SR_Arg_ArgumentOutOfRangeException + " (Parameter \'randomizer\')");
1262
1263
  }
1263
1264
  const j = (i + ~~(r * (len - i))) | 0;
1264
1265
  const tmp = item_2(i, arr);
@@ -1275,7 +1276,7 @@ export function randomSample(count, xs) {
1275
1276
  }
1276
1277
  export function removeAt(index, xs) {
1277
1278
  if ((index < 0) ? true : (index >= xs.length)) {
1278
- throw new Exception((SR_indexOutOfBounds + "\\nParameter name: ") + "index");
1279
+ throw new Exception(SR_indexOutOfBounds + " (Parameter \'index\')");
1279
1280
  }
1280
1281
  let i = -1;
1281
1282
  return filter((_arg) => {
@@ -1307,14 +1308,14 @@ export function removeManyAt(index, count, xs) {
1307
1308
  }, xs);
1308
1309
  const status_1 = (((status === 0) && ((i + 1) === (index + count))) ? 1 : status) | 0;
1309
1310
  if (status_1 < 1) {
1310
- throw new Exception((SR_indexOutOfBounds + "\\nParameter name: ") + ((status_1 < 0) ? "index" : "count"));
1311
+ throw new Exception(SR_indexOutOfBounds + ((" (Parameter \'" + ((status_1 < 0) ? "index" : "count")) + "\')"));
1311
1312
  }
1312
1313
  return ys;
1313
1314
  }
1314
1315
  export function updateAt(index, y, xs, cons) {
1315
1316
  const len = xs.length | 0;
1316
1317
  if ((index < 0) ? true : (index >= len)) {
1317
- throw new Exception((SR_indexOutOfBounds + "\\nParameter name: ") + "index");
1318
+ throw new Exception(SR_indexOutOfBounds + " (Parameter \'index\')");
1318
1319
  }
1319
1320
  const target = Helpers_allocateArrayFromCons(cons, len);
1320
1321
  for (let i = 0; i <= (len - 1); i++) {
@@ -1325,7 +1326,7 @@ export function updateAt(index, y, xs, cons) {
1325
1326
  export function resize(xs, newSize, zero, cons) {
1326
1327
  let array = undefined, array_1 = undefined, start_2 = undefined, count_2 = undefined;
1327
1328
  if (newSize < 0) {
1328
- throw new Exception("The input must be non-negative.\\nParameter name: newSize");
1329
+ throw new Exception("The input must be non-negative. (Parameter \'newSize\')");
1329
1330
  }
1330
1331
  const zero_1 = defaultArg(zero, defaultOf());
1331
1332
  if (Operators_IsNull(xs.contents)) {
@@ -7,10 +7,6 @@ import { Exception } from "./Util.js";
7
7
  function emptyContinuation(_x) {
8
8
  // NOP
9
9
  }
10
- // see AsyncBuilder.Delay
11
- function delay(generator) {
12
- return protectedCont((ctx) => generator()(ctx));
13
- }
14
10
  // MakeAsync: body:(AsyncActivation<'T> -> AsyncReturn) -> Async<'T>
15
11
  export function makeAsync(body) {
16
12
  return body;
@@ -49,23 +45,50 @@ export function throwIfCancellationRequested(token) {
49
45
  }
50
46
  }
51
47
  export function startChild(computation, ms) {
52
- const promise = startAsPromise(computation);
53
- let promiseToRun = promise;
54
- if (ms) {
55
- // Race the computation against a timeout: whichever settles first wins.
56
- promiseToRun = new Promise((resolve, reject) => {
57
- const timeoutId = setTimeout(() => reject(TimeoutException_$ctor()), ms);
58
- promise.then(value => { clearTimeout(timeoutId); resolve(value); }, error => { clearTimeout(timeoutId); reject(error); });
59
- });
60
- }
61
- // JS Promises are hot, computation has already started
62
- // but we delay returning the result
63
- return protectedCont((ctx) => protectedReturn(awaitPromise(promiseToRun))(ctx));
48
+ return protectedCont((ctx) => {
49
+ // Share the parent's cancellation token so cancelling the parent
50
+ // cancels the child, like .NET Async.StartChild
51
+ const promise = startAsPromise(computation, ctx.cancelToken);
52
+ let promiseToRun = promise;
53
+ if (ms) {
54
+ // Race the computation against a timeout: whichever settles first wins.
55
+ promiseToRun = new Promise((resolve, reject) => {
56
+ const timeoutId = setTimeout(() => reject(TimeoutException_$ctor()), ms);
57
+ promise.then(value => { clearTimeout(timeoutId); resolve(value); }, error => { clearTimeout(timeoutId); reject(error); });
58
+ });
59
+ }
60
+ // Prevent an unhandled rejection when the child is cancelled or fails
61
+ // while nobody awaits it (in F# an unobserved child's cancellation or
62
+ // failure is simply not propagated). awaitPromise attaches its own
63
+ // handlers to the same promise, so awaiting still observes the result.
64
+ promiseToRun.catch(emptyContinuation);
65
+ // JS Promises are hot, computation has already started
66
+ // but we delay returning the result
67
+ protectedReturn(awaitPromise(promiseToRun))(ctx);
68
+ });
64
69
  }
65
70
  export function awaitPromise(p) {
66
71
  return fromContinuations((conts) => p.then(conts[0]).catch((err) => (err instanceof OperationCanceledException
67
72
  ? conts[2] : conts[1])(err)));
68
73
  }
74
+ export function awaitEvent(event, cancelAction) {
75
+ return protectedCont((ctx) => {
76
+ let tokenId;
77
+ const handler = ((_sender, arg) => {
78
+ ctx.cancelToken.removeListener(tokenId);
79
+ event.RemoveHandler(handler);
80
+ ctx.onSuccess(arg);
81
+ });
82
+ tokenId = ctx.cancelToken.addListener(() => {
83
+ event.RemoveHandler(handler);
84
+ if (cancelAction != null) {
85
+ cancelAction();
86
+ }
87
+ ctx.onCancel(new OperationCanceledException());
88
+ });
89
+ event.AddHandler(handler);
90
+ });
91
+ }
69
92
  export function cancellationToken() {
70
93
  return protectedCont((ctx) => ctx.onSuccess(ctx.cancelToken));
71
94
  }
@@ -88,17 +111,19 @@ export function ignore(computation) {
88
111
  return protectedBind(computation, (_x) => protectedReturn(void 0));
89
112
  }
90
113
  export function parallel(computations) {
91
- return delay(() => awaitPromise(Promise.all(Array.from(computations, (w) => startAsPromise(w)))));
114
+ // Children share the parent's cancellation token, like .NET Async.Parallel
115
+ return protectedCont((ctx) => awaitPromise(Promise.all(Array.from(computations, (w) => startAsPromise(w, ctx.cancelToken))))(ctx));
92
116
  }
93
117
  export function sequential(computations) {
94
- function _sequential(computations) {
118
+ function _sequential(computations, cancelToken) {
95
119
  let pr = Promise.resolve([]);
96
120
  for (const c of computations) {
97
- pr = pr.then(results => startAsPromise(c).then(r => results.concat([r])));
121
+ pr = pr.then(results => startAsPromise(c, cancelToken).then(r => results.concat([r])));
98
122
  }
99
123
  return pr;
100
124
  }
101
- return delay(() => awaitPromise(_sequential(computations)));
125
+ // Children share the parent's cancellation token, like .NET Async.Sequential
126
+ return protectedCont((ctx) => awaitPromise(_sequential(computations, ctx.cancelToken))(ctx));
102
127
  }
103
128
  export function sleep(millisecondsDueTime) {
104
129
  return protectedCont((ctx) => {
@@ -121,10 +146,14 @@ export function startImmediate(computation, cancellationToken) {
121
146
  }
122
147
  export function startWithContinuations(computation, continuation, exceptionContinuation, cancellationContinuation, cancelToken) {
123
148
  const trampoline = new Trampoline();
149
+ // Mark the computation completed as soon as a terminal continuation is entered
150
+ // so protectedCont lets exceptions from continuation code propagate instead of
151
+ // routing them to onError (see Trampoline.completed).
152
+ const done = (cont) => (x) => { trampoline.completed = true; return cont(x); };
124
153
  computation({
125
- onSuccess: continuation ? continuation : emptyContinuation,
126
- onError: exceptionContinuation,
127
- onCancel: cancellationContinuation,
154
+ onSuccess: done(continuation ? continuation : emptyContinuation),
155
+ onError: done(exceptionContinuation),
156
+ onCancel: done(cancellationContinuation),
128
157
  cancelToken: cancelToken ? cancelToken : defaultCancellationToken,
129
158
  trampoline,
130
159
  });
@@ -47,6 +47,7 @@ export class Trampoline {
47
47
  }
48
48
  constructor() {
49
49
  this.callCount = 0;
50
+ this.completed = false;
50
51
  }
51
52
  incrementAndCheck() {
52
53
  return this.callCount++ > Trampoline.maxTrampolineCallCount;
@@ -67,6 +68,9 @@ export function protectedCont(f) {
67
68
  f(ctx);
68
69
  }
69
70
  catch (err) {
71
+ if (ctx.trampoline.completed) {
72
+ throw err;
73
+ }
70
74
  ctx.onError(ensureErrorOrException(err));
71
75
  }
72
76
  });
@@ -76,6 +80,13 @@ export function protectedCont(f) {
76
80
  f(ctx);
77
81
  }
78
82
  catch (err) {
83
+ // Once a terminal continuation has run the computation is complete, so
84
+ // an exception from user continuation code must propagate rather than be
85
+ // routed to onError (which would resolve the computation a second time,
86
+ // e.g. a succeeded try/with body re-entering its with handler).
87
+ if (ctx.trampoline.completed) {
88
+ throw err;
89
+ }
79
90
  ctx.onError(ensureErrorOrException(err));
80
91
  }
81
92
  }
@@ -85,12 +96,18 @@ export function protectedBind(computation, binder) {
85
96
  return protectedCont((ctx) => {
86
97
  computation({
87
98
  onSuccess: (x) => {
99
+ // Only guard the binder evaluation itself: the resulting computation
100
+ // is protected on its own, and re-catching what it throws would
101
+ // route continuation exceptions back into onError (double-resolve).
102
+ let bound;
88
103
  try {
89
- binder(x)(ctx);
104
+ bound = binder(x);
90
105
  }
91
106
  catch (err) {
92
107
  ctx.onError(ensureErrorOrException(err));
108
+ return;
93
109
  }
110
+ bound(ctx);
94
111
  },
95
112
  onError: ctx.onError,
96
113
  onCancel: ctx.onCancel,
@@ -155,12 +172,16 @@ export class AsyncBuilder {
155
172
  cancelToken: ctx.cancelToken,
156
173
  trampoline: ctx.trampoline,
157
174
  onError: (ex) => {
175
+ // See protectedBind: only guard the handler evaluation itself.
176
+ let handled;
158
177
  try {
159
- catchHandler(ex)(ctx);
178
+ handled = catchHandler(ex);
160
179
  }
161
180
  catch (err) {
162
181
  ctx.onError(ensureErrorOrException(err));
182
+ return;
163
183
  }
184
+ handled(ctx);
164
185
  },
165
186
  });
166
187
  });
@@ -99,12 +99,12 @@ export function toIntN_unchecked(bits, x, signed) {
99
99
  return signed ? BigInt.asIntN(bits, x) : BigInt.asUintN(bits, x);
100
100
  }
101
101
  export function toIntN(bits, x, signed) {
102
- let higher_bits = abs(x) >> BigInt(bits);
103
- if (higher_bits !== 0n) {
102
+ const truncated = signed ? BigInt.asIntN(bits, x) : BigInt.asUintN(bits, x);
103
+ if (truncated !== x) {
104
104
  const s = signed ? "a signed" : "an unsigned";
105
105
  throw new Exception(`Value was either too large or too small for ${s} ${bits}-bit integer.`);
106
106
  }
107
- return signed ? BigInt.asIntN(bits, x) : BigInt.asUintN(bits, x);
107
+ return truncated;
108
108
  }
109
109
  export function toInt8(x) { return Number(toIntN(8, x, true)); }
110
110
  export function toUInt8(x) { return Number(toIntN(8, x, false)); }
@@ -136,6 +136,9 @@ export function toFloat64(x) { return Number(x); }
136
136
  export function toDecimal(x) {
137
137
  const isNegative = x < zero;
138
138
  const bits = abs(x);
139
+ if ((bits >> 96n) !== zero) {
140
+ throw new Exception("Value was either too large or too small for a Decimal.");
141
+ }
139
142
  const low = Number(BigInt.asUintN(32, bits));
140
143
  const mid = Number(BigInt.asUintN(32, bits >> 32n));
141
144
  const high = Number(BigInt.asUintN(32, bits >> 64n));
@@ -178,6 +181,8 @@ export function divRem(x, y, out) {
178
181
  }
179
182
  }
180
183
  export function greatestCommonDivisor(x, y) {
184
+ x = abs(x);
185
+ y = abs(y);
181
186
  while (y > zero) {
182
187
  const q = x / y;
183
188
  const r = x - q * y;
@@ -186,8 +191,16 @@ export function greatestCommonDivisor(x, y) {
186
191
  }
187
192
  return x;
188
193
  }
194
+ // Number of bits in the binary representation of x (x must be positive)
195
+ function bitLength(x) {
196
+ const hex = x.toString(16);
197
+ return (hex.length - 1) * 4 + (32 - Math.clz32(fromHexCode(hex.charCodeAt(0))));
198
+ }
189
199
  export function getBitLength(x) {
190
- return fromFloat64(x === zero ? 1 : log2(abs(x)) + 1);
200
+ if (x < zero) {
201
+ x = -x - one; // two's complement bit length excluding the sign bit
202
+ }
203
+ return x === zero ? zero : BigInt(bitLength(x));
191
204
  }
192
205
  export function log2(x) {
193
206
  const n = Number(x);
@@ -219,7 +232,10 @@ export function log(x, base) {
219
232
  return log2(x) / Math.log2(base);
220
233
  }
221
234
  export function ilog2(x) {
222
- return BigInt(log2(x));
235
+ if (x < zero) {
236
+ throw new Exception("Value must be non-negative.");
237
+ }
238
+ return x === zero ? zero : BigInt(bitLength(x) - 1);
223
239
  }
224
240
  // export function copySign
225
241
  // export function createChecked
@@ -248,35 +264,20 @@ function fromHexCode(code) {
248
264
  }
249
265
  function toSignedBytes(x, isBigEndian) {
250
266
  const isNeg = x < 0n;
251
- if (isNeg) {
252
- const len = log2(-x);
253
- const bits = len + (8 - len % 8);
254
- const pow2 = (1n << BigInt(bits));
255
- x = x + pow2; // two's complement
256
- }
257
- const hex = x.toString(16);
258
- const len = hex.length;
259
- const odd = len % 2;
260
- const first = hex.charCodeAt(0);
261
- const isLow = 48 <= first && first <= 55; // 0..7
262
- const start = (isNeg && isLow) || (!isNeg && !isLow) ? 1 : 0;
263
- const bytes = new Uint8Array(start + (len + odd) / 2);
264
- const inc = isBigEndian ? 1 : -1;
265
- let pos = isBigEndian ? 0 : bytes.length - 1;
266
- if (start > 0) {
267
- bytes[pos] = isNeg ? 255 : 0;
268
- pos += inc;
269
- }
270
- if (odd > 0) {
271
- bytes[pos] = fromHexCode(first);
272
- pos += inc;
267
+ const sentinel = isNeg ? -1n : 0n;
268
+ const bytes = []; // little-endian
269
+ do {
270
+ bytes.push(Number(BigInt.asUintN(8, x)));
271
+ x = x >> 8n;
272
+ } while (x !== sentinel);
273
+ // extra byte if the top byte's sign bit would misrepresent the sign
274
+ if (isNeg !== (bytes[bytes.length - 1] > 127)) {
275
+ bytes.push(isNeg ? 255 : 0);
273
276
  }
274
- for (let i = odd; i < len; i += 2, pos += inc) {
275
- const a = fromHexCode(hex.charCodeAt(i));
276
- const b = fromHexCode(hex.charCodeAt(i + 1));
277
- bytes[pos] = (a << 4) | b;
277
+ if (isBigEndian) {
278
+ bytes.reverse();
278
279
  }
279
- return bytes;
280
+ return new Uint8Array(bytes);
280
281
  }
281
282
  function fromSignedBytes(bytes, isBigEndian) {
282
283
  if (bytes == null) {
@@ -77,7 +77,7 @@ export function doubleToInt64Bits(value) {
77
77
  export function toBoolean(bytes, offset) {
78
78
  const array = ArrayBuffer.isView(bytes) ? bytes : Uint8Array.from(bytes);
79
79
  const view = new DataView(array.buffer, array.byteOffset, array.byteLength);
80
- return view.getUint8(offset) === 1 ? true : false;
80
+ return view.getUint8(offset) !== 0;
81
81
  }
82
82
  export function toChar(bytes, offset) {
83
83
  const array = ArrayBuffer.isView(bytes) ? bytes : Uint8Array.from(bytes);
@@ -134,5 +134,5 @@ export function toString(bytes, offset, count) {
134
134
  else if (offset != null) {
135
135
  buffer = buffer.subarray(offset);
136
136
  }
137
- return Array.from(buffer).map((b) => ("0" + b.toString(16)).slice(-2)).join("-");
137
+ return Array.from(buffer).map((b) => ("0" + b.toString(16)).slice(-2).toUpperCase()).join("-");
138
138
  }