<commit_before>package hdm.pk070.jscheme.eval;

import hdm.pk070.jscheme.error.SchemeError;
import hdm.pk070.jscheme.obj.SchemeObject;
import hdm.pk070.jscheme.obj.builtin.function.SchemeBuiltinFunction;
import hdm.pk070.jscheme.obj.builtin.simple.SchemeCons;
import hdm.pk070.jscheme.obj.builtin.simple.SchemeNil;
import hdm.pk070.jscheme.obj.builtin.simple.SchemeSymbol;
import hdm.pk070.jscheme.obj.builtin.syntax.SchemeBuiltinSyntax;
import hdm.pk070.jscheme.reader.SchemeReader;
import hdm.pk070.jscheme.stack.SchemeCallStack;
import hdm.pk070.jscheme.table.environment.Environment;
import hdm.pk070.jscheme.table.environment.entry.EnvironmentEntry;

/**
 * A class for evaluating all kinds of Scheme lists.
 *
 * @author patrick.kleindienst
 */
class ListEvaluator extends AbstractEvaluator<SchemeCons> {

    static ListEvaluator getInstance() {
        return new ListEvaluator();
    }

    private ListEvaluator() {
    }

    /**
     * Takes an arbitrary list expression from the {@link SchemeReader} as well as an {@link Environment} and passes
     * it along to a specified evaluation class depending on what kind of expression it has been given. For this, it
     * has to evaluate the function slot, which is accessible as the CAR of the list expression.
     *
     * @param expression
     *         The list expression to evaluate
     * @param environment
     *         The evaluation context
     * @return A {@link SchemeObject} as a list evaluation result
     * @throws SchemeError
     */
    @Override
    public SchemeObject doEval(SchemeCons expression, Environment<SchemeSymbol, EnvironmentEntry> environment) throws
            SchemeError {
        // Extract function slot (car of expression)
        SchemeObject functionSlot = expression.getCar();
        // Evaluate function slot
        SchemeObject evaluatedFunctionSlot = SchemeEval.getInstance().eval(functionSlot, environment);
        // Extract arg list (cdr of expression)
        SchemeObject argumentList = expression.getCdr();

        // Check if function slot is built-in function
        if (evaluatedFunctionSlot.subtypeOf(SchemeBuiltinFunction.class)) {
            return evaluateBuiltinFunction(((SchemeBuiltinFunction) evaluatedFunctionSlot), argumentList, environment);

            // Check if function slot is built-in syntax (e.g. define)
        } else if (evaluatedFunctionSlot.subtypeOf(SchemeBuiltinSyntax.class)) {
            return evaluateBuiltinSyntax(((SchemeBuiltinSyntax) evaluatedFunctionSlot), argumentList, environment);
        }

        // Reaching this section means we don't have a valid function slot -> throw SchemeError
        throw new SchemeError(String.format("application: not a procedure [expected: procedure that can be applied to" +
                " arguments, given: %s]", functionSlot));
    }

    private SchemeObject evaluateBuiltinSyntax(SchemeBuiltinSyntax builtinSyntax, SchemeObject argumentList,
                                               Environment<SchemeSymbol, EnvironmentEntry> environment) throws
            SchemeError {

        return builtinSyntax.apply(argumentList, environment);
    }

    /**
     * Gets passed a {@link SchemeBuiltinFunction} and evaluates it in the context of the {@link Environment}
     * argument.
     *
     * @param builtinFunction
     *         The pre-defined function to call
     * @param argumentList
     *         The argument list for the function call
     * @param environment
     *         The {@link Environment} the function body gets evaluated in
     * @return A {@link SchemeObject} as a result of the function call
     * @throws SchemeError
     */
    private SchemeObject evaluateBuiltinFunction(SchemeBuiltinFunction builtinFunction, SchemeObject argumentList,
                                                 Environment<SchemeSymbol, EnvironmentEntry> environment) throws
            SchemeError {
        SchemeObject restArguments;
        restArguments = argumentList;
        int argumentCount = 0;

        // as long as end of argumentList is not reached ...
        while (!restArguments.typeOf(SchemeNil.class)) {
            SchemeObject currentArgument = ((SchemeCons) restArguments).getCar();
            SchemeObject evaluatedArgument = SchemeEval.getInstance().eval(currentArgument, environment);
            restArguments = ((SchemeCons) restArguments).getCdr();

            // push evaluated arg to stack
            SchemeCallStack.instance().push(evaluatedArgument);

            // increment arg counter
            argumentCount++;
        }

        // call built-in function
        return builtinFunction.call(argumentCount);
    }
}<commit_msg>Added stub for evaluation of custom user function<commit_after>package hdm.pk070.jscheme.eval;

import hdm.pk070.jscheme.error.SchemeError;
import hdm.pk070.jscheme.obj.SchemeObject;
import hdm.pk070.jscheme.obj.builtin.function.SchemeBuiltinFunction;
import hdm.pk070.jscheme.obj.builtin.simple.SchemeCons;
import hdm.pk070.jscheme.obj.builtin.simple.SchemeNil;
import hdm.pk070.jscheme.obj.builtin.simple.SchemeSymbol;
import hdm.pk070.jscheme.obj.builtin.syntax.SchemeBuiltinSyntax;
import hdm.pk070.jscheme.obj.custom.SchemeCustomUserFunction;
import hdm.pk070.jscheme.reader.SchemeReader;
import hdm.pk070.jscheme.stack.SchemeCallStack;
import hdm.pk070.jscheme.table.environment.Environment;
import hdm.pk070.jscheme.table.environment.entry.EnvironmentEntry;

/**
 * A class for evaluating all kinds of Scheme lists.
 *
 * @author patrick.kleindienst
 */
class ListEvaluator extends AbstractEvaluator<SchemeCons> {

    static ListEvaluator getInstance() {
        return new ListEvaluator();
    }

    private ListEvaluator() {
    }

    /**
     * Takes an arbitrary list expression from the {@link SchemeReader} as well as an {@link Environment} and passes
     * it along to a specified evaluation class depending on what kind of expression it has been given. For this, it
     * has to evaluate the function slot, which is accessible as the CAR of the list expression.
     *
     * @param expression
     *         The list expression to evaluate
     * @param environment
     *         The evaluation context
     * @return A {@link SchemeObject} as a list evaluation result
     * @throws SchemeError
     */
    @Override
    public SchemeObject doEval(SchemeCons expression, Environment<SchemeSymbol, EnvironmentEntry> environment) throws
            SchemeError {
        // Extract function slot (car of expression)
        SchemeObject functionSlot = expression.getCar();
        // Evaluate function slot
        SchemeObject evaluatedFunctionSlot = SchemeEval.getInstance().eval(functionSlot, environment);
        // Extract arg list (cdr of expression)
        SchemeObject argumentList = expression.getCdr();

        // Check if function slot is a built-in function
        if (evaluatedFunctionSlot.subtypeOf(SchemeBuiltinFunction.class)) {
            return evaluateBuiltinFunction(((SchemeBuiltinFunction) evaluatedFunctionSlot), argumentList, environment);

            // Check if function slot is a built-in syntax (e.g. define)
        } else if (evaluatedFunctionSlot.subtypeOf(SchemeBuiltinSyntax.class)) {
            return evaluateBuiltinSyntax(((SchemeBuiltinSyntax) evaluatedFunctionSlot), argumentList, environment);
            // Check if function slot is a user-defined function
        } else if (evaluatedFunctionSlot.typeOf(SchemeCustomUserFunction.class)) {

        }

        // Reaching this section means we don't have a valid function slot -> throw SchemeError
        throw new SchemeError(String.format("application: not a procedure [expected: procedure that can be applied to" +
                " arguments, given: %s]", functionSlot));
    }

    private SchemeObject evaluateBuiltinSyntax(SchemeBuiltinSyntax builtinSyntax, SchemeObject argumentList,
                                               Environment<SchemeSymbol, EnvironmentEntry> environment) throws
            SchemeError {

        return builtinSyntax.apply(argumentList, environment);
    }

    /**
     * Gets passed a {@link SchemeBuiltinFunction} and evaluates it in the context of the {@link Environment}
     * argument.
     *
     * @param builtinFunction
     *         The pre-defined function to call
     * @param argumentList
     *         The argument list for the function call
     * @param environment
     *         The {@link Environment} the function body gets evaluated in
     * @return A {@link SchemeObject} as a result of the function call
     * @throws SchemeError
     */
    private SchemeObject evaluateBuiltinFunction(SchemeBuiltinFunction builtinFunction, SchemeObject argumentList,
                                                 Environment<SchemeSymbol, EnvironmentEntry> environment) throws
            SchemeError {
        SchemeObject restArguments;
        restArguments = argumentList;
        int argumentCount = 0;

        // as long as end of argumentList is not reached ...
        while (!restArguments.typeOf(SchemeNil.class)) {
            SchemeObject currentArgument = ((SchemeCons) restArguments).getCar();
            SchemeObject evaluatedArgument = SchemeEval.getInstance().eval(currentArgument, environment);
            restArguments = ((SchemeCons) restArguments).getCdr();

            // push evaluated arg to stack
            SchemeCallStack.instance().push(evaluatedArgument);

            // increment arg counter
            argumentCount++;
        }

        // call built-in function
        return builtinFunction.call(argumentCount);
    }

    /**
     * @param customFunction
     * @param argumentList
     * @param environment
     * @return
     */
    private SchemeObject evaluateCustomUserFunction(SchemeCustomUserFunction customFunction, SchemeObject
            argumentList, Environment<SchemeSymbol, EnvironmentEntry> environment) {
        return null;
    }
}
{'fraction_non_alphanumeric': 0.07708521529659741, 'fraction_numerical': 0.007728595804476563, 'mean_word_length': 2.9089839152608867, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6716716', 'n_tokens_mistral': 2542, 'n_tokens_neox': 2383, 'n_words': 728}