package com.drawbridge.jsengine.ast;
import java.util.LinkedList;
import com.drawbridge.jsengine.Scope;
import com.drawbridge.jsengine.jsobjects.ExecutionException;
import com.drawbridge.jsengine.jsobjects.JSType;
import com.drawbridge.utils.Utils;
import com.google.caja.lexer.FilePosition;
import com.google.caja.parser.js.ArrayConstructor;
import com.google.caja.parser.js.AssignOperation;
import com.google.caja.parser.js.Block;
import com.google.caja.parser.js.BooleanLiteral;
import com.google.caja.parser.js.Conditional;
import com.google.caja.parser.js.ControlOperation;
import com.google.caja.parser.js.Declaration;
import com.google.caja.parser.js.ExpressionStmt;
import com.google.caja.parser.js.ForLoop;
import com.google.caja.parser.js.FunctionConstructor;
import com.google.caja.parser.js.FunctionDeclaration;
import com.google.caja.parser.js.Identifier;
import com.google.caja.parser.js.IntegerLiteral;
import com.google.caja.parser.js.Noop;
import com.google.caja.parser.js.ObjectConstructor;
import com.google.caja.parser.js.RealLiteral;
import com.google.caja.parser.js.Reference;
import com.google.caja.parser.js.ReturnStmt;
import com.google.caja.parser.js.SimpleOperation;
import com.google.caja.parser.js.SpecialOperation;
import com.google.caja.parser.js.StringLiteral;
import com.google.caja.parser.js.ValueProperty;
public abstract class Evaluator
{
public abstract JSType evaluate() throws EvaluatorException, ExecutionException;
public boolean compare(Evaluator e)
{
if (!e.getClass().equals(getClass()))
return false;
if (mChildren.size() != e.mChildren.size())
return false;
for (int i = 0; i < mChildren.size(); i++)
{
if (mChildren.get(i) == null || e.mChildren.get(i) == null || !mChildren.get(i).compare(e.mChildren.get(i)))
return false;
}
if (e.getFilePosition().equals(getFilePosition()))
return true;
else
return false;
}
/**
* Generates code interleaved with original code
*
* @return
* @throws Exception
*/
// public abstract String generateCode() throws Exception;
/**
* Returns blocks to be shown in the Visual Language Representation
*
* @return
*/
public abstract LinkedList<com.drawbridge.vl.blocks.Block> getBlocks();
private FilePosition mFilePosition;
public final Scope mScope;
public Evaluator mParent;
public LinkedList<Evaluator> mChildren = new LinkedList<Evaluator>();
public Evaluator(Evaluator parent, Scope scope, FilePosition position) {
mParent = parent;
mFilePosition = position;
this.mScope = scope;
}
/**
* Returns a new evaluator for a given AST component
*
* @param Parent
* - The parent evaluator for this object
* @param Scope
* - The scope for this object
* @param Object
* - The AST object we want to use
* @return Returns an appropriate evaluator
*/
public static Evaluator getEvaluator(Evaluator parent, Scope scope, Object object)
{
if (object instanceof SpecialOperation)
{
return new SpecialOperationEvaluator(parent, scope, (SpecialOperation) object);
}
else if (object instanceof FunctionDeclaration)
{
return new FunctionDeclarationEvaluator(parent, scope, (FunctionDeclaration) object);
}
else if (object instanceof ControlOperation)
{
return new ControlOperationEvaluator(parent, scope, (ControlOperation) object);
}
else if (object instanceof SimpleOperation)
{
return new SimpleOperationEvaluator(parent, scope, (SimpleOperation) object);
}
else if (object instanceof IntegerLiteral)
{
return new IntegerLiteralEvaluator(parent, scope, (IntegerLiteral) object);
}
else if (object instanceof RealLiteral)
{
return new RealLiteralEvaluator(parent, scope, (RealLiteral) object);
}
else if (object instanceof BooleanLiteral)
{
return new BooleanLiteralEvaluator(parent, scope, (BooleanLiteral) object);
}
else if (object instanceof Noop)
{
return new NoopEvaluator(parent, scope, (Noop) object);
}
else if (object instanceof StringLiteral)
{
return new StringLiteralEvaluator(parent, scope, (StringLiteral) object);
}
else if (object instanceof AssignOperation)
{
return new AssignOperationEvaluator(parent, scope, (AssignOperation) object);
}
else if (object instanceof ArrayConstructor)
{
return new ArrayConstructorEvaluator(parent, scope, (ArrayConstructor) object);
}
else if (object instanceof Declaration)
{
return new DeclarationEvaluator(parent, scope, (Declaration) object);
}
else if (object instanceof ReturnStmt)
{
return new ReturnStmtEvaluator(parent, scope, (ReturnStmt) object);
}
else if (object instanceof Identifier)
{
return new IdentifierEvaluator(parent, scope, (Identifier) object);
}
else if (object instanceof ForLoop)
{
return new ForLoopEvaluator(parent, scope, (ForLoop) object);
}
else if (object instanceof Conditional)
{
return new ConditionalEvaluator(parent, scope, (Conditional) object);
}
else if (object instanceof ExpressionStmt)
{
return new ExpressionStmtEvaluator(parent, scope, (ExpressionStmt) object);
}
else if (object instanceof ObjectConstructor)
{
return new ObjectConstructorEvaluator(parent, scope, (ObjectConstructor) object);
}
else if (object instanceof ValueProperty)
{
return new ValuePropertyEvaluator(parent, scope, (ValueProperty) object);
}
else if (object instanceof Reference)
{
return new ReferenceEvaluator(parent, scope, (Reference) object);
}
else if (object instanceof FunctionConstructor)
{
return new FunctionConstructorEvaluator(parent, scope, (FunctionConstructor) object);
}
else if (object instanceof Block)
{
return new BlockEvaluator(parent, scope, (Block) object);
}
else
{
if (object != null)
Utils.out.println("Evaluator returned null for class of type: " + object.getClass().getName());
else
Utils.out.println("Evaluator returned null for class of type: null");
return null;
}
}
public FilePosition getFilePosition()
{
return mFilePosition;
}
public void setFilePosition(FilePosition f)
{
mFilePosition = f;
}
public boolean contains(int startPosInFile, int endPosInFile)
{
if (this.getFilePosition().startCharInFile() <= startPosInFile &&
this.getFilePosition().endCharInFile() >= endPosInFile)
{
return true;
}
else
return false;
}
/**
*
* @param child
* @return -1 if not child
*/
public int getChildIndex(Evaluator child)
{
if (mChildren == null)
return -1;
for (int i = 0; i < mChildren.size(); i++)
{
if (mChildren.get(i).equals(child))
{
return i;
}
}
return -1;
}
public class EvaluatorException extends Exception
{
private static final long serialVersionUID = -6787406324868348906L;
public EvaluatorException() {
super();
}
public EvaluatorException(String message) {
super(message);
}
public EvaluatorException(String message, Throwable cause) {
super(message, cause);
}
public EvaluatorException(Throwable cause) {
super(cause);
}
}
@Override
public String toString()
{
return this.getClass().getSimpleName();
}
}