async function evaluateMatcher(matcher, str) {
        var result = matcher.apply(this, [str]); // eslint-disable-line no-useless-call
        if(isPromise(result)) {
            result = await result;
        }
        if(result && !(typeof result.start === 'number' || result.end === 'number' || Array.isArray(result.groups) || isFunction(result.next))) {
            // the matcher function didn't return the correct structure
            throw {
                code: "T1010",
                stack: (new Error()).stack,
            };
        }
        return result;
    }
Evaluate the matcher function against the str arg

@param {*} matcher - matching function (native or lambda)
@param {string} str - the string to match against
@returns {object} - structure that represents the match(es)