UNPKG

@effectful/transducers

Version:

JS syntax transformation framework for @effectful/js

120 lines (119 loc) 3.86 kB
"use strict"; exports.__esModule = true; exports.default = void 0; var _core = require("../core"); var Kit = require("../kit"); var T = require("@babel/types"); const SpecVars = (0, _core.symbol)("SpecVars", "ctrl"); const specNames = { arguments: true }; var _default = exports.default = Kit.pipe(Kit.wrap("eager-generators-transform", function* transform(s) { function* make(i) { i.value.node.generator = false; const lab = s.label(); yield* s.peelTo(_core.Tag.body); yield* s.peelTo(_core.Tag.body); const specVars = {}; yield s.tok(_core.Tag.push, SpecVars, { node: specVars }); yield s.enter(_core.Tag.push, _core.Tag.ReturnStatement); yield s.enter(_core.Tag.argument, _core.Tag.CallExpression); yield s.tok(_core.Tag.callee, T.identifier("e$y$make")); yield s.enter(_core.Tag.arguments, _core.Tag.Array); yield s.enter(_core.Tag.push, _core.Tag.ArrowFunctionExpression, { node: { id: { type: "Identifier", name: i.value.node.id != null ? `${i.value.node.id.name}Impl` : "EagerGen" }, params: [{ type: "Identifier", name: "e$y$buf" }] } }); yield s.enter(_core.Tag.body, _core.Tag.BlockStatement); yield s.enter(_core.Tag.body, _core.Tag.Array); yield* walk(specVars); yield* lab(); } function* walk(specVars) { for (const i of s.sub()) { switch (i.type) { case _core.Tag.YieldExpression: if (i.enter) { const lab = s.label(); yield s.enter(i.pos, _core.Tag.CallExpression); yield s.tok(_core.Tag.callee, T.identifier(i.value.node.delegate ? "e$y$star" : "e$y")); yield s.enter(_core.Tag.arguments, _core.Tag.Array); yield s.tok(_core.Tag.push, T.identifier("e$y$buf")); yield s.enter(_core.Tag.push, Kit.Subst); yield* walk(specVars); yield* lab(); } continue; case _core.Tag.Identifier: if (specVars != null && specNames[i.value.node.name]) { specVars[i.value.node.name] = true; if (i.enter) //TODO: unique names yield s.tok(i.pos, T.identifier(`e$y$${i.value.node.name}`)); continue; } case _core.Tag.FunctionExpression: case _core.Tag.ArrowFunctionExpression: case _core.Tag.FunctionDeclaration: if (i.enter && i.value.node.generator) { yield i; yield* make(i); continue; } } yield i; } } for (const i of s) { yield i; switch (i.type) { case _core.Tag.Class: case _core.Tag.ClassBody: case _core.Tag.ClassMethod: case _core.Tag.FunctionExpression: case _core.Tag.ArrowFunctionExpression: case _core.Tag.FunctionDeclaration: if (i.enter) { if (!i.value.node.generator) break; if (Kit.hasAnnot(i.value.node, "@LAZY")) { yield* s.sub(); break; } yield* make(i); } } } }), Array.from, function* completeSpecVars(si) { const s = Kit.auto(si); for (const i of s) { if (i.type === SpecVars) { const lab = s.label(); const k = Object.keys(i.value.node); if (k.length) { yield s.enter(i.pos, _core.Tag.VariableDeclaration, { node: { kind: "var" } }); yield s.enter(_core.Tag.declarations, _core.Tag.Array); for (const j of k) { yield s.enter(_core.Tag.push, _core.Tag.VariableDeclarator); yield s.tok(_core.Tag.id, T.identifier(`e$y$${j}`)); yield s.tok(_core.Tag.init, T.identifier(j)); yield* s.leave(); } yield* lab(); } } else yield i; } }, Kit.completeSubst);