package de.skuzzle.polly.core.parser.ast.lang; import java.util.Collection; import java.util.Collections; import de.skuzzle.polly.core.parser.Position; import de.skuzzle.polly.core.parser.ast.ResolvableIdentifier; import de.skuzzle.polly.core.parser.ast.declarations.Declaration; 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.expressions.literals.FunctionLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.Literal; 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; /** * This represents a casting operator. Casting operators are normal function calls * to a function which name equals the name of the cast target type. * * @author Simon Taddiken * */ public class Cast extends Operator { protected final static ResolvableIdentifier PARAM_NAME = new ResolvableIdentifier( Position.NONE, "$param"); private final Type operandType; /** * Creates a new Casting operator. * * @param operator The operator type. Important: Must be one of the values from the * 'casting' section in <code>OpType</code>. * @param target Target type to cast to. */ public Cast(OpType operator, Type target) { super(operator); this.setUnique(target); this.operandType = Type.newTypeVar(); } @Override public void execute(Stack<Literal> stack, Namespace ns, ExecutionVisitor execVisitor) throws ASTTraversalException { // on a function call, parameters are already executed to be a Literal final Literal operand = (Literal) ns.resolveFirst(PARAM_NAME).getExpression(); stack.push(operand.castTo(this.getUnique())); } @Override protected FunctionLiteral createFunction() { // create parameter that accepts any expression (Type.ANY) final Collection<Declaration> p = Collections.singletonList( this.typeToParameter(this.operandType, PARAM_NAME)); final FunctionLiteral func = new FunctionLiteral(Position.NONE, p, this); func.setUnique(new ProductType(this.operandType).mapTo(this.getUnique())); return func; } @Override public Declaration createDeclaration() { final FunctionLiteral func = this.createFunction(); final Declaration vd = new Declaration( func.getPosition(), this.getUnique().getName(), func); vd.setNative(true); return vd; } }