All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aya.normalize.Finalizer Maven / Gradle / Ivy

The newest version!
// 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.normalize;

import kala.collection.immutable.ImmutableSeq;
import kala.collection.mutable.MutableList;
import kala.collection.mutable.MutableSinglyLinkedList;
import org.aya.normalize.error.UnsolvedLit;
import org.aya.normalize.error.UnsolvedMeta;
import org.aya.syntax.compile.JitMatchy;
import org.aya.syntax.core.def.Matchy;
import org.aya.syntax.core.term.MetaPatTerm;
import org.aya.syntax.core.term.Param;
import org.aya.syntax.core.term.Term;
import org.aya.syntax.core.term.call.MatchCall;
import org.aya.syntax.core.term.call.MetaCall;
import org.aya.syntax.core.term.repr.MetaLitTerm;
import org.aya.syntax.ref.MetaVar;
import org.aya.tyck.TyckState;
import org.aya.tyck.tycker.Problematic;
import org.aya.tyck.tycker.Stateful;
import org.aya.util.reporter.Reporter;
import org.jetbrains.annotations.NotNull;

public interface Finalizer {
  @NotNull TyckState state();
  default @NotNull Term doZonk(@NotNull Term term) {
    return switch (term) {
      case MetaCall meta -> state().computeSolution(meta, this::zonk);
      case MetaPatTerm meta -> meta.inline(this::zonk);
      case MetaLitTerm meta -> meta.inline(this::zonk);
      case MatchCall match -> match.update(
        match.args().map(this::zonk),
        match.captures().map(this::zonk),
        switch (match.ref()) {
          case JitMatchy jit -> jit;
          case Matchy matchy -> matchy.descent(this::zonk);
        });
      default -> term.descent(this::zonk);
    };
  }
  @NotNull Term zonk(@NotNull Term term);

  record Freeze(@NotNull Stateful delegate) implements Finalizer {
    @Override public @NotNull TyckState state() { return delegate.state(); }
    @Override public @NotNull Term zonk(@NotNull Term term) { return doZonk(term); }
  }

  /**
   * The terminology "Zonk" is borrowed from GHC,
   * see StackOverflow.
   */
  record Zonk(
    @NotNull T delegate, @NotNull MutableSinglyLinkedList stack,
    @NotNull MutableList alreadyReported
  ) implements Finalizer, Stateful, Problematic {
    public Zonk(@NotNull T delegate) {
      this(delegate, MutableSinglyLinkedList.create(), MutableList.create());
    }
    @Override public @NotNull TyckState state() { return delegate.state(); }
    @Override public @NotNull Reporter reporter() { return delegate.reporter(); }

    public ImmutableSeq zonk(ImmutableSeq tele) {
      return tele.map(wp -> wp.descent(this::zonk));
    }

    public @NotNull Term zonk(@NotNull Term term) {
      stack.push(term);
      var result = doZonk(term);
      // result shall not be MetaPatTerm
      switch (result) {
        case MetaCall(var ref, _) when !ref.isUser() && !alreadyReported.contains(ref) -> {
          alreadyReported.append(ref);
          fail(new UnsolvedMeta(stack.view()
            .drop(1)
            .map(this::freezeHoles)
            .toImmutableSeq(), ref.pos(), ref.name()));
        }
        case MetaLitTerm mlt -> fail(new UnsolvedLit(mlt));
        default -> {
        }
      }
      stack.pop();
      return result;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy