Reference.java

package org.sterling.runtime.expression;

import static org.sterling.util.StringUtil.stringify;

import java.util.Objects;
import org.sterling.SterlingException;
import org.sterling.runtime.GlobalModule;

public class Reference extends Expression {

    private final Symbol symbol;
    private final GlobalModule globalModule;

    public Reference(Symbol symbol) {
        this.symbol = symbol;
        this.globalModule = null;
    }

    public Reference(Symbol symbol, GlobalModule globalModule) {
        this.symbol = symbol;
        this.globalModule = globalModule;
    }

    @Override
    public <R, D> R accept(ExpressionVisitor<R, D> visitor, D data) throws SterlingException {
        return visitor.visitReference(this, data);
    }

    @Override
    public Expression apply(Expression argument) throws SterlingException {
        return reduce().apply(argument);
    }

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

    public Symbol getSymbol() {
        return symbol;
    }

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

    @Override
    public Expression reduce() throws SterlingException {
        return globalModule.load(symbol.getValue());
    }

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

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