package de.skuzzle.polly.core.parser.ast.lang.functions; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import de.skuzzle.polly.core.parser.Position; import de.skuzzle.polly.core.parser.ast.declarations.Namespace; import de.skuzzle.polly.core.parser.ast.declarations.types.ProductType; import de.skuzzle.polly.core.parser.ast.declarations.types.Type; import de.skuzzle.polly.core.parser.ast.declarations.types.TypeVar; import de.skuzzle.polly.core.parser.ast.expressions.Call; import de.skuzzle.polly.core.parser.ast.expressions.Expression; import de.skuzzle.polly.core.parser.ast.expressions.literals.FunctionLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ListLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.Literal; import de.skuzzle.polly.core.parser.ast.expressions.literals.NumberLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ProductLiteral; import de.skuzzle.polly.core.parser.ast.lang.BinaryOperator; import de.skuzzle.polly.core.parser.ast.visitor.ASTTraversalException; import de.skuzzle.polly.core.parser.ast.visitor.ExecutionVisitor; import de.skuzzle.polly.tools.collections.Stack; public class Sort extends BinaryOperator<ListLiteral, FunctionLiteral> { public Sort() { super(OpType.SORT); final TypeVar tv = Type.newTypeVar("A"); this.initTypes(tv.listOf(), tv.listOf(), new ProductType(tv, tv).mapTo(Type.NUM)); } @Override protected void exec(final Stack<Literal> stack, Namespace ns, ListLiteral left, final FunctionLiteral right, final Position resultPos, final ExecutionVisitor execVisitor) throws ASTTraversalException { final Comparator<Expression> c = new Comparator<Expression>() { @Override public int compare(Expression l1, Expression l2) { final Call call = new Call(resultPos, right, new ProductLiteral(resultPos, Arrays.asList(new Expression[] {l1, l2}))); try { call.visit(execVisitor); } catch (ASTTraversalException e) { throw new RuntimeException(e); } final NumberLiteral nl = (NumberLiteral) stack.pop(); return (int) nl.getValue(); } }; final List<Expression> copy = new ArrayList<Expression>(left.getContent()); Collections.sort(copy, c); final ListLiteral result = new ListLiteral(resultPos, copy); result.setUnique(left.getUnique()); stack.push(result); } }