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

org.aya.concrete.stmt.Decl 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.stmt;

import kala.collection.immutable.ImmutableSeq;
import kala.collection.mutable.DynamicSeq;
import kala.control.Either;
import kala.control.Option;
import org.aya.api.concrete.ConcreteDecl;
import org.aya.api.ref.DefVar;
import org.aya.concrete.Expr;
import org.aya.concrete.Pattern;
import org.aya.concrete.resolve.context.Context;
import org.aya.core.def.*;
import org.aya.core.sort.Sort;
import org.aya.core.term.Term;
import org.aya.generic.Modifier;
import org.aya.util.binop.OpDecl;
import org.aya.util.error.SourcePos;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.EnumSet;
import java.util.function.BiFunction;

/**
 * Concrete definition, corresponding to {@link Def}.
 *
 * @author re-xyr
 */
public sealed abstract class Decl extends Signatured implements Stmt, ConcreteDecl {
  public final @NotNull Accessibility accessibility;
  public @Nullable Context ctx = null;
  public @NotNull Expr result;

  @Override public @NotNull Accessibility accessibility() {
    return accessibility;
  }

  protected Decl(
    @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
    @NotNull Accessibility accessibility,
    @Nullable OpInfo opInfo,
    @NotNull BindBlock bindBlock,
    @NotNull ImmutableSeq telescope,
    @NotNull Expr result
  ) {
    super(sourcePos, entireSourcePos, opInfo, bindBlock, telescope);
    this.accessibility = accessibility;
    this.result = result;
  }

  @Contract(pure = true) public abstract @NotNull DefVar ref();

  protected abstract  R doAccept(@NotNull Visitor visitor, P p);

  @Override public final  R accept(Stmt.@NotNull Visitor visitor, P p) {
    return accept((Visitor) visitor, p);
  }

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

  @ApiStatus.NonExtendable
  public final @Override  R doAccept(Stmt.@NotNull Visitor visitor, P p) {
    return doAccept((Decl.Visitor) visitor, p);
  }

  public interface Visitor {
    default void traceEntrance(@NotNull Signatured item, P p) {
    }
    default void traceExit(P p, R r) {
    }

    @ApiStatus.NonExtendable
    default  RR traced(@NotNull T yeah, P p, @NotNull BiFunction f) {
      traceEntrance(yeah, p);
      var r = f.apply(yeah, p);
      traceExit(p, r);
      return r;
    }

    @ApiStatus.OverrideOnly R visitCtor(Decl.@NotNull DataCtor ctor, P p);
    @ApiStatus.OverrideOnly R visitField(Decl.@NotNull StructField field, P p);
    R visitData(Decl.@NotNull DataDecl decl, P p);
    R visitStruct(Decl.@NotNull StructDecl decl, P p);
    R visitFn(Decl.@NotNull FnDecl decl, P p);
    R visitPrim(Decl.@NotNull PrimDecl decl, P p);
  }

  /**
   * @author ice1000
   * @implSpec the result field of {@link PrimDecl} might be {@link org.aya.concrete.Expr.ErrorExpr},
   * which means it's unspecified in the concrete syntax.
   * @see PrimDef
   */
  public static final class PrimDecl extends Decl implements OpDecl {
    public final @NotNull DefVar ref;

    public PrimDecl(
      @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
      @Nullable OpDecl.OpInfo opInfo,
      @NotNull DefVar ref,
      @NotNull ImmutableSeq telescope,
      @NotNull Expr result
    ) {
      super(sourcePos, entireSourcePos, Accessibility.Public, opInfo, BindBlock.EMPTY, telescope, result);
      ref.concrete = this;
      this.ref = ref;
    }

    @Override public boolean needTyck() {
      return ref.concrete.signature == null;
    }

    @Override public @NotNull DefVar ref() {
      return ref;
    }

    @Override protected  R doAccept(@NotNull Decl.Visitor visitor, P p) {
      return visitor.visitPrim(this, p);
    }
  }

  public static final class DataCtor extends Signatured implements OpDecl {
    public final @NotNull DefVar ref;
    public DefVar dataRef;
    /** Similar to {@link Signatured#signature}, but stores the bindings in {@link DataCtor#patterns} */
    public ImmutableSeq patternTele;
    public @NotNull ImmutableSeq clauses;
    public @NotNull ImmutableSeq patterns;
    public final boolean coerce;

    public DataCtor(
      @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
      @Nullable OpInfo opInfo,
      @NotNull String name,
      @NotNull ImmutableSeq telescope,
      @NotNull ImmutableSeq clauses,
      @NotNull ImmutableSeq patterns,
      boolean coerce,
      @NotNull BindBlock bindBlock
    ) {
      super(sourcePos, entireSourcePos, opInfo, bindBlock, telescope);
      this.clauses = clauses;
      this.coerce = coerce;
      this.patterns = patterns;
      this.ref = DefVar.concrete(this, name);
    }

