package ktak.differegex;

import java.util.Comparator;

import ktak.immutablejava.Function;

public abstract class Regex<CharType> {
    
    protected abstract <R> R visit(Visitor<R,CharType> visitor);
    
    protected abstract <R> R match(
            Function<EmptySet<CharType>,R> emptySetCase,
            Function<EmptyString<CharType>,R> emptyStringCase,
            Function<SingleChar<CharType>,R> singleCharCase,
            Function<Sequence<CharType>,R> sequenceCase,
            Function<Alternation<CharType>,R> alternationCase,
            Function<ZeroOrMore<CharType>,R> zeroOrMoreCase,
            Function<Conjunction<CharType>,R> conjunctionCase,
            Function<Negation<CharType>,R> negationCase);
    
    protected interface Visitor<R,CharType> {
        R visitEmptySet(EmptySet<CharType> emptySet);
        R visitEmptyString(EmptyString<CharType> emptyString);
        R visitSingleChar(SingleChar<CharType> singleChar);
        R visitSequence(Sequence<CharType> sequence);
        R visitAlternation(Alternation<CharType> alternation);
        R visitZeroOrMore(ZeroOrMore<CharType> zeroOrMore);
        R visitConjunction(Conjunction<CharType> conjunction);
        R visitNegation(Negation<CharType> negation);
    }
    
    protected abstract boolean matchesEmptyString();
    
    protected abstract Partition<CharType> partition(Comparator<CharType> cmp);
    
}

@@ -1396,10 +1396,831 @@
 );%0A    %0A
+    public static %3CCharType%3E Regex%3CCharType%3E emptyString() %7B%0A        return new EmptyString%3CCharType%3E();%0A    %7D%0A    %0A    public static %3CCharType%3E Regex%3CCharType%3E singleChar(CharType matchChar) %7B%0A        return new SingleChar%3CCharType%3E(matchChar);%0A    %7D%0A    %0A    public Regex%3CCharType%3E seq(Regex%3CCharType%3E second) %7B%0A        return new Sequence%3CCharType%3E(this, second);%0A    %7D%0A    %0A    public Regex%3CCharType%3E alt(Regex%3CCharType%3E second) %7B%0A        return new Alternation%3CCharType%3E(this, second);%0A    %7D%0A    %0A    public Regex%3CCharType%3E zeroOrMore() %7B%0A        return new ZeroOrMore%3CCharType%3E(this);%0A    %7D%0A    %0A    public Regex%3CCharType%3E conj(Regex%3CCharType%3E second) %7B%0A        return new Conjunction%3CCharType%3E(this, second);%0A    %7D%0A    %0A    public Regex%3CCharType%3E negate() %7B%0A        return new Negation%3CCharType%3E(this);%0A    %7D%0A    %0A
 %7D%0A

add public Regex constructor methods