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

org.aya.concrete.Expr Maven / Gradle / Ivy

There is a newer version: 0.33.0
Show newest version
// Copyright (c) 2020-2021 Yinsen (Tesla) Zhang.
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.concrete;

import kala.collection.immutable.ImmutableSeq;
import kala.collection.mutable.DynamicSeq;
import kala.control.Either;
import kala.tuple.Unit;
import kala.value.Ref;
import org.aya.api.concrete.ConcreteExpr;
import org.aya.api.distill.AyaDocile;
import org.aya.api.distill.DistillerOptions;
import org.aya.api.error.Reporter;
import org.aya.api.ref.LocalVar;
import org.aya.api.ref.Var;
import org.aya.concrete.desugar.AyaBinOpSet;
import org.aya.concrete.desugar.Desugarer;
import org.aya.concrete.resolve.context.ModuleContext;
import org.aya.concrete.resolve.visitor.ExprResolver;
import org.aya.concrete.stmt.QualifiedID;
import org.aya.distill.BaseDistiller;
import org.aya.distill.ConcreteDistiller;
import org.aya.generic.Level;
import org.aya.generic.ParamLike;
import org.aya.generic.ref.PreLevelVar;
import org.aya.pretty.doc.Doc;
import org.aya.tyck.ExprTycker;
import org.aya.util.binop.BinOpParser;
import org.aya.util.error.SourceNode;
import org.aya.util.error.SourcePos;
import org.aya.util.error.WithPos;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.function.Function;

/**
 * @author re-xyr
 */
public sealed interface Expr extends ConcreteExpr {
   R doAccept(@NotNull Visitor visitor, P p);

  default  R accept(@NotNull Visitor visitor, P p) {
    visitor.traceEntrance(this, p);
    var ret = doAccept(visitor, p);
    visitor.traceExit(ret, this, p);
    return ret;
  }

  /**
   * @see org.aya.concrete.stmt.Stmt#resolve
   * @see org.aya.concrete.resolve.visitor.StmtShallowResolver
   */
  @Contract(pure = true)
  default Expr resolve(@NotNull ModuleContext context) {
    var exprResolver = new ExprResolver(ExprResolver.RESTRICTIVE);
    return accept(exprResolver, context);
  }

  @Override default @NotNull Expr desugar(@NotNull Reporter reporter) {
    return accept(new Desugarer(new AyaBinOpSet(reporter)), Unit.unit());
  }

  @Override default @NotNull Doc toDoc(@NotNull DistillerOptions options) {
    return accept(new ConcreteDistiller(options), BaseDistiller.Outer.Free);
  }

  interface Visitor {
    default void traceEntrance(@NotNull Expr expr, P p) {
    }
    default void traceExit(R r, @NotNull Expr expr, P p) {
    }
    R visitRef(@NotNull RefExpr expr, P p);
    R visitUnresolved(@NotNull UnresolvedExpr expr, P p);
    R visitLam(@NotNull LamExpr expr, P p);
    R visitPi(@NotNull PiExpr expr, P p);
    R visitSigma(@NotNull SigmaExpr expr, P p);
    R visitRawUniv(@NotNull RawUnivExpr expr, P p);
    R visitUniv(@NotNull UnivExpr expr, P p);
    R visitApp(@NotNull AppExpr expr, P p);
    R visitHole(@NotNull HoleExpr expr, P p);
    R visitTup(@NotNull TupExpr expr, P p);
    R visitProj(@NotNull ProjExpr expr, P p);
    R visitNew(@NotNull NewExpr expr, P p);
    R visitLitInt(@NotNull LitIntExpr expr, P p);
    R visitRawUnivArgs(@NotNull RawUnivArgsExpr expr, P p);
    R visitUnivArgs(@NotNull UnivArgsExpr expr, P p);
    R visitLsuc(@NotNull LSucExpr expr, P p);
    R visitLmax(@NotNull LMaxExpr expr, P p);
    R visitLitString(@NotNull LitStringExpr expr, P p);
    R visitBinOpSeq(@NotNull BinOpSeq binOpSeq, P p);
    R visitError(@NotNull ErrorExpr error, P p);
  }

  sealed interface WithTerm extends Expr {
    @NotNull Ref theCore();
    default @Nullable ExprTycker.Result core() {
      return theCore().value;
    }
  }