    @Override public @NotNull DefVar ref() {
      return ref;
    }
  }

  /**
   * Concrete data definition
   *
   * @author kiva
   * @see DataDef
   */
  public static final class DataDecl extends Decl implements OpDecl {
    public final @NotNull DefVar ref;
    public final @NotNull ImmutableSeq body;
    /** Yet type-checked constructors */
    public final @NotNull DynamicSeq<@NotNull CtorDef> checkedBody = DynamicSeq.create();
    public Sort sort;

    public DataDecl(
      @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
      @NotNull Accessibility accessibility,
      @Nullable OpInfo opInfo,
      @NotNull String name,
      @NotNull ImmutableSeq telescope,
      @NotNull Expr result,
      @NotNull ImmutableSeq body,
      @NotNull BindBlock bindBlock
    ) {
      super(sourcePos, entireSourcePos, accessibility, opInfo, bindBlock, telescope, result);
      this.body = body;
      this.ref = DefVar.concrete(this, name);
      body.forEach(ctors -> ctors.dataRef = ref);
    }

    @Override protected  R doAccept(@NotNull Decl.Visitor visitor, P p) {
      return visitor.visitData(this, p);
    }

    @Override public @NotNull DefVar ref() {
      return this.ref;
    }
  }

  /**
   * Concrete structure definition
   *
   * @author vont
   */
  public static final class StructDecl extends Decl implements OpDecl {
    public final @NotNull DefVar ref;
    public @NotNull
    final ImmutableSeq fields;
    public Sort sort;

    public StructDecl(
      @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
      @NotNull Accessibility accessibility,
      @Nullable OpInfo opInfo,
      @NotNull String name,
      @NotNull ImmutableSeq telescope,
      @NotNull Expr result,
      // @NotNull ImmutableSeq superClassNames,
      @NotNull ImmutableSeq fields,
      @NotNull BindBlock bindBlock
    ) {
      super(sourcePos, entireSourcePos, accessibility, opInfo, bindBlock, telescope, result);
      this.fields = fields;
      this.ref = DefVar.concrete(this, name);
      fields.forEach(field -> field.structRef = ref);
    }

    @Override public @NotNull DefVar ref() {
      return ref;
    }

    @Override protected  R doAccept(Decl.@NotNull Visitor visitor, P p) {
      return visitor.visitStruct(this, p);
    }
  }

  public static final class StructField extends Signatured implements OpDecl {
    public final @NotNull DefVar ref;
    public DefVar structRef;
    public @NotNull ImmutableSeq clauses;
    public @NotNull Expr result;
    public @NotNull Option body;

    public final boolean coerce;

    public StructField(
      @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
      @Nullable OpInfo opInfo,
      @NotNull String name,
      @NotNull ImmutableSeq telescope,
      @NotNull Expr result,
      @NotNull Option body,
      @NotNull ImmutableSeq clauses,
      boolean coerce,
      @NotNull BindBlock bindBlock
    ) {
      super(sourcePos, entireSourcePos, opInfo, bindBlock, telescope);
      this.coerce = coerce;
      this.result = result;
      this.clauses = clauses;
      this.body = body;
      this.ref = DefVar.concrete(this, name);
    }

    @Override public @NotNull DefVar ref() {
      return ref;
    }

    @Override public @Nullable OpDecl.OpInfo opInfo() {
      return opInfo;
    }
  }

  /**
   * Concrete function definition
   *
   * @author re-xyr
   * @see FnDef
   */
  public static final class FnDecl extends Decl implements OpDecl {
    public final @NotNull EnumSet modifiers;
    public final @NotNull DefVar ref;
    public @NotNull Either> body;

    public FnDecl(
      @NotNull SourcePos sourcePos, @NotNull SourcePos entireSourcePos,
      @NotNull Accessibility accessibility,
      @NotNull EnumSet modifiers,
      @Nullable OpDecl.OpInfo opInfo,
      @NotNull String name,
      @NotNull ImmutableSeq telescope,
      @NotNull Expr result,
      @NotNull Either> body,
      @NotNull BindBlock bindBlock
    ) {
      super(sourcePos, entireSourcePos, accessibility, opInfo, bindBlock, telescope, result);
      this.modifiers = modifiers;
      this.ref = DefVar.concrete(this, name);
      this.body = body;
    }

    @Override protected  R doAccept(@NotNull Decl.Visitor visitor, P p) {
      return visitor.visitFn(this, p);
    }

    @Override public @NotNull DefVar ref() {
      return this.ref;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy