<commit_before>var _ = require('underscore');
var CodeGenerator = require('./code-generator');
var errors = require('../errors');

var UNARY_OPS_TO_FUNCTIONS = {
    '+':   'pos',
    '-':   'neg',
    '~':   'bnot',
    'NOT': 'lnot'
};

var BINARY_OPS_TO_FUNCTIONS = {
    '+':   'add',
    '-':   'sub',
    '*':   'mul',
    '/':   'div',
    '%':   'mod',
    '&':   'band',
    '|':   'bor',
    '^':   'bxor',
    '<<':  'shl',
    '>>':  'shr',
    '>>>': 'shrz',
    '==':  'eql',
    '!=':  'neq',
    '=~':  'match',
    '!~':  'nmatch',
    '<':   'lt',
    '>':   'gt',
    '<=':  'lte',
    '>=':  'gte',
    'in':  'in',
    'AND': 'land',
    'OR':  'lor',
    '??':  'coal'
};

var SYMBOL_TYPE_NAMES = {
    'function': 'function',
    'reducer': 'reducer',
    'sub': 'subgraph',
    'import': 'module'
};

//
// generate a javascript program that when run returns a flowgraph
// datastructure representing the juttle program fully evaluated
// in build context.  this intermediate form can then be optimized,
// before a final pass traverses it and spits out the target implementation
// (which is currently limited to javascript running against the
// juttle js runtime)
//
var Build = CodeGenerator.extend({
    initialize: function() {
        // XXX/sm we can easily get rid of emit and just recursively return
        // the code strings, except we rely on returning the uname for the
        // proc when building the graph contruction code
        this.code = '';
    },
    gen: function(ast) {
        var code, body;
        var self = this;

        _.each(ast.modules, function(ast) {
            self.gen_ModuleDef(ast);
        } );

        this.gen_SubDef(ast, {path_info: {mod: '', sub: []}});
        body = this.code;
        //
        // wrap main in a closure so it does not pollute the name space.
        // call main and return its value, which is the flowgraph head object.
        // this should be the only object reference into the entire
        // compiled world and associated runtime.
        //
        code = '(function(builder) {\n';
        code += 'var sinks=[];\n';
        code += body;
        code += 'builder.record_stats(' + JSON.stringify(ast.stats) + ');';
        code += 'return { sinks: sinks,';
        code += 'graph: ' + ast.uname + '() };\n';
        code += '});\n';
        return code;
    },
    emit: function(s) {
        this.code += s;
    },
    gen_var: function(uname) {
        return 'var ' + uname + ';\n';
    },
    gen_var_decl: function(decl) {
        var code = this.gen_var(decl.uname);
        code += decl.uname;
        code += ' = ';
        code += decl.expr ? this.gen_expr(decl.expr) : 'null';
        code += ';\n';
        return code;
    },
    gen_const_decl: function(decl) {<commit_msg>Build: Do not return anything from generated build function<commit_after>var _ = require('underscore');
var CodeGenerator = require('./code-generator');
var errors = require('../errors');

var UNARY_OPS_TO_FUNCTIONS = {
    '+':   'pos',
    '-':   'neg',
    '~':   'bnot',
    'NOT': 'lnot'
};

var BINARY_OPS_TO_FUNCTIONS = {
    '+':   'add',
    '-':   'sub',
    '*':   'mul',
    '/':   'div',
    '%':   'mod',
    '&':   'band',
    '|':   'bor',
    '^':   'bxor',
    '<<':  'shl',
    '>>':  'shr',
    '>>>': 'shrz',
    '==':  'eql',
    '!=':  'neq',
    '=~':  'match',
    '!~':  'nmatch',
    '<':   'lt',
    '>':   'gt',
    '<=':  'lte',
    '>=':  'gte',
    'in':  'in',
    'AND': 'land',
    'OR':  'lor',
    '??':  'coal'
};

var SYMBOL_TYPE_NAMES = {
    'function': 'function',
    'reducer': 'reducer',
    'sub': 'subgraph',
    'import': 'module'
};

//
// generate a javascript program that when run returns a flowgraph
// datastructure representing the juttle program fully evaluated
// in build context.  this intermediate form can then be optimized,
// before a final pass traverses it and spits out the target implementation
// (which is currently limited to javascript running against the
// juttle js runtime)
//
var Build = CodeGenerator.extend({
    initialize: function() {
        // XXX/sm we can easily get rid of emit and just recursively return
        // the code strings, except we rely on returning the uname for the
        // proc when building the graph contruction code
        this.code = '';
    },
    gen: function(ast) {
        var code, body;
        var self = this;

        _.each(ast.modules, function(ast) {
            self.gen_ModuleDef(ast);
        } );

        this.gen_SubDef(ast, {path_info: {mod: '', sub: []}});
        body = this.code;
        //
        // wrap main in a closure so it does not pollute the name space.
        // call main and return its value, which is the flowgraph head object.
        // this should be the only object reference into the entire
        // compiled world and associated runtime.
        //
        code = '(function(builder) {\n';
        code += body;
        code += 'builder.record_stats(' + JSON.stringify(ast.stats) + ');';
        code += ast.uname + '();\n';
        code += '});\n';
        return code;
    },
    emit: function(s) {
        this.code += s;
    },
    gen_var: function(uname) {
        return 'var ' + uname + ';\n';
    },
    gen_var_decl: function(decl) {
        var code = this.gen_var(decl.uname);
        code += decl.uname;
        code += ' = ';
        code += decl.expr ? this.gen_expr(decl.expr) : 'null';
        code += ';\n';
        return code;
    },
    gen_const_decl: function(decl) {
{'fraction_non_alphanumeric': 0.17758527341635083, 'fraction_numerical': 0.0, 'mean_word_length': 2.1065022421524664, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6848250', 'n_tokens_mistral': 1841, 'n_tokens_neox': 1799, 'n_words': 498}