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(); } }