diff --git a/cspell.json b/cspell.json index 20fda3420..a7fece6ad 100644 --- a/cspell.json +++ b/cspell.json @@ -128,7 +128,8 @@ "CHKSIGNU", "CHKSIGNS", "RAWRESERVE", - "SENDRAWMSG" + "SENDRAWMSG", + "SDBEGINSQ" ], "flagWords": [], "ignorePaths": [ diff --git a/src/generator/writers/writeFunction.ts b/src/generator/writers/writeFunction.ts index fd613afeb..cb2727018 100644 --- a/src/generator/writers/writeFunction.ts +++ b/src/generator/writers/writeFunction.ts @@ -24,7 +24,7 @@ import { resolveFuncTupleType } from "./resolveFuncTupleType"; import { ops } from "./ops"; import { freshIdentifier } from "./freshIdentifier"; import { idTextErr, throwInternalCompilerError } from "../../errors"; -import { prettyPrint, prettyPrintAsmShuffle } from "../../prettyPrinter"; +import { prettyPrintAsmShuffle } from "../../prettyPrinter"; export function writeCastedExpression( expression: AstExpression, @@ -554,9 +554,7 @@ export function writeFunction(f: FunctionDescription, ctx: WriterContext) { }; ctx.asm( prettyPrintAsmShuffle(asmShuffleEscaped), - fAst.instructions - .map((instruction) => prettyPrint(instruction)) - .join(" "), + fAst.instructions.join(" "), ); }); if (f.isMutating) { diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 161c90950..75a91ea99 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -576,17 +576,6 @@ Line 2, col 23: `; exports[`grammar should fail items-asm-fun-1 1`] = ` -":2:5: Parse error: expected "0X", "0x", "0", "1".."9", "_", "A".."Z", or "a".."z" - -Line 2, col 5: - 1 | asm fun keccak256(s: Slice): Int { -> 2 | + - ^ - 3 | INT -" -`; - -exports[`grammar should fail items-asm-fun-2 1`] = ` ":1:5: Parse error: expected ")" Line 1, col 5: @@ -596,7 +585,7 @@ Line 1, col 5: " `; -exports[`grammar should fail items-asm-fun-3 1`] = ` +exports[`grammar should fail items-asm-fun-2 1`] = ` ":1:9: Parse error: expected ")", "->", "_", "A".."Z", or "a".."z" Line 1, col 9: @@ -606,7 +595,7 @@ Line 1, col 9: " `; -exports[`grammar should fail items-asm-fun-4 1`] = ` +exports[`grammar should fail items-asm-fun-3 1`] = ` ":1:14: Parse error: expected "0" or "1".."9" Line 1, col 14: @@ -616,7 +605,7 @@ Line 1, col 14: " `; -exports[`grammar should fail items-asm-fun-5 1`] = ` +exports[`grammar should fail items-asm-fun-4 1`] = ` ":1:7: Parse error: expected "0" or "1".."9" Line 1, col 7: @@ -3295,31 +3284,16 @@ exports[`grammar should parse expr-with-var 1`] = ` exports[`grammar should parse items-asm-funs 1`] = ` { - "id": 44, + "id": 46, "imports": [], "items": [ { "attributes": [], - "id": 9, + "id": 6, "instructions": [ - { - "id": 6, - "kind": "number", - "loc": 1, - "value": 1n, - }, - { - "id": 7, - "kind": "id", - "loc": INT, - "text": "INT", - }, - { - "id": 8, - "kind": "id", - "loc": HASHEXT_KECCAK256, - "text": "HASHEXT_KECCAK256", - }, + "1", + "INT", + "HASHEXT_KECCAK256", ], "kind": "asm_function_def", "loc": asm fun keccak256(s: Slice): Int { @@ -3370,38 +3344,33 @@ exports[`grammar should parse items-asm-funs 1`] = ` "type": "extends", }, ], - "id": 18, + "id": 14, "instructions": [ - { - "id": 17, - "kind": "id", - "loc": LDVARUINT16, - "text": "LDVARUINT16", - }, + "LDVARUINT16", ], "kind": "asm_function_def", "loc": asm( -> 1 0) extends fun loadCoins(self: Slice): Int { LDVARUINT16 }, "name": { - "id": 12, + "id": 9, "kind": "id", "loc": loadCoins, "text": "loadCoins", }, "params": [ { - "id": 16, + "id": 13, "kind": "typed_parameter", "loc": self: Slice, "name": { - "id": 14, + "id": 11, "kind": "id", "loc": self, "text": "self", }, "type": { - "id": 15, + "id": 12, "kind": "type_id", "loc": Slice, "text": "Slice", @@ -3409,7 +3378,7 @@ exports[`grammar should parse items-asm-funs 1`] = ` }, ], "return": { - "id": 13, + "id": 10, "kind": "type_id", "loc": Int, "text": "Int", @@ -3418,13 +3387,13 @@ exports[`grammar should parse items-asm-funs 1`] = ` "args": [], "ret": [ { - "id": 10, + "id": 7, "kind": "number", "loc": 1, "value": 1n, }, { - "id": 11, + "id": 8, "kind": "number", "loc": 0, "value": 0n, @@ -3439,55 +3408,50 @@ exports[`grammar should parse items-asm-funs 1`] = ` "type": "extends", }, ], - "id": 29, + "id": 24, "instructions": [ - { - "id": 28, - "kind": "id", - "loc": STDICT, - "text": "STDICT", - }, + "STDICT", ], "kind": "asm_function_def", "loc": asm(c b) extends fun storeDict(b: Builder, c: Cell) { STDICT }, "name": { - "id": 21, + "id": 17, "kind": "id", "loc": storeDict, "text": "storeDict", }, "params": [ { - "id": 24, + "id": 20, "kind": "typed_parameter", "loc": b: Builder, "name": { - "id": 22, + "id": 18, "kind": "id", "loc": b, "text": "b", }, "type": { - "id": 23, + "id": 19, "kind": "type_id", "loc": Builder, "text": "Builder", }, }, { - "id": 27, + "id": 23, "kind": "typed_parameter", "loc": c: Cell, "name": { - "id": 25, + "id": 21, "kind": "id", "loc": c, "text": "c", }, "type": { - "id": 26, + "id": 22, "kind": "type_id", "loc": Cell, "text": "Cell", @@ -3498,13 +3462,13 @@ exports[`grammar should parse items-asm-funs 1`] = ` "shuffle": { "args": [ { - "id": 19, + "id": 15, "kind": "id", "loc": c, "text": "c", }, { - "id": 20, + "id": 16, "kind": "id", "loc": b, "text": "b", @@ -3520,55 +3484,50 @@ exports[`grammar should parse items-asm-funs 1`] = ` "type": "extends", }, ], - "id": 43, + "id": 37, "instructions": [ - { - "id": 42, - "kind": "id", - "loc": LDIX, - "text": "LDIX", - }, + "LDIX", ], "kind": "asm_function_def", "loc": asm(s len -> 1 0) extends fun loadInt(self: Slice, len: Int): Int { LDIX }, "name": { - "id": 34, + "id": 29, "kind": "id", "loc": loadInt, "text": "loadInt", }, "params": [ { - "id": 38, + "id": 33, "kind": "typed_parameter", "loc": self: Slice, "name": { - "id": 36, + "id": 31, "kind": "id", "loc": self, "text": "self", }, "type": { - "id": 37, + "id": 32, "kind": "type_id", "loc": Slice, "text": "Slice", }, }, { - "id": 41, + "id": 36, "kind": "typed_parameter", "loc": len: Int, "name": { - "id": 39, + "id": 34, "kind": "id", "loc": len, "text": "len", }, "type": { - "id": 40, + "id": 35, "kind": "type_id", "loc": Int, "text": "Int", @@ -3576,7 +3535,7 @@ exports[`grammar should parse items-asm-funs 1`] = ` }, ], "return": { - "id": 35, + "id": 30, "kind": "type_id", "loc": Int, "text": "Int", @@ -3584,13 +3543,13 @@ exports[`grammar should parse items-asm-funs 1`] = ` "shuffle": { "args": [ { - "id": 30, + "id": 25, "kind": "id", "loc": s, "text": "s", }, { - "id": 31, + "id": 26, "kind": "id", "loc": len, "text": "len", @@ -3598,13 +3557,13 @@ exports[`grammar should parse items-asm-funs 1`] = ` ], "ret": [ { - "id": 32, + "id": 27, "kind": "number", "loc": 1, "value": 1n, }, { - "id": 33, + "id": 28, "kind": "number", "loc": 0, "value": 0n, @@ -3612,6 +3571,76 @@ exports[`grammar should parse items-asm-funs 1`] = ` ], }, }, + { + "attributes": [], + "id": 43, + "instructions": [ + "x{02}", + "SDBEGINSQ", + ], + "kind": "asm_function_def", + "loc": asm fun checkAndRemoveAddExtensionPrefix(self: Slice): Int { + x{02} SDBEGINSQ +}, + "name": { + "id": 38, + "kind": "id", + "loc": checkAndRemoveAddExtensionPrefix, + "text": "checkAndRemoveAddExtensionPrefix", + }, + "params": [ + { + "id": 42, + "kind": "typed_parameter", + "loc": self: Slice, + "name": { + "id": 40, + "kind": "id", + "loc": self, + "text": "self", + }, + "type": { + "id": 41, + "kind": "type_id", + "loc": Slice, + "text": "Slice", + }, + }, + ], + "return": { + "id": 39, + "kind": "type_id", + "loc": Int, + "text": "Int", + }, + "shuffle": { + "args": [], + "ret": [], + }, + }, + { + "attributes": [], + "id": 45, + "instructions": [ + "-ROT", + ], + "kind": "asm_function_def", + "loc": asm fun checkAndRemoveAddExtensionPrefix() { + -ROT +}, + "name": { + "id": 44, + "kind": "id", + "loc": checkAndRemoveAddExtensionPrefix, + "text": "checkAndRemoveAddExtensionPrefix", + }, + "params": [], + "return": null, + "shuffle": { + "args": [], + "ret": [], + }, + }, ], "kind": "module", } diff --git a/src/grammar/ast.ts b/src/grammar/ast.ts index 90a022d57..44a83a0ea 100644 --- a/src/grammar/ast.ts +++ b/src/grammar/ast.ts @@ -62,7 +62,7 @@ export type AstAsmFunctionDef = { loc: SrcInfo; }; -export type AstAsmInstruction = AstId | AstNumber; +export type AstAsmInstruction = string; export type AstAsmShuffle = { args: AstId[]; ret: AstNumber[]; @@ -661,7 +661,6 @@ export type AstNode = | AstFuncId | AstExpression | AstStatement - | AstAsmInstruction | AstTypeDecl | AstFieldDecl | AstTypedParameter diff --git a/src/grammar/compare.ts b/src/grammar/compare.ts index eb9307396..eb5ab0251 100644 --- a/src/grammar/compare.ts +++ b/src/grammar/compare.ts @@ -51,6 +51,7 @@ import { AstNode, AstFuncId, AstAsmFunctionDef, + AstAsmInstruction, } from "./ast"; import { AstRenamer } from "./rename"; import { throwInternalCompilerError } from "../errors"; @@ -159,7 +160,7 @@ export class AstComparator { this.compare(funcName1, funcName2) && this.compareNullableNodes(returnType1, returnType2) && this.compareArray(params1, params2) && - this.compareArray(instructions1, instructions2) + this.compareAsmInstructions(instructions1, instructions2) ); } case "function_decl": { @@ -788,6 +789,16 @@ export class AstComparator { return this.compareArray(nodes1, nodes2); } + private compareAsmInstructions( + instructions1: AstAsmInstruction[], + instructions2: AstAsmInstruction[], + ): boolean { + if (instructions1.length !== instructions2.length) { + return false; + } + return instructions1.every((val1, i1) => val1 === instructions2[i1]); + } + private compareAttributes< T extends | AstFunctionAttribute diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index 20726167b..e2c821e05 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -22,7 +22,7 @@ Tact { ModuleFunction = FunctionDefinition | AsmFunction - AsmFunction = "asm" AsmShuffle? FunctionAttribute* fun id Parameters (":" Type)? "{" AsmInstruction+ "}" + AsmFunction = "asm" AsmShuffle? FunctionAttribute* fun id Parameters (":" Type)? "{" asmInstruction+ "}" ModuleConstant = ConstantDefinition @@ -98,9 +98,8 @@ Tact { | external "(" Parameter? ")" "{" Statement* "}" --externalRegular | external "(" stringLiteral ")" "{" Statement* "}" --externalComment - AsmInstruction = id - | integerLiteralDec - | integerLiteralHex + asmInstruction = ("x" | "X" | "b" | "B") "{" hexDigit* "}" --data + | ~comment (~space ~"}" any)+ --any Statement = StatementLet | StatementBlock diff --git a/src/grammar/grammar.ts b/src/grammar/grammar.ts index ef589b4ad..63db0fea0 100644 --- a/src/grammar/grammar.ts +++ b/src/grammar/grammar.ts @@ -361,9 +361,7 @@ semantics.addOperation("astOfItem", { name: funId.astOfExpression(), return: unwrapOptNode(optReturnType, (t) => t.astOfType()), params: funParameters.astsOfList(), - instructions: asmInstructions.children.map((s) => - s.astOfExpression(), - ), + instructions: asmInstructions.children.map((s) => s.sourceString), loc: createRef(this), }); }, diff --git a/src/grammar/hash.ts b/src/grammar/hash.ts index ab2bf996d..f4ec27fc2 100644 --- a/src/grammar/hash.ts +++ b/src/grammar/hash.ts @@ -24,7 +24,6 @@ import { AstNode, AstAsmFunctionDef, AstAsmInstruction, - idText, } from "./ast"; import { createHash } from "crypto"; import { throwInternalCompilerError } from "../errors"; @@ -305,16 +304,7 @@ export class AstHasher { } private hashInstructions(instructions: AstAsmInstruction[]): string { - return instructions - .map((instruction) => { - switch (instruction.kind) { - case "number": - return instruction.value.toString(); - case "id": - return idText(instruction); - } - }) - .join("|"); + return instructions.join("|"); } private hashStructFieldInitializer( diff --git a/src/grammar/iterators.ts b/src/grammar/iterators.ts index f4fc22d74..4a8501470 100644 --- a/src/grammar/iterators.ts +++ b/src/grammar/iterators.ts @@ -46,9 +46,6 @@ export function traverse(node: AstNode, callback: (node: AstNode) => void) { node.params.forEach((e) => { traverse(e, callback); }); - node.instructions.forEach((e) => { - traverse(e, callback); - }); break; case "function_decl": traverse(node.name, callback); diff --git a/src/grammar/test-failed/items-asm-fun-1.tact b/src/grammar/test-failed/items-asm-fun-1.tact index 8e7466355..bc4e3061e 100644 --- a/src/grammar/test-failed/items-asm-fun-1.tact +++ b/src/grammar/test-failed/items-asm-fun-1.tact @@ -1,6 +1,4 @@ -asm fun keccak256(s: Slice): Int { - + - INT - HASHEXT_KECCAK256 +asm(1 0) extends fun loadCoins(self: Slice): Int { + LDVARUINT16 } diff --git a/src/grammar/test-failed/items-asm-fun-2.tact b/src/grammar/test-failed/items-asm-fun-2.tact index bc4e3061e..8df0bd748 100644 --- a/src/grammar/test-failed/items-asm-fun-2.tact +++ b/src/grammar/test-failed/items-asm-fun-2.tact @@ -1,4 +1,4 @@ -asm(1 0) extends fun loadCoins(self: Slice): Int { - LDVARUINT16 +asm(c b 42) extends fun storeDict(b: Builder, c: Cell) { + STDICT } diff --git a/src/grammar/test-failed/items-asm-fun-3.tact b/src/grammar/test-failed/items-asm-fun-3.tact index 8df0bd748..f1eb4c247 100644 --- a/src/grammar/test-failed/items-asm-fun-3.tact +++ b/src/grammar/test-failed/items-asm-fun-3.tact @@ -1,4 +1,4 @@ -asm(c b 42) extends fun storeDict(b: Builder, c: Cell) { - STDICT +asm(s len -> len 1 0) extends fun loadInt(self: Slice, len: Int): Int { + LDIX } diff --git a/src/grammar/test-failed/items-asm-fun-4.tact b/src/grammar/test-failed/items-asm-fun-4.tact index f1eb4c247..46713e863 100644 --- a/src/grammar/test-failed/items-asm-fun-4.tact +++ b/src/grammar/test-failed/items-asm-fun-4.tact @@ -1,4 +1,3 @@ -asm(s len -> len 1 0) extends fun loadInt(self: Slice, len: Int): Int { +asm(->) extends fun loadInt(self: Slice, len: Int): Int { LDIX } - diff --git a/src/grammar/test-failed/items-asm-fun-5.tact b/src/grammar/test-failed/items-asm-fun-5.tact deleted file mode 100644 index 46713e863..000000000 --- a/src/grammar/test-failed/items-asm-fun-5.tact +++ /dev/null @@ -1,3 +0,0 @@ -asm(->) extends fun loadInt(self: Slice, len: Int): Int { - LDIX -} diff --git a/src/grammar/test/items-asm-funs.tact b/src/grammar/test/items-asm-funs.tact index 7abb7ac57..7525e63d1 100644 --- a/src/grammar/test/items-asm-funs.tact +++ b/src/grammar/test/items-asm-funs.tact @@ -15,3 +15,11 @@ asm(c b) extends fun storeDict(b: Builder, c: Cell) { asm(s len -> 1 0) extends fun loadInt(self: Slice, len: Int): Int { LDIX } + +asm fun checkAndRemoveAddExtensionPrefix(self: Slice): Int { + x{02} SDBEGINSQ +} + +asm fun checkAndRemoveAddExtensionPrefix() { + -ROT +} diff --git a/src/prettyPrinter.ts b/src/prettyPrinter.ts index b8277aeab..5b3d10a21 100644 --- a/src/prettyPrinter.ts +++ b/src/prettyPrinter.ts @@ -589,12 +589,7 @@ export class PrettyPrinter { } ppAstAsmInstruction(instruction: AstAsmInstruction): string { - switch (instruction.kind) { - case "number": - return `${this.indent()}${instruction.value.toString()}`; - case "id": - return `${this.indent()}${idText(instruction)}`; - } + return `${this.indent()}${instruction}`; } ppAstStatementLet(statement: AstStatementLet): string { diff --git a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap index 5135364ab..a8080b3fe 100644 --- a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap +++ b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap @@ -636,14 +636,9 @@ exports[`resolveDescriptors should resolve descriptors for asm-extends-fun 1`] = "type": "mutates", }, ], - "id": 13, + "id": 12, "instructions": [ - { - "id": 12, - "kind": "id", - "loc": LDREF, - "text": "LDREF", - }, + "LDREF", ], "kind": "asm_function_def", "loc": asm(-> 1 0) extends mutates fun loadRef(self: Slice): Cell { LDREF }, @@ -799,14 +794,9 @@ exports[`resolveDescriptors should resolve descriptors for asm-fun-no-arg-shuffl { "ast": { "attributes": [], - "id": 10, + "id": 9, "instructions": [ - { - "id": 9, - "kind": "id", - "loc": NOP, - "text": "NOP", - }, + "NOP", ], "kind": "asm_function_def", "loc": asm(-> 0) fun foo(x: Int): Int { @@ -928,20 +918,10 @@ exports[`resolveDescriptors should resolve descriptors for asm-fun-no-ret-shuffl { "ast": { "attributes": [], - "id": 14, + "id": 12, "instructions": [ - { - "id": 12, - "kind": "id", - "loc": DROP, - "text": "DROP", - }, - { - "id": 13, - "kind": "id", - "loc": DROP, - "text": "DROP", - }, + "DROP", + "DROP", ], "kind": "asm_function_def", "loc": asm(y x) fun foo(x: Int, y: Int) { @@ -1094,14 +1074,9 @@ exports[`resolveDescriptors should resolve descriptors for asm-fun-no-shuffle 2` { "ast": { "attributes": [], - "id": 8, + "id": 7, "instructions": [ - { - "id": 7, - "kind": "id", - "loc": DROP, - "text": "DROP", - }, + "DROP", ], "kind": "asm_function_def", "loc": asm fun foo(x: Int) { @@ -1359,14 +1334,9 @@ exports[`resolveDescriptors should resolve descriptors for asm-fun-shuffle-pair { "ast": { "attributes": [], - "id": 22, + "id": 21, "instructions": [ - { - "id": 21, - "kind": "id", - "loc": SWAP, - "text": "SWAP", - }, + "SWAP", ], "kind": "asm_function_def", "loc": asm(-> 1 0) fun foo(x: Int, y: Int): Pair {