Skip to content

Instantly share code, notes, and snippets.

@nmn
Last active January 21, 2016 03:40
Show Gist options
  • Save nmn/e995cce0c9fcab8a7375 to your computer and use it in GitHub Desktop.
Save nmn/e995cce0c9fcab8a7375 to your computer and use it in GitHub Desktop.
A work in progress to make a Babel plugin that compiles VerbalExpression (nice library to create RegEx) into proper RegEx's at compile time
import VerEx from 'verbal-expressions';
const eventualCallIs = name => {
// FOR PERF
const boundCheck = node =>
node.type === 'Identifier' && node.name === name ||
node.type === 'MemberExpression' && boundCheck(node.object) ||
node.type === 'CallExpression' && boundCheck(node.callee)
return boundCheck;
};
const allLiteral = (soFar, obj) => soFar && Boolean(obj.type.match(/Literal$/))
const literal = node =>
node.type === 'Identifier'
||
node.type === 'CallExpression' &&
node.arguments.reduce(allLiteral, true) &&
literal(node.callee)
||
node.type === 'MemberExpression' &&
node.property.type === 'Identifier' &&
node.object.type === 'CallExpression' &&
literal(node.object)
const chainToArray = (node) =>
node.type === 'CallExpression' ?
[...chainToArray(node.callee), node.arguments.map(arg => arg.value)]
: node.type === 'MemberExpression' ?
[...chainToArray(node.object), ...chainToArray(node.property)]
: node.type === 'Identifier' ?
[node.name]
:
[];
const chainFn = (obj, [methodName, args, ...rest]) =>
rest.length ?
chainFn(obj[methodName](...args), rest)
: obj[methodName](...args);
export default function ({types: t}) {
return {
visitor: {
CallExpression(path) {
if( path.parent.type !== 'MemberExpression'
&& eventualCallIs('VerEx')(path.node.callee)
&& literal(path.node)
){
var x = chainToArray(path.node);
if(x[0] === 'VerEx' && Array.isArray(x[1]) && x[1].length === 0) {
let veo = chainFn(VerEx(), x.slice(2));
path.replaceWithSourceString(veo.toString());
}
}
}
}
};
}
@nmn
Copy link
Author

nmn commented Jan 4, 2016

...And it's done. Seems to work right.

Current limitations:

  • You can't just chain the regex methods after the creating the regEx.
  • Currently impossible to use VerEx chain as an argument in another VerEx Chain.

So this will not work:

var tester2 =
    VerEx()
    .startOfLine()
    .then(
      VerEx()
      .then('http')
      .maybe('s')
      .or()
      .then('ftp')
    )
    .then('://')
    .maybe('www.')
    .anythingBut(' ')
    .endOfLine()

http://astexplorer.net/#/TiJfAVumDf/1

@srph
Copy link

srph commented Jan 21, 2016

Interesting. Why not spawn a repo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment