<commit_before>package javarepl;

import com.googlecode.totallylazy.*;
import com.googlecode.totallylazy.numbers.Numbers;
import javarepl.expressions.Import;
import javarepl.expressions.Method;
import javarepl.expressions.Type;
import javarepl.expressions.WithKey;
import jline.console.ConsoleReader;
import jline.console.completer.AggregateCompleter;
import jline.console.completer.ArgumentCompleter;
import jline.console.completer.StringsCompleter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import static com.googlecode.totallylazy.Callables.asString;
import static com.googlecode.totallylazy.Pair.functions.values;
import static com.googlecode.totallylazy.Predicates.*;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.totallylazy.Strings.blank;
import static com.googlecode.totallylazy.Strings.replace;
import static com.googlecode.totallylazy.Strings.startsWith;
import static java.lang.String.format;
import static java.lang.System.exit;
import static java.lang.System.getProperty;
import static java.util.regex.Matcher.quoteReplacement;
import static javarepl.Evaluation.functions.classSource;
import static javarepl.Evaluation.functions.expression;
import static javarepl.Utils.applicationVersion;
import static javarepl.Utils.resolveClasspath;
import static javarepl.expressions.Expression.functions.source;
import static javarepl.expressions.WithKey.functions.key;

public class Main {
    public static void main(String[] args) throws Exception {
        Sequence<String> arguments = sequence(args);
        boolean simpleConsole = arguments.contains("-sc");

        new Main(simpleConsole).run();
    }

    private final Evaluator evaluator;
    private final ExpressionReader expressionReader;

    public Main(boolean simpleConsole) throws Exception {
        System.out.println(format("Welcome to JavaREPL version %s (%s, Java %s)", applicationVersion(), getProperty("java.vm.name"), getProperty("java.version")));

        evaluator = new Evaluator();
        expressionReader = new ExpressionReader(simpleConsole ? readFromSimpleConsole() : readFromExtendedConsole());

        System.out.println("Type in expression to evaluate.");
        System.out.println("Type :help for more options.");
        System.out.println("");
    }

    public void run() throws IOException {
        Rules<String, Function1<String, Void>> rules = Rules.<String, Function1<String, Void>>rules()
                .addLast(equalTo(":quit").or(equalTo(null)), quitApplication())
                .addLast(equalTo(":help"), showHelp())
                .addLast(equalTo(":src"), showLastSource())
                .addLast(equalTo(":history"), showHistory())
                .addLast(equalTo(":clear"), clearContext())
                .addLast(startsWith(":cp "), addClasspath())
                .addLast(startsWith(":list "), list())
                .addLast(equalTo(":!"), evaluateLatest())
                .addLast(not(blank()), evaluate())
                .addLast(always(), noAction());

        do {
            rules.apply(expressionReader.readExpression().getOrNull());
            System.out.println();
        } while (true);
    }

    private Function1<String, Function1<String, Void>> showHelp() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                String help = new StringBuilder().append("Available commands: \n")
                        .append("    :help - display this help\n")
                        .append("    :cp <path> - includes given file or directory in the classpath\n")
                        .append("    :history - shows the history\n")
                        .append("    :list <results|types|methods|imports|all> - list specified values\n")
                        .append("    :src - display last compiled source\n")
                        .append("    :clear - clears all variables\n")
                        .append("    :! - evaluate the latest expression\n")
                        .append("    :quit - exits the app\n")
                        .toString();
                System.out.println(help);
                return null;
            }
        };
    }

    private Function1<String, Function1<String, Void>> quitApplication() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                exit(0);
                return null;
            }
        };
    }

    private Function1<String, Function1<String, Void>> showHistory() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                Sequence<String> history = Numbers.range(1)
                        .zip(evaluator.evaluations().map(expression().then(source()).then(replace("\n", "\n   "))))
                        .map(values().then(Sequences.toString("  ")));

                listValues("History", history);

                return null;
            }
        };
    }

    private Function1<String, Function1<String, Void>> showLastSource() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                System.out.println(evaluator.lastEvaluation().map(classSource()).getOrElse("No source"));
                return null;
            }


        };
    }

    private Function1<String, Function1<String, Void>> clearContext() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                evaluator.clear();<commit_msg>added limit to displaying history<commit_after>package javarepl;

