Search code examples
javascriptsweet.js

Inserting arbitrary strings into sweet.js output


How do you insert a arbitrary string into the output that sweet.js generates?

This is very useful for programatically doing things where the string is different based on various conditions.

For example, on line 25 in the code below, I would like to insert a string as the result.

sweet.js code:

    import { produceNormalParams } from './abc/produceNormalParams'
    import { produceParamChecks }  from './abc/produceParamChecks'
    import { produceInnerChecks }  from './abc/produceInnerChecks'

    syntax function = function(ctx) {
        let funcName   = ctx.next().value;
        let funcParams = ctx.next().value;
        let funcBody   = ctx.next().value;

        //produce the normal params array
        var normalParams = produceNormalParams(funcParams)

        //produce the checks
        var paramChecks = produceParamChecks(funcParams)

        //produce the original funcBody code
        var inner = produceInnerChecks(funcParams)

        var someArbitraryString = "console.log('hey')"

        //put them together as the final result
        var result = #`function ${funcName} ${normalParams} {
            ${someArbitraryString}
            ${paramChecks}
            ${inner}
        }`

        return result
    }

Example Input:

    module.exports = multiply

    function multiply(a:array,b,c:array) {
        return a * c
    }

Example Output:

    // Example Output
    module.exports = multiply;
    function multiply(a_31, b_32, c_33) {
        console.log('hey')
        if (Object.prototype.toString.call(a_31) !== "[object Array]") throw new Error("Must be array:" + a_31);
        if (Object.prototype.toString.call(c_33) !== "[object Array]") throw new Error("Must be array:" + c_33);
        return a_31 * c_33;
    }

Solution

  • While you can't insert arbitrary strings into a syntax template, you can interpolate other syntax templates.

    import { produceNormalParams } from './abc/produceNormalParams' for syntax;   
    import { produceParamChecks }  from './abc/produceParamChecks' for syntax;
    import { produceInnerChecks }  from './abc/produceInnerChecks' for syntax;
    
    syntax function = function(ctx) {
        let funcName   = ctx.next().value;
        let funcParams = ctx.next().value;
        let funcBody   = ctx.next().value;
    
        //produce the normal params array
        var normalParams = produceNormalParams(funcParams);
    
        //produce the checks
        var paramChecks = produceParamChecks(funcParams);
    
        //produce the original funcBody code
        var inner = produceInnerChecks(funcParams);
    
        var someArbitrarySyntax = #`console.log('hey')`;
    
        //put them together as the final result
        var result = #`function ${funcName} ${normalParams} {
            ${someArbitrarySyntax}
            ${paramChecks}
            ${inner}
        }`;
    
        return result
    }
    

    Note the for syntax trailing the import statements. These are necessary for the imports to be available during compile time.