/*
@Copyright (c) 2006 The Regents of the University of California.
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the
above copyright notice and the following two paragraphs appear in all
copies of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
PT_COPYRIGHT_VERSION_2
COPYRIGHTENDKEY
*/
package ptolemy.caltrop.ddi.util;
import java.util.Map;
import caltrop.interpreter.Context;
import caltrop.interpreter.ExprEvaluator;
import caltrop.interpreter.InputChannel;
import caltrop.interpreter.InputPort;
import caltrop.interpreter.InterpreterException;
import caltrop.interpreter.StmtEvaluator;
import caltrop.interpreter.ast.Action;
import caltrop.interpreter.ast.Actor;
import caltrop.interpreter.ast.Expression;
import caltrop.interpreter.ast.InputPattern;
import caltrop.interpreter.ast.Statement;
import caltrop.interpreter.environment.Environment;
//////////////////////////////////////////////////////////////////////////
//// DataFlowWithRatesActorInterpreter
/**
This class extends the DataflowActorInterpreter, overriding the
checking of preconditions to assume that input tokens are present.
This interpreter is assumed to operate in a DDI where token rates
are published, such as SDF and DDF.
@author Steve Neuendorffer
@version $Id: DataflowWithRatesActorInterpreter.java,v 1.8 2006/08/21 23:53:35 cxh Exp $
@since Ptolemy II 5.2
@Pt.ProposedRating Red (cxh)
@Pt.AcceptedRating Red (cxh)
@see caltrop.interpreter.ddi.util.DataflowActorInterpreter
@see caltrop.interpreter.ast.Actor
@see caltrop.interpreter.ast.Action
@see #actionSetup
@see #actionEvaluatePrecondition
@see #actionStep
@see #actionComputeOutputs
@see #actionClear
*/
public class DataflowWithRatesActorInterpreter extends DataflowActorInterpreter {
/**
* Defines a new actor interpreter for the specified actor.
*
* @param actor The actor.
* @param context The interpretation context.
* @param actorEnv The global environment.
* @param inputPortMap Map from input port names to channels.
* @param outputPortMap Map from output port names to channels.
* @see caltrop.interpreter.InputChannel
* @see caltrop.interpreter.OutputChannel
*/
public DataflowWithRatesActorInterpreter(final Actor actor,
final Context context, final Environment actorEnv,
final Map inputPortMap, final Map outputPortMap) {
super(actor, context, actorEnv, inputPortMap, outputPortMap);
}
/**
* Evaluate the preconditions for the action and return its
* result. If this method returns false, some condition required
* for the successful completion of the action is not
* satisfied.
*
* @return True, if the action precondition was satisfied.
* @exception caltrop.interpreter.InterpreterException If the
* evaluation of the guards could not be successfully completed.
*/
public boolean actionEvaluatePrecondition() {
if (envAction == null) {
throw new InterpreterException(
"DataflowActorInterpreter: Must call actionSetup() "
+ "before calling actionEvaluatePrecondition().");
}
final Action action = envAction;
final ExprEvaluator eval = new ExprEvaluator(context, env);
final Expression[] guards = action.getGuards();
for (int i = 0; i < guards.length; i++) {
final Object g = eval.evaluate(guards[i]);
if (!context.booleanValue(g)) {
// System.out.println("guard not satisfied:" + guards[i]);
return false;
}
}
return true;
}
/**
* Execute the action body, potentially changing the value of
* actor state variables and action-scope variables.
*
* @exception caltrop.interpreter.InterpreterException If the
* action body could not be executed successfully.
*/
public void actionStep() {
if (envAction == null) {
throw new InterpreterException(
"DataflowActorInterpreter: Must call actionSetup() "
+ "before calling actionStep().");
}
// First evaluate the action-level thunks, so that their value
// will not be affected by subsequent assignments to action
// or actor variables.
env.freezeLocal();
final Action action = envAction;
final InputPattern[] inputPatterns = action.getInputPatterns();
for (int i = 0; i < inputPatterns.length; i++) {
final InputPattern inputPattern = inputPatterns[i];
// FIXME: handle multiports
final InputChannel channel = ((InputPort) (inputPortMap
.get(inputPattern.getPortname()))).getChannel(0);
if (inputPattern.getRepeatExpr() == null) {
if (!channel.hasAvailable(inputPattern.getVariables().length)) {
throw new InterpreterException("Not enough inputs:"
+ inputPattern.getVariables().length);
}
} else {
int repeatVal = context.intValue(env.get(new EnvironmentKey(
inputPattern.getPortname())));
if (!channel.hasAvailable(inputPattern.getVariables().length
* repeatVal)) {
throw new InterpreterException(
"Not enough repeated inputs:"
+ (inputPattern.getVariables().length * repeatVal));
}
}
}
final StmtEvaluator eval = new StmtEvaluator(context, env);
final Statement[] body = action.getBody();
for (int i = 0; i < body.length; i++) {
eval.evaluate(body[i]);
}
}
}