From 388e50c33dde9de4ab0adea2465c7f0a74e37647 Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Sun, 26 Apr 2020 02:35:14 -0500 Subject: [PATCH] Two's compliment packed integers. Closes #425. --- test/cycle/packed.t.js | 4 ++-- test/generated/packed.parser.all.js | 2 ++ test/generated/packed.parser.bff.js | 2 ++ test/generated/packed.parser.inc.js | 2 ++ test/language/packed.t.js | 4 ++-- unpack.js | 14 +++++++++++++- 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/test/cycle/packed.t.js b/test/cycle/packed.t.js index df0bc41b..3af4ea4e 100644 --- a/test/cycle/packed.t.js +++ b/test/cycle/packed.t.js @@ -8,11 +8,11 @@ function prove (okay) { header: { literal: 'deaf', one: 1, - two: 3, + two: -3, three: 12 } } }, - objects: [{ header: { one: 1, two: 5, three: 1 } }] + objects: [{ header: { one: 1, two: -4, three: 1 } }] }) } diff --git a/test/generated/packed.parser.all.js b/test/generated/packed.parser.all.js index 8e6e8894..80ac262f 100644 --- a/test/generated/packed.parser.all.js +++ b/test/generated/packed.parser.all.js @@ -18,6 +18,8 @@ module.exports = function (parsers) { object.header.one = $_ >>> 15 & 0x1 object.header.two = $_ >>> 12 & 0x7 + object.header.two = + object.header.two & 0x4 ? (0x7 - object.header.two + 1) * -1 : object.header.two object.header.three = $_ & 0xfff return object diff --git a/test/generated/packed.parser.bff.js b/test/generated/packed.parser.bff.js index b4f49a1d..d3081897 100644 --- a/test/generated/packed.parser.bff.js +++ b/test/generated/packed.parser.bff.js @@ -23,6 +23,8 @@ module.exports = function (parsers) { object.header.one = $_ >>> 15 & 0x1 object.header.two = $_ >>> 12 & 0x7 + object.header.two = + object.header.two & 0x4 ? (0x7 - object.header.two + 1) * -1 : object.header.two object.header.three = $_ & 0xfff return { start: $start, object: object, parse: null } diff --git a/test/generated/packed.parser.inc.js b/test/generated/packed.parser.inc.js index ff50a860..762a3b60 100644 --- a/test/generated/packed.parser.inc.js +++ b/test/generated/packed.parser.inc.js @@ -32,6 +32,8 @@ module.exports = function (parsers) { object.header.one = $_ >>> 15 & 0x1 object.header.two = $_ >>> 12 & 0x7 + object.header.two = + object.header.two & 0x4 ? (0x7 - object.header.two + 1) * -1 : object.header.two object.header.three = $_ & 0xfff diff --git a/test/language/packed.t.js b/test/language/packed.t.js index 46767dff..1941bdc9 100644 --- a/test/language/packed.t.js +++ b/test/language/packed.t.js @@ -5,7 +5,7 @@ require('proof')(1, okay => { header: { literal: 'deaf', one: 1, - two: 3, + two: -3, three: 12 } } @@ -40,7 +40,7 @@ require('proof')(1, okay => { bits: 3, fixed: true, endianness: 'big', - compliment: false + compliment: true }, { name: 'three', dotted: '.three', diff --git a/unpack.js b/unpack.js index 680db350..f09df433 100644 --- a/unpack.js +++ b/unpack.js @@ -1,4 +1,6 @@ const fiddle = require('./fiddle/unpack') +const unsign = require('./fiddle/unsign') +const $ = require('programmatic') function unpack (path, field, assignee) { let bits = field.bits, offset = 0, bit = 0 @@ -7,8 +9,18 @@ function unpack (path, field, assignee) { bit += field.bits return field }) + // TODO Faster with an if statement rather than a reassignment (see + // generated code) or with a temporary variable. return packing.filter(field => field.type == 'integer').map(function (field) { - return `${path}${field.dotted} = ${fiddle(bits, field.offset, field.bits, assignee)}` + const assign = `${path}${field.dotted} = ${fiddle(bits, field.offset, field.bits, assignee)}` + if (field.compliment) { + return $(` + `, assign, ` + ${path}${field.dotted} = + `, unsign(path + field.dotted, field.bits), ` + `) + } + return assign }).join('\n') }