Say.java

package org.sterling.runtime.expression;

import static org.sterling.runtime.expression.ExpressionConversions.convertString;

import java.io.PrintStream;
import org.sterling.SterlingException;

public class Say extends Expression {

    private final PrintStream out;

    public Say() {
        out = System.out;
    }

    @Override
    public Expression apply(Expression argument) throws SterlingException {
        return new SayClosure(out, argument);
    }

    private static final class SayClosure extends Expression {

        private final PrintStream out;
        private final Expression argument;

        public SayClosure(PrintStream out, Expression argument) {
            this.out = out;
            this.argument = argument;
        }

        @Override
        public Expression reduce() throws SterlingException {
            StringConstant expression = convertString(argument.evaluate());
            out.println(expression.getValue());
            return expression;
        }

        @Override
        protected boolean isReducible() {
            return true;
        }
    }
}