<commit_before>/// <reference path="../typings/argparser.d.ts" />
/// <reference path="../typings/tsd.d.ts" />

'use strict';

import argparser = require('argparser');
import readline = require('readline');

import BT = require('../lib/back_talker');
import {Shell} from '../lib/shell';


var args = argparser.nonvals("ast").parse(),
  rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

var print_parse_tree = function(pt, prefix = "") {
    console.log(prefix + "<" + (pt.isa || "unknown")  + ">" + '"' + pt.textValue + '"');

    pt.elements.forEach(function(e) {
        print_parse_tree(e, prefix + "  ");
    });
};

var evaluator = new BT.Evaluator(scope),
    scope = evaluator.scope,
    shell = new Shell(evaluator);
    ;

scope.addFunc({
    patterns: ['q'],
    impl: function() {
      console.log('goodbye!');
      rl.close();
      process.exit();
    }
});

shell.eval = function(source) {
  try {
    var ast = BT.parse(source, print_parse_tree);
    if (args.opt("ast")) {
      console.log(ast);
    }
    console.log(shell.evaluator.eval(ast));
  } catch (e) {
    if (e instanceof BT.Syntax.ParseError) {
        console.log(e.message);
    } else {
        throw e;
    }
  }
}

rl.setPrompt("::>");
rl.prompt();

rl.on('line', function(line) {
  shell.processLine(line);
  if (shell.multiline) {
    rl.setPrompt(".. ");
  } else {
    rl.setPrompt("::>");
  }
  rl.prompt();
});<commit_msg>Refactor REPL add basic debugging commands<commit_after>/// <reference path="../typings/argparser.d.ts" />
/// <reference path="../typings/tsd.d.ts" />

'use strict';

import argparser = require('argparser');
import readline = require('readline');

import BT = require('../lib/back_talker');
import {Shell} from '../lib/shell';


class REPL {
  print_parse = false
  print_ast = false

  rl: readline.ReadLine;
  evaluator: BT.Evaluator;
  shell: Shell;
  scope: BT.Scope;

  constructor() {
    this.rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });

    this.print_ast = argparser.nonvals("ast").parse().ast

    this.evaluator = new BT.Evaluator(),
    this.scope = this.evaluator.scope,
    this.shell = new Shell(this.evaluator);
    this.shell.eval = (source) => this.shell_eval(source);

    this.init_scope();
  }

  shell_eval(source) {
    try {
      var ast = BT.parse(source, (a) => this.print_parse_tree(a));
      if (this.print_ast) {
        console.log(ast);
      }
      console.log(this.shell.evaluator.eval(ast));
    } catch (e) {
      if (e instanceof BT.Syntax.ParseError) {
          console.log(e.message);
      } else {
          throw e;
      }
    }
  }

  print_parse_tree(pt, prefix = "") {
    if (!this.print_parse) {
      return;
    }

    console.log(prefix + "<" + (pt.isa || "unknown")  + ">" + '"' + pt.textValue + '"');

    pt.elements.forEach(e => this.print_parse_tree(e, prefix + "  "));
  }

  init_scope() {
    this.scope.addFunc({
        patterns: ['q'],
        impl: () => {
          console.log('goodbye!');
          this.rl.close();
          process.exit();
        }
    });

    this.scope.addFunc({
        patterns: ["repl <debug|stop debug|no debug>:on <ast|parse>:what"],
        impl: (args) => {
          var on = args.named.on == 0;
          if (args.named.what == 0) {
            this.print_ast = on;
          } else {
            this.print_parse = on;
          }
        }
    });

    this.scope.addFunc({
        patterns: ["repl ls", "help"],
        impl: (args) => {
          this.scope.funcs.each((k, v) => console.log(k));
        }
    });
  }

  begin() {
    this.rl.setPrompt("::>");
    this.rl.prompt();

    this.rl.on('line', (line) => {
      this.shell.processLine(line);
      if (this.shell.multiline) {
        this.rl.setPrompt(".. ");
      } else {
        this.rl.setPrompt("::>");
      }
      this.rl.prompt();
    });
  }
}

new REPL().begin();
{'fraction_non_alphanumeric': 0.19195751138088013, 'fraction_numerical': 0.0005058168942842691, 'mean_word_length': 2.348856900931414, 'pattern_counts': {'":': 4, '<': 11, '<?xml version=': 0, '>': 23, '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': '2703413', 'n_tokens_mistral': 1395, 'n_tokens_neox': 1373, 'n_words': 235}