Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Span } from './span';
import * as transform from './transform';

export { code, node, transform, Property, PropertyType, Span };
export { Endianess } from "./code";
export { Edge } from './edge';
export { LoopChecker } from './loop-checker';
export { ISpanAllocatorResult, SpanAllocator } from './span-allocator';
Expand Down Expand Up @@ -72,6 +73,8 @@ export class Builder {
otherwise?: node.Node): node.Invoke {
let res: node.Invoke;

// TODO: (Vizonex) Should we add a check for non-existant unpack properties here?

// `.invoke(name)`
if (map === undefined) {
res = new node.Invoke(fn, {});
Expand Down
16 changes: 16 additions & 0 deletions src/code/creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,20 @@ export class Creator {
public test(field: string, value: number): code.Test {
return new code.Test(field, value);
}

/**
* Intrinsic operation.
*
* state[field] <<= 8 or >>= 8 (depending on endianess)
* state[field] |= value
* return (state[field] < (property size limit)) ? 0 : -1;
*
* @param field Property Name
* @param endianness Endianness Enum to determine if big
* or little endianness should be accounted for.
* defaults to `Endianess.Little`
*/
public unpack(field: string, endianness?: code.Endianess) : code.Unpack {
return new code.Unpack(field, endianness);
}
}
1 change: 1 addition & 0 deletions src/code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { Store } from './store';
export { Test } from './test';
export { Update } from './update';
export { Value } from './value';
export { Unpack, Endianess } from './unpack';
32 changes: 32 additions & 0 deletions src/code/unpack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Field } from "./field";

/** Options for `code.unpack()` */
export enum Endianess {
Little = 0,
Big = 1
};

/** Helps with making unpacking protocols.
* It unpacks variables via left & right shifting
* based on a given endianness argument
*/
export class Unpack extends Field {
public readonly bigEndian:boolean;
/**
* @param field Name of the property that should be unpacked to
* @param endianness determines how to unpack the value provided
* Default Value: `Endianess.Little`.
*/

constructor (field: string, endianness?:Endianess){
if (endianness === undefined){
endianness = Endianess.Little;
}
super(
'match',
endianness == Endianess.Little ? 'unpack_le' : 'unpack_be',
field
);
this.bigEndian = endianness == Endianess.Big;
}
}
16 changes: 15 additions & 1 deletion test/builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { beforeEach, describe, it, type TestContext } from 'node:test';
import { Builder } from '../src/builder';
import { Builder, Endianess } from '../src/builder';

describe('LLParse/Builder', () => {
let b: Builder;
Expand Down Expand Up @@ -88,4 +88,18 @@ describe('LLParse/Builder', () => {
10,
]);
});

it('should create an unpack for Invoke'), (t: TestContext) => {
const start = b.node('start');
b.property('i16', 'unpack_value');
const unpack_error = b.error(0, 'failed to unpack value');
const invoke = b.invoke(
b.code.unpack('unpack_value', Endianess.Little),
start, unpack_error
);
const otherwise = invoke.getOtherwiseEdge();
t.assert.deepStrictEqual(
otherwise?.node, unpack_error
);
}
});