<commit_before>package backend;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import commands.Command;
import commands.CommandFactory;
import commands.CommandInvoker;
import exceptions.EndOfStackException;
import exceptions.InvalidCommandException;
import exceptions.InvalidCommandStringException;
import exceptions.InvalidSyntaxException;
import exceptions.InvalidWordException;
import exceptions.NotEnoughParametersException;
import exceptions.SlogoException;
import exceptions.VariableNotFoundException;

public class Interpreter {
	/**
	 * TODO: change the methods so that this looks like a real API
	 */
	/**
	 * TODO: Make documentation for all public methods and vars (all classes)
	 */
	/**
	 * TODO: AdvancedCommands such as If and Repeat must return appropriate
	 * values
	 */
	CommandFactory commandFactory;
	public CommandInvoker commandInvoker;
	private Map<String, Double> variables = new HashMap<String, Double>();
	private Map<String, UserCommand> userCommands = new HashMap<String, UserCommand>();
	public ArrayList<String> listOfWords;

	public Interpreter() throws IOException, InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		commandInvoker = new CommandInvoker(this);
		commandFactory = new CommandFactory();
	}

	public Double evaluateCommand(ArrayList<String> wordList)
			throws InvalidCommandStringException, InvalidWordException,
			NotEnoughParametersException, InvalidCommandException,
			InstantiationException, IllegalAccessException,
			ClassNotFoundException, InvalidSyntaxException, SlogoException,
			EndOfStackException {

		String firstWord = wordList.remove(0);
		if (isConstantValue(firstWord)) {
			return Double.parseDouble(firstWord);
		} else if (isCommand(firstWord)) {
			firstWord = firstWord.toLowerCase();
			ArrayList<Double> parameters = new ArrayList<Double>();
			Command newCommand = commandFactory.createCommand(firstWord);
			for (int i = 0; i < newCommand.NUM_OF_PARAMETERS; i++) {
				if (wordList.size() > 0) {
					parameters.add(evaluateCommand(wordList));
				} else {
					throw new NotEnoughParametersException();
				}
			}
			newCommand.loadParameters(parameters);
			return commandInvoker.obey(newCommand);
		} else if (isVariable(firstWord)) {
			return getVariable(firstWord.substring(1));
		} else if (isUserCommand(firstWord)) {
			return getAndExecuteUserCommand(firstWord);
		} else {
			throw new InvalidWordException();
		}
	}

	public ArrayList<Double> interpret(String text)
			throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, InvalidSyntaxException, SlogoException {
		text = text.trim();
		listOutCommands(text);
		ArrayList<Double> evaluatedValues = new ArrayList<Double>();
		while (listOfWords.size() > 0) {
			try {
				evaluatedValues.add(evaluateCommand(listOfWords));
			} catch (EndOfStackException e) {
				System.out.println("caught");
			}
		}
		return evaluatedValues;
	}

	private double getAndExecuteUserCommand(String commandName)
			throws InvalidSyntaxException, InstantiationException,
			IllegalAccessException, ClassNotFoundException, SlogoException {
		/**
		 * TODO: Correctly implement return value
		 */
		UserCommand command;
		try {
			command = userCommands.get(commandName);
		} catch (Exception e) {
			throw new InvalidCommandException();
		}
		try { // Set parameters to appropriate variables
			for (int i = 0; i < command.parameters.length; i++) {
				variables.put(command.parameters[i].substring(1),
						Double.valueOf(listOfWords.remove(0)));
			}
		} catch (Exception e) {
			throw new InvalidSyntaxException();
		}
		interpret(command.commands);
		return 1;
	}

	private boolean isCommand(String word) {
		return commandFactory.commands.containsKey(word.toLowerCase());
	}

	private boolean isUserCommand(String word) {
		return userCommands.containsKey(word);
	}

	private boolean isConstantValue(String word) {
		try {
			Double.parseDouble(word);
			return true;
		} catch (Exception e) {
			return false;
		}
	}<commit_msg>Fixed variable parsing in user commands<commit_after>package backend;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import commands.Command;
import commands.CommandFactory;
import commands.CommandInvoker;
import exceptions.EndOfStackException;
import exceptions.InvalidCommandException;
import exceptions.InvalidCommandStringException;
import exceptions.InvalidSyntaxException;
import exceptions.InvalidWordException;
import exceptions.NotEnoughParametersException;
import exceptions.SlogoException;
import exceptions.VariableNotFoundException;

public class Interpreter {
	/**
	 * TODO: change the methods so that this looks like a real API
	 */
	/**
	 * TODO: Make documentation for all public methods and vars (all classes)
	 */
	/**
	 * TODO: AdvancedCommands such as If and Repeat must return appropriate
	 * values
	 */
	CommandFactory commandFactory;
	public CommandInvoker commandInvoker;
	private Map<String, Double> variables = new HashMap<String, Double>();
	private Map<String, UserCommand> userCommands = new HashMap<String, UserCommand>();
	public ArrayList<String> listOfWords;

	public Interpreter() throws IOException, InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		commandInvoker = new CommandInvoker(this);
		commandFactory = new CommandFactory();
	}

	public Double evaluateCommand(ArrayList<String> wordList)
			throws InvalidCommandStringException, InvalidWordException,
			NotEnoughParametersException, InvalidCommandException,
			InstantiationException, IllegalAccessException,
			ClassNotFoundException, InvalidSyntaxException, SlogoException,
			EndOfStackException {

		String firstWord = wordList.remove(0);
		if (isConstantValue(firstWord)) {
			return Double.parseDouble(firstWord);
		} else if (isCommand(firstWord)) {
			firstWord = firstWord.toLowerCase();
			ArrayList<Double> parameters = new ArrayList<Double>();
			Command newCommand = commandFactory.createCommand(firstWord);
			for (int i = 0; i < newCommand.NUM_OF_PARAMETERS; i++) {
				if (wordList.size() > 0) {
					parameters.add(evaluateCommand(wordList));
				} else {
					throw new NotEnoughParametersException();
				}
			}
			newCommand.loadParameters(parameters);
			return commandInvoker.obey(newCommand);
		} else if (isVariable(firstWord)) {
			return getVariable(firstWord.substring(1));
		} else if (isUserCommand(firstWord)) {
			return getAndExecuteUserCommand(firstWord);
		} else {
			throw new InvalidWordException();
		}
	}

	public ArrayList<Double> interpret(String text)
			throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, InvalidSyntaxException, SlogoException {
		System.out.println("interpreting : " + text);
		text = text.trim();
		listOutCommands(text);
		ArrayList<Double> evaluatedValues = new ArrayList<Double>();
		while (listOfWords.size() > 0) {
			try {
				evaluatedValues.add(evaluateCommand(listOfWords));
			} catch (EndOfStackException e) {
				System.out.println("caught");
			}
		}
		return evaluatedValues;
	}

	private double getAndExecuteUserCommand(String commandName)
			throws InvalidSyntaxException, InstantiationException,
			IllegalAccessException, ClassNotFoundException, SlogoException {
		/**
		 * TODO: Correctly implement return value
		 */
		UserCommand command;
		try {
			command = userCommands.get(commandName);
		} catch (Exception e) {
			throw new InvalidCommandException();
		}
		try { // Set parameters to appropriate variables
			ArrayList<Double> userCommandParameters = new ArrayList<Double>();
			for(int i = 0; i < command.parameters.length; i++) {
				if (listOfWords.size() > 0) {
					userCommandParameters.add(evaluateCommand(listOfWords));
				}
				else {
					throw new NotEnoughParametersException();
				}
			}
			System.out.println(userCommandParameters.toString());
			for (int i = 0; i < command.parameters.length; i++) {
				variables.put(command.parameters[i].substring(1), userCommandParameters.remove(0));
			}
		} catch (Exception e) {
			throw new InvalidSyntaxException();
		}
		interpret(command.commands);
		return 1;
	}

	private boolean isCommand(String word) {
		return commandFactory.commands.containsKey(word.toLowerCase());
	}

	private boolean isUserCommand(String word) {
		return userCommands.containsKey(word);
	}

	private boolean isConstantValue(String word) {
		try {
			Double.parseDouble(word);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
{'fraction_non_alphanumeric': 0.09662790697674419, 'fraction_numerical': 0.002325581395348837, 'mean_word_length': 5.091359773371105, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 32, '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': '3802267', 'n_tokens_mistral': 2640, 'n_tokens_neox': 2317, 'n_words': 576}