Skip to content

Commit

Permalink
refactor(ast): unified StatementTry and StatementTryCatch (#1418)
Browse files Browse the repository at this point in the history
  • Loading branch information
i582 authored Jan 20, 2025
1 parent 97fbcbb commit a0c8381
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 137 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Generated TS wrappers now use `const` where possible for variable declarations: PR [#1292](https://github.com/tact-lang/tact/pull/1292)
- Allow serialization specifiers for trait fields PR: [#1303](https://github.com/tact-lang/tact/pull/1303)
- Remove unused typechecker wrapper with the file `check.ts` it is contained in: PR [#1313](https://github.com/tact-lang/tact/pull/1313)
- Unified `StatementTry` and `StatementTryCatch` AST nodes: PR [#1418](https://github.com/tact-lang/tact/pull/1418)

### Fixed

Expand Down
14 changes: 4 additions & 10 deletions src/ast/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ export type AstStatement =
| AstStatementUntil
| AstStatementRepeat
| AstStatementTry
| AstStatementTryCatch
| AstStatementForEach
| AstStatementDestruct
| AstStatementBlock;
Expand Down Expand Up @@ -301,15 +300,10 @@ export type AstStatementRepeat = {
export type AstStatementTry = {
kind: "statement_try";
statements: AstStatement[];
id: number;
loc: SrcInfo;
};

export type AstStatementTryCatch = {
kind: "statement_try_catch";
statements: AstStatement[];
catchName: AstId;
catchStatements: AstStatement[];
catchBlock?: {
catchName: AstId;
catchStatements: AstStatement[];
};
id: number;
loc: SrcInfo;
};
Expand Down
13 changes: 7 additions & 6 deletions src/ast/clone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,13 @@ export function cloneNode<T extends AstNode>(
return cloneNode({
...src,
statements: src.statements.map(recurse),
});
} else if (src.kind === "statement_try_catch") {
return cloneNode({
...src,
statements: src.statements.map(recurse),
catchStatements: src.catchStatements.map(recurse),
catchBlock: src.catchBlock
? {
catchName: src.catchBlock.catchName,
catchStatements:
src.catchBlock.catchStatements.map(recurse),
}
: undefined,
});
} else if (src.kind === "statement_foreach") {
return cloneNode({
Expand Down
54 changes: 33 additions & 21 deletions src/ast/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
AstStatementWhile,
AstStatementForEach,
AstStatementTry,
AstStatementTryCatch,
AstCondition,
AstStatementAugmentedAssign,
AstStatementAssign,
Expand Down Expand Up @@ -507,30 +506,43 @@ export class AstComparator {
}

case "statement_try": {
const { statements: tryStatements1 } = node1 as AstStatementTry;
const { statements: tryStatements2 } = node2 as AstStatementTry;
return this.compareArray(tryStatements1, tryStatements2);
}

case "statement_try_catch": {
const {
statements: tryCatchStatements1,
catchName: catchName1,
catchStatements: catchStatements1,
} = node1 as AstStatementTryCatch;
catchBlock: catchBlock1,
} = node1 as AstStatementTry;
const {
statements: tryCatchStatements2,
catchName: catchName2,
catchStatements: catchStatements2,
} = node2 as AstStatementTryCatch;
return (
this.compareArray(
tryCatchStatements1,
tryCatchStatements2,
) &&
this.compare(catchName1, catchName2) &&
this.compareArray(catchStatements1, catchStatements2)
);
catchBlock: catchBlock2,
} = node2 as AstStatementTry;

if (
!this.compareArray(tryCatchStatements1, tryCatchStatements2)
) {
return false;
}

if (catchBlock1 === undefined && catchBlock2 === undefined) {
return true;
}

if (catchBlock1 !== undefined && catchBlock2 !== undefined) {
const {
catchName: catchName1,
catchStatements: catchStatements1,
} = catchBlock1;

const {
catchName: catchName2,
catchStatements: catchStatements2,
} = catchBlock2;

return (
this.compare(catchName1, catchName2) &&
this.compareArray(catchStatements1, catchStatements2)
);
}

return false;
}

case "statement_foreach": {
Expand Down
18 changes: 5 additions & 13 deletions src/ast/getAstSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,23 +342,15 @@ export const getAstSchema = (
StatementTry: (
statements: A.AstStatement[],
loc: Loc,
catchBlock?: {
catchName: A.AstId;
catchStatements: A.AstStatement[];
},
): A.AstStatementTry =>
createNode<A.AstStatementTry>({
kind: "statement_try",
statements,
loc: toSrcInfo(loc),
}),
StatementTryCatch: (
statements: A.AstStatement[],
catchName: A.AstId,
catchStatements: A.AstStatement[],
loc: Loc,
): A.AstStatementTryCatch =>
createNode<A.AstStatementTryCatch>({
kind: "statement_try_catch",
statements,
catchName,
catchStatements,
catchBlock: catchBlock,
loc: toSrcInfo(loc),
}),
StatementForEach: (
Expand Down
6 changes: 4 additions & 2 deletions src/ast/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ export class AstHasher {
case "statement_repeat":
return `${node.kind}|${this.hash(node.iterations)}|${this.hashStatements(node.statements)}`;
case "statement_try":
if (node.catchBlock !== undefined) {
return `${node.kind}|${this.hashStatements(node.statements)}|${this.hash(node.catchBlock.catchName)}|${this.hashStatements(node.catchBlock.catchStatements)}`;
}

return `${node.kind}|${this.hashStatements(node.statements)}`;
case "statement_try_catch":
return `${node.kind}|${this.hashStatements(node.statements)}|${this.hash(node.catchName)}|${this.hashStatements(node.catchStatements)}`;
case "statement_foreach":
return `${node.kind}|${this.hash(node.map)}|${this.hashStatements(node.statements)}`;
case "statement_destruct":
Expand Down
15 changes: 6 additions & 9 deletions src/ast/iterators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,12 @@ export function traverse(node: AstNode, callback: (node: AstNode) => void) {
node.statements.forEach((e) => {
traverse(e, callback);
});
break;
case "statement_try_catch":
node.statements.forEach((e) => {
traverse(e, callback);
});
traverse(node.catchName, callback);
node.catchStatements.forEach((e) => {
traverse(e, callback);
});
if (node.catchBlock !== undefined) {
traverse(node.catchBlock.catchName, callback);
node.catchBlock.catchStatements.forEach((e) => {
traverse(e, callback);
});
}
break;
case "statement_foreach":
traverse(node.keyName, callback);
Expand Down
16 changes: 8 additions & 8 deletions src/ast/rename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,14 @@ export class AstRenamer {
return {
...stmt,
statements: this.renameStatements(stmt.statements),
};
case "statement_try_catch":
return {
...stmt,
statements: this.renameStatements(stmt.statements),
catchStatements: this.renameStatements(
stmt.catchStatements,
),
catchBlock: stmt.catchBlock
? {
catchName: stmt.catchBlock.catchName,
catchStatements: this.renameStatements(
stmt.catchBlock.catchStatements,
),
}
: undefined,
};
case "statement_foreach":
return {
Expand Down
33 changes: 16 additions & 17 deletions src/generator/writers/writeFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,26 +227,25 @@ export function writeStatement(
writeStatement(s, self, returns, ctx);
}
});
ctx.append("} catch (_) { }");
return;
}
case "statement_try_catch": {
ctx.append(`try {`);
ctx.inIndent(() => {
for (const s of f.statements) {
writeStatement(s, self, returns, ctx);

const catchBlock = f.catchBlock;
if (catchBlock !== undefined) {
if (isWildcard(catchBlock.catchName)) {
ctx.append(`} catch (_) {`);
} else {
ctx.append(
`} catch (_, ${funcIdOf(catchBlock.catchName)}) {`,
);
}
});
if (isWildcard(f.catchName)) {
ctx.append(`} catch (_) {`);
ctx.inIndent(() => {
for (const s of catchBlock.catchStatements!) {
writeStatement(s, self, returns, ctx);
}
});
} else {
ctx.append(`} catch (_, ${funcIdOf(f.catchName)}) {`);
ctx.append("} catch (_) { ");
}
ctx.inIndent(() => {
for (const s of f.catchStatements) {
writeStatement(s, self, returns, ctx);
}
});

ctx.append(`}`);
return;
}
Expand Down
20 changes: 8 additions & 12 deletions src/grammar/next/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,23 +567,19 @@ const parseStatementUntil =
};

const parseStatementTry =
({
body,
handler,
loc,
}: $ast.StatementTry): Handler<
A.AstStatementTry | A.AstStatementTryCatch
> =>
({ body, handler, loc }: $ast.StatementTry): Handler<A.AstStatementTry> =>
(ctx) => {
if (handler) {
return ctx.ast.StatementTryCatch(
return ctx.ast.StatementTry(parseStatements(body)(ctx), loc, {
catchName: parseId(handler.name)(ctx),
catchStatements: parseStatements(handler.body)(ctx),
});
} else {
return ctx.ast.StatementTry(
parseStatements(body)(ctx),
parseId(handler.name)(ctx),
parseStatements(handler.body)(ctx),
loc,
undefined,
);
} else {
return ctx.ast.StatementTry(parseStatements(body)(ctx), loc);
}
};

Expand Down
10 changes: 7 additions & 3 deletions src/grammar/prev/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -987,10 +987,14 @@ semantics.addOperation<AstNode>("astOfStatement", {
_rbraceCatch,
) {
return createNode({
kind: "statement_try_catch",
kind: "statement_try",
statements: tryBlock.children.map((s) => s.astOfStatement()),
catchName: exitCodeId.astOfExpression(),
catchStatements: catchBlock.children.map((s) => s.astOfStatement()),
catchBlock: {
catchName: exitCodeId.astOfExpression(),
catchStatements: catchBlock.children.map((s) =>
s.astOfStatement(),
),
},
loc: createRef(this),
});
},
Expand Down
11 changes: 0 additions & 11 deletions src/optimizer/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
AstStatementRepeat,
AstStatementReturn,
AstStatementTry,
AstStatementTryCatch,
AstStatementUntil,
AstStatementWhile,
AstStaticCall,
Expand Down Expand Up @@ -1581,9 +1580,6 @@ export class Interpreter {
case "statement_try":
this.interpretTryStatement(ast);
break;
case "statement_try_catch":
this.interpretTryCatchStatement(ast);
break;
case "statement_until":
this.interpretUntilStatement(ast);
break;
Expand Down Expand Up @@ -1745,13 +1741,6 @@ export class Interpreter {
);
}

public interpretTryCatchStatement(ast: AstStatementTryCatch) {
throwNonFatalErrorConstEval(
"try-catch statements currently not supported",
ast.loc,
);
}

public interpretUntilStatement(ast: AstStatementUntil) {
let condition;
let iterCount = 0;
Expand Down
23 changes: 12 additions & 11 deletions src/prettyPrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,19 +790,22 @@ export const ppAstStatementForEach: Printer<A.AstStatementForEach> =
]);

export const ppAstStatementTry: Printer<A.AstStatementTry> =
({ statements }) =>
(c) =>
c.concat([c.row(`try `), ppStatementBlock(statements)(c)]);
({ statements, catchBlock }) =>
(c) => {
const catchBlocks =
catchBlock !== undefined
? [
c.row(` catch (${ppAstId(catchBlock.catchName)}) `),
ppStatementBlock(catchBlock.catchStatements)(c),
]
: [];

export const ppAstStatementTryCatch: Printer<A.AstStatementTryCatch> =
({ statements, catchName, catchStatements }) =>
(c) =>
c.concat([
return c.concat([
c.row(`try `),
ppStatementBlock(statements)(c),
c.row(` catch (${ppAstId(catchName)}) `),
ppStatementBlock(catchStatements)(c),
...catchBlocks,
]);
};

export const ppAstStatementDestruct: Printer<A.AstStatementDestruct> =
({ type, identifiers, ignoreUnspecifiedFields, expression }) =>
Expand Down Expand Up @@ -845,7 +848,6 @@ export const ppAstStatement: Printer<A.AstStatement> =
statement_repeat: ppAstStatementRepeat,
statement_foreach: ppAstStatementForEach,
statement_try: ppAstStatementTry,
statement_try_catch: ppAstStatementTryCatch,
statement_destruct: ppAstStatementDestruct,
statement_block: ppAstStatementBlock,
});
Expand Down Expand Up @@ -913,7 +915,6 @@ export const ppAstNode: Printer<A.AstNode> = makeVisitor<A.AstNode>()({
statement_until: ppAstStatementUntil,
statement_repeat: ppAstStatementRepeat,
statement_try: ppAstStatementTry,
statement_try_catch: ppAstStatementTryCatch,
statement_foreach: ppAstStatementForEach,
statement_block: ppAstStatementBlock,
import: ppAstImport,
Expand Down
Loading

0 comments on commit a0c8381

Please sign in to comment.