package de.skuzzle.polly.core.parser.ast.expressions.literals;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Locale;
import de.skuzzle.polly.core.parser.ast.declarations.Declaration;
import de.skuzzle.polly.core.parser.ast.expressions.Expression;
import de.skuzzle.polly.core.parser.ast.lang.Function;
import de.skuzzle.polly.core.parser.ast.visitor.Unparser;
import de.skuzzle.polly.core.parser.util.TimeSpanFormat;
import de.skuzzle.polly.tools.io.StringBuilderWriter;
import de.skuzzle.polly.tools.strings.IteratorPrinter;
import de.skuzzle.polly.tools.strings.IteratorPrinter.StringProvider;
/**
* Visitor style interface to format literals into a string representation. It can be
* used in conjunction with {@link Literal#format(LiteralFormatter)}.
*
* @author Simon Taddiken
*/
public interface LiteralFormatter {
/**
* This formatter formats all literals so that the result will be parseable again.
*/
public LiteralFormatter DEFAULT = new LiteralFormatter() {
private final TimeSpanFormat TIMESPAN_FORMAT = new TimeSpanFormat(false);
private final DateFormat DATE_FORMAT = new SimpleDateFormat(
"HH:mm@dd.MM.yyyy");
@Override
public String formatNumberLiteral(NumberLiteral number) {
final DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(
Locale.ENGLISH);
df.applyPattern("0.#####");
final double val = number.getValue();
if (Math.round(val) == val) {
int intVal = (int) val;
return Integer.toString(intVal, number.getRadix());
}
return df.format(val);
}
@Override
public String formatDate(DateLiteral date) {
return DATE_FORMAT.format(date.getValue());
}
@Override
public String formatTimespan(TimespanLiteral timespan) {
return TIMESPAN_FORMAT.format(timespan.getSeconds());
}
@Override
public String formatChannel(ChannelLiteral channelLiteral) {
return "#" + channelLiteral.getValue();
}
@Override
public String formatString(StringLiteral string) {
return "\"" + string.getValue() + "\"";
}
@Override
public String formatUser(UserLiteral user) {
return "@" + user.getValue();
}
@Override
public String formatList(ListLiteral listLiteral) {
StringBuilder b = new StringBuilder();
b.append("{");
IteratorPrinter.print(
listLiteral.getContent(), ", ",
new StringProvider<Expression>() {
@Override
public String toString(Expression o) {
return Unparser.toString(o);
}
}, new PrintWriter(new StringBuilderWriter(b)));
b.append("}");
return b.toString();
}
@Override
public String formatFunction(FunctionLiteral functionLiteral) {
final StringBuilder b = new StringBuilder();
b.append("\\(");
final Iterator<Declaration> it = functionLiteral.getFormal().iterator();
while (it.hasNext()) {
final Declaration formal = it.next();
b.append(formal.getType().getName());
b.append(" ");
b.append(formal.getName());
if (it.hasNext()) {
b.append(",");
}
}
if (!(functionLiteral.getBody() instanceof Function)) {
b.append(":");
b.append(Unparser.toString(functionLiteral.getBody(), this));
}
b.append(")");
return b.toString();
}
@Override
public String formatHelp(HelpLiteral helpLiteral) {
return "?";
}
};
/**
* Formats a number literal to string.
*
* @param number The literal to format.
* @return A String representation of that literal.
*/
public String formatNumberLiteral(NumberLiteral number);
/**
* Formats a date literal to string.
*
* @param date The literal to format.
* @return A String representation of that literal.
*/
public String formatDate(DateLiteral date);
/**
* Formats a timespan literal to string.
*
* @param timespan The literal to format.
* @return A String representation of that literal.
*/
public String formatTimespan(TimespanLiteral timespan);
/**
* Formats a channel literal to string.
*
* @param channel The literal to format.
* @return A String representation of that literal.
*/
public String formatChannel(ChannelLiteral channel);
/**
* Formats a string literal to string (yeah, funny ehh?).
*
* @param string The literal to format.
* @return A String representation of that literal.
*/
public String formatString(StringLiteral string);
/**
* Formats a user literal to string.
*
* @param user The literal to format.
* @return A String representation of that literal.
*/
public String formatUser(UserLiteral user);
/**
* Formats a list literal to string.
*
* @param listLiteral The literal to format.
* @return A String representation of that literal.
*/
public String formatList(ListLiteral listLiteral);
/**
* Formats a function literal to string.
*
* @param functionLiteral The literal to format.
* @return A String representation of that literal.
*/
public String formatFunction(FunctionLiteral functionLiteral);
/**
* Formats a help literal to string.
*
* @param helpLiteral The literal to format.
* @return A String representation of that literal.
*/
public String formatHelp(HelpLiteral helpLiteral);
}