package scotch.compiler.syntax.pattern; import static scotch.compiler.syntax.builder.BuilderUtil.require; import static scotch.util.Either.right; import java.util.ArrayList; import java.util.List; import java.util.Optional; import com.google.common.collect.ImmutableList; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import scotch.compiler.analyzer.DependencyAccumulator; import scotch.compiler.analyzer.NameAccumulator; import scotch.compiler.analyzer.PrecedenceParser; import scotch.compiler.analyzer.NameQualifier; import scotch.compiler.analyzer.TypeChecker; import scotch.compiler.syntax.builder.SyntaxBuilder; import scotch.compiler.syntax.scope.Scope; import scotch.compiler.syntax.value.Value; import scotch.compiler.text.SourceLocation; import scotch.util.Either; import scotch.compiler.syntax.type.Type; @EqualsAndHashCode(callSuper = false) @ToString(exclude = "sourceLocation") public class UnshuffledStructMatch extends PatternMatch { public static Builder builder() { return new Builder(); } @Getter private final SourceLocation sourceLocation; @Getter private final Type type; private final List<PatternMatch> patternMatches; public UnshuffledStructMatch(SourceLocation sourceLocation, Type type, List<PatternMatch> patternMatches) { this.sourceLocation = sourceLocation; this.type = type; this.patternMatches = ImmutableList.copyOf(patternMatches); } @Override public PatternMatch accumulateDependencies(DependencyAccumulator state) { throw new UnsupportedOperationException(); // TODO } @Override public PatternMatch accumulateNames(NameAccumulator state) { throw new UnsupportedOperationException(); // TODO } @Override public PatternMatch bind(Value argument, Scope scope) { return this; } @Override public PatternMatch bindMethods(TypeChecker state) { throw new UnsupportedOperationException(); // TODO } @Override public PatternMatch bindTypes(TypeChecker state) { throw new UnsupportedOperationException(); // TODO } @Override public PatternMatch checkTypes(TypeChecker state) { throw new UnsupportedOperationException(); // TODO } @Override public Either<PatternMatch, List<PatternMatch>> destructure() { return right(patternMatches); } public List<PatternMatch> getPatternMatches() { return patternMatches; } @Override public PatternMatch qualifyNames(NameQualifier state) { throw new UnsupportedOperationException(); // TODO } @Override public void reducePatterns(PatternReducer reducer) { throw new UnsupportedOperationException(); // TODO } @Override public PatternMatch shuffle(PrecedenceParser state) { return state.shuffle(this); } @Override public PatternMatch withType(Type type) { throw new UnsupportedOperationException(); // TODO } public static class Builder implements SyntaxBuilder<PatternMatch> { private final List<PatternMatch> patternMatches = new ArrayList<>(); private Optional<SourceLocation> sourceLocation = Optional.empty(); private Optional<Type> type = Optional.empty(); @Override public PatternMatch build() { if (patternMatches.size() == 1) { return patternMatches.get(0); } else { return new UnshuffledStructMatch( require(sourceLocation, "Source location"), require(type, "Type"), patternMatches ); } } public Builder withPatternMatch(PatternMatch patternMatch) { patternMatches.add(patternMatch); return this; } @Override public Builder withSourceLocation(SourceLocation sourceLocation) { this.sourceLocation = Optional.of(sourceLocation); return this; } public Builder withType(Type type) { this.type = Optional.of(type); return this; } } }