ExpressionFactory.java

package org.sterling.runtime.expression;

import static java.util.Arrays.asList;
import static java.util.Collections.EMPTY_SET;
import static org.sterling.runtime.expression.BooleanConstant.FALSE;
import static org.sterling.runtime.expression.BooleanConstant.TRUE;
import static org.sterling.runtime.expression.NullConstant.NULL;

import java.util.HashSet;
import java.util.Set;
import org.sterling.runtime.GlobalModule;

public final class ExpressionFactory {

    public static final Variable SELF = variable("self");

    public static AccessedExpression access(Expression object, Expression member) {
        return new AccessedExpression(object, member);
    }

    public static AppliedExpression apply(Expression lambda, Expression argument) {
        return new AppliedExpression(lambda, argument);
    }

    public static Argument argument(String identifier, Expression expression) {
        return argument(variable(identifier), expression);
    }

    public static Argument argument(Variable variable, Expression expression) {
        return new Argument(variable, expression);
    }

    public static BoundExpression bind(Expression lambda, Argument argument) {
        return new BoundExpression(lambda, argument);
    }

    public static Conditional conditional() {
        return Conditional.INSTANCE;
    }

    public static Expression conditional(
        Expression condition,
        Expression truePath,
        Expression falsePath
    ) {
        return apply(apply(apply(conditional(), condition), truePath), falsePath);
    }

    public static BooleanConstant constant(boolean value) {
        return value ? TRUE : FALSE;
    }

    public static CharacterConstant constant(char value) {
        return new CharacterConstant(value);
    }

    public static DoubleConstant constant(double value) {
        return new DoubleConstant(value);
    }

    public static IntegerConstant constant(int value) {
        return new IntegerConstant(value);
    }

    public static StringConstant constant(String value) {
        return new StringConstant(value);
    }

    public static DeclaredExpression declaration(String identifier, Expression expression) {
        return declaration(symbol(identifier), expression);
    }

    public static DeclaredExpression declaration(Symbol symbol, Expression expression) {
        return new DeclaredExpression(symbol, expression);
    }

    public static Lambda lambda(Variable variable, Expression expression) {
        return new Lambda(variable, expression);
    }

    public static MemberExpression member(ObjectExpression object, Expression member) {
        return new MemberExpression(object, member);
    }

    public static ModuleExpression module(GlobalModule loader) {
        return module(symbol("global"), loader);
    }

    @SuppressWarnings("unchecked")
    public static ModuleExpression module(Symbol symbol, GlobalModule loader) {
        return module(symbol, loader, EMPTY_SET);
    }

    public static ModuleExpression module(Symbol symbol, GlobalModule loader, Set<DeclaredExpression> members) {
        return new ModuleExpression(symbol, loader, members);
    }

    public static ObjectExpression object(DeclaredExpression... members) {
        return new ObjectExpression(new HashSet<>(asList(members)));
    }

    public static NullConstant nothing() {
        return NULL;
    }

    public static Symbol symbol(String identifier) {
        return new Symbol(identifier);
    }

    public static Reference reference(String identifier, GlobalModule repository) {
        return new Reference(symbol(identifier), repository);
    }

    public static Reference reference(String identifier) {
        return reference(symbol(identifier));
    }

    public static Reference reference(Symbol symbol) {
        return new Reference(symbol);
    }

    public static Variable variable(String identifier) {
        return new Variable(identifier);
    }

    private ExpressionFactory() {
        // intentionally empty
    }
}