import com.googlecode.totallylazy.*;
import com.googlecode.totallylazy.numbers.Numbers;
import javarepl.expressions.Import;
import javarepl.expressions.Method;
import javarepl.expressions.Type;
import javarepl.expressions.WithKey;
import jline.console.ConsoleReader;
import jline.console.completer.AggregateCompleter;
import jline.console.completer.ArgumentCompleter;
import jline.console.completer.StringsCompleter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import static com.googlecode.totallylazy.Callables.asString;
import static com.googlecode.totallylazy.Pair.functions.values;
import static com.googlecode.totallylazy.Predicates.*;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.totallylazy.Strings.blank;
import static com.googlecode.totallylazy.Strings.replace;
import static com.googlecode.totallylazy.Strings.startsWith;
import static java.lang.Integer.parseInt;
import static java.lang.String.format;
import static java.lang.System.exit;
import static java.lang.System.getProperty;
import static java.util.regex.Matcher.quoteReplacement;
import static javarepl.Evaluation.functions.classSource;
import static javarepl.Evaluation.functions.expression;
import static javarepl.Utils.applicationVersion;
import static javarepl.Utils.resolveClasspath;
import static javarepl.expressions.Expression.functions.source;
import static javarepl.expressions.WithKey.functions.key;

public class Main {
    public static void main(String[] args) throws Exception {
        Sequence<String> arguments = sequence(args);
        boolean simpleConsole = arguments.contains("-sc");

        new Main(simpleConsole).run();
    }

    private final Evaluator evaluator;
    private final ExpressionReader expressionReader;

    public Main(boolean simpleConsole) throws Exception {
        System.out.println(format("Welcome to JavaREPL version %s (%s, Java %s)", applicationVersion(), getProperty("java.vm.name"), getProperty("java.version")));

        evaluator = new Evaluator();
        expressionReader = new ExpressionReader(simpleConsole ? readFromSimpleConsole() : readFromExtendedConsole());

        System.out.println("Type in expression to evaluate.");
        System.out.println("Type :help for more options.");
        System.out.println("");
    }

    public void run() throws IOException {
        Rules<String, Function1<String, Void>> rules = Rules.<String, Function1<String, Void>>rules()
                .addLast(equalTo(":quit").or(equalTo(null)), quitApplication())
                .addLast(equalTo(":help"), showHelp())
                .addLast(equalTo(":src"), showLastSource())
                .addLast(startsWith(":history"), showHistory())
                .addLast(equalTo(":clear"), clearContext())
                .addLast(startsWith(":cp "), addClasspath())
                .addLast(startsWith(":list "), list())
                .addLast(equalTo(":!"), evaluateLatest())
                .addLast(not(blank()), evaluate())
                .addLast(always(), noAction());

        do {
            rules.apply(expressionReader.readExpression().getOrNull());
            System.out.println();
        } while (true);
    }

    private Function1<String, Function1<String, Void>> showHelp() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                String help = new StringBuilder().append("Available commands: \n")
                        .append("    :help - display this help\n")
                        .append("    :cp <path> - includes given file or directory in the classpath\n")
                        .append("    :history [num] - shows the history (optional 'num' is number of evaluations to show)\n")
                        .append("    :list <results|types|methods|imports|all> - list specified values\n")
                        .append("    :src - display last compiled source\n")
                        .append("    :clear - clears all variables\n")
                        .append("    :! - evaluate the latest expression\n")
                        .append("    :quit - exits the app\n")
                        .toString();
                System.out.println(help);
                return null;
            }
        };
    }

    private Function1<String, Function1<String, Void>> quitApplication() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                exit(0);
                return null;
            }
        };
    }

    private Function1<String, Function1<String, Void>> showHistory() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                Sequence<String> sequence = sequence(line.split(" "));
                Integer limit = (sequence.size() == 2) ? parseInt(sequence.second()) : evaluator.evaluations().size();

                Sequence<String> history = Numbers.range(1)
                        .zip(evaluator.evaluations().map(expression().then(source()).then(replace("\n", "\n   "))))
                        .map(values().then(Sequences.toString("  ")));

                listValues("History", history.reverse().take(limit).reverse());

                return null;
            }
        };
    }

    private Function1<String, Function1<String, Void>> showLastSource() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                System.out.println(evaluator.lastEvaluation().map(classSource()).getOrElse("No source"));
                return null;
            }


        };
    }

    private Function1<String, Function1<String, Void>> clearContext() {
        return new Function1<String, Function1<String, Void>>() {
            public Function1<String, Void> call(String line) throws Exception {
                evaluator.clear();
{'fraction_non_alphanumeric': 0.11980033277870217, 'fraction_numerical': 0.004908485856905158, 'mean_word_length': 2.712476837554046, 'pattern_counts': {'":': 16, '<': 70, '<?xml version=': 0, '>': 70, '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': '4516829', 'n_tokens_mistral': 3234, 'n_tokens_neox': 3067, 'n_words': 700}