  /**
   * @author re-xyr
   */
  record UnresolvedExpr(
    @NotNull SourcePos sourcePos,
    @NotNull QualifiedID name
  ) implements Expr {
    public UnresolvedExpr(@NotNull SourcePos sourcePos, @NotNull String name) {
      this(sourcePos, new QualifiedID(sourcePos, name));
    }

    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitUnresolved(this, p);
    }
  }

  record ErrorExpr(@NotNull SourcePos sourcePos, @NotNull AyaDocile description) implements Expr {
    public ErrorExpr(@NotNull SourcePos sourcePos, @NotNull Doc description) {
      this(sourcePos, options -> description);
    }

    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitError(this, p);
    }
  }

  /**
   * @author ice1000
   */
  record HoleExpr(
    @Override @NotNull SourcePos sourcePos,
    boolean explicit,
    @Nullable Expr filling,
    Ref> accessibleLocal
  ) implements Expr {
    public HoleExpr(@NotNull SourcePos sourcePos, boolean explicit, @Nullable Expr filling) {
      this(sourcePos, explicit, filling, new Ref<>());
    }

    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitHole(this, p);
    }
  }

  /**
   * @author re-xyr
   */
  record AppExpr(
    @NotNull SourcePos sourcePos,
    @NotNull Expr function,
    @NotNull NamedArg argument
  ) implements Expr {
    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitApp(this, p);
    }
  }

  static @NotNull Expr unapp(@NotNull Expr expr, @NotNull DynamicSeq args) {
    while (expr instanceof AppExpr app) {
      args.append(app.argument);
      expr = app.function;
    }
    args.reverse();
    return expr;
  }

  /**
   * @author AustinZhu
   */
  record NamedArg(boolean explicit, @Nullable String name, @NotNull Expr expr)
    implements AyaDocile, SourceNode, BinOpParser.Elem {

    public NamedArg(boolean explicit, @NotNull Expr expr) {
      this(explicit, null, expr);
    }

    @Override public @NotNull Doc toDoc(@NotNull DistillerOptions options) {
      var doc = name == null ? expr.toDoc(options) :
        Doc.braced(Doc.sep(Doc.plain(name), Doc.symbol("=>"), expr.toDoc(options)));
      return Doc.bracedUnless(doc, explicit);
    }

    @Override public @NotNull SourcePos sourcePos() {
      return expr.sourcePos();
    }
  }

  /**
   * @author re-xyr
   */
  record PiExpr(
    @NotNull SourcePos sourcePos,
    boolean co,
    @NotNull Expr.Param param,
    @NotNull Expr last
  ) implements Expr {
    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitPi(this, p);
    }
  }

  /**
   * @author re-xyr
   */
  record LamExpr(
    @NotNull SourcePos sourcePos,
    @NotNull Expr.Param param,
    @NotNull Expr body
  ) implements Expr {
    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitLam(this, p);
    }
  }

  /**
   * @author re-xyr
   */
  record SigmaExpr(
    @NotNull SourcePos sourcePos,
    boolean co,
    @NotNull ImmutableSeq<@NotNull Param> params
  ) implements Expr {
    @Override public  R doAccept(@NotNull Visitor visitor, P p) {
      return visitor.visitSigma(this, p);
    }
  }

  /**
   * 
   * def infix + add (a b : Nat) => ...
   * def test => zero + zero
   * 
* * @author ice1000 */ record RefExpr( @NotNull SourcePos sourcePos, @NotNull Var resolvedVar, @NotNull Ref theCore ) implements Expr, WithTerm { public RefExpr(@NotNull SourcePos sourcePos, @NotNull Var resolvedVar) { this(sourcePos, resolvedVar, new Ref<>()); } @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitRef(this, p); } } /** * @author re-xyr, ice1000 */ record RawUnivExpr(@NotNull SourcePos sourcePos) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitRawUniv(this, p); } } record UnivExpr(@NotNull SourcePos sourcePos, @NotNull Level level) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitUniv(this, p); } } record RawUnivArgsExpr(@NotNull SourcePos sourcePos, @NotNull ImmutableSeq univArgs) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitRawUnivArgs(this, p); } } record UnivArgsExpr( @Override @NotNull SourcePos sourcePos, @NotNull ImmutableSeq> univArgs ) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitUnivArgs(this, p); } } /** * @author re-xyr */ record TupExpr( @Override @NotNull SourcePos sourcePos, @NotNull ImmutableSeq<@NotNull Expr> items ) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitTup(this, p); } } /** * @param resolvedIx will be modified during tycking * @author re-xyr */ record ProjExpr( @NotNull SourcePos sourcePos, @NotNull Expr tup, @NotNull Either> ix, @NotNull Ref<@Nullable Var> resolvedIx, @NotNull Ref theCore ) implements Expr, WithTerm { public ProjExpr( @NotNull SourcePos sourcePos, @NotNull Expr tup, @NotNull Either> ix, @NotNull Ref<@Nullable Var> resolvedIx ) { this(sourcePos, tup, ix, resolvedIx, new Ref<>()); } @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitProj(this, p); } } record NewExpr( @NotNull SourcePos sourcePos, @NotNull Expr struct, @NotNull ImmutableSeq fields ) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitNew(this, p); } } record Field( @NotNull String name, @NotNull ImmutableSeq> bindings, @NotNull Expr body ) { } /** * @author kiva */ record LitIntExpr(@NotNull SourcePos sourcePos, int integer) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitLitInt(this, p); } } record LSucExpr(@NotNull SourcePos sourcePos, @NotNull Expr expr) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitLsuc(this, p); } } record LMaxExpr(@NotNull SourcePos sourcePos, @NotNull ImmutableSeq levels) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitLmax(this, p); } } record LitStringExpr(@NotNull SourcePos sourcePos, @NotNull String string) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitLitString(this, p); } } /** * @author kiva */ record BinOpSeq( @NotNull SourcePos sourcePos, @NotNull ImmutableSeq seq ) implements Expr { @Override public R doAccept(@NotNull Visitor visitor, P p) { return visitor.visitBinOpSeq(this, p); } } /** * @author re-xyr */ record Param( @NotNull SourcePos sourcePos, @NotNull LocalVar ref, @Nullable Expr type, boolean pattern, boolean explicit ) implements ParamLike { public Param(@NotNull Param param, @Nullable Expr type) { this(param.sourcePos, param.ref, type, param.pattern, param.explicit); } public Param(@NotNull SourcePos sourcePos, @NotNull LocalVar var, boolean explicit) { this(sourcePos, var, null, false, explicit); } public @NotNull Expr.Param mapExpr(@NotNull Function<@NotNull Expr, @Nullable Expr> mapper) { return new Param(sourcePos, ref, type != null ? mapper.apply(type) : null, pattern, explicit); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy