package code.type.typechecker;

import code.type.*;
import code.type.visitor.TypeVisitor;

/**
 * A typechecker that implements the Occurs Checks in the context of an Environment.
 *
 * The second argument to all visit methods should be a TypeVariable.
 * The purpose of the visit method is to check if the second argument "occurs" in the first argument.
 * If it occurs then return true, else return false.
 *
 * @author Pravin Damle
 * @since 12/5/04
 */
public class OccursCheckTypeVarVisitor 
    implements TypeVisitor<Boolean,Object> {

    private TypeVariable checkIfThisVarOccurs ;
    public OccursCheckTypeVarVisitor(TypeVariable checkIfThisVarOccurs) {
        this.checkIfThisVarOccurs = checkIfThisVarOccurs ;
    }

    public Boolean visit(TypeVariable var, Object o) {
        return new Boolean (var.name.equals(checkIfThisVarOccurs.name));
    }

    public Boolean visit(TypeConstructor tc, Object o) {
        return new Boolean(false) ;

    }

    public Boolean visit(FunctionType t, Object o) {
        Boolean occursdomain = t.domain.accept(this,o) ;
        Boolean occursrange =  t.range.accept(this,o) ;
        return new Boolean ( occursdomain.booleanValue() ||
			     occursrange.booleanValue()) ;

    }

    public Boolean visit(TypeConstructorApplication tc, Object o) {
        for (int i = 0; i < tc.arguments.length; i++) {
            if ( ((Boolean)tc.arguments[i].accept(this,o)).booleanValue() )
                return new Boolean(true);
        }
        return new Boolean(false) ;
    }
}


