<commit_before>"use strict";

let Input = require('./input.js');
let parser = require('./parser.js');
let Environment = require('./environment.js');
let Type = require('./types/type.js');
let makeStatement = require('./statements/factory.js');
let makeType = require('./types/factory.js');
let process = require('process');
let errors = require('./errors.js');

let out = function(o) {
  console.log(JSON.stringify(o, null, 2));
};

let load = function(parsed, env) {
  let ast = makeStatement(parsed, env);
  return {
    ast: ast,
    env: env,
  };
};

let loadPrelude = function() {
  let env = new Environment();
  load(parser.parse(new Input('prelude.model')), env);
  return env;
};

let repl = function(env) {
  var readline = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
  });

  let printError = function(error) {
    if (error instanceof errors.Base) { // modeling error
      console.log(`${error}`);
    } else { // JS error
      if (error.stack !== undefined) {
        console.log(`${error.stack}`);
      } else {
        console.log(`${error}`);
      }
    }
  };

  var forgivingParse = function(input, env) {
    let parse = (input) => load(parser.parse(new Input('REPL', input)), env);
    let rescueAttempts = [
      (input) => parse(input + ';'),
      (input) => parse('print ' + input),
      (input) => parse('print ' + input + ';'),
    ];
    try {
      return parse(input);
    } catch ( originalError ) {
      let module = null;
      rescueAttempts.forEach((attempt) => {
        if (module === null) {
          try {
            module = attempt(input);
          } catch ( uselessError ) {
            // do nothing
          }
        }
      });
      if (module === null) {
        throw originalError;
      } else {
        return module;
      }
    }
  };

  var loop = function() {
    let processInput = function(input) {
      if (input.endsWith('\\')) {
        readline.question('... ', (more) => processInput(input.slice(0, -1) + more));
        return;
      } else if (input == '.types') {
        console.log(`${env.getTypeNames().join(' ')}`);
      } else if (input == '.vars') {
        console.log(`${env.getVarNames().join(' ')}`);
      } else if (input.startsWith('.js')) {
        try {
          eval(input.slice(3));
        } catch ( e ) {
          printError(e);
        }
      } else if (input == 'exit') {
        readline.close();
        return;
      } else if (input.length == 0) {
        // do nothing
      } else if (input[0] == '.') {
        console.log('huh?');
      } else {
        try {
          let module = forgivingParse(input, env);
          module.ast.typecheck();
          module.ast.execute();
        } catch ( e ) {
          printError(e);
        }
      }
      loop();
    };
    readline.question('> ', processInput);
  };
  loop();
};

module.exports = {
  load: load,
  loadPrelude: loadPrelude,
  repl: repl,
};

if (require.main === module) {
  let prelude = loadPrelude();
  let env = new Environment(prelude);

  if (process.argv.length > 2) { // filename given
    let filename = process.argv[2];
    let module = load(parser.parse(new Input(filename)), env);
    module.ast.typecheck();
    module.ast.execute();
    let printEnv = () => {
      env.getVarNames().forEach((v) => {
        console.log(v, '=', env.getVar(v).toString());
      });
      console.log();
    };
    printEnv();
    for (let rule in env.rules) {
      console.log('Executing ', rule);
      env.rules[rule].fire();
      printEnv();
    }
  }

  repl(env);
}
<commit_msg>Add ".fire <rule> [index]" to REPL<commit_after>"use strict";

let Input = require('./input.js');
let parser = require('./parser.js');
let Environment = require('./environment.js');
let Type = require('./types/type.js');
let makeStatement = require('./statements/factory.js');
let makeType = require('./types/factory.js');
let process = require('process');
let errors = require('./errors.js');

let out = function(o) {
  console.log(JSON.stringify(o, null, 2));
};

let load = function(parsed, env) {
  let ast = makeStatement(parsed, env);
  return {
    ast: ast,
    env: env,
  };
};

let loadPrelude = function() {
  let env = new Environment();
  load(parser.parse(new Input('prelude.model')), env);
  return env;
};

let printEnv = (env) => {
  env.getVarNames().forEach((v) => {
    console.log(v, '=', env.getVar(v).toString());
  });
  console.log();
};

let repl = function(env) {
  var readline = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
  });

  let printError = function(error) {
    if (error instanceof errors.Base) { // modeling error
      console.log(`${error}`);
    } else { // JS error
      if (error.stack !== undefined) {
        console.log(`${error.stack}`);
      } else {
        console.log(`${error}`);
      }
    }
  };

  var forgivingParse = function(input, env) {
    let parse = (input) => load(parser.parse(new Input('REPL', input)), env);
    let rescueAttempts = [
      (input) => parse(input + ';'),
      (input) => parse('print ' + input),
      (input) => parse('print ' + input + ';'),
    ];
    try {
      return parse(input);
    } catch ( originalError ) {
      let module = null;
      rescueAttempts.forEach((attempt) => {
        if (module === null) {
          try {
            module = attempt(input);
          } catch ( uselessError ) {
            // do nothing
          }
        }
      });
      if (module === null) {
        throw originalError;
      } else {
        return module;
      }
    }
  };

  var loop = function() {
    let processInput = function(input) {
      if (input.endsWith('\\')) {
        readline.question('... ', (more) => processInput(input.slice(0, -1) + more));
        return;
      } else if (input == '.types') {
        console.log(`${env.getTypeNames().join(' ')}`);
      } else if (input == '.vars') {
        console.log(`${env.getVarNames().join(' ')}`);
      } else if (input.startsWith('.js')) {
        try {
          eval(input.slice(3));
        } catch ( e ) {
          printError(e);
        }
      } else if (input == 'exit') {
        readline.close();
        return;
      } else if (input.startsWith('.fire')) {
        let args = input.split(' ');
        try {
          if (args.length == 2) {
            env.rules[args[1]].fire();
            printEnv(env);
          } else if (args.length == 3) {
            env.rules[args[1]].fire(Number(args[2]));
            printEnv(env);
          } else {
            console.log('huh?');
          }
        } catch ( e ) {
          printError(e);
        }
      } else if (input[0] == '.') {
        console.log('huh?');
      } else {
        try {
          let module = forgivingParse(input, env);
          module.ast.typecheck();
          module.ast.execute();
        } catch ( e ) {
          printError(e);
        }
      }
      loop();
    };
    readline.question('> ', processInput);
  };
  loop();
};

module.exports = {
  load: load,
  loadPrelude: loadPrelude,
  repl: repl,
};

if (require.main === module) {
  let prelude = loadPrelude();
  let env = new Environment(prelude);

  if (process.argv.length > 2) { // filename given
    let filename = process.argv[2];
    let module = load(parser.parse(new Input(filename)), env);
    module.ast.typecheck();
    module.ast.execute();
    printEnv(env);
    for (let rule in env.rules) {
      console.log('Executing', rule);
      env.rules[rule].fire();
      printEnv(env);
    }
  }

  repl(env);
}

{'fraction_non_alphanumeric': 0.18307449328770728, 'fraction_numerical': 0.0026322716504343247, 'mean_word_length': 2.1596673596673597, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 24, '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': '6968043', 'n_tokens_mistral': 2406, 'n_tokens_neox': 2406, 'n_words': 515}