@abaplint/runtime 2.13.92 → 2.13.94

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 (40) hide show
  1. package/build/src/builtin/_extremum.d.ts +9 -0
  2. package/build/src/builtin/_extremum.js +75 -0
  3. package/build/src/builtin/escape.d.ts +2 -2
  4. package/build/src/builtin/escape.js +29 -4
  5. package/build/src/builtin/nmax.d.ts +1 -2
  6. package/build/src/builtin/nmax.js +3 -28
  7. package/build/src/builtin/nmin.d.ts +1 -2
  8. package/build/src/builtin/nmin.js +3 -28
  9. package/build/src/builtin/round.d.ts +14 -5
  10. package/build/src/builtin/round.js +69 -21
  11. package/build/src/compare/eq.js +20 -3
  12. package/build/src/compare/gt.js +8 -2
  13. package/build/src/compare/in.d.ts +3 -1
  14. package/build/src/compare/in.js +35 -18
  15. package/build/src/expand_in.js +66 -28
  16. package/build/src/operators/_bit_operations.d.ts +1 -5
  17. package/build/src/operators/_bit_operations.js +24 -23
  18. package/build/src/operators/bit-and.js +1 -11
  19. package/build/src/operators/bit-or.js +1 -11
  20. package/build/src/operators/bit-xor.js +1 -11
  21. package/build/src/primary_key.d.ts +2 -0
  22. package/build/src/primary_key.js +49 -0
  23. package/build/src/statements/concatenate.js +13 -3
  24. package/build/src/statements/create_data.js +14 -2
  25. package/build/src/statements/delete_database.js +15 -0
  26. package/build/src/statements/delete_internal.d.ts +1 -0
  27. package/build/src/statements/delete_internal.js +14 -3
  28. package/build/src/statements/describe.js +17 -1
  29. package/build/src/statements/insert_database.d.ts +1 -0
  30. package/build/src/statements/insert_database.js +11 -0
  31. package/build/src/statements/read_table.js +93 -7
  32. package/build/src/statements/shift.js +22 -4
  33. package/build/src/statements/sort.js +22 -0
  34. package/build/src/statements/write.js +9 -6
  35. package/build/src/template_formatting.js +18 -4
  36. package/build/src/types/date.js +6 -0
  37. package/build/src/types/hex.js +7 -4
  38. package/build/src/types/integer.js +5 -8
  39. package/build/src/types/table.js +11 -1
  40. package/package.json +1 -1
@@ -3,6 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.templateFormatting = templateFormatting;
4
4
  const alpha_1 = require("./alpha");
5
5
  const types_1 = require("./types");
6
+ /** DECIMALS for a decimal number: its decimal digits are rounded, half away
7
+ * from zero, the way ABAP rounds commercially - 2.675 gives 2.68, where
8
+ * toFixed( ) on the nearest binary float gives 2.67 */
9
+ function decimalsOfDecimal(value, decimals) {
10
+ const shift = (x, places) => {
11
+ const [mantissa, exponent] = (x + "").split("e");
12
+ return Number(mantissa + "e" + (Number(exponent || 0) + places));
13
+ };
14
+ const rounded = shift(Math.round(shift(Math.abs(value), decimals)), -decimals);
15
+ return (value < 0 && rounded !== 0 ? "-" : "") + rounded.toFixed(decimals);
16
+ }
6
17
  function templateFormatting(source, options) {
7
18
  let text = "";
8
19
  if (source instanceof types_1.FieldSymbol) {
@@ -22,7 +33,10 @@ function templateFormatting(source, options) {
22
33
  }
23
34
  else if (source instanceof types_1.DecFloat34) {
24
35
  const raw = source.getRaw();
25
- if (Number.isInteger(raw)) {
36
+ if (options?.decimals !== undefined) {
37
+ text = decimalsOfDecimal(raw, options.decimals);
38
+ }
39
+ else if (Number.isInteger(raw)) {
26
40
  text = raw.toFixed(0);
27
41
  }
28
42
  else {
@@ -43,7 +57,7 @@ function templateFormatting(source, options) {
43
57
  }
44
58
  }
45
59
  else if (source instanceof types_1.Packed) {
46
- if (options?.decimals) {
60
+ if (options?.decimals !== undefined) {
47
61
  text = source.toFixed(options.decimals);
48
62
  }
49
63
  else {
@@ -127,10 +141,10 @@ function templateFormatting(source, options) {
127
141
  else if (options.width) {
128
142
  text = text.trimEnd().padEnd(options.width, " ");
129
143
  }
130
- else if (options.decimals && source instanceof types_1.Integer) {
144
+ else if (options.decimals !== undefined && source instanceof types_1.Integer) {
131
145
  text = source.get().toFixed(options.decimals);
132
146
  }
133
- else if (options.decimals && source instanceof types_1.Float) {
147
+ else if (options.decimals !== undefined && source instanceof types_1.Float) {
134
148
  text = source.getRaw().toFixed(options.decimals);
135
149
  }
136
150
  }
@@ -32,7 +32,13 @@ class Date {
32
32
  else if (value instanceof float_1.Float) {
33
33
  this.set(Math.round(value.getRaw()));
34
34
  }
35
+ else if (value instanceof string_1.String) {
36
+ // an empty string is the initial date, a shorter one is filled with blanks
37
+ const str = value.get();
38
+ this.value = str === "" ? "00000000" : str;
39
+ }
35
40
  else if (typeof value === "string") {
41
+ // raw character results, eg. from CONCATENATE, are filled with blanks
36
42
  this.value = value;
37
43
  }
38
44
  else {
@@ -6,7 +6,7 @@ const float_1 = require("./float");
6
6
  const xstring_1 = require("./xstring");
7
7
  const throw_error_1 = require("../throw_error");
8
8
  const integer8_1 = require("./integer8");
9
- const REGEXP = /^(?![A-F0-9])/;
9
+ const HEX_PREFIX = /^[A-F0-9]*/;
10
10
  class Hex {
11
11
  value;
12
12
  length;
@@ -73,9 +73,12 @@ class Hex {
73
73
  return this.set(v);
74
74
  }
75
75
  else {
76
- this.value = v;
77
- if (this.value.match(REGEXP)) {
78
- this.value = "";
76
+ // c -> x: the leading hexadecimal digits, upper case only, and a
77
+ // trailing half byte padded with 0; the first other character ends
78
+ // the conversion, so "ABG1" is AB, "0a1B" is 00
79
+ this.value = HEX_PREFIX.exec(v)[0];
80
+ if (this.value.length % 2 === 1) {
81
+ this.value += "0";
79
82
  }
80
83
  }
81
84
  }
@@ -93,14 +93,11 @@ class Integer {
93
93
  this.set(roundHalfAwayFromZero(value.getRaw()));
94
94
  }
95
95
  else if (value instanceof hex_1.Hex || value instanceof xstring_1.XString || value instanceof hex_uint8_1.HexUInt8) {
96
- const hex = value.get();
97
- let num = parseInt(hex, 16);
98
- // handle two complement, the first bit is the sign
99
- if (hex.length >= 8) {
100
- const maxVal = Math.pow(2, hex.length / 2 * 8);
101
- if (num > maxVal / 2 - 1) {
102
- num = num - maxVal;
103
- }
96
+ // the last four bytes, 00 on the left, as a signed integer; an empty xstring is 0
97
+ const hex = value.get().slice(-8);
98
+ let num = hex === "" ? 0 : parseInt(hex, 16);
99
+ if (hex.length === 8 && num > 0x7FFFFFFF) {
100
+ num = num - 0x100000000;
104
101
  }
105
102
  this.set(num);
106
103
  }
@@ -550,8 +550,18 @@ class Table {
550
550
  return val;
551
551
  }
552
552
  }
553
- /* appends and returns this */
553
+ /* appends and returns this - how VALUE #( ) builds a table, row by row.
554
+ * A sorted table gets each row at its sorted place, as INSERT ... INTO
555
+ * TABLE puts it: pushed, it was in insertion order until something
556
+ * assigned it, so a VALUE #( ) handed straight to a method or looped over
557
+ * was a SORTED table unsorted, and every binary search on it could miss.
558
+ * A duplicate of a unique key is kept, as before */
554
559
  appendThis(item) {
560
+ const primary = this.getOptions()?.primaryKey;
561
+ if (primary?.type === TableAccessType.sorted && !(item instanceof data_reference_1.DataReference)) {
562
+ this.insertSorted(item, (a, b) => (0, sort_1.compareRows)(a, b, primary.keyFields), false);
563
+ return this;
564
+ }
555
565
  this.append(item);
556
566
  return this;
557
567
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/runtime",
3
- "version": "2.13.92",
3
+ "version": "2.13.94",
4
4
  "description": "Transpiler - Runtime",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/src/index.d.ts",