@@ -13,8 +13,6 @@ export namespace WASM {
1313
1414 export enum Special {
1515 nothing = 'nothing' ,
16- nan = 'nan' ,
17- infinity = 'infinity' ,
1816 unknown = 'unknown'
1917 }
2018
@@ -29,17 +27,78 @@ export namespace WASM {
2927 [ 'i64' , Integer . i64 ]
3028 ] ) ;
3129
30+ export class WasmInt {
31+ private constructor (
32+ private readonly kind : 'finite' | 'inf' | 'nan' ,
33+ private readonly finiteValue ?: bigint ,
34+ private readonly positive : boolean = true
35+ ) {
36+ }
37+
38+ static finite ( value : bigint ) : WasmInt {
39+ return new WasmInt ( 'finite' , value , value >= 0 ) ;
40+ }
41+
42+ static infinity ( positive : boolean = true ) : WasmInt {
43+ return new WasmInt ( 'inf' , undefined , positive ) ;
44+ }
45+
46+ static nan ( positive : boolean = true ) : WasmInt {
47+ return new WasmInt ( 'nan' , undefined , positive ) ;
48+ }
49+
50+ isFinite ( ) : boolean {
51+ return this . kind === 'finite' ;
52+ }
53+
54+ isInfinity ( ) : boolean {
55+ return this . kind === 'inf' ;
56+ }
57+
58+ isNaN ( ) : boolean {
59+ return this . kind === 'nan' ;
60+ }
61+
62+ toBigInt ( ) : bigint {
63+ if ( this . finiteValue !== undefined ) {
64+ return this . finiteValue ;
65+ }
66+ throw new Error ( `Cannot convert ${ this . toString ( ) } to bigint.` ) ;
67+ }
68+
69+ toNumber ( ) : number {
70+ switch ( this . kind ) {
71+ case 'finite' :
72+ return Number ( this . finiteValue ! ) ;
73+ case 'inf' :
74+ return this . positive ? Infinity : - Infinity ;
75+ case 'nan' :
76+ return this . positive ? NaN : - NaN ;
77+ }
78+ }
79+
80+ equals ( other : WasmInt ) : boolean {
81+ return this . kind === 'finite'
82+ ? this . finiteValue === other . finiteValue
83+ : this . kind === other . kind && this . positive === other . positive ;
84+ }
85+
86+ toString ( ) : string {
87+ if ( this . kind === 'finite' ) {
88+ return this . finiteValue ! . toString ( ) ;
89+ }
90+ return `${ this . positive ? '' : '-' } ${ this . kind } ` ;
91+ }
92+ }
93+
94+
3295 export interface Value < T extends Type > {
3396 type : T ;
34- value : T extends Integer ? bigint : number ;
97+ value : T extends Integer ? WasmInt : number ;
3598 }
3699
37100 export function equals < T extends Type > ( a : Value < T > , b : Value < T > ) : boolean {
38101 switch ( a . type ) {
39- case Special . nan :
40- return b . type === Special . nan ;
41- case Special . infinity :
42- return b . type === Special . infinity ;
43102 case Special . nothing :
44103 return b . type === Special . nothing ;
45104 case Special . unknown :
@@ -56,38 +115,44 @@ export namespace WASM {
56115 type : Special . nothing , value : 0
57116 }
58117
59- export const nan : WASM . Value < Special > = { value : NaN , type : Special . nan } ;
118+ export function isInteger ( type : Type ) : type is Integer {
119+ return type === Integer . u32 || type === Integer . i32 || type === Integer . u64 || type === Integer . i64 ;
120+ }
60121
61- export const negnan : WASM . Value < Special > = { value : - NaN , type : Special . nan } ;
122+ export function isFloat ( type : Type ) : type is Float {
123+ return type === Float . f32 || type === Float . f64 ;
124+ }
62125
63- export const infinity : WASM . Value < Special > = { value : Infinity , type : Special . infinity } ;
126+ export function nan ( type : WASM . Type , positive : boolean = true ) : WASM . Value < Type > {
127+ return { value : isInteger ( type ) ? WasmInt . nan ( positive ) : ( positive ? NaN : - NaN ) , type} ;
128+ }
64129
65- export const neginfinity : WASM . Value < Special > = { value : - Infinity , type : Special . infinity } ;
130+ export function inf ( type : WASM . Type , positive : boolean = true ) : WASM . Value < Type > {
131+ return { value : isInteger ( type ) ? WasmInt . infinity ( positive ) : ( positive ? Infinity : - Infinity ) , type} ;
132+ }
66133
67134 export function u32 ( n : bigint ) : WASM . Value < Integer > {
68- return { value : n , type : Integer . u32 } ;
135+ return { value : WasmInt . finite ( n ) , type : Integer . u32 } ;
69136 }
70137
71138 export function i32 ( n : bigint ) : WASM . Value < Integer > {
72- return { value : n , type : Integer . i32 } ;
139+ return { value : WasmInt . finite ( n ) , type : Integer . i32 } ;
73140 }
74141
75- const determineType : ( n : number ) => WASM . Type = ( n : number ) => n === Infinity || n === - Infinity ? Special . infinity : ( isNaN ( n ) ? Special . nan : Float . f64 ) ;
76-
77142 export function f32 ( n : number ) : WASM . Value < Type > {
78- return { value : n , type : determineType ( n ) } ;
143+ return { value : n , type : Float . f32 } ;
79144 }
80145
81146 export function f64 ( n : number ) : WASM . Value < Type > {
82- return { value : n , type : determineType ( n ) } ;
147+ return { value : n , type : Float . f64 } ;
83148 }
84149
85150 export function u64 ( n : bigint ) : WASM . Value < Integer > {
86- return { value : n , type : Integer . u64 } ;
151+ return { value : WasmInt . finite ( n ) , type : Integer . u64 } ;
87152 }
88153
89154 export function i64 ( n : bigint ) : WASM . Value < Integer > {
90- return { value : n , type : Integer . i64 } ;
155+ return { value : WasmInt . finite ( n ) , type : Integer . i64 } ;
91156 }
92157
93158 export interface Frame {
0 commit comments