org.aya.generic.stmt.Shaped Maven / Gradle / Ivy
// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang.
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.generic.stmt;
import kala.collection.immutable.ImmutableSeq;
import kala.function.IndexedFunction;
import org.aya.generic.AyaDocile;
import org.aya.syntax.core.def.AnyDef;
import org.aya.syntax.core.def.ConDef;
import org.aya.syntax.core.term.Term;
import org.aya.syntax.core.term.call.DataCall;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.BiPredicate;
import java.util.function.IntUnaryOperator;
/**
* What should I do after I creating a new Shape?
*
* - impl your Shape, see {@link org.aya.syntax.core.term.repr.IntegerTerm},
* and do everything you should after you creating a {@link Term}/{@link org.aya.syntax.core.pat.Pat}.
*
- impl TermComparator, see {@code TermComparator.doCompareUntyped(Term, Term)}
* - impl PatMatcher, see {@code PatMatcher#match(Pat, Term)}
* - impl PatUnifier, see {@link org.aya.syntax.core.pat.PatToTerm}
*
*
* @param
*/
public interface Shaped {
@NotNull Term type();
sealed interface Inductive extends Shaped {
@Override @NotNull DataCall type();
/** Usually called for patterns, not terms, so terms can implement this as identity */
@NotNull T constructorForm();
}
non-sealed interface Nat extends Inductive {
@NotNull T makeZero();
@NotNull T makeSuc(@NotNull T t);
@NotNull T destruct(int repr);
int repr();
default @Override @NotNull T constructorForm() {
int repr = repr();
if (repr == 0) return makeZero();
return makeSuc(destruct(repr - 1));
}
@NotNull Shaped.Nat map(@NotNull IntUnaryOperator f);
}
non-sealed interface Bool extends Inductive {
@NotNull T makeCon0();
@NotNull T makeCon1();
int repr();
default @Override @NotNull T constructorForm() {
int repr = repr();
if (repr == 0) return makeCon0();
return makeCon1();
}
}
non-sealed interface List extends Inductive {
@NotNull ImmutableSeq repr();
@NotNull T makeNil();
@NotNull T makeCons(T x, T xs);
@NotNull T destruct(@NotNull ImmutableSeq repr);
/**
* Comparing two List
*
* @param other another list
* @param comparator a comparator that should compare the subterms between two List.
* @return true if they match (a term matches a pat or two terms are equivalent,
* which depends on the type parameters {@link T} and {@link O}), false if otherwise.
*/
default boolean compareUntyped(@NotNull Shaped.List other, @NotNull BiPredicate comparator) {
var lhsRepr = repr();
var rhsRepr = other.repr();
// the size should equal.
return lhsRepr.sizeEquals(rhsRepr)
&& lhsRepr.allMatchWith(rhsRepr, comparator);
}
@Override default @NotNull T constructorForm() {
var elements = repr();
if (elements.isEmpty()) return makeNil();
return makeCons(elements.getFirst(), destruct(elements.drop(1)));
}
}
/**
* Something Shaped which is applicable, like
* {@link org.aya.syntax.core.def.FnDef}, {@link ConDef}, and probably {@link org.aya.syntax.core.def.DataDef}.
*/
interface Applicable {
@NotNull Def ref();
/**
* Applying arguments.
*
* @param args arguments
* @return null if failed
*/
@Nullable Term apply(@NotNull ImmutableSeq args);
@NotNull Applicable descent(@NotNull IndexedFunction f);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy