diff --git a/lib/binary_parser.ts b/lib/binary_parser.ts index 111fd3b..caf7a1b 100644 --- a/lib/binary_parser.ts +++ b/lib/binary_parser.ts @@ -1,7 +1,7 @@ class Context { code = ""; scopes = [["vars"]]; - bitFields: Parser[] = []; + bitFields: (Parser & { thisVar: string })[] = []; tmpVariableCount = 0; references = new Map(); importPath: string; @@ -1018,13 +1018,14 @@ export class Parser { return this.generateNext(ctx); } - private generateAssert(ctx: Context) { + private generateAssert( + ctx: Context, + varName = ctx.generateVariable(this.varName), + ) { if (!this.options.assert) { return; } - const varName = ctx.generateVariable(this.varName); - switch (typeof this.options.assert) { case "function": { @@ -1093,6 +1094,7 @@ export class Parser { parser.generateAssert = this.generateAssert.bind(this); parser.generateFormatter = this.generateFormatter.bind(this); parser.varName = ctx.generateVariable(parser.varName); + parser.thisVar = ctx.generateVariable(); ctx.bitFields.push(parser); if (!this.next || this.nextNotBit()) { @@ -1166,7 +1168,7 @@ export class Parser { } if (parser.options.assert) { - parser.generateAssert(ctx); + parser.generateAssert(ctx, parser.varName); } if (parser.options.formatter) { @@ -1174,6 +1176,7 @@ export class Parser { ctx, parser.varName, parser.options.formatter, + parser.thisVar, ); } @@ -1557,12 +1560,11 @@ export class Parser { ctx: Context, varName: string, formatter: Function, + thisVar = ctx.generateVariable(), ) { if (typeof formatter === "function") { const func = ctx.addImport(formatter); - ctx.pushCode( - `${varName} = ${func}.call(${ctx.generateVariable()}, ${varName});`, - ); + ctx.pushCode(`${varName} = ${func}.call(${thisVar}, ${varName});`); } } diff --git a/test/primitive_parser.ts b/test/primitive_parser.ts index 66f2489..25659ec 100644 --- a/test/primitive_parser.ts +++ b/test/primitive_parser.ts @@ -303,6 +303,22 @@ function primitiveParserTests( expect(parser.parse(buf)).toStrictEqual({ a: 0xa, b: 0xbc, c: 0xd }); expect(options).toStrictEqual({}); }); + + it("should assert and format bit fields spanning into a nest", () => { + let self: any; + const parser = new Parser() + .bit4("a", { + assert: 0xa, + formatter: function (v) { + self = this; + return v; + }, + }) + .nest("n", { type: new Parser().bit4("b") }); + const result = parser.parse(binaryLiteral("1010 1011")); + expect(result).toStrictEqual({ a: 0xa, n: { b: 0xb } }); + expect(self).toBe(result); + }); }); describe("String parser", () => {