@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
81 lines (79 loc) • 3.3 kB
JavaScript
;
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