package de.skuzzle.polly.core.parser.ast;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import de.skuzzle.polly.core.parser.Position;
import de.skuzzle.polly.core.parser.TokenType;
import de.skuzzle.polly.core.parser.ast.directives.Directive;
import de.skuzzle.polly.core.parser.ast.expressions.Expression;
import de.skuzzle.polly.core.parser.ast.expressions.literals.Literal;
import de.skuzzle.polly.core.parser.ast.expressions.literals.LiteralFormatter;
import de.skuzzle.polly.core.parser.ast.visitor.ASTTraversal;
import de.skuzzle.polly.core.parser.ast.visitor.ASTTraversalException;
import de.skuzzle.polly.core.parser.ast.visitor.ASTVisitor;
import de.skuzzle.polly.core.parser.ast.visitor.Transformation;
import de.skuzzle.polly.tools.io.StringBuilderWriter;
import de.skuzzle.polly.tools.strings.IteratorPrinter;
/**
* The root Node holds a collection of parsed expressions.
*
* @author Simon Taddiken
*/
public final class Root extends Node {
private ArrayList<Expression> expressions;
private Identifier command;
private List<Literal> results;
private final boolean hasProblems;
private final Map<TokenType, Directive> directives;
/**
* Creates a new Root Node with given {@link Position} and a collection of parsed
* expressions.
*
* @param position The Node's position.
* @param command Name of the parsed command.
* @param expressions Collection of parsed expressions.
* @param hasProblems Whether the AST contains {@link Problem} nodes.
* @param directives List of directives
*/
public Root(Position position, Identifier command,
Collection<Expression> expressions, boolean hasProblems,
Map<TokenType, Directive> directives) {
super(position);
this.command = command;
this.expressions = new ArrayList<Expression>(expressions);
this.hasProblems = hasProblems;
this.directives = directives;
}
/**
* Sets the expressions of this root.
*
* @param expressions The new expressions.
*/
public void setExpressions(List<Expression> expressions) {
if (expressions instanceof ArrayList) {
this.expressions = (ArrayList<Expression>) expressions;
} else {
this.expressions = new ArrayList<Expression>(expressions);
}
}
/**
* Whether this AST contains problem nodes.
*
* @return Whether this AST contains problem nodes.
*/
public boolean hasProblems() {
return this.hasProblems;
}
/**
* Gets a collection of parsed expressions.
*
* @return The parsed expressions.
*/
public Collection<Expression> getExpressions() {
return this.expressions;
}
/**
* Gets the name of the parsed command.
*
* @return The command name.
*/
public Identifier getCommand() {
return this.command;
}
/**
* Sets the command named of this root.
*
* @param command The command name.
*/
public void setCommand(Identifier command) {
this.command = command;
}
/**
* Gets a list of directives
* @return Directives
*/
public Map<TokenType, Directive> getDirectives() {
return this.directives;
}
@Override
public boolean visit(ASTVisitor visitor) throws ASTTraversalException {
return visitor.visit(this);
}
@Override
public Root transform(Transformation transformation) throws ASTTraversalException {
return transformation.transformRoot(this);
}
@Override
public boolean traverse(ASTTraversal visitor) throws ASTTraversalException {
switch (visitor.before(this)) {
case ASTTraversal.SKIP: return true;
case ASTTraversal.ABORT: return false;
}
if (!this.command.traverse(visitor)) {
return false;
}
for (final Expression exp : this.expressions) {
if (!exp.traverse(visitor)) {
return false;
}
}
for (final Directive dir : this.directives.values()) {
if (!dir.traverse(visitor)) {
return false;
}
}
return visitor.after(this) == ASTTraversal.CONTINUE;
}
public void setResults(List<Literal> results) {
this.results = results;
}
public List<Literal> getResults() {
return this.results;
}
@Override
public String toString() {
final StringBuilder b = new StringBuilder();
b.append(":");
b.append(this.command);
if (this.results != null && !this.results.isEmpty()) {
b.append(" ");
IteratorPrinter.print(this.results, " ",
new IteratorPrinter.StringProvider<Literal>() {
@Override
public String toString(Literal o) {
return o.format(LiteralFormatter.DEFAULT);
}
},
new PrintWriter(new StringBuilderWriter(b)));
}
return b.toString();
}
}