@abaplint/runtime 2.13.37 → 2.13.39
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.
|
@@ -19,16 +19,7 @@ function find(input, options) {
|
|
|
19
19
|
abap.builtin.sy.get().subrc.set(0);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
s =
|
|
23
|
-
s = s.replace(/\[/g, "\\[");
|
|
24
|
-
s = s.replace(/\]/g, "\\]");
|
|
25
|
-
s = s.replace(/\?/g, "\\?");
|
|
26
|
-
s = s.replace(/\(/g, "\\(");
|
|
27
|
-
s = s.replace(/\)/g, "\\)");
|
|
28
|
-
s = s.replace(/\./g, "\\.");
|
|
29
|
-
s = s.replace(/\|/g, "\\|");
|
|
30
|
-
s = s.replace(/\*/g, "\\*");
|
|
31
|
-
s = s.replace(/\+/g, "\\+");
|
|
22
|
+
s = abap_regex_1.ABAPRegExp.escapeRegExp(s);
|
|
32
23
|
let flags = "g";
|
|
33
24
|
if (options.ignoringCase === true) {
|
|
34
25
|
flags += "i";
|
|
@@ -44,14 +44,13 @@ class WriteStatement {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
else if (source instanceof types_1.Packed) {
|
|
47
|
-
let num = source.get();
|
|
48
|
-
let decimals = source.getDecimals();
|
|
49
47
|
if (NO_DEICMAL_CURRENCIES.includes(options?.currency?.get().trimEnd() || "")) {
|
|
50
48
|
// todo: more work needed here,
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
result = (source.get() * 100).toFixed(0).replace(".", ",");
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
result = source.toFixed(source.getDecimals()).replace(".", ",");
|
|
53
53
|
}
|
|
54
|
-
result = num.toFixed(decimals).replace(".", ",");
|
|
55
54
|
right = true;
|
|
56
55
|
}
|
|
57
56
|
else {
|
|
@@ -44,10 +44,10 @@ function templateFormatting(source, options) {
|
|
|
44
44
|
}
|
|
45
45
|
else if (source instanceof types_1.Packed) {
|
|
46
46
|
if (options?.decimals) {
|
|
47
|
-
text = source.
|
|
47
|
+
text = source.toFixed(options.decimals);
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
|
-
text = source.
|
|
50
|
+
text = source.toFixed(source.getDecimals());
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
@@ -11,10 +11,12 @@ export declare class Packed implements INumeric {
|
|
|
11
11
|
});
|
|
12
12
|
clone(): Packed;
|
|
13
13
|
getQualifiedName(): string | undefined;
|
|
14
|
-
private
|
|
14
|
+
private numberToScaled;
|
|
15
|
+
private stringToScaled;
|
|
15
16
|
set(value: INumeric | number | string): this;
|
|
16
17
|
getLength(): number;
|
|
17
18
|
getDecimals(): number;
|
|
19
|
+
toFixed(decimals: number): string;
|
|
18
20
|
clear(): void;
|
|
19
21
|
get(): number;
|
|
20
22
|
}
|
|
@@ -5,14 +5,41 @@ const float_1 = require("./float");
|
|
|
5
5
|
const throw_error_1 = require("../throw_error");
|
|
6
6
|
const integer8_1 = require("./integer8");
|
|
7
7
|
const digits = new RegExp(/^\s*-?\+?\d*\.?\d*(?:E[+-]?\d+)? *$/i);
|
|
8
|
+
function pow10(exp) {
|
|
9
|
+
return 10n ** BigInt(exp);
|
|
10
|
+
}
|
|
11
|
+
// rescale a non-negative magnitude from fromScale to toScale decimal places,
|
|
12
|
+
// rounding half away from zero
|
|
13
|
+
function rescale(mag, fromScale, toScale) {
|
|
14
|
+
if (toScale >= fromScale) {
|
|
15
|
+
return mag * pow10(toScale - fromScale);
|
|
16
|
+
}
|
|
17
|
+
const div = pow10(fromScale - toScale);
|
|
18
|
+
const q = mag / div;
|
|
19
|
+
const r = mag % div;
|
|
20
|
+
return r * 2n >= div ? q + 1n : q;
|
|
21
|
+
}
|
|
22
|
+
// format a non-negative magnitude at the given scale as a decimal string
|
|
23
|
+
function formatMag(mag, scale) {
|
|
24
|
+
let s = mag.toString();
|
|
25
|
+
if (scale === 0) {
|
|
26
|
+
return s;
|
|
27
|
+
}
|
|
28
|
+
while (s.length <= scale) {
|
|
29
|
+
s = "0" + s;
|
|
30
|
+
}
|
|
31
|
+
const intPart = s.slice(0, s.length - scale);
|
|
32
|
+
const fracPart = s.slice(s.length - scale);
|
|
33
|
+
return intPart + "." + fracPart;
|
|
34
|
+
}
|
|
8
35
|
class Packed {
|
|
9
|
-
//
|
|
36
|
+
// value holds the number scaled by 10^decimals, as a bigint, to keep full precision
|
|
10
37
|
value;
|
|
11
38
|
length;
|
|
12
39
|
decimals;
|
|
13
40
|
qualifiedName;
|
|
14
41
|
constructor(input) {
|
|
15
|
-
this.value =
|
|
42
|
+
this.value = 0n;
|
|
16
43
|
this.length = 666;
|
|
17
44
|
if (input?.length) {
|
|
18
45
|
this.length = input.length;
|
|
@@ -31,29 +58,60 @@ class Packed {
|
|
|
31
58
|
getQualifiedName() {
|
|
32
59
|
return this.qualifiedName;
|
|
33
60
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return
|
|
61
|
+
numberToScaled(value) {
|
|
62
|
+
const factor = Math.pow(10, this.decimals);
|
|
63
|
+
return BigInt(Math.round(value * factor));
|
|
64
|
+
}
|
|
65
|
+
stringToScaled(input) {
|
|
66
|
+
let str = input.trim();
|
|
67
|
+
let negative = false;
|
|
68
|
+
while (str.length > 0 && (str[0] === "+" || str[0] === "-")) {
|
|
69
|
+
if (str[0] === "-") {
|
|
70
|
+
negative = true;
|
|
71
|
+
}
|
|
72
|
+
str = str.slice(1);
|
|
73
|
+
}
|
|
74
|
+
if (/[eE]/.test(str)) {
|
|
75
|
+
// scientific notation, fall back to floating point parsing
|
|
76
|
+
return this.numberToScaled(parseFloat((negative ? "-" : "") + str));
|
|
77
|
+
}
|
|
78
|
+
let intPart = str;
|
|
79
|
+
let fracPart = "";
|
|
80
|
+
const dot = str.indexOf(".");
|
|
81
|
+
if (dot >= 0) {
|
|
82
|
+
intPart = str.slice(0, dot);
|
|
83
|
+
fracPart = str.slice(dot + 1);
|
|
84
|
+
}
|
|
85
|
+
if (intPart === "") {
|
|
86
|
+
intPart = "0";
|
|
87
|
+
}
|
|
88
|
+
const kept = fracPart.slice(0, this.decimals).padEnd(this.decimals, "0");
|
|
89
|
+
let scaled = BigInt(intPart + kept);
|
|
90
|
+
// round half up based on the first dropped fractional digit
|
|
91
|
+
if (fracPart.length > this.decimals && fracPart[this.decimals] >= "5") {
|
|
92
|
+
scaled += 1n;
|
|
93
|
+
}
|
|
94
|
+
return negative ? -scaled : scaled;
|
|
37
95
|
}
|
|
38
96
|
set(value) {
|
|
39
97
|
if (typeof value === "number") {
|
|
40
|
-
this.value = value;
|
|
98
|
+
this.value = this.numberToScaled(value);
|
|
41
99
|
}
|
|
42
100
|
else if (typeof value === "string") {
|
|
43
101
|
if (value.trim().length === 0) {
|
|
44
|
-
this.value =
|
|
102
|
+
this.value = 0n;
|
|
45
103
|
return this;
|
|
46
104
|
}
|
|
47
105
|
else if (digits.test(value) === false) {
|
|
48
106
|
(0, throw_error_1.throwError)("CX_SY_CONVERSION_NO_NUMBER");
|
|
49
107
|
}
|
|
50
|
-
this.value = this.
|
|
108
|
+
this.value = this.stringToScaled(value);
|
|
51
109
|
}
|
|
52
110
|
else if (value instanceof integer8_1.Integer8) {
|
|
53
|
-
this.value =
|
|
111
|
+
this.value = value.get() * pow10(this.decimals);
|
|
54
112
|
}
|
|
55
113
|
else if (value instanceof float_1.Float) {
|
|
56
|
-
this.value = this.
|
|
114
|
+
this.value = this.numberToScaled(value.getRaw());
|
|
57
115
|
}
|
|
58
116
|
else {
|
|
59
117
|
this.set(value.get());
|
|
@@ -66,11 +124,20 @@ class Packed {
|
|
|
66
124
|
getDecimals() {
|
|
67
125
|
return this.decimals;
|
|
68
126
|
}
|
|
127
|
+
// returns the value as a fixed decimal string with the given number of
|
|
128
|
+
// decimals, keeping full precision (unlike get() which is limited to double)
|
|
129
|
+
toFixed(decimals) {
|
|
130
|
+
const negative = this.value < 0n;
|
|
131
|
+
const mag = negative ? -this.value : this.value;
|
|
132
|
+
const scaled = rescale(mag, this.decimals, decimals);
|
|
133
|
+
const formatted = formatMag(scaled, decimals);
|
|
134
|
+
return (negative ? "-" : "") + formatted;
|
|
135
|
+
}
|
|
69
136
|
clear() {
|
|
70
|
-
this.value =
|
|
137
|
+
this.value = 0n;
|
|
71
138
|
}
|
|
72
139
|
get() {
|
|
73
|
-
return this.value;
|
|
140
|
+
return Number(this.value) / Math.pow(10, this.decimals);
|
|
74
141
|
}
|
|
75
142
|
}
|
|
76
143
|
exports.Packed = Packed;
|
|
@@ -45,9 +45,9 @@ class String {
|
|
|
45
45
|
this.value = value.getCharacter().trimEnd();
|
|
46
46
|
}
|
|
47
47
|
else if (value instanceof packed_1.Packed) {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
this.value
|
|
48
|
+
const fixed = value.toFixed(value.getDecimals());
|
|
49
|
+
const lv_sign = fixed.startsWith("-") ? "-" : " ";
|
|
50
|
+
this.value = (fixed.startsWith("-") ? fixed.slice(1) : fixed) + lv_sign;
|
|
51
51
|
}
|
|
52
52
|
else if (value instanceof integer_1.Integer) {
|
|
53
53
|
const lv_sign = value.get() >= 0 ? " " : "-";
|