diff --git a/index.ts b/index.ts index 0d505a1..714ca76 100644 --- a/index.ts +++ b/index.ts @@ -1,4 +1,6 @@ import { generateCode } from "./src/main"; -export { generateCode, generateCodeByAST, generateCodeWithGenerator } from "./src/main"; +export * from "./src/ast"; +export { generateCode, getTLBCode, getTLBCodeByAST, generateCodeByAST, generateCodeWithGenerator } from "./src/main"; +export { isBigInt as isBigIntForJson, isBigIntExpr as isBigIntExprForJson } from "./src/generators/typescript/utils"; export { CodeGenerator } from "./src/generators/generator"; export { TypescriptGenerator } from "./src/generators/typescript/generator"; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cfe6b7d..2274f62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ton-community/tlb-codegen", - "version": "1.0.1", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ton-community/tlb-codegen", - "version": "1.0.1", + "version": "1.1.0", "license": "ISC", "dependencies": { "@ton-community/tlb-parser": "^0.1.3", diff --git a/package.json b/package.json index 4c5a80d..7b5160d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ton-community/tlb-codegen", - "version": "1.0.1", + "version": "1.1.0", "description": "", "main": "build/index.js", "scripts": { diff --git a/src/ast.ts b/src/ast.ts index 36b3d49..44e7912 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -70,6 +70,7 @@ export type TLBNamedType = { export type TLBMathExprType = { kind: "TLBExprMathType"; expr: TLBMathExpr; + initialExpr: TLBMathExpr; }; export type TLBBoolType = { diff --git a/src/astbuilder/handle_type.ts b/src/astbuilder/handle_type.ts index d5e5a92..540a6f3 100644 --- a/src/astbuilder/handle_type.ts +++ b/src/astbuilder/handle_type.ts @@ -278,13 +278,14 @@ export function getType( return { kind: "TLBExprMathType", expr: getCalculatedExpression(new TLBVarExpr(expr.name), constructor), + initialExpr: new TLBVarExpr(expr.name), }; } else { return { kind: "TLBNamedType", name: expr.name, arguments: [] }; } } } else if (expr instanceof NumberExpr) { - return { kind: "TLBExprMathType", expr: new TLBNumberExpr(expr.num) }; + return { kind: "TLBExprMathType", expr: new TLBNumberExpr(expr.num), initialExpr: new TLBNumberExpr(expr.num) }; } else if (expr instanceof NegateExpr && expr.expr instanceof NameExpr) { return { kind: "TLBNegatedType", variableName: expr.expr.name }; } else if (expr instanceof CellRefExpr) { @@ -309,6 +310,7 @@ export function getType( return { kind: "TLBExprMathType", expr: getCalculatedExpression(convertToMathExpr(expr), constructor), + initialExpr: convertToMathExpr(expr), }; } } else if (expr instanceof CondExpr) { diff --git a/src/main.ts b/src/main.ts index c7cc107..13429ff 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,15 +11,29 @@ import { CodeGenerator, CommonGenDeclaration } from "./generators/generator"; import { TypescriptGenerator } from "./generators/typescript/generator"; import fs from 'fs' - -export function generateCodeByAST(tree: Program, input: string, getGenerator: (tlbCode: TLBCode) => CodeGenerator) { +export function getTLBCodeByAST(tree: Program, input: string) { let oldTlbCode: TLBCodeBuild = { types: new Map() }; - let splittedInput = input.split("\n"); - fillConstructors(tree.declarations, oldTlbCode, splittedInput); let tlbCode: TLBCode = convertCodeToReadonly(oldTlbCode); + return tlbCode; +} + +export function getTLBCode(inputPath: string) { + const input = fs.readFileSync( + inputPath, + 'utf-8', + ) + + const tree = ast(input) + + return getTLBCodeByAST(tree, input); +} + + +export function generateCodeByAST(tree: Program, input: string, getGenerator: (tlbCode: TLBCode) => CodeGenerator) { + let tlbCode = getTLBCodeByAST(tree, input) let codeGenerator: CodeGenerator = getGenerator(tlbCode); codeGenerator.addTonCoreClassUsage("Builder"); diff --git a/test/generated_files/generated_test.ts b/test/generated_files/generated_test.ts index 93ea548..f23094b 100644 --- a/test/generated_files/generated_test.ts +++ b/test/generated_files/generated_test.ts @@ -19,6 +19,52 @@ export interface Simple { readonly b: number; } +// a$_ {Arg:Type} arg:Arg = TypedArg Arg; + +export interface TypedArg { + readonly kind: 'TypedArg'; + readonly arg: Arg; +} + +// a$_ x:(TypedArg Simple) = TypedArgUser; + +export interface TypedArgUser { + readonly kind: 'TypedArgUser'; + readonly x: TypedArg; +} + +// a$_ {Arg:Type} {n:#} arg:Arg c:(## n) = ParamAndTypedArg n Arg; + +export interface ParamAndTypedArg { + readonly kind: 'ParamAndTypedArg'; + readonly n: number; + readonly arg: Arg; + readonly c: bigint; +} + +// a$_ x:(ParamAndTypedArg 5 Simple) = ParamAndTypedArgUser; + +export interface ParamAndTypedArgUser { + readonly kind: 'ParamAndTypedArgUser'; + readonly x: ParamAndTypedArg; +} + +// _ x:Simple y:Simple = TwoSimples; + +export interface TwoSimples { + readonly kind: 'TwoSimples'; + readonly x: Simple; + readonly y: Simple; +} + +// _ one_maybe:(Maybe Simple) second_maybe:(Maybe Simple) = TwoMaybes; + +export interface TwoMaybes { + readonly kind: 'TwoMaybes'; + readonly one_maybe: Maybe; + readonly second_maybe: Maybe; +} + // bool_false$0 a:# b:(## 7) c:# = TwoConstructors; // bool_true$1 b:# = TwoConstructors; @@ -676,6 +722,13 @@ export interface AnyAddressUser { readonly src: Address | ExternalAddress | null; } +// _ inside:AddressUser = InsideAddressUser; + +export interface InsideAddressUser { + readonly kind: 'InsideAddressUser'; + readonly inside: AddressUser; +} + // a$_ b:Bit = BitUser; export interface BitUser { @@ -807,6 +860,41 @@ export interface HashmapAugEUser { readonly x: Dictionary; } +// message$_ {X:Type} body:(Either X ^X) = Message X; + +export interface Message { + readonly kind: 'Message'; + readonly body: Either; +} + +// _ (Message Any) = MessageAny; + +export interface MessageAny { + readonly kind: 'MessageAny'; + readonly anon0: Message; +} + +// _ x:^FixedIntParam = ShardState; + +export interface ShardState { + readonly kind: 'ShardState'; + readonly x: FixedIntParam; +} + +// a$_ {X:Type} a:^X = InsideCell X; + +export interface InsideCell { + readonly kind: 'InsideCell'; + readonly a: X; +} + +// a$_ inside_cell:^(InsideCell ShardState) = InsideCellUser; + +export interface InsideCellUser { + readonly kind: 'InsideCellUser'; + readonly inside_cell: InsideCell; +} + // tmpa$_ a:# b:# = Simple; export function loadSimple(slice: Slice): Simple { @@ -828,6 +916,124 @@ export function storeSimple(simple: Simple): (builder: Builder) => void { } +// a$_ {Arg:Type} arg:Arg = TypedArg Arg; + +export function loadTypedArg(slice: Slice, loadArg: (slice: Slice) => Arg): TypedArg { + let arg: Arg = loadArg(slice); + return { + kind: 'TypedArg', + arg: arg, + } + +} + +export function storeTypedArg(typedArg: TypedArg, storeArg: (arg: Arg) => (builder: Builder) => void): (builder: Builder) => void { + return ((builder: Builder) => { + storeArg(typedArg.arg)(builder); + }) + +} + +// a$_ x:(TypedArg Simple) = TypedArgUser; + +export function loadTypedArgUser(slice: Slice): TypedArgUser { + let x: TypedArg = loadTypedArg(slice, loadSimple); + return { + kind: 'TypedArgUser', + x: x, + } + +} + +export function storeTypedArgUser(typedArgUser: TypedArgUser): (builder: Builder) => void { + return ((builder: Builder) => { + storeTypedArg(typedArgUser.x, storeSimple)(builder); + }) + +} + +// a$_ {Arg:Type} {n:#} arg:Arg c:(## n) = ParamAndTypedArg n Arg; + +export function loadParamAndTypedArg(slice: Slice, n: number, loadArg: (slice: Slice) => Arg): ParamAndTypedArg { + let arg: Arg = loadArg(slice); + let c: bigint = slice.loadUintBig(n); + return { + kind: 'ParamAndTypedArg', + n: n, + arg: arg, + c: c, + } + +} + +export function storeParamAndTypedArg(paramAndTypedArg: ParamAndTypedArg, storeArg: (arg: Arg) => (builder: Builder) => void): (builder: Builder) => void { + return ((builder: Builder) => { + storeArg(paramAndTypedArg.arg)(builder); + builder.storeUint(paramAndTypedArg.c, paramAndTypedArg.n); + }) + +} + +// a$_ x:(ParamAndTypedArg 5 Simple) = ParamAndTypedArgUser; + +export function loadParamAndTypedArgUser(slice: Slice): ParamAndTypedArgUser { + let x: ParamAndTypedArg = loadParamAndTypedArg(slice, 5, loadSimple); + return { + kind: 'ParamAndTypedArgUser', + x: x, + } + +} + +export function storeParamAndTypedArgUser(paramAndTypedArgUser: ParamAndTypedArgUser): (builder: Builder) => void { + return ((builder: Builder) => { + storeParamAndTypedArg(paramAndTypedArgUser.x, storeSimple)(builder); + }) + +} + +// _ x:Simple y:Simple = TwoSimples; + +export function loadTwoSimples(slice: Slice): TwoSimples { + let x: Simple = loadSimple(slice); + let y: Simple = loadSimple(slice); + return { + kind: 'TwoSimples', + x: x, + y: y, + } + +} + +export function storeTwoSimples(twoSimples: TwoSimples): (builder: Builder) => void { + return ((builder: Builder) => { + storeSimple(twoSimples.x)(builder); + storeSimple(twoSimples.y)(builder); + }) + +} + +// _ one_maybe:(Maybe Simple) second_maybe:(Maybe Simple) = TwoMaybes; + +export function loadTwoMaybes(slice: Slice): TwoMaybes { + let one_maybe: Maybe = loadMaybe(slice, loadSimple); + let second_maybe: Maybe = loadMaybe(slice, loadSimple); + return { + kind: 'TwoMaybes', + one_maybe: one_maybe, + second_maybe: second_maybe, + } + +} + +export function storeTwoMaybes(twoMaybes: TwoMaybes): (builder: Builder) => void { + return ((builder: Builder) => { + storeMaybe(twoMaybes.one_maybe, storeSimple)(builder); + storeMaybe(twoMaybes.second_maybe, storeSimple)(builder); + }) + +} + // bool_false$0 a:# b:(## 7) c:# = TwoConstructors; // bool_true$1 b:# = TwoConstructors; @@ -2867,6 +3073,24 @@ export function storeAnyAddressUser(anyAddressUser: AnyAddressUser): (builder: B } +// _ inside:AddressUser = InsideAddressUser; + +export function loadInsideAddressUser(slice: Slice): InsideAddressUser { + let inside: AddressUser = loadAddressUser(slice); + return { + kind: 'InsideAddressUser', + inside: inside, + } + +} + +export function storeInsideAddressUser(insideAddressUser: InsideAddressUser): (builder: Builder) => void { + return ((builder: Builder) => { + storeAddressUser(insideAddressUser.inside)(builder); + }) + +} + // a$_ b:Bit = BitUser; export function loadBitUser(slice: Slice): BitUser { @@ -3319,3 +3543,122 @@ export function storeHashmapAugEUser(hashmapAugEUser: HashmapAugEUser): (builder } +// message$_ {X:Type} body:(Either X ^X) = Message X; + +export function loadMessage(slice: Slice, loadX: (slice: Slice) => X): Message { + let body: Either = loadEither(slice, loadX, ((slice: Slice) => { + let slice1 = slice.loadRef().beginParse(true); + return loadX(slice1) + + })); + return { + kind: 'Message', + body: body, + } + +} + +export function storeMessage(message: Message, storeX: (x: X) => (builder: Builder) => void): (builder: Builder) => void { + return ((builder: Builder) => { + storeEither(message.body, storeX, ((arg: X) => { + return ((builder: Builder) => { + let cell1 = beginCell(); + storeX(arg)(cell1); + builder.storeRef(cell1); + + }) + + }))(builder); + }) + +} + +// _ (Message Any) = MessageAny; + +export function loadMessageAny(slice: Slice): MessageAny { + let anon0: Message = loadMessage(slice, ((slice: Slice) => { + return slice.asCell() + + })); + return { + kind: 'MessageAny', + anon0: anon0, + } + +} + +export function storeMessageAny(messageAny: MessageAny): (builder: Builder) => void { + return ((builder: Builder) => { + storeMessage(messageAny.anon0, ((arg: Cell) => { + return ((builder: Builder) => { + builder.storeSlice(arg.beginParse(true)); + }) + + }))(builder); + }) + +} + +// _ x:^FixedIntParam = ShardState; + +export function loadShardState(slice: Slice): ShardState { + let slice1 = slice.loadRef().beginParse(true); + let x: FixedIntParam = loadFixedIntParam(slice1); + return { + kind: 'ShardState', + x: x, + } + +} + +export function storeShardState(shardState: ShardState): (builder: Builder) => void { + return ((builder: Builder) => { + let cell1 = beginCell(); + storeFixedIntParam(shardState.x)(cell1); + builder.storeRef(cell1); + }) + +} + +// a$_ {X:Type} a:^X = InsideCell X; + +export function loadInsideCell(slice: Slice, loadX: (slice: Slice) => X): InsideCell { + let slice1 = slice.loadRef().beginParse(true); + let a: X = loadX(slice1); + return { + kind: 'InsideCell', + a: a, + } + +} + +export function storeInsideCell(insideCell: InsideCell, storeX: (x: X) => (builder: Builder) => void): (builder: Builder) => void { + return ((builder: Builder) => { + let cell1 = beginCell(); + storeX(insideCell.a)(cell1); + builder.storeRef(cell1); + }) + +} + +// a$_ inside_cell:^(InsideCell ShardState) = InsideCellUser; + +export function loadInsideCellUser(slice: Slice): InsideCellUser { + let slice1 = slice.loadRef().beginParse(true); + let inside_cell: InsideCell = loadInsideCell(slice1, loadShardState); + return { + kind: 'InsideCellUser', + inside_cell: inside_cell, + } + +} + +export function storeInsideCellUser(insideCellUser: InsideCellUser): (builder: Builder) => void { + return ((builder: Builder) => { + let cell1 = beginCell(); + storeInsideCell(insideCellUser.inside_cell, storeShardState)(cell1); + builder.storeRef(cell1); + }) + +} + diff --git a/test/tlb/test.tlb b/test/tlb/test.tlb index bf6da31..c6a1027 100644 --- a/test/tlb/test.tlb +++ b/test/tlb/test.tlb @@ -1,5 +1,15 @@ tmpa$_ a:# b:# = Simple; +a$_ {Arg:Type} arg:Arg = TypedArg Arg; +a$_ x:(TypedArg Simple) = TypedArgUser; + +a$_ {Arg:Type} {n:#} arg:Arg c:(## n) = ParamAndTypedArg n Arg; +a$_ x:(ParamAndTypedArg 5 Simple) = ParamAndTypedArgUser; + +_ x:Simple y:Simple = TwoSimples; + +_ one_maybe:(Maybe Simple) second_maybe:(Maybe Simple) = TwoMaybes; + bool_false$0 a:# b:(## 7) c:# = TwoConstructors; bool_true$1 b:# = TwoConstructors; @@ -146,6 +156,8 @@ _ src:MsgAddressInt = AddressUser; _ src:MsgAddressExt = ExtAddressUser; _ src:MsgAddress = AnyAddressUser; +_ inside:AddressUser = InsideAddressUser; + bit$_ (## 1) = Bit; a$_ b:Bit = BitUser; @@ -181,4 +193,12 @@ ahme_empty$0 {n:#} {X:Type} {Y:Type} extra:Y ahme_root$1 {n:#} {X:Type} {Y:Type} root:^(HashmapAug n X Y) extra:Y = HashmapAugE n X Y; -a$_ x:(HashmapAugE 16 Grams FixedIntParam) = HashmapAugEUser; \ No newline at end of file +a$_ x:(HashmapAugE 16 Grams FixedIntParam) = HashmapAugEUser; + +message$_ {X:Type} body:(Either X ^X) = Message X; + +_ (Message Any) = MessageAny; + +_ x:^FixedIntParam = ShardState; +a$_ {X:Type} a:^X = InsideCell X; +a$_ inside_cell:^(InsideCell ShardState) = InsideCellUser;