UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

82 lines (80 loc) 3.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SwitchStatementCompiler = void 0; const tslib_1 = require("tslib"); const ts_utils_1 = require("@neo-one/ts-utils"); const typescript_1 = tslib_1.__importDefault(require("typescript")); const constants = tslib_1.__importStar(require("../../constants")); const NodeCompiler_1 = require("../NodeCompiler"); class SwitchStatementCompiler extends NodeCompiler_1.NodeCompiler { constructor() { super(...arguments); this.kind = typescript_1.default.SyntaxKind.SwitchStatement; } visitNode(sb, node, optionsIn) { const options = sb.pushValueOptions(optionsIn); sb.withProgramCounter((pc) => { const switchExpr = ts_utils_1.tsUtils.expression.getExpression(node); const switchExprType = sb.context.analysis.getType(switchExpr); let breakOptions = sb.breakPCOptions(sb.noPushValueOptions(options), pc.getLast()); if (breakOptions.finallyPC !== undefined) { breakOptions = sb.finallyPCOptions(breakOptions, pc.getLast()); } const caseBlock = ts_utils_1.tsUtils.statement.getCaseBlock(node); const clauses = ts_utils_1.tsUtils.statement.getClauses(caseBlock); const { found: defaultFound, statements: defaultClauseStatements } = clauses.reduce((acc, clause) => { const { found, statements } = acc; if (found) { return { found, statements: statements.concat(ts_utils_1.tsUtils.statement.getStatements(clause)), }; } if (typescript_1.default.isDefaultClause(clause)) { return { found: true, statements: ts_utils_1.tsUtils.statement.getStatements(clause) }; } return { found: false, statements }; }, { found: false, statements: [] }); const matched = sb.scope.addUnique(); const val = sb.scope.addUnique(); sb.visit(switchExpr, options); sb.scope.set(sb, node, options, val); sb.emitPushBoolean(switchExpr, false); sb.scope.set(sb, node, options, matched); clauses.forEach((clause) => { if (typescript_1.default.isDefaultClause(clause)) { return; } sb.emitHelper(clause, options, sb.helpers.if({ condition: () => { const expr = ts_utils_1.tsUtils.expression.getExpression(clause); sb.scope.get(sb, node, options, val); sb.visit(expr, options); sb.emitHelper(expr, options, sb.helpers.equalsEqualsEquals({ leftType: switchExprType, rightType: sb.context.analysis.getType(expr), })); sb.scope.get(sb, node, options, matched); sb.emitOp(node, 'BOOLOR'); }, whenTrue: () => { sb.emitPushBoolean(node, true); sb.scope.set(sb, node, options, matched); ts_utils_1.tsUtils.statement.getStatements(clause).forEach((statement) => { sb.visit(statement, breakOptions); }); }, })); }); if (defaultFound) { defaultClauseStatements.forEach((statement) => { sb.visit(statement, breakOptions); }); } sb.emitPushInt(node, constants.BREAK_COMPLETION); }); sb.emitOp(node, 'DROP'); } } exports.SwitchStatementCompiler = SwitchStatementCompiler; //# sourceMappingURL=SwitchStatementCompiler.js.map