package de.skuzzle.polly.core.parser.ast.lang; 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.MapType; import de.skuzzle.polly.core.parser.ast.declarations.types.Type; import de.skuzzle.polly.core.parser.ast.expressions.Empty; import de.skuzzle.polly.core.parser.ast.expressions.Native; 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.core.parser.ast.visitor.resolving.AbstractTypeResolver; import de.skuzzle.polly.tools.collections.Stack; /** * Represents a hardcoded function in the AST. Those functions are fully compatible with * user created function declarations but provide basic operations like the one provided * by the {@link Math} class. Those can not be expressed using primitive polly * expressions and thus need a special treatment. * * @author Simon Taddiken * @see Native */ public abstract class Function extends Native { private final ResolvableIdentifier name; /** * Creates a new function with the given name. * * @param name This function's name. */ public Function(String name) { super(Type.UNKNOWN); this.name = new ResolvableIdentifier(Position.NONE, name); } /** * Creates a {@link FunctionLiteral} which represents this hardcoded function. * * @return A {@link FunctionLiteral}. */ protected abstract FunctionLiteral createFunction(); /** * <p>Creates a proper declaration for this operator. Additionally, sets this * Function's type according to the return type of the {@link FunctionLiteral} * created by {@link #createFunction()}. This method should be called only once per * instance.</p> * * <p>The created declaration will have the 'isPrimitive' flag set to true and the * 'mustCopy' flag set according to whether the function's type contains type * variables.</p> * * @return A declaration for this function. */ public Declaration createDeclaration() { final FunctionLiteral func = this.createFunction(); final Declaration vd = new Declaration(func.getPosition(), this.name, func); this.setUnique(((MapType) func.getUnique()).getTarget()); vd.setNative(true); return vd; } /** * Creates a new Parameter from a given type and name. * * @param type The parameters type. * @param name The parameters name. * @return A new parameter instance. */ protected Declaration typeToParameter(Type type, ResolvableIdentifier name) { return new Declaration(name.getPosition(), name, new Empty(type, name.getPosition())); } @Override public void execute(Stack<Literal> stack, Namespace ns, ExecutionVisitor execVisitor) throws ASTTraversalException {} @Override public void resolveType(Namespace ns, AbstractTypeResolver typeResolver) throws ASTTraversalException {} }