UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

81 lines (79 loc) 3.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ForLoopHelper = void 0; const tslib_1 = require("tslib"); const constants = tslib_1.__importStar(require("../../../constants")); const Helper_1 = require("../Helper"); class ForLoopHelper extends Helper_1.Helper { constructor({ each, cleanup, condition, incrementor, handleReturn }) { super(); this.each = each; this.condition = condition; this.incrementor = incrementor; this.handleReturn = handleReturn === undefined ? cleanup : handleReturn; this.cleanup = cleanup; } emit(sb, node, options) { sb.withProgramCounter((loopPC) => { if (this.condition !== undefined) { this.condition(); } if (!loopPC.getFirst().equals(loopPC.getCurrent())) { sb.emitJmp(node, 'JMPIFNOT', loopPC.getLast()); } sb.withProgramCounter((finallyPC) => { this.each(sb.finallyPCOptions(sb.breakPCOptions(sb.continuePCOptions(sb.noCatchPCOptions(options), finallyPC.getLast()), finallyPC.getLast()), finallyPC.getLast())); if (this.incrementor !== undefined) { this.incrementor(); } sb.emitJmp(node, 'JMP', loopPC.getFirst()); }); sb.emitOp(node, 'DROP'); const condition = (value) => () => { sb.emitOp(node, 'DUP'); sb.emitPushInt(node, value); sb.emitOp(node, 'NUMEQUAL'); }; const val = sb.scope.addUnique(); sb.emitHelper(node, options, sb.helpers.case([ { condition: condition(constants.THROW_COMPLETION), whenTrue: () => { sb.emitOp(node, 'DROP'); sb.scope.set(sb, node, options, val); this.handleReturn(); sb.scope.get(sb, node, options, val); sb.emitHelper(node, options, sb.helpers.throwCompletionBase); }, }, { condition: condition(constants.NORMAL_COMPLETION), whenTrue: () => { sb.emitOp(node, 'DROP'); sb.scope.set(sb, node, options, val); this.handleReturn(); sb.scope.get(sb, node, options, val); sb.emitHelper(node, options, sb.helpers.return); }, }, { condition: condition(constants.BREAK_COMPLETION), whenTrue: () => { sb.emitOp(node, 'DROP'); sb.emitOp(node, 'DROP'); }, }, ], () => { sb.emitOp(node, 'DROP'); sb.emitOp(node, 'DROP'); if (this.incrementor !== undefined) { this.incrementor(); } sb.emitJmp(node, 'JMP', loopPC.getFirst()); })); }); this.cleanup(); } } exports.ForLoopHelper = ForLoopHelper; //# sourceMappingURL=ForLoopHelper.js.map