<commit_before>const fs = require('fs');
const util = require('util');
const parseArgs = require('minimist');
const readline = require('readline');

const argv = parseArgs(process.argv.slice(2), {
  boolean: 'verbose',
  alias: {
    v: 'verbose',
  },
});

const { SymbolNode } = require('./nodes');
const Lexer = require('./lexer');
const Parser = require('./parser');
const Evaluator = require('./evaluator');
const Environment = require('./environment');

(() => {
  function interpret(input, environment = null) {
    const lexer = new Lexer(input);
    const parser = new Parser(lexer.lex());
    const evaluator = new Evaluator(parser.parse(), environment);
    return evaluator.evaluate();
  }

  module.exports = {
    Lexer,
    Parser,
    Evaluator,
    interpret,
  };

  function runFile(filename) {
    let input;
    try {
      input = fs.readFileSync(filename, 'utf8');
    } catch (e) {
      console.log(e.message);
      process.exit();
    }

    const debugInfo = { input };

    try {
      const lexer = new Lexer(input);
      const tokens = lexer.lex();
      debugInfo.tokens = tokens;

      const parser = new Parser(tokens);
      const ast = parser.parse();
      debugInfo.ast = ast;

      const evaluator = new Evaluator(ast);
      const output = evaluator.evaluate();
      debugInfo.output = output;
      debugInfo.prettyOutput = output.toString();
    } catch (e) {
      if (argv.verbose) {
        console.log(util.inspect(debugInfo, { depth: null, colors: true }));
      }
      throw e;
    }

    if (argv.verbose) {
      console.log(util.inspect(debugInfo, { depth: null, colors: true }));
    } else {
      console.log(debugInfo.prettyOutput);
    }
  }

  function runRepl() {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });

    const replEnvironment = new Environment();

    rl.prompt();
    rl.on('line', (line) => {
      let result = null;
      try {
        result = interpret(line, replEnvironment);
      } catch (e) {
        console.log(e.message);
      }
      if (result) {
        replEnvironment.define(new SymbolNode('_'), result);
        console.log(result.toString());
      }
      rl.prompt();
    }).on('close', () => {
      process.exit(0);
    });
  }

  if (!module.parent) {
    if (argv._.length > 0) {
      runFile(argv._.shift());<commit_msg>Ignore blank lines in REPL<commit_after>const fs = require('fs');
const util = require('util');
const parseArgs = require('minimist');
const readline = require('readline');

const argv = parseArgs(process.argv.slice(2), {
  boolean: 'verbose',
  alias: {
    v: 'verbose',
  },
});

const { SymbolNode } = require('./nodes');
const Lexer = require('./lexer');
const Parser = require('./parser');
const Evaluator = require('./evaluator');
const Environment = require('./environment');

(() => {
  function interpret(input, environment = null) {
    const lexer = new Lexer(input);
    const parser = new Parser(lexer.lex());
    const evaluator = new Evaluator(parser.parse(), environment);
    return evaluator.evaluate();
  }

  module.exports = {
    Lexer,
    Parser,
    Evaluator,
    interpret,
  };

  function runFile(filename) {
    let input;
    try {
      input = fs.readFileSync(filename, 'utf8');
    } catch (e) {
      console.log(e.message);
      process.exit();
    }

    const debugInfo = { input };

    try {
      const lexer = new Lexer(input);
      const tokens = lexer.lex();
      debugInfo.tokens = tokens;

      const parser = new Parser(tokens);
      const ast = parser.parse();
      debugInfo.ast = ast;

      const evaluator = new Evaluator(ast);
      const output = evaluator.evaluate();
      debugInfo.output = output;
      debugInfo.prettyOutput = output.toString();
    } catch (e) {
      if (argv.verbose) {
        console.log(util.inspect(debugInfo, { depth: null, colors: true }));
      }
      throw e;
    }

    if (argv.verbose) {
      console.log(util.inspect(debugInfo, { depth: null, colors: true }));
    } else {
      console.log(debugInfo.prettyOutput);
    }
  }

  function runRepl() {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });

    const replEnvironment = new Environment();

    rl.prompt();
    rl.on('line', (line) => {
      if (line.trim()) {
        let result = null;
        try {
          result = interpret(line, replEnvironment);
        } catch (e) {
          console.log(e.message);
        }
        if (result) {
          replEnvironment.define(new SymbolNode('_'), result);
          console.log(result.toString());
        }
      }
      rl.prompt();
    }).on('close', () => {
      process.exit(0);
    });
  }

  if (!module.parent) {
    if (argv._.length > 0) {
      runFile(argv._.shift());
{'fraction_non_alphanumeric': 0.15605622157916493, 'fraction_numerical': 0.0016535758577924762, 'mean_word_length': 2.521834061135371, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '5468265', 'n_tokens_mistral': 1520, 'n_tokens_neox': 1477, 'n_words': 335}