Skip to content

Instantly share code, notes, and snippets.

@pelotom
Last active December 30, 2020 11:18
Show Gist options
  • Select an option

  • Save pelotom/98e0de19adfc164f9248 to your computer and use it in GitHub Desktop.

Select an option

Save pelotom/98e0de19adfc164f9248 to your computer and use it in GitHub Desktop.

Revisions

  1. pelotom revised this gist Mar 16, 2016. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -5,9 +5,7 @@ const λ = ({raw}, ...subs) => {

    const evaluate = new Function('___subs', '___args', `return (${expr});`)

    return (...args) => {
    return evaluate(subs, args)
    }
    return (...args) => evaluate(subs, args)
    }

    /*
  2. pelotom revised this gist Mar 16, 2016. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,10 @@
    const λ = ({raw}, ...subs) => {
    const expr = raw
    .reduce((prev, next, n) => prev + '(___subs[' + (n - 1) + '])' + next)
    .replace(/#(\d+)/g, (_, n) => '(___args[' + n + '])')
    const evaluate = new Function('___subs', '___args', 'return (' + expr + ');')
    .reduce((prev, next, n) => prev + `(___subs[${n - 1}])` + next)
    .replace(/#(\d+)/g, (_, n) => `(___args[${n}])`)

    const evaluate = new Function('___subs', '___args', `return (${expr});`)

    return (...args) => {
    return evaluate(subs, args)
    }
  3. pelotom revised this gist Mar 16, 2016. 1 changed file with 12 additions and 4 deletions.
    16 changes: 12 additions & 4 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,14 @@
    const λ = ({raw: [raw]}) => eval('(function (...args) { return (' +
    raw.replace(/#(\d+)/g, (_, n) => '(args[' + n + '])') +
    '); })')
    const λ = ({raw}, ...subs) => {
    const expr = raw
    .reduce((prev, next, n) => prev + '(___subs[' + (n - 1) + '])' + next)
    .replace(/#(\d+)/g, (_, n) => '(___args[' + n + '])')

    const evaluate = new Function('___subs', '___args', 'return (' + expr + ');')

    return (...args) => {
    return evaluate(subs, args)
    }
    }

    /*
    @@ -11,7 +19,7 @@ const λ = ({raw: [raw]}) => eval('(function (...args) { return (' +
    ["foo", true, 3]
    > const field = 'x', n = 4
    > [{x: 8}, {x: 3}, {x: 9}].map(λ`#0[field] * (#1 + n)`)
    > [{x: 8}, {x: 3}, {x: 9}].map(λ`#0[${field}] * (#1 + ${n})`)
    [32,15,54]
    */
  4. pelotom revised this gist Mar 16, 2016. 1 changed file with 3 additions and 20 deletions.
    23 changes: 3 additions & 20 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,23 +1,6 @@
    const λ = ({raw: [raw]}, ...subs) => {
    if (subs.length > 0) {
    console.error('Interpolation is unnecessary, just use x instead of ${x}')
    return
    }

    const indices = []
    const expr = raw.replace(/#(\d+)/g, (_, n) => {
    indices.push(n)
    return '(vars[' + n + '])'
    })

    const f = eval('(function (vars) { return (' + expr + '); })')

    return (...args) => {
    const vars = {}
    indices.forEach(i => { vars[i] = args[i] })
    return f(vars)
    }
    }
    const λ = ({raw: [raw]}) => eval('(function (...args) { return (' +
    raw.replace(/#(\d+)/g, (_, n) => '(args[' + n + '])') +
    '); })')

    /*
  5. pelotom revised this gist Mar 16, 2016. 1 changed file with 18 additions and 19 deletions.
    37 changes: 18 additions & 19 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,23 +1,22 @@
    const λ = ({raw}, ...subs) => (...args) => {
    const buf = [],
    table = {}

    function addVar(name, val) {
    table[name] = val
    return name
    const λ = ({raw: [raw]}, ...subs) => {
    if (subs.length > 0) {
    console.error('Interpolation is unnecessary, just use x instead of ${x}')
    return
    }

    for (let i = 0; i < raw.length; i++) {
    buf.push(raw[i].replace(/#(\d+)/g, (_, n) => addVar('__arg_' + n, args[n])))
    if (i < raw.length - 1)
    buf.push(addVar('__sub_' + i, subs[i]))

    const indices = []
    const expr = raw.replace(/#(\d+)/g, (_, n) => {
    indices.push(n)
    return '(vars[' + n + '])'
    })

    const f = eval('(function (vars) { return (' + expr + '); })')

    return (...args) => {
    const vars = {}
    indices.forEach(i => { vars[i] = args[i] })
    return f(vars)
    }

    const expr = buf.join(''),
    vars = Object.keys(table),
    vals = vars.map(k => table[k])

    return (new (Function.prototype.bind.apply(Function, [null, vars, `return ${expr}`]))).apply(null, vals)
    }

    /*
    @@ -29,7 +28,7 @@ const λ = ({raw}, ...subs) => (...args) => {
    ["foo", true, 3]
    > const field = 'x', n = 4
    > [{x: 8}, {x: 3}, {x: 9}].map(λ`#0[${field}] * (#1 + ${n})`)
    > [{x: 8}, {x: 3}, {x: 9}].map(λ`#0[field] * (#1 + n)`)
    [32,15,54]
    */
  6. pelotom revised this gist Mar 16, 2016. 1 changed file with 10 additions and 10 deletions.
    20 changes: 10 additions & 10 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,23 +1,23 @@
    const λ = ({raw}, ...subs) => (...args) => {
    const buf = [],
    table = {}
    function addVar(name, value) {
    table[name] = value

    function addVar(name, val) {
    table[name] = val
    return name
    }

    for (let i = 0; i < raw.length; i++) {
    buf.push(raw[i].replace(/#(\d+)/g, (_, n) => addVar('__arg_' + n, args[n])))
    if (i < raw.length - 1)
    buf.push(addVar('__sub_' + i, subs[i]))
    }
    const expr = buf.join('')
    const keys = Object.keys(table)
    const values = keys.map(k => table[k])
    return (new (Function.prototype.bind.apply(Function, [null, keys, `return ${expr}`]))).apply(null, values)

    const expr = buf.join(''),
    vars = Object.keys(table),
    vals = vars.map(k => table[k])

    return (new (Function.prototype.bind.apply(Function, [null, vars, `return ${expr}`]))).apply(null, vals)
    }

    /*
  7. pelotom revised this gist Mar 16, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -22,7 +22,7 @@ const λ = ({raw}, ...subs) => (...args) => {

    /*
    > λ`(#0 + #1) * #2`(4, 2, 7)
    > λ`(#0 + #2) * #1`(4, 7, 2)
    42
    > [{x: 'foo'}, {x: true}, {x: 3}].map(λ`#0.x`)
  8. pelotom revised this gist Mar 16, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -8,9 +8,9 @@ const λ = ({raw}, ...subs) => (...args) => {
    }

    for (let i = 0; i < raw.length; i++) {
    buf.push(raw[i].replace(/#(\d+)/g, (_, n) => addVar('___' + n, args[n])))
    buf.push(raw[i].replace(/#(\d+)/g, (_, n) => addVar('__arg_' + n, args[n])))
    if (i < raw.length - 1)
    buf.push(addVar('____' + i, subs[i]))
    buf.push(addVar('__sub_' + i, subs[i]))
    }

    const expr = buf.join('')
  9. pelotom revised this gist Mar 16, 2016. 1 changed file with 22 additions and 12 deletions.
    34 changes: 22 additions & 12 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,25 +1,35 @@
    function λ({raw: [raw]}) {
    const splat = raw.split('_'),
    buf = [],
    vars = []
    const λ = ({raw}, ...subs) => (...args) => {
    const buf = [],
    table = {}

    for (let i = 0; i < splat.length - 1; i++) {
    const varName = '___' + i
    buf.push(splat[i], varName)
    vars.push(varName)
    function addVar(name, value) {
    table[name] = value
    return name
    }

    buf.push(splat[splat.length - 1])
    for (let i = 0; i < raw.length; i++) {
    buf.push(raw[i].replace(/#(\d+)/g, (_, n) => addVar('___' + n, args[n])))
    if (i < raw.length - 1)
    buf.push(addVar('____' + i, subs[i]))
    }

    const expr = buf.join('')
    const keys = Object.keys(table)
    const values = keys.map(k => table[k])

    return new (Function.prototype.bind.apply(Function, [null, vars, 'return ' + buf.join('')]))
    return (new (Function.prototype.bind.apply(Function, [null, keys, `return ${expr}`]))).apply(null, values)
    }

    /*
    > λ`(_ + _) * _`(4, 2, 7)
    > λ`(#0 + #1) * #2`(4, 2, 7)
    42
    > [{x: 'foo'}, {x: true}, {x: 3}].map(λ`_.x`)
    > [{x: 'foo'}, {x: true}, {x: 3}].map(λ`#0.x`)
    ["foo", true, 3]
    > const field = 'x', n = 4
    > [{x: 8}, {x: 3}, {x: 9}].map(λ`#0[${field}] * (#1 + ${n})`)
    [32,15,54]
    */
  10. pelotom revised this gist Mar 16, 2016. 1 changed file with 11 additions and 10 deletions.
    21 changes: 11 additions & 10 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,17 @@
    function λ(strings, ...args) {
    const splat = strings.raw[0].split('_')

    let buf = '', table = {}
    function λ({raw: [raw]}) {
    const splat = raw.split('_'),
    buf = [],
    vars = []

    for (let i = 0; i < splat.length - 1; i++) {
    const varName = '___' + i
    buf += splat[i] + varName
    table[varName] = args[i]
    buf.push(splat[i], varName)
    vars.push(varName)
    }
    buf += splat[splat.length - 1]

    const keys = Object.keys(table)
    return new (Function.prototype.bind.apply(Function, [null, ...keys, 'return ' + buf]))

    buf.push(splat[splat.length - 1])

    return new (Function.prototype.bind.apply(Function, [null, vars, 'return ' + buf.join('')]))
    }

    /*
  11. pelotom created this gist Mar 15, 2016.
    24 changes: 24 additions & 0 deletions tagged-template-dsl-example.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    function λ(strings, ...args) {
    const splat = strings.raw[0].split('_')

    let buf = '', table = {}
    for (let i = 0; i < splat.length - 1; i++) {
    const varName = '___' + i
    buf += splat[i] + varName
    table[varName] = args[i]
    }
    buf += splat[splat.length - 1]

    const keys = Object.keys(table)
    return new (Function.prototype.bind.apply(Function, [null, ...keys, 'return ' + buf]))
    }

    /*
    > λ`(_ + _) * _`(4, 2, 7)
    42
    > [{x: 'foo'}, {x: true}, {x: 3}].map(λ`_.x`)
    ["foo", true, 3]
    */