diff --git a/src/generator/gen-constructors.ts b/src/generator/gen-constructors.ts index 65c02d4..bf60cbe 100644 --- a/src/generator/gen-constructors.ts +++ b/src/generator/gen-constructors.ts @@ -101,17 +101,14 @@ const generateOpcode = (name: string, instruction: $.Opcode): t.Statement[] => { } const generateArgs = (args: $.args): CompiledArgs => { - switch (args.$) { - case "simpleArgs": - return generateSimpleArgs(args) - case "dictpush": - return generateDictpush(args) + if (args.length === 2 && args[0]?.$ === "dict") { + return generateDictpush() } - throw new Error("Unexpected arg type") + return generateSimpleArgs(args) } -const generateDictpush = (_args: $.dictpush): CompiledArgs => { +const generateDictpush = (): CompiledArgs => { return [ // TODO: rename parameters ["arg0", t.tsNumberKeyword()], @@ -119,8 +116,8 @@ const generateDictpush = (_args: $.dictpush): CompiledArgs => { ] } -const generateSimpleArgs = (args: $.simpleArgs): CompiledArgs => { - return args.children.map((arg, index) => [`arg${index}`, generateArg(arg)]) +const generateSimpleArgs = (args: $.args): CompiledArgs => { + return args.map((arg, index) => [`arg${index}`, generateArg(arg)]) } const generateArg = (arg: $.arg): t.TSType => { @@ -151,6 +148,8 @@ const generateArg = (arg: $.arg): t.TSType => { return t.tsTypeReference(t.tsQualifiedName(TON_CORE_QUALIFIER, t.identifier("Slice"))) case "exoticCell": return t.tsTypeReference(t.tsQualifiedName(UTIL_QUALIFIER, t.identifier("ExoticCell"))) + case "dict": + throw new Error("Must be handled in Args") } throw new Error("Unexpected arg type") diff --git a/src/generator/gen-converter.ts b/src/generator/gen-converter.ts index 4a7dfa5..2473897 100644 --- a/src/generator/gen-converter.ts +++ b/src/generator/gen-converter.ts @@ -143,7 +143,7 @@ function generateConvertorFunction( } function generateBody(name: string, instruction: $.Opcode) { - const len = argsLen(instruction.args) + const len = instruction.args.length const argsConst = t.variableDeclaration("const", [ t.variableDeclarator( @@ -198,17 +198,6 @@ function generateBody(name: string, instruction: $.Opcode) { return t.blockStatement([argsConst, lenCheck, ...argsStatements]) } -const argsLen = (args: $.args): number => { - switch (args.$) { - case "simpleArgs": - return args.children.length - case "dictpush": - return 2 - } - - throw new Error("Unexpected arg type") -} - function isIntegerArg(arg: $.arg) { return ( arg.$ === "int" || @@ -283,7 +272,7 @@ function returnThreeArgInstr(name: string) { ) } -const generateSimpleArgs = (name: string, args: $.arg[]): t.Statement[] => { +const generateSimpleArgs = (name: string, args: $.args): t.Statement[] => { if (args.length === 0) { return [ t.returnStatement( @@ -401,14 +390,11 @@ const generateDictpush = (name: string): t.Statement[] => { } const generateArgs = (name: string, args: $.args): t.Statement[] => { - switch (args.$) { - case "simpleArgs": - return generateSimpleArgs(name, args.children) - case "dictpush": - return generateDictpush(name) + if (args.length === 2 && args[0]?.$ === "dict") { + return generateDictpush(name) } - throw new Error("Unexpected arg type") + return generateSimpleArgs(name, args) } const generateInstr = (name: string, instruction: $.Opcode): t.Statement[] => { diff --git a/src/generator/gen-printer.ts b/src/generator/gen-printer.ts index 81049af..979091f 100644 --- a/src/generator/gen-printer.ts +++ b/src/generator/gen-printer.ts @@ -61,7 +61,7 @@ function generatePrintFunction( } const args = opcode.args - const countArgs = argsLen(args) + const countArgs = args.length const statements: t.Statement[] = [] @@ -75,7 +75,7 @@ function generatePrintFunction( }), ...fiftInstructions.flatMap(([name, opcode]) => { const args = opcode.args - const countArgs = argsLen(args) + const countArgs = args.length const statements: t.Statement[] = [] @@ -109,18 +109,7 @@ function generatePrintFunction( ) } -const argsLen = (args: $.args): number => { - switch (args.$) { - case "simpleArgs": - return args.children.length - case "dictpush": - return 2 - } - - throw new Error("Unexpected arg type") -} - -const generateSimpleArgs = (args: $.arg[]): t.Statement[] => { +const generateSimpleArgs = (args: $.args): t.Statement[] => { return args.flatMap((arg, index) => { const stmt = generateArg(`arg${index}`, arg) if (index !== args.length - 1) { @@ -192,6 +181,8 @@ const generateArg = (name: string, arg: $.arg): t.Statement[] => { ), ), ] + case "dict": + throw new Error("Must be handled in Args") } throw new Error("Unexpected arg type") @@ -214,14 +205,11 @@ const generateDictpush = (): t.Statement[] => { } const generateArgs = (args: $.args): t.Statement[] => { - switch (args.$) { - case "simpleArgs": - return generateSimpleArgs(args.children) - case "dictpush": - return generateDictpush() + if (args.length === 2 && args[0]?.$ === "dict") { + return generateDictpush() } - throw new Error("Unexpected arg type") + return generateSimpleArgs(args) } function writeAppend(val: string) { diff --git a/src/generator/gen-types.ts b/src/generator/gen-types.ts index 1e14846..502e777 100644 --- a/src/generator/gen-types.ts +++ b/src/generator/gen-types.ts @@ -160,30 +160,24 @@ const generateOpcode = (name: string, instruction: $.Opcode): t.Statement[] => { } const generateLoadArgs = (args: $.args): (t.Expression | t.SpreadElement)[] => { - switch (args.$) { - case "simpleArgs": - return generateSimpleArgs(args).map(arg => wrapIntoLoad(arg)) - case "dictpush": - return generateDictpush(args).map(arg => t.spreadElement(wrapIntoLoad(arg))) + if (args.length === 2 && args[0]?.$ === "dict") { + return generateDictpush().map(arg => t.spreadElement(wrapIntoLoad(arg))) } - throw new Error("Unexpected arg type") + return generateArgs(args).map(arg => wrapIntoLoad(arg)) } const generateStoreArgs = (args: $.args): t.Statement[] => { - switch (args.$) { - case "simpleArgs": - return generateSimpleArgs(args).map((arg, index) => wrapIntoStore(`arg${index}`, arg)) - case "dictpush": - return [ - wrapIntoArrayStore( - ["arg0", "arg1"], - t.memberExpression(UTIL_QUALIFIER, t.identifier("dictpush")), - ), - ] + if (args.length === 2 && args[0]?.$ === "dict") { + return [ + wrapIntoArrayStore( + ["arg0", "arg1"], + t.memberExpression(UTIL_QUALIFIER, t.identifier("dictpush")), + ), + ] } - throw new Error("Unexpected arg type") + return generateArgs(args).map((arg, index) => wrapIntoStore(`arg${index}`, arg)) } // codeSlice(uint(2), uint(7)) @@ -208,12 +202,11 @@ const generateSlice = (args: $.slice): t.Expression => { ]) } -const generateDictpush = (_args: $.dictpush): t.Expression[] => { +const generateDictpush = (): t.Expression[] => { return [t.memberExpression(UTIL_QUALIFIER, t.identifier("dictpush"))] } -const generateSimpleArgs = (args: $.simpleArgs): t.Expression[] => - args.children.map(arg => generateArg(arg)) +const generateArgs = (args: $.args): t.Expression[] => args.map(arg => generateArg(arg)) function generateTypeDescription(name: string, arg: number) { return t.callExpression(t.memberExpression(UTIL_QUALIFIER, t.identifier(name)), [ @@ -263,6 +256,8 @@ const generateArg = (arg: $.arg): t.Expression => { return generateInlineCodeSlice(arg) case "slice": return generateSlice(arg) + case "dict": + throw new Error("Must be handled in Args") } throw new Error("Unexpected arg type") diff --git a/src/generator/instructions.ts b/src/generator/instructions.ts index 0f746e8..30fa728 100644 --- a/src/generator/instructions.ts +++ b/src/generator/instructions.ts @@ -14,6 +14,7 @@ export type arg = | codeSlice | refCodeSlice | inlineCodeSlice + | dict | exoticCell | debugstr @@ -64,10 +65,8 @@ export const minusOne: minusOne = {$: "minusOne"} export type setcpArg = {$: "setcpArg", range: range} export const setcpArg: setcpArg = {$: "setcpArg", range: range(-15n, 239n)} -export type args = simpleArgs | dictpush - -export type simpleArgs = {$: "simpleArgs", children: arg[]} -export const seq = (...args: arg[]): simpleArgs => ({$: "simpleArgs", children: args}) +export type args = arg[] +export const seq = (...args: arg[]): args => args export type codeSlice = {$: "codeSlice", refs: arg, bits: arg} export const codeSlice = (refs: arg, bits: arg): codeSlice => ({$: "codeSlice", refs, bits}) @@ -81,6 +80,9 @@ export const refCodeSlice: refCodeSlice = {$: "refCodeSlice"} export type slice = {$: "slice", refs: arg, bits: arg, pad: number} export const slice = (refs: arg, bits: arg, pad: number): slice => ({$: "slice", refs, bits, pad}) +export type dict = {$: "dict"} +export const dict: dict = {$: "dict"} + export type exoticCell = {$: "exoticCell"} export const exoticCell: exoticCell = {$: "exoticCell"} @@ -350,6 +352,7 @@ const uint3range = range(0n, BigInt(Math.pow(2, 3) - 1)) const uint5range = range(0n, BigInt(Math.pow(2, 5) - 1)) const uint6range = range(0n, BigInt(Math.pow(2, 6) - 1)) const uint7range = range(0n, BigInt(Math.pow(2, 7) - 1)) +const uint10range = range(0n, BigInt(Math.pow(2, 10) - 1)) const uint11range = range(0n, BigInt(Math.pow(2, 11) - 1)) const uint14range = range(0n, BigInt(Math.pow(2, 14) - 1)) @@ -364,6 +367,7 @@ const uint5 = uint(5, uint5range) const uint6 = uint(6, uint6range) const uint7 = uint(7, uint7range) const uint8 = uint(8, uint8range) +const uint10 = uint(10, uint10range) const uint11 = uint(11, uint11range) const uint14 = uint(14, uint14range) const hash = uint(8, {min: 0n, max: 4n}) @@ -1145,8 +1149,8 @@ export const instructions: Record = { IFNBITJMPREF: effects(cat("continuation_cond_loop", mkext((0xe3c >> 1) | 0b1, 11, 5, seq(uint5, refCodeSlice), `exec_if_bit_jmpref`)), ImplicitJumpRef(), CellLoad()), // END SECTION - DICTPUSHCONST: cat("dictionary", mkfixedn(0x3d29, 14, 10, dictpush, `exec_push_const_dict`)), - PFXDICTSWITCH: cat("dictionary", mkfixedn(0xf4ac00 >> 10, 14, 10, dictpush, `exec_const_pfx_dict_switch`)), + DICTPUSHCONST: cat("dictionary", mkfixedn(0x3d29, 14, 10, seq(dict, uint10), `exec_push_const_dict`)), + PFXDICTSWITCH: cat("dictionary", mkfixedn(0xf4ac00 >> 10, 14, 10, seq(dict, uint10), `exec_const_pfx_dict_switch`)), // SECTION: sdbegins SDBEGINSX: cat("cell_deserialize", mksimple(0xd726, 16, `(_1) => exec_slice_begins_with(_1, false)`)),