UNPKG

coffee-subscript

Version:

Integration between CoffeeScript and arbitrary DSL-s that compile to JavaScript

148 lines (139 loc) 4.47 kB
// Generated by CoffeeScript 1.6.2 (function() { var CoffeeScript; CoffeeScript = require('coffee-script'); exports.preprocess = function(mixedCode, opts) { var ast, char, coffeeCode, escape, fragments, i, inQuote, indent, indentRE, j, k, lines, max, parens, queue, scopeNode, squiggleStart, startPos, stopPos, _i, _ref; if (opts == null) { opts = {}; } fragments = []; mixedCode = mixedCode.replace(/«([^»]*)»/g, function(_, dslCode) { var padding; fragments.push({ kind: 'expression', dslCode: dslCode }); padding = dslCode.replace(/[^\n]/g, ''); return "`@" + (fragments.length - 1) + padding + "`"; }); lines = mixedCode.split('\n'); i = 0; while (i < lines.length) { if (/\(\s*~>.*\)/.test(lines[i])) { while ((squiggleStart = lines[i].indexOf("~>")) !== -1) { startPos = squiggleStart; while (startPos > 0) { startPos--; if (lines[i][startPos] === "(") { break; } } max = lines[i].length - 1; escape = false; inQuote = false; parens = 1; stopPos = squiggleStart + 1; while (parens) { stopPos++; if (stopPos > max) { throw "Did not match paren"; } char = lines[i][stopPos]; if (inQuote) { if (escape) { escape = false; } else if (char === "\\") { escape = true; } else if (char === '"') { inQuote = false; } } else if (char === '"') { inQuote = true; } else if (char === "(") { parens++; } else if (char === ")") { parens--; } } fragments.push({ kind: 'function', dslCode: lines[i].slice(squiggleStart + 2, +(stopPos - 1) + 1 || 9e9) }); lines[i] = lines[i].replace(lines[i].slice(startPos, +stopPos + 1 || 9e9), "`@" + (fragments.length - 1) + "`"); } i++; } else if (/~>\s*$/.test(lines[i])) { indent = lines[i].replace(/^([ \t]*).*$/, '$1'); indentRE = new RegExp('^' + indent.replace(/\t/g, '\\t') + '[ \t]'); j = i + 1; while (j < lines.length && indentRE.test(lines[j])) { j++; } fragments.push({ kind: 'function', dslCode: lines.slice(i + 1, j).join('\n') }); lines[i] = lines[i].replace(/~>\s*$/, "`@" + (fragments.length - 1) + "`"); for (k = _i = _ref = i + 1; _i < j; k = _i += 1) { lines[k] = ''; } i = j; } else { i++; } } coffeeCode = lines.join('\n'); ast = CoffeeScript.nodes(coffeeCode); ast.vars = {}; queue = [ast]; while (queue.length) { scopeNode = queue.shift(); scopeNode.traverseChildren(false, function(node) { var m, name, v, _ref1, _ref2, _ref3; name = node.constructor.name; if (name === 'Code') { node.vars = {}; _ref1 = scopeNode.vars; for (k in _ref1) { v = _ref1[k]; node.vars[k] = v; } queue.push(node); } else if (name === 'Literal' && (m = node.value.match(/^@(\d+)$/))) { fragments[+m[1]].vars = scopeNode.vars; } else if (name === 'Assign') { if (v = (_ref2 = node.variable) != null ? (_ref3 = _ref2.base) != null ? _ref3.value : void 0 : void 0) { scopeNode.vars[v] = {}; } } return true; }); } return coffeeCode = coffeeCode.replace(/`@(\d+)`/g, function(_, id) { var f, jsCode, name, _ref1; f = fragments[+id]; jsCode = require((_ref1 = opts.dsl) != null ? _ref1 : 'apl').compile(f.dslCode, { embedded: true, kind: f.kind, vars: (function() { var _ref1, _results; _ref1 = f.vars; _results = []; for (name in _ref1) { _ = _ref1[name]; _results.push({ name: name }); } return _results; })() }); jsCode = "(function () { " + jsCode + " })"; if (f.kind === 'expression') { jsCode += '()'; } return "`" + jsCode + "`"; }); }; }).call(this);