package de.skuzzle.polly.core.util; import java.util.ArrayList; import java.util.List; import de.skuzzle.polly.core.parser.Position; import de.skuzzle.polly.core.parser.ast.declarations.types.ListType; 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.Expression; import de.skuzzle.polly.core.parser.ast.expressions.literals.BooleanLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ChannelLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.DateLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.FunctionLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.HelpLiteral; 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.StringLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.TimespanLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.UserLiteral; import de.skuzzle.polly.sdk.Types; import de.skuzzle.polly.sdk.Types.FunctionType;; /** * This class maps from parser literals and types to sdk types. * * @author Simon */ public class TypeMapper { /** * Maps a sdk type to a parser type, discarding the <tt>types</tt> value. * @param types The sdk Type * @return The corresponding parser type. */ public static Type typesToType(Types types) { if (types instanceof Types.BooleanType) { return Type.BOOLEAN; } else if(types instanceof Types.ChannelType) { return Type.CHANNEL; } else if (types instanceof Types.TimespanType) { return Type.TIMESPAN; } else if (types instanceof Types.DateType) { return Type.DATE; } else if (types instanceof Types.NumberType) { return Type.NUM; } else if (types instanceof Types.UserType) { return Type.USER; } else if (types instanceof Types.StringType) { return Type.STRING; } else if (types instanceof Types.HelpType) { return Type.HELP; } else if (types instanceof Types.ListType) { Types.ListType lt = (Types.ListType) types; return TypeMapper.typesToType(lt.getElementType()).listOf(); } throw new IllegalArgumentException("Invalid type"); } /** * Maps a parser type to a sdk type with empty values. * @param type The parser type. * @return The corresponding sdk type. */ public static Types typeToTypes(Type type) { if (type == Type.BOOLEAN) { return new Types.BooleanType(false); } else if (type == Type.CHANNEL) { return Types.CHANNEL; } else if (type == Type.TIMESPAN) { return Types.TIMESPAN; } else if (type == Type.DATE) { return Types.DATE; } else if (type == Type.NUM) { return Types.NUMBER; } else if (type == Type.STRING) { return Types.STRING; } else if (type == Type.USER) { return Types.USER; } else if (type == Type.HELP) { return Types.HELP; } else if (type instanceof ListType) { ListType lt = (ListType) type; return new Types.ListType(TypeMapper.typeToTypes(lt.getSubType())); } else if (type instanceof MapType) { return new FunctionType(); } throw new IllegalArgumentException("Invalid type"); } /** * Maps a sdk type to a parser literal with the same value and empty position. * @param types The sdk type. * @return A corresponding parser literal. */ public static Literal typesToLiteral(Types types) { if (types instanceof Types.BooleanType) { Types.BooleanType bt = (Types.BooleanType) types; return new BooleanLiteral(Position.NONE, bt.getValue()); } else if(types instanceof Types.ChannelType) { Types.ChannelType bt = (Types.ChannelType) types; return new ChannelLiteral(Position.NONE, bt.getValue()); } else if (types instanceof Types.TimespanType) { Types.TimespanType ts = (Types.TimespanType) types; return new TimespanLiteral(Position.NONE, (int)ts.getSpan()); } else if (types instanceof Types.DateType) { Types.DateType ct = (Types.DateType) types; return new DateLiteral(Position.NONE, ct.getValue()); } else if (types instanceof Types.NumberType) { Types.NumberType bt = (Types.NumberType) types; return new NumberLiteral(Position.NONE, bt.getValue()); } else if (types instanceof Types.UserType) { Types.UserType bt = (Types.UserType) types; return new UserLiteral(Position.NONE, bt.getValue()); } else if (types instanceof Types.StringType) { Types.StringType bt = (Types.StringType) types; return new StringLiteral(Position.NONE, bt.getValue()); } else if (types instanceof Types.HelpType) { return new HelpLiteral(Position.NONE); } else if (types instanceof Types.ListType) { Types.ListType lt = (Types.ListType) types; ArrayList<Expression> elements = new ArrayList<Expression>(); Types unique = null; for (Types t : lt.getElements()) { elements.add(TypeMapper.typesToLiteral(t)); unique = t; } final ListLiteral ll = new ListLiteral(Position.NONE, elements); ll.setUnique(TypeMapper.typesToType(unique).listOf()); return ll; } throw new IllegalArgumentException("Invalid type"); } /** * Maps a parser literal to a sdk type with the same value. * @param literal The parser literal. * @return A corresponding sdk type with same value. */ public static Types literalToTypes(Expression literal) { if (literal instanceof BooleanLiteral) { BooleanLiteral bl = (BooleanLiteral) literal; return new Types.BooleanType(bl.getValue()); } else if (literal instanceof ChannelLiteral) { ChannelLiteral bl = (ChannelLiteral) literal; return new Types.ChannelType(bl.getValue()); } else if (literal instanceof TimespanLiteral) { TimespanLiteral ts = (TimespanLiteral) literal; return new Types.TimespanType(ts.getSeconds()); } else if (literal instanceof DateLiteral) { DateLiteral dt = (DateLiteral) literal; return new Types.DateType(dt.getValue()); } else if (literal instanceof NumberLiteral) { NumberLiteral bl = (NumberLiteral) literal; return new Types.NumberType(bl.getValue(), bl.getRadix()); } else if (literal instanceof UserLiteral) { UserLiteral bl = (UserLiteral) literal; return new Types.UserType(bl.getValue()); } else if (literal instanceof StringLiteral) { StringLiteral bl = (StringLiteral) literal; return new Types.StringType(bl.getValue()); } else if (literal instanceof HelpLiteral) { return Types.HELP; } else if (literal instanceof ListLiteral) { ListLiteral lt = (ListLiteral) literal; List<Types> elements = new ArrayList<Types>(); for (Expression lit : lt.getContent()) { elements.add(TypeMapper.literalToTypes(lit)); } return new Types.ListType(elements); } else if (literal instanceof FunctionLiteral) { return new FunctionType(); } throw new IllegalArgumentException("Invalid type"); } }