StringConstant.java

package org.sterling.runtime.expression;

import static org.sterling.runtime.expression.BooleanConstant.FALSE;
import static org.sterling.runtime.expression.BooleanConstant.TRUE;
import static org.sterling.runtime.expression.ExpressionConversions.convertString;
import static org.sterling.runtime.expression.ExpressionConversions.convertSymbol;
import static org.sterling.runtime.expression.ExpressionFactory.constant;
import static org.sterling.runtime.expression.ExpressionFactory.symbol;
import static org.sterling.util.StringUtil.stringify;

import java.util.Objects;
import org.sterling.SterlingException;
import org.sterling.runtime.exception.ConversionException;

public class StringConstant extends Expression {

    private final String value;

    public StringConstant(String value) {
        this.value = value;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Expression access(Expression member) throws SterlingException {
        switch (convertSymbol(member).getValue()) {
            case "+": return new ConcatenateClosure(value);
            case "toSymbol": return symbol(value);
            case "toBoolean": return toBoolean();
            case "toInteger": return toInteger();
            case "toString": return this;
            default: return super.access(member);
        }
    }

    @Override
    public boolean equals(Object o) {
        return o == this || o instanceof StringConstant && Objects.equals(value, ((StringConstant) o).value);
    }

    public String getValue() {
        return value;
    }

    @Override
    public int hashCode() {
        return Objects.hash(value);
    }

    @Override
    public String toString() {
        return stringify(this, '"' + value + '"');
    }

    private BooleanConstant toBoolean()  {
        return "true".equalsIgnoreCase(value) ? TRUE : FALSE;
    }

    private IntegerConstant toInteger() throws SterlingException {
        try {
            return constant(Integer.valueOf(value));
        } catch (NumberFormatException exception) {
            throw new ConversionException(exception);
        }
    }

    private static final class ConcatenateClosure extends Expression {

        private final String value;

        public ConcatenateClosure(String value) {
            this.value = value;
        }

        @SuppressWarnings("unchecked")
        @Override
        public Expression apply(Expression operand) throws SterlingException {
            return new StringConstant(value + convertString(operand).value);
        }

        @Override
        public String toString() {
            return stringify(this, '"' + value + '"');
        }
    }
}