From 460cee9a8f4a874f6373e44549c49d1c63b10109 Mon Sep 17 00:00:00 2001 From: chenyan-dfinity Date: Fri, 10 Apr 2020 13:21:25 -0700 Subject: [PATCH] feat(userlib): add float64 support --- src/userlib/js/package.json | 2 +- src/userlib/js/src/idl.test.ts | 15 ++++++++++++ src/userlib/js/src/idl.ts | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/userlib/js/package.json b/src/userlib/js/package.json index ae1cb82d4d..13acb24be4 100644 --- a/src/userlib/js/package.json +++ b/src/userlib/js/package.json @@ -9,7 +9,7 @@ "ci": "npm run prettier && npm run lint && npm run build && npm run test", "lint": "tslint --project tsconfig.json --config tslint.json", "lint:fix": "npm run lint -- --fix", - "prettier": "npx prettier --check src/**/*.ts bootstrap/**/*.ts", + "prettier": "npx prettier --check src/*.ts src/**/*.ts bootstrap/*.ts bootstrap/**/*.ts", "prettier:write": "npm run prettier -- --write", "test": "jest --verbose" }, diff --git a/src/userlib/js/src/idl.test.ts b/src/userlib/js/src/idl.test.ts index 6ad257548f..72c9654f5f 100644 --- a/src/userlib/js/src/idl.test.ts +++ b/src/userlib/js/src/idl.test.ts @@ -86,6 +86,21 @@ test('IDL encoding (nat)', () => { expect(() => IDL.encode([IDL.Nat], [-1])).toThrow(/Invalid nat argument/); }); +test('IDL encoding (float64)', () => { + // Float64 + test_(IDL.Float64, 3, '4449444c0001720000000000000840', 'Float'); + test_(IDL.Float64, 6, '4449444c0001720000000000001840', 'Float'); + test_(IDL.Float64, 0.5, '4449444c000172000000000000e03f', 'Float'); + test_(IDL.Float64, Number.NaN, '4449444c000172010000000000f07f', 'NaN'); + test_(IDL.Float64, Number.POSITIVE_INFINITY, '4449444c000172000000000000f07f', '+infinity'); + test_(IDL.Float64, Number.NEGATIVE_INFINITY, '4449444c000172000000000000f0ff', '-infinity'); + test_(IDL.Float64, Number.EPSILON, '4449444c000172000000000000b03c', 'eps'); + test_(IDL.Float64, Number.MIN_VALUE, '4449444c0001720100000000000000', 'min_value'); + test_(IDL.Float64, Number.MAX_VALUE, '4449444c000172ffffffffffffef7f', 'max_value'); + test_(IDL.Float64, Number.MIN_SAFE_INTEGER, '4449444c000172ffffffffffff3fc3', 'min_safe_integer'); + test_(IDL.Float64, Number.MAX_SAFE_INTEGER, '4449444c000172ffffffffffff3f43', 'max_safe_integer'); +}); + test('IDL encoding (fixed-width number)', () => { // Fixed-width number test_(IDL.Int8, 0, '4449444c00017700', 'Int8'); diff --git a/src/userlib/js/src/idl.ts b/src/userlib/js/src/idl.ts index 078ba293be..0c9a7e837d 100644 --- a/src/userlib/js/src/idl.ts +++ b/src/userlib/js/src/idl.ts @@ -21,6 +21,7 @@ const enum IDLTypeIds { Bool = -2, Nat = -3, Int = -4, + Float64 = -14, Text = -15, Empty = -17, Opt = -18, @@ -111,6 +112,9 @@ export abstract class Visitor { public visitNat(t: NatClass, data: D): R { return this.visitPrimitive(t, data); } + public visitFloat(t: FloatClass, data: D): R { + return this.visitPrimitive(t, data); + } public visitFixedInt(t: FixedIntClass, data: D): R { return this.visitPrimitive(t, data); } @@ -412,6 +416,42 @@ export class NatClass extends PrimitiveType { } } +/** + * Represents an IDL Float + */ +export class FloatClass extends PrimitiveType { + public accept(v: Visitor, d: D): R { + return v.visitFloat(this, d); + } + + public covariant(x: any): x is number { + return typeof x === 'number' || x instanceof Number; + } + + public encodeValue(x: number) { + const buf = Buffer.allocUnsafe(8); + buf.writeDoubleLE(x, 0); + return buf; + } + + public encodeType() { + return slebEncode(IDLTypeIds.Float64); + } + + public decodeValue(b: Pipe) { + const x = b.read(8); + return x.readDoubleLE(0); + } + + get name() { + return 'float64'; + } + + public valueToString(x: number) { + return x.toString(); + } +} + /** * Represents an IDL fixed-width Int(n) */ @@ -1189,6 +1229,8 @@ export const Text = new TextClass(); export const Int = new IntClass(); export const Nat = new NatClass(); +export const Float64 = new FloatClass(); + export const Int8 = new FixedIntClass(8); export const Int16 = new FixedIntClass(16); export const Int32 = new FixedIntClass(32);