001/* Token that contains a function.
002
003 Copyright (c) 2002-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.data;
029
030import ptolemy.data.expr.ASTPtRootNode;
031import ptolemy.data.expr.ParseTreeEvaluator;
032import ptolemy.data.expr.ParseTreeTypeInference;
033import ptolemy.data.expr.PtParser;
034import ptolemy.data.type.FunctionType;
035import ptolemy.data.type.Type;
036import ptolemy.kernel.util.IllegalActionException;
037
038///////////////////////////////////////////////////////////////////
039//// FunctionToken
040
041/**
042 A token that contains a function. The function takes a fixed number of
043 arguments, supplied as a list of tokens.
044
045 Currently, no operations between function tokens (add, multiply, etc.)
046 are supported.
047
048 @author Xiaojun Liu, Steve Neuendorffer
049 @version $Id$
050 @since Ptolemy II 2.1
051 @Pt.ProposedRating Yellow (liuxj)
052 @Pt.AcceptedRating Red (liuxj)
053 */
054public class FunctionToken extends Token {
055    /** Create a new FunctionToken that applies the given function.
056     *  The type of the function token will be the same as the given
057     *  type.
058     *  @param f The function.
059     *  @param type The function type.
060     */
061    public FunctionToken(Function f, FunctionType type) {
062        _function = f;
063        _type = type;
064    }
065
066    /** Create a new FunctionToken from the given string.
067     *  @param init The initialization string, for example
068     *  <code>function(x,y) 4+x+y</code>.
069     *  @exception IllegalActionException If an error occurs, or the
070     *  string cannot be parsed into a function.
071     */
072    public FunctionToken(String init) throws IllegalActionException {
073        PtParser parser = new PtParser();
074        ASTPtRootNode tree = parser.generateParseTree(init);
075        ParseTreeTypeInference inference = new ParseTreeTypeInference();
076        inference.inferTypes(tree);
077
078        Token token = new ParseTreeEvaluator().evaluateParseTree(tree);
079
080        if (token instanceof FunctionToken) {
081            _function = ((FunctionToken) token)._function;
082            _type = ((FunctionToken) token)._type;
083        } else {
084            throw new IllegalActionException("A function token cannot be"
085                    + " created from the expression '" + init + "'");
086        }
087    }
088
089    ///////////////////////////////////////////////////////////////////
090    ////                         public methods                    ////
091
092    /** Apply this function to the given list of arguments.
093     *  @param args the arguments to which the function is applied
094     *  @return The results of applying the arguments to this function.
095     *  @exception IllegalActionException If the arguments are not
096     *  compatible with this function, or an error occurs during
097     *  evaluation.
098     */
099    public Token apply(Token[] args) throws IllegalActionException {
100        return _function.apply(args);
101    }
102
103    /** Return the function of this token.
104     *  @return A Function.
105     */
106    public Function getFunction() {
107        return _function;
108    }
109
110    /** Return the number of arguments of the function.
111     *  @return The number of arguments of the function.
112     */
113    public int getNumberOfArguments() {
114        return _function.getNumberOfArguments();
115    }
116
117    /** Return the type of this token.
118     *  @return A FunctionType.
119     */
120    @Override
121    public Type getType() {
122        return _type;
123    }
124
125    /** Test for closeness of the values of this Token and the argument
126     *  Token.  For function tokens, checking for closeness is the same
127     *  as checking for equality.
128     *  @param rightArgument The token to compare to this token.
129     *  @param epsilon This argument is ignored in this method.
130     *  @return A true-valued token if the first argument is equal to
131     *  this token.
132     */
133    @Override
134    public BooleanToken isCloseTo(Token rightArgument, double epsilon) {
135        return isEqualTo(rightArgument);
136    }
137
138    /** Test for equality of the values of this Token and the argument
139     *  Token.  Two function tokens are equal if they correspond to the
140     *  same expression, under renaming of any bound variables.
141     *  @param rightArgument The token to compare to this token.
142     *  @return A token containing true if the value element of the first
143     *  argument is equal to the value of this token.
144     */
145    @Override
146    public BooleanToken isEqualTo(Token rightArgument) {
147        FunctionToken convertedArgument = (FunctionToken) rightArgument;
148        return BooleanToken.getInstance(
149                convertedArgument._function.isCongruent(_function));
150    }
151
152    /** Return a String representation of this function.
153     */
154    @Override
155    public String toString() {
156        return _function.toString();
157    }
158
159    ///////////////////////////////////////////////////////////////////
160    ////                         private fields                    ////
161    // The object that implements the function.
162    private Function _function;
163
164    // The type of this function.
165    private FunctionType _type;
166}