Skip to content

Commit

Permalink
type parametrized by number
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyProgrammist committed Nov 14, 2023
1 parent c50bfe2 commit 0cfb88f
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 19 deletions.
78 changes: 73 additions & 5 deletions generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,21 @@ export function storeD(d: D): Builder {
}
export type Maybe<TheType> = Maybe_nothing<TheType> | Maybe_just<TheType>;
export type Maybe_nothing<TheType> = {

TheType: number;
};
export type Maybe_just<TheType> = {
TheType: number;
value: TheType;
};
export function loadMaybe<TheType>(slice: Slice, loadTheType: (slice: Slice) => TheType): Maybe<TheType> {
export function loadMaybe<TheType>(slice: Slice, loadTheType: (slice: Slice) => TheType, TheType: number): Maybe<TheType> {
if (slice.preloadUint(1) == 0b0) {
return {

TheType: TheType
};
};
if (slice.preloadUint(1) == 0b1) {
return {
TheType: TheType,
value: loadTheType(slice)
};
};
Expand Down Expand Up @@ -144,19 +146,27 @@ export function storeTheJust(theJust: TheJust): Builder {
}
export type Either<X,Y> = Either_left<X,Y> | Either_right<X,Y>;
export type Either_left<X,Y> = {
X: number;
Y: number;
value: X;
};
export type Either_right<X,Y> = {
X: number;
Y: number;
value: Y;
};
export function loadEither<X,Y>(slice: Slice, loadX: (slice: Slice) => X, loadY: (slice: Slice) => Y): Either<X,Y> {
export function loadEither<X,Y>(slice: Slice, loadX: (slice: Slice) => X, loadY: (slice: Slice) => Y, X: number, Y: number): Either<X,Y> {
if (slice.preloadUint(1) == 0b0) {
return {
X: X,
Y: Y,
value: loadX(slice)
};
};
if (slice.preloadUint(1) == 0b1) {
return {
X: X,
Y: Y,
value: loadY(slice)
};
};
Expand All @@ -174,11 +184,15 @@ export function storeEither<X,Y>(either: Either<X,Y>, storeX: (x: X) => (builder
};
}
export type Both<X,Y> = {
X: number;
Y: number;
first: X;
second: Y;
};
export function loadBoth<X,Y>(slice: Slice, loadX: (slice: Slice) => X, loadY: (slice: Slice) => Y): Both<X,Y> {
export function loadBoth<X,Y>(slice: Slice, loadX: (slice: Slice) => X, loadY: (slice: Slice) => Y, X: number, Y: number): Both<X,Y> {
return {
X: X,
Y: Y,
first: loadX(slice),
second: loadY(slice)
};
Expand All @@ -189,3 +203,57 @@ export function storeBoth<X,Y>(both: Both<X,Y>, storeX: (x: X) => (builder: Buil
storeY(both.second)(builder);
};
}
export type Unit = {

};
export function loadUnit(slice: Slice): Unit {
return {

};
}
export function storeUnit(unit: Unit): Builder {
return (builder: Builder) => {

};
}
export type True = {

};
export function loadTrue(slice: Slice): True {
return {

};
}
export function storeTrue(true: True): Builder {
return (builder: Builder) => {

};
}
export type Example = {
x: number;
value: number;
};
export function loadExample(slice: Slice, x: number): Example {
return {
x: x,
value: slice.loadUint(x)
};
}
export function storeExample(example: Example): Builder {
return (builder: Builder) => {
builder.storeUint(example.value, example.x);
};
}
export type BitInteger = {
t: Example;
};
export function loadBitInteger(slice: Slice): BitInteger {
return {
t: loadExample(slice, 4)
};
}
export function storeBitInteger(bitInteger: BitInteger): Builder {
return (builder: Builder) => {
storeExample(bitInteger.t)(builder);
};
}
64 changes: 64 additions & 0 deletions maybe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,67 @@ export function storeTheJust(theJust: TheJust): Builder {
storeMaybe<number>(theJust.x, storeTheNumber)(builder);
};
}



export type Example = {
value: number;
x: number;
};
export function loadExample(slice: Slice, x: number): Example {
return {
value: slice.loadUint(x),
x: x
};
}
export function storeExample(example: Example): Builder {
return (builder: Builder) => {
builder.storeUint(example.value, example.x)
};
}

export type BitInteger = {
e: Example;
};
export function loadBitInteger(slice: Slice): BitInteger {
return {
e: loadExample(slice, 4)
};
}
export function storeBitInteger(bitInteger: BitInteger): Builder {
return (builder: Builder) => {
storeExample(bitInteger.e)(builder);
};
}



export type Example2 = {
value: number;
x: number;
};
export function loadExample2(slice: Slice, x: number): Example {
return {
value: slice.loadUint(x / 2),
x: x / 2
};
}
export function storeExample2(example: Example2): Builder {
return (builder: Builder) => {
builder.storeUint(example.value, example.x)
};
}

export type BitInteger2 = {
e: Example2;
};
export function loadBitInteger2(slice: Slice): BitInteger2 {
return {
e: loadExample2(slice, 4)
};
}
export function storeBitInteger2(bitInteger: BitInteger2): Builder {
return (builder: Builder) => {
storeExample2(bitInteger.e)(builder);
};
}
7 changes: 7 additions & 0 deletions tests/fixtures/tlb/my.tlb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ left$0 {X:Type} {Y:Type} value:X = Either X Y;
right$1 {X:Type} {Y:Type} value:Y = Either X Y;
pair$_ {X:Type} {Y:Type} first:X second:Y = Both X Y;

unit$_ = Unit;
true$_ = True;

a$_ {x:#} value:(## x) = Example x;

//a$_ {x:#} value:(## x) = Example (x * 2);

a$_ t:(Example 4) = BitInteger;
59 changes: 45 additions & 14 deletions tests/my.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import util from 'util'

import { parse } from '../src'
import { ast } from '../src'
import { BuiltinZeroArgs, FieldNamedDef, Program, Declaration, BuiltinOneArgExpr, NumberExpr, NameExpr, CombinatorExpr } from '../src/ast/nodes'
import { BuiltinZeroArgs, FieldNamedDef, Program, Declaration, BuiltinOneArgExpr, NumberExpr, NameExpr, CombinatorExpr, FieldBuiltinDef } from '../src/ast/nodes'

import { parse as parseBabel } from "@babel/parser";
import generate from "@babel/generator";
// import { expressionStatement } from '@babel/types'
import { ExportNamedDeclaration, ExpressionStatement as BabelExpressionStatement, Identifier as BabelIdentifier, ObjectProperty as BabelObjectProperty, TSPropertySignature, TSTypeReference, anyTypeAnnotation, arrowFunctionExpression, blockStatement, callExpression, exportNamedDeclaration, expressionStatement, functionDeclaration, identifier, importDeclaration, importSpecifier, memberExpression, numericLiteral, objectExpression, objectProperty, returnStatement, stringLiteral, tsPropertySignature, tsTypeAliasDeclaration, tsTypeAnnotation, tsTypeLiteral, tsTypeReference, tsUnionType, typeAnnotation, MemberExpression as BabelMemberExpression, typeParameter} from '@babel/types'
import { ExportNamedDeclaration, ExpressionStatement as BabelExpressionStatement, Identifier as BabelIdentifier, ObjectProperty as BabelObjectProperty, TSPropertySignature, TSTypeReference, anyTypeAnnotation, arrowFunctionExpression, blockStatement, callExpression, exportNamedDeclaration, expressionStatement, functionDeclaration, identifier, importDeclaration, importSpecifier, memberExpression, numericLiteral, objectExpression, objectProperty, returnStatement, stringLiteral, tsPropertySignature, tsTypeAliasDeclaration, tsTypeAnnotation, tsTypeLiteral, tsTypeReference, tsUnionType, typeAnnotation, MemberExpression as BabelMemberExpression, typeParameter, tsLiteralType} from '@babel/types'

const fixturesDir = path.resolve(__dirname, 'fixtures')

Expand Down Expand Up @@ -422,9 +422,12 @@ describe('parsing into intermediate representation using grammar', () => {
let storeStatements: Statement[] = []

let typeParameters: TypeParametersExpression = tTypeParametersExpression([]);
let implicitFields = new Map<string, string>();



value.forEach(declaration => {
console.log(value)
let structName: string;
if (value.length > 1) {
structName = declaration.combinator.name + '_' + declaration.constructorDef.name;
Expand All @@ -448,26 +451,42 @@ describe('parsing into intermediate representation using grammar', () => {
let tagBinary = '0b' + tag.slice(1);

declaration?.fields.forEach(field => {
if (field instanceof FieldBuiltinDef) {
implicitFields.set(field.name, field.type);
}
})

declaration?.fields.forEach(field => {
console.log(field)

if (field instanceof FieldBuiltinDef) {
structProperties.push(tTypedIdentifier(tIdentifier(field.name), tIdentifier('number')));
loadProperties.push(tObjectProperty(tIdentifier(field.name), tIdentifier(field.name)))

}

if (field instanceof FieldNamedDef) {
let bits = -1;
console.log(util.inspect(field, false, null, true /* enable colors */))
let bits: Expression | undefined;


// console.log(field)
if (field.expr instanceof BuiltinZeroArgs) {
if (field.expr.name == '#') {
bits = 32;
bits = tNumericLiteral(32);
}
}
if (field.expr instanceof BuiltinOneArgExpr) {
if (field.expr.name == '##') {
if (field.expr.arg instanceof NumberExpr) {
bits = field.expr.arg.num;
bits = tNumericLiteral(field.expr.arg.num);
}
if (field.expr.arg instanceof NameExpr) {
bits = tIdentifier(field.expr.arg.name);
}
}
}
if (field.expr instanceof CombinatorExpr) {
let typeParameterArray: Array<Identifier> = []
let loadFunctionsArray: Array<Identifier> = []
let loadFunctionsArray: Array<Expression> = []
let storeFunctionsArray: Array<Expression> = []

field.expr.args.forEach(element => {
Expand All @@ -476,25 +495,32 @@ describe('parsing into intermediate representation using grammar', () => {
loadFunctionsArray.push(tIdentifier('load' + element.name))
storeFunctionsArray.push(tIdentifier('store' + element.name))
}
if (element instanceof NumberExpr) {
loadFunctionsArray.push(tNumericLiteral(element.num))
}
});

let currentTypeParameters = tTypeParametersExpression(typeParameterArray);

let insideLoadParameters: Array<Expression> = [tIdentifier('slice')];
let insideStoreParameters: Array<Expression> = [tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(field.name))];

structProperties.push(tTypedIdentifier(tIdentifier(field.name), tTypeWithParameters(tIdentifier(field.expr.name), currentTypeParameters)));
loadProperties.push(tObjectProperty(tIdentifier(field.name), tFunctionCall(tIdentifier('load' + field.expr.name), [tIdentifier('slice')].concat(loadFunctionsArray), currentTypeParameters)))
loadProperties.push(tObjectProperty(tIdentifier(field.name), tFunctionCall(tIdentifier('load' + field.expr.name), insideLoadParameters.concat(loadFunctionsArray), currentTypeParameters)))
insideStoreStatements.push(tExpressionStatement(tFunctionCall(tFunctionCall(tIdentifier('store' + field.expr.name), insideStoreParameters.concat(storeFunctionsArray), currentTypeParameters), [tIdentifier('builder')])))
}
if (field.expr instanceof NameExpr) {
structProperties.push(tTypedIdentifier(tIdentifier(field.name), tIdentifier(field.expr.name)));
loadProperties.push(tObjectProperty(tIdentifier(field.name), tFunctionCall(tIdentifier('load' + field.expr.name), [tIdentifier('slice')])))
insideStoreStatements.push(tExpressionStatement(tFunctionCall(tFunctionCall(tIdentifier('store' + field.expr.name), [tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(field.name))]), [tIdentifier('builder')])))
}
if (bits != -1) {
if (bits != undefined) {
structProperties.push(tTypedIdentifier(tIdentifier(field.name), tIdentifier('number')))
loadProperties.push(tObjectProperty(tIdentifier(field.name), tFunctionCall(tMemberExpression(tIdentifier('slice'), tIdentifier('loadUint')), [tNumericLiteral(bits)])))
insideStoreStatements.push(tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier('builder'), tIdentifier('storeUint')), [tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(field.name)), tNumericLiteral(bits)])))
loadProperties.push(tObjectProperty(tIdentifier(field.name), tFunctionCall(tMemberExpression(tIdentifier('slice'), tIdentifier('loadUint')), [bits])))
if (bits.type == "Identifier") {
bits = tMemberExpression(tIdentifier(variableCombinatorName), bits);
}
insideStoreStatements.push(tExpressionStatement(tFunctionCall(tMemberExpression(tIdentifier('builder'), tIdentifier('storeUint')), [tMemberExpression(tIdentifier(variableCombinatorName), tIdentifier(field.name)), bits])))
}
}
})
Expand All @@ -504,15 +530,16 @@ describe('parsing into intermediate representation using grammar', () => {

declaration.combinator.args.forEach(element => {
if (element instanceof NameExpr) {
typeParameterArray.push(tIdentifier(element.name))
if (implicitFields.has(element.name) && implicitFields.get(element.name) == 'Type') {
typeParameterArray.push(tIdentifier(element.name))
}
}
});

typeParameters = tTypeParametersExpression(typeParameterArray);
}

unionTypes.push(tTypeWithParameters(tIdentifier(structName), typeParameters));


let structX = tStructDeclaration(tIdentifier(structName), structProperties, typeParameters);

Expand Down Expand Up @@ -540,6 +567,10 @@ describe('parsing into intermediate representation using grammar', () => {
loadFunctionParameters.push(tTypedIdentifier(tIdentifier('load' + element.name), tArrowFunctionType([tTypedIdentifier(tIdentifier('slice'), tIdentifier('Slice'))], element)))
});

implicitFields.forEach((value: string, key: string) => {
loadFunctionParameters.push(tTypedIdentifier(tIdentifier(key), tIdentifier('number')))
});

let loadFunction = tFunctionDeclaration(tIdentifier('load' + combinatorName), typeParameters, tTypeWithParameters(tIdentifier(combinatorName), typeParameters), loadFunctionParameters, loadStatements);
tmpDeclarations.push(loadFunction)

Expand Down

0 comments on commit 0cfb88f

Please sign in to comment.