/* Copyright 2009-2016 David Hadka * * This file is part of the MOEA Framework. * * The MOEA Framework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * The MOEA Framework is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ package org.moeaframework.util.tree; /** * The node for defining a callable, named function. Once a named function is * defined, it can be invoked using {@link Call}. The behavior (body) of this * function can be mutated. For immutable functions, see {@link Lambda}. * * @see Call */ public class Define extends Node { /** * The name of this function. */ private final String functionName; /** * The names of the arguments to this function. */ private final String[] variableNames; /** * The types of the arguments to this function. */ private final Class<?>[] variableTypes; /** * Constructs a new node for defining a function that takes no arguments. * * @param functionName the name of the function * @param returnType the return type of the function */ public Define(String functionName, Class<?> returnType) { this(functionName, returnType, new String[0], new Class<?>[0]); } /** * Constructs a new node for defining a function that takes one argument. * * @param functionName the name of the function * @param returnType the return type of the function * @param variableName the name of the argument * @param variableType the type of the argument */ public Define(String functionName, Class<?> returnType, String variableName, Class<?> variableType) { this(functionName, returnType, new String[] { variableName }, new Class<?>[] { variableType }); } /** * Constructs a new node for defining a function that takes two arguments. * * @param functionName the name of the function * @param returnType the return type of the function * @param name1 the name of the first argument * @param type1 the type of the first argument * @param name2 the name of the second argument * @param type2 the type of the second argument */ public Define(String functionName, Class<?> returnType, String name1, Class<?> type1, String name2, Class<?> type2) { this(functionName, returnType, new String[] { name1, name2 }, new Class<?>[] { type1, type2 }); } /** * Constructs a new node for defining a function that takes a * user-defined number of arguments. * * @param functionName the name of the function * @param returnType the return type of the function * @param variableNames the names of the arguments to the function * @param variableTypes the types of the arguments to the function */ public Define(String functionName, Class<?> returnType, String[] variableNames, Class<?>[] variableTypes) { super(Void.class, returnType); this.functionName = functionName; this.variableNames = variableNames; this.variableTypes = variableTypes; } /** * Returns the name of this function. * * @return the name of this function */ public String getFunctionName() { return functionName; } /** * Returns the names of the arguments to this function. * * @return the names of the arguments to this function */ public String[] getVariableNames() { return variableNames; } /** * Returns the types of the arguments to this function. * * @return the types of the arguments to this function */ public Class<?>[] getVariableTypes() { return variableTypes; } @Override public Node copyNode() { return new Define(functionName, getArgumentType(0), variableNames, variableTypes); } @Override public Void evaluate(Environment environment) { environment.set(functionName, getArgument(0)); return null; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append('('); sb.append(getClass().getSimpleName()); sb.append(' '); sb.append(getFunctionName()); sb.append(" ("); for (int i = 0; i < variableNames.length; i++) { if (i > 0) { sb.append(' '); } sb.append(variableNames[i]); } sb.append(") "); sb.append(getArgument(0).toString()); sb.append(')'); return sb.toString(); } }