• Jump To … +
    compile.js error.js find.js parse.js prune.js rescue.js readme.t.js tree.js
  • compile.js

  • ¶
    const subordinate = require('subordinate')
    
    function sortof (value) {
        if (value == null) {
            return null
        }
        return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
    }
    
    function condition (test) {
        const conditions = []
        switch (test.type) {
        case 'root': {
                return conditions
            }
        case 'error': {
                conditions.push(e => e instanceof test.error)
                for (const pattern of test.patterns) {
                    conditions.push(value => subordinate(value, pattern))
                }
                return conditions
            }
        case 'boolean':
        case 'number':
        case 'string': {
                conditions.push(value => typeof value == test.type)
                for (const pattern of test.patterns) {
                    conditions.push(value => subordinate(value, pattern))
                }
                return conditions
            }
        case 'symbol': {
                conditions.push(value => sortof(value) == test.type)
                for (const pattern of test.patterns) {
                    conditions.push(value => subordinate(value, pattern))
                }
                return conditions
            }
        }
    }
    
    function compile ({ test, next }) {
        const conditions = condition(test)
        const descend = next == null
            ? { dive: [] }
            : Array.isArray(next)
                ? next.map(next => {
                    return { match: next.match, dive: next.dive, test: compile(next) }
                })
                : { dive: next.dive, test: compile(next) }
        return function (object) {
            if (conditions.every(condition => condition(object))) {
                return descend
            }
            return null
        }
    }
    
    module.exports = function (ast) {
        return { match: ast.match, dive: ast.dive, test: compile(ast) }
    }