JSFiddle - React, Tailwind, and code Playground

by Daedalus

JavaScript

class AliasParser {
    constructor(identifiers) {
        this.identifiers = Object.assign(
            {
                $chr(num) {
                    return String.fromCharCode(num);
                }
            },
            identifiers
        );
    }

    /**
     * Parse a function statement
     *
     * @see https://stackoverflow.com/a/28641953/785241
     * @param {string} statement
     * @returns {array}
     */
    parseStatement(statement) {
        var regex = new RegExp("(\\$[a-z]+)\\((.+)\\)", "gi");
        var results = regex.exec(statement);
        // This regex matches for the widest pattern: identifier(stuff-inside)
        // Running the previous output would result in matching groups of:
        // identifier: a
        // stuff-inside: b,c(e,f(h,i,j),g(k,l,m(o,p,q))),d(r,s,t)

        var root = [];
        // We need a way to split the stuff-inside by commas that are not enclosed in parenthesis.
        // We want to turn stuff-inside into the following array:
        // [ 'b', 'c(e,f(h,i,j),g(k,l,m(o,p,q)))', 'd(r,s,t)' ]
        // Since my regex-fu is bad, I wrote a function to do this, explained in the next step.
        if (results !== null) {
            var parameters = this.splitStatementByExternalCommas(results[2]);

            var node = {
                params: []
            };
            parameters.forEach(parameter => {
                if (parameter.indexOf("(") == -1) {
                    node.params.push(parameter.trim());
                } else {
                    // Recursion. This function produces an anonymous wrapper object around a node.
                    // I will need to unwrap my result.
                    var wrappedNode = this.parseStatement(parameter);
                    var key;
                    for (key in wrappedNode) {
                        let nodeObj = wrappedNode[key];
                        nodeObj.param = parameter;
                        node.params.push(nodeObj);
             ...