Skip to content

Commit 5d7bb76

Browse files
committed
Add nan and infinite as separate types
1 parent d4e3c06 commit 5d7bb76

6 files changed

Lines changed: 104 additions & 61 deletions

File tree

src/debug/WARDuino.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export namespace WARDuino {
55
import Frame = WASM.Frame;
66
import Table = WASM.Table;
77
import Memory = WASM.Memory;
8+
import Type = WASM.Type;
89

910
export interface CallbackMapping {
1011
callbackid: string;
@@ -77,9 +78,9 @@ export namespace WARDuino {
7778
pc_error?: number;
7879
exception_msg?: string;
7980
breakpoints?: number[];
80-
stack?: Value<bigint | number>[];
81+
stack?: Value<Type>[];
8182
callstack?: Frame[];
82-
globals?: Value<bigint | number>[];
83+
globals?: Value<Type>[];
8384
table?: Table;
8485
memory?: Memory;
8586
br_table?: BRTable;

src/framework/Testee.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function timeout<T>(label: string, time: number, promise: Promise<T>): Pr
2727
* @param field dot string describing the field of the value (or path)
2828
*/
2929
export function getValue(object: any, field: string): any {
30-
if (object?.type == WASM.Type.nothing) {
30+
if (object?.type === WASM.Special.nothing) {
3131
return undefined;
3232
}
3333

src/framework/scenario/Invoker.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {Target} from '../Testee';
55
import Value = WASM.Value;
66
import Type = WASM.Type;
77
import nothing = WASM.nothing;
8+
import Special = WASM.Special;
9+
import Float = WASM.Float;
810

911
export class Invoker implements Step {
1012
readonly title: string;
@@ -28,9 +30,10 @@ export function invoke(func: string, args: Value<any>[]): Instruction {
2830
return {kind: Kind.Request, value: Message.invoke(func, args)};
2931
}
3032

31-
export function returns<T extends bigint | number>(n: Value<T>): Expectation[] {
32-
if (n.type == Type.nothing) {
33+
export function returns<T extends Type>(n: Value<T>): Expectation[] {
34+
if (n.type == Special.nothing) {
3335
return [{'value': {kind: 'primitive', value: undefined} as Expected<undefined>}]
3436
}
35-
return [{'value': {kind: 'primitive', value: n.value} as Expected<T>}]
37+
type R = T extends Float ? number : bigint;
38+
return [{'value': {kind: 'primitive', value: n.value} as Expected<R>}]
3639
}

src/messaging/Message.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export interface Request<R> {
2828

2929
export namespace Message {
3030
import Inspect = WARDuino.Inspect;
31+
import Integer = WASM.Integer;
32+
import Float = WASM.Float;
3133
export const run: Request<Ack> = {
3234
type: Interrupt.run,
3335
parser: (line: string) => {
@@ -162,7 +164,7 @@ export namespace Message {
162164
}
163165
}
164166

165-
export function invoke(func: string, args: Value<bigint | number>[]): Request<WASM.Value<bigint | number> | Exception> {
167+
export function invoke(func: string, args: Value<Type>[]): Request<WASM.Value<Type> | Exception> {
166168
function fidx(map: SourceMap.Mapping, func: string): number {
167169
const fidx: number | void = map.functions.find((closure: SourceMap.Closure) => closure.name === func)?.index;
168170
if (fidx === undefined) {
@@ -171,15 +173,15 @@ export namespace Message {
171173
return fidx!;
172174
}
173175

174-
function convert(args: Value<bigint | number>[]) {
176+
function convert(args: Value<Type>[]) {
175177
let payload: string = '';
176-
args.forEach((arg: Value<bigint | number>) => {
177-
if (arg.type === Type.i32 || arg.type === Type.i64) {
178-
payload += WASM.leb128(arg.value);
179-
} else {
180-
const buff = Buffer.alloc(arg.type === Type.f32 ? 4 : 8);
181-
write(buff, Number(arg.value), 0, true, arg.type === Type.f32 ? 23 : 52, buff.length); // todo fix precision loss
178+
args.forEach((arg: Value<Type>) => {
179+
if (arg.type === Float.f32 || arg.type === Float.f64) {
180+
const buff = Buffer.alloc(arg.type === Float.f32 ? 4 : 8);
181+
write(buff, Number(arg.value), 0, true, arg.type === Float.f32 ? 23 : 52, buff.length); // todo fix precision loss
182182
payload += buff.toString('hex');
183+
} else {
184+
payload += WASM.leb128(arg.value);
183185
}
184186
});
185187
return payload;

src/messaging/Parsers.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {WARDuino} from '../debug/WARDuino';
66
import {JSONParse} from 'json-with-bigint';
77
import State = WARDuino.State;
88
import nothing = WASM.nothing;
9-
9+
import Type = WASM.Type;
1010
export function identityParser(text: string) {
1111
return stripEnd(text);
1212
}
@@ -15,7 +15,7 @@ export function stateParser(text: string): State {
1515
return JSONParse(text);
1616
}
1717

18-
export function invokeParser(text: string): WASM.Value<bigint | number> | Exception {
18+
export function invokeParser(text: string): WASM.Value<Type> | Exception {
1919
if (exception(text)) {
2020
return {text: text};
2121
}
@@ -60,38 +60,50 @@ export function breakpointHitParser(text: string): Breakpoint {
6060
}
6161

6262
export function signed(value: bigint, bits = 32) {
63-
let x = BigInt(value);
63+
let x = value;
6464
const sign = 1n << BigInt(bits - 1);
6565
const mod = 1n << BigInt(bits);
6666
return x >= sign ? x - mod : x;
6767

6868
}
6969

70-
function stacking(objects: {value: bigint, type: any}[]): WASM.Value<bigint | number>[] {
71-
const stacked: WASM.Value<bigint | number>[] = [];
70+
function extractType(object: {value: bigint | number, type: any}): Type {
71+
if (isNaN(<number>object.value)) return WASM.Special.nan;
72+
if (<number>object.value === Infinity) return WASM.Special.infinity;
73+
return WASM.typing.get(object.type.toLowerCase()) ?? WASM.Special.unknown;
74+
}
75+
76+
function stacking(objects: {value: bigint | number, type: any}[]): WASM.Value<Type>[] {
77+
const stacked: WASM.Value<Type>[] = [];
7278
for (const object of objects) {
73-
const type: WASM.Type = WASM.typing.get(object.type.toLowerCase()) ?? WASM.Type.unknown;
79+
const type: WASM.Type = extractType(object);
7480
let buff;
7581
switch (type) {
76-
case WASM.Type.u32:
77-
case WASM.Type.u64:
82+
case WASM.Special.nan:
83+
stacked.push({value: NaN, type: type});
84+
break;
85+
case WASM.Special.infinity:
86+
stacked.push({value: Infinity, type: type});
87+
break;
88+
case WASM.Integer.u32:
89+
case WASM.Integer.u64:
7890
stacked.push({value: object.value, type: type});
7991
break;
80-
case WASM.Type.i32:
81-
stacked.push({value: signed(object.value, 32), type: type});
92+
case WASM.Integer.i32:
93+
stacked.push({value: signed(BigInt(object.value), 32), type: type});
8294
break;
83-
case WASM.Type.i64:
84-
stacked.push({value: signed(object.value, 64), type: type});
95+
case WASM.Integer.i64:
96+
stacked.push({value: signed(BigInt(object.value), 64), type: type});
8597
break;
86-
case WASM.Type.f32:
98+
case WASM.Float.f32:
8799
buff = Buffer.from(Number(object.value.toString(16)).toString(16), 'hex');
88100
stacked.push({value: ieee754.read(buff, 0, false, 23, buff.length), type: type});
89101
break;
90-
case WASM.Type.f64:
102+
case WASM.Float.f64:
91103
buff = Buffer.from(BigInt(object.value.toString(16)).toString(16), 'hex');
92104
stacked.push({value: ieee754.read(buff, 0, false, 52, buff.length), type: type});
93105
break;
94-
case WASM.Type.unknown:
106+
case WASM.Special.unknown:
95107
break;
96108
}
97109
}

src/sourcemap/Wasm.ts

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,82 @@
11
export namespace WASM {
2-
export enum Type {
3-
f32,
4-
f64,
5-
u32,
6-
i32,
7-
u64,
8-
i64,
9-
nothing,
10-
unknown
2+
export enum Float {
3+
f32 = 'f32',
4+
f64 = 'f64'
115
}
126

7+
export enum Integer {
8+
u32 = 'u32',
9+
i32 = 'i32',
10+
u64 = 'u64',
11+
i64 = 'i64'
12+
}
13+
14+
export enum Special {
15+
nothing = 'nothing',
16+
nan = 'nan',
17+
infinity = 'infinity',
18+
unknown = 'unknown'
19+
}
20+
21+
export type Type = Float | Integer | Special;
22+
1323
export const typing = new Map<string, Type>([
14-
['f32', Type.f32],
15-
['f64', Type.f64],
16-
['u32', Type.u32],
17-
['i32', Type.i32],
18-
['u64', Type.u64],
19-
['i64', Type.i64]
24+
['f32', Float.f32],
25+
['f64', Float.f64],
26+
['u32', Integer.u32],
27+
['i32', Integer.i32],
28+
['u64', Integer.u64],
29+
['i64', Integer.i64]
2030
]);
2131

22-
export interface Value<T extends bigint | number> {
23-
type: Type;
24-
value: T;
32+
export interface Value<T extends Type> {
33+
type: T;
34+
value: T extends Integer ? bigint : number;
35+
}
36+
37+
export function equals<T extends Type>(a: Value<T>, b: Value<T>): boolean {
38+
switch (a.type) {
39+
case Special.nan:
40+
return b.type === Special.nan;
41+
case Special.infinity:
42+
return b.type === Special.infinity;
43+
case Special.nothing:
44+
return b.type === Special.nothing;
45+
case Special.unknown:
46+
return b.type === Special.unknown;
47+
default:
48+
return a.type === b.type && a.value === b.value;
49+
}
2550
}
2651

27-
export interface Nothing extends Value<number> {}
52+
export interface Nothing extends Value<Special> {}
2853

2954
export const nothing: Nothing = {
30-
type: Type.nothing, value: 0
55+
type: Special.nothing, value: 0
3156
}
3257

33-
export function u32(n: bigint): WASM.Value<bigint> {
34-
return {value: n, type: Type.u32};
58+
export function u32(n: bigint): WASM.Value<Integer> {
59+
return {value: n, type: Integer.u32};
3560
}
3661

37-
export function i32(n: bigint): WASM.Value<bigint> {
38-
return {value: n, type: Type.i32};
62+
export function i32(n: bigint): WASM.Value<Integer> {
63+
return {value: n, type: Integer.i32};
3964
}
4065

41-
export function f32(n: number): WASM.Value<number> {
42-
return {value: n, type: Type.f32};
66+
export function f32(n: number): WASM.Value<Float> {
67+
return {value: n, type: Float.f32};
4368
}
4469

45-
export function f64(n: number): WASM.Value<number> {
46-
return {value: n, type: Type.f64};
70+
export function f64(n: number): WASM.Value<Float> {
71+
return {value: n, type: Float.f64};
4772
}
4873

49-
export function u64(n: bigint): WASM.Value<bigint> {
50-
return {value: n, type: Type.u64};
74+
export function u64(n: bigint): WASM.Value<Integer> {
75+
return {value: n, type: Integer.u64};
5176
}
5277

53-
export function i64(n: bigint): WASM.Value<bigint> {
54-
return {value: n, type: Type.i64};
78+
export function i64(n: bigint): WASM.Value<Integer> {
79+
return {value: n, type: Integer.i64};
5580
}
5681

5782
export interface Frame {

0 commit comments

Comments
 (0)