Skip to content

Commit 820678c

Browse files
committed
Fix support for scientific notation in latch spec tests
1 parent 4f28bbc commit 820678c

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

tests/latch/src/util/spec.util.ts

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ export function parseResult(input: string): WASM.Value | undefined {
2121
let value;
2222
delta = consume(input, cursor, /^[^)]*/d);
2323
if (type === WASM.Type.f32 || type === WASM.Type.f64) {
24-
value = parseHexFloat(input.slice(cursor, cursor + delta));
24+
value = parseFloat(input.slice(cursor, cursor + delta));
2525
} else {
26-
value = parseInteger(input.slice(cursor, cursor + delta));
26+
const bytes = type === WASM.Type.i64 ? 8 : 4;
27+
value = parseInteger(input.slice(cursor, cursor + delta), bytes);
2728
}
2829

2930
if (value === undefined) {
@@ -51,9 +52,10 @@ export function parseArguments(input: string, index: Cursor): WASM.Value[] {
5152
delta = consume(input, cursor, /^[^)]*/d);
5253
let maybe: number | undefined;
5354
if (type === WASM.Type.f32 || type === WASM.Type.f64) {
54-
maybe = parseHexFloat(input.slice(cursor, cursor + delta));
55+
maybe = parseFloat(input.slice(cursor, cursor + delta));
5556
} else {
56-
maybe = parseInteger(input.slice(cursor, cursor + delta));
57+
const bytes = type === WASM.Type.i64 ? 8 : 4;
58+
maybe = parseInteger(input.slice(cursor, cursor + delta), bytes);
5759
}
5860

5961
if (maybe !== undefined) {
@@ -97,7 +99,7 @@ function sign(integer: number): number {
9799
return Math.sign(integer) || 1;
98100
}
99101

100-
function parseHexFloat(input: string): number {
102+
function parseFloat(input: string): number {
101103
if (input.includes('-inf')) {
102104
return -Infinity;
103105
}
@@ -106,8 +108,17 @@ function parseHexFloat(input: string): number {
106108
return Infinity;
107109
}
108110

109-
const radix: number = input.includes('0x') ? 16 : 10;
110-
let base: string = input, mantissa, exponent = 0;
111+
if (input.includes('0x')) {
112+
return parseHexFloat(input);
113+
}
114+
115+
return Number(input);
116+
}
117+
118+
function parseHexFloat(input: string): number {
119+
const radix = 16;
120+
let base: string = input;
121+
let exponent = 0;
111122

112123
const splitIndex = input.indexOf('p');
113124
if (splitIndex !== -1) {
@@ -116,6 +127,8 @@ function parseHexFloat(input: string): number {
116127
}
117128

118129
const dotIndex = base.indexOf('.');
130+
let mantissa: number;
131+
119132
if (dotIndex !== -1) {
120133
const [integer, fractional] = base.split('.').map(hexStr => parseInt(hexStr, radix));
121134
const fraction = fractional / Math.pow(radix, base.length - dotIndex - 1);
@@ -131,12 +144,22 @@ function parseInteger(hex: string, bytes: number = 4): number {
131144
if (!hex.includes('0x')) {
132145
return parseInt(hex);
133146
}
134-
const mask = parseInt('0x80' + '00'.repeat(bytes - 1), 16);
135-
let integer = parseInt(hex, 16);
136-
if (integer >= mask) {
137-
integer = integer - mask * 2;
147+
148+
const bigIntValue = BigInt(hex);
149+
const bitSize = bytes * 8;
150+
const signBit = BigInt(1) << BigInt(bitSize - 1);
151+
const mask = (BigInt(1) << BigInt(bitSize)) - BigInt(1);
152+
153+
// mask to the correct bit width
154+
const masked = bigIntValue & mask;
155+
// check if negative (sign bit is set)
156+
if (masked >= signBit) {
157+
// convert from two's complement
158+
const result = masked - (BigInt(1) << BigInt(bitSize));
159+
return Number(result);
138160
}
139-
return integer;
161+
162+
return Number(masked);
140163
}
141164

142165
export function find(regex: RegExp, input: string) {

0 commit comments

Comments
 (0)