Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pretty print/literate mode features #1094

Merged
merged 5 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions base/src/main/java/org/aya/resolve/visitor/ExprResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ public ExprResolver(@NotNull Context ctx, @NotNull Options options) {
// if (resolvedIx == null) ctx.reportAndThrow(new FieldError.UnknownField(projName.sourcePos(), projName.join()));
yield new Expr.Proj(tup, ix, resolvedIx, theCore);
}
case Expr.Hole(var expl, var fill, var local) -> {
case Expr.Hole(var expl, var fill, var core, var local) -> {
assert local.isEmpty();
yield new Expr.Hole(expl, fill, ctx.collect(MutableList.create()).toImmutableSeq());
yield new Expr.Hole(expl, fill, core,
ctx.collect(MutableList.create()).toImmutableSeq());
}
default -> expr;
};
Expand Down
6 changes: 6 additions & 0 deletions base/src/main/java/org/aya/tyck/ExprTycker.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
public final class ExprTycker extends AbstractTycker implements Unifiable {
public final @NotNull MutableTreeSet<WithPos<Expr.WithTerm>> withTerms =
MutableTreeSet.create(Comparator.comparing(SourceNode::sourcePos));
public final @NotNull MutableList<WithPos<Expr.Hole>> userHoles = MutableList.create();
private @NotNull LocalLet localLet;

public void addWithTerm(@NotNull Expr.WithTerm with, @NotNull SourcePos pos, @NotNull Term type) {
Expand All @@ -73,6 +74,7 @@ public ExprTycker(@NotNull TyckState state, @NotNull Reporter reporter) {
public void solveMetas() {
state.solveMetas(reporter);
withTerms.forEach(with -> with.data().theCoreType().update(this::freezeHoles));
userHoles.forEach(hole -> hole.data().solution().update(this::freezeHoles));
}

/**
Expand Down Expand Up @@ -102,6 +104,8 @@ case PiTerm(var dom, var cod) -> {
};
case Expr.Hole hole -> {
var freshHole = freshMeta(Constants.randomName(hole), expr.sourcePos(), new MetaVar.OfType(type));
hole.solution().set(freshHole);
userHoles.append(new WithPos<>(expr.sourcePos(), hole));
if (hole.explicit()) fail(new Goal(state, freshHole, hole.accessibleLocal()));
yield new Jdg.Default(freshHole, type);
}
Expand Down Expand Up @@ -149,6 +153,8 @@ case PiTerm(var dom, var cod) -> {
: new Closure.Jit(i -> new AppTerm(result.wellTyped(), i));
checkBoundaries(eq, closure, expr.sourcePos(), msg ->
new CubicalError.BoundaryDisagree(expr, msg, new UnifyInfo(state)));
if (expr.data() instanceof Expr.WithTerm with)
addWithTerm(with, expr.sourcePos(), eq);
return new Jdg.Default(new LamTerm(closure), eq);
}
}
Expand Down
12 changes: 12 additions & 0 deletions base/src/main/java/org/aya/tyck/tycker/TeleTycker.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.aya.tyck.Jdg;
import org.aya.tyck.error.UnifyError;
import org.aya.unify.Synthesizer;
import org.aya.util.error.SourcePos;
import org.aya.util.error.WithPos;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
Expand All @@ -29,6 +30,7 @@ public sealed interface TeleTycker extends Contextful {
* @return well-typed type or {@link ErrorTerm}
*/
@NotNull Term checkType(@NotNull WithPos<Expr> typeExpr, boolean isResult);
void addWithTerm(@NotNull Expr.WithTerm with, @NotNull SourcePos pos, @NotNull Term type);

/**
* @return a locally nameless signature computed from what's in the localCtx.
Expand Down Expand Up @@ -63,6 +65,7 @@ public sealed interface TeleTycker extends Contextful {
default @NotNull MutableSeq<Param> checkTeleFree(ImmutableSeq<Expr.Param> cTele) {
return MutableSeq.from(cTele.view().map(p -> {
var pTy = checkType(p.typeExpr(), false);
addWithTerm(p, p.sourcePos(), pTy);
localCtx().put(p.ref(), pTy);
return new Param(p.ref().name(), pTy, p.explicit());
}));
Expand Down Expand Up @@ -112,6 +115,9 @@ record Default(@Override @NotNull ExprTycker tycker) implements Impl {
@Override public @NotNull Term checkType(@NotNull WithPos<Expr> typeExpr, boolean isResult) {
return tycker.ty(typeExpr);
}
@Override public void addWithTerm(Expr.@NotNull WithTerm with, @NotNull SourcePos pos, @NotNull Term type) {
tycker.addWithTerm(with, pos, type);
}
}

final class InlineCode implements Impl {
Expand All @@ -129,6 +135,9 @@ final class InlineCode implements Impl {
result = jdg;
return jdg.wellTyped();
}
@Override public void addWithTerm(Expr.@NotNull WithTerm with, @NotNull SourcePos pos, @NotNull Term type) {
tycker.addWithTerm(with, pos, type);
}
@Override public @NotNull ExprTycker tycker() { return tycker; }
}

Expand All @@ -140,5 +149,8 @@ record Con(@NotNull ExprTycker tycker, @NotNull SortTerm dataResult) implements
}
return result;
}
@Override public void addWithTerm(Expr.@NotNull WithTerm with, @NotNull SourcePos pos, @NotNull Term type) {
tycker.addWithTerm(with, pos, type);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,21 @@ static void checkHighlights(@NotNull ImmutableSeq<HighlightInfo> highlights) {
case HighlightInfo.Def def -> Doc.linkDef(highlightVar(raw, def.kind()), def.target(), hover(def.type()));
case HighlightInfo.Ref ref -> Doc.linkRef(highlightVar(raw, ref.kind()), ref.target(), hover(ref.type()));
case HighlightInfo.Lit lit -> highlightLit(raw, lit.kind());
case HighlightInfo.Err err -> {
var doc = doHighlight(StringSlice.of(raw), base, err.children());
var style = switch (err.problem().level()) {
case HighlightInfo.Err(var problem, var children) -> {
var doc = doHighlight(StringSlice.of(raw), base, children);
var style = switch (problem.level()) {
case ERROR -> BasePrettier.ERROR;
case WARN -> BasePrettier.WARNING;
case GOAL -> BasePrettier.GOAL;
case INFO -> null;
};
yield style == null ? doc : new Doc.Tooltip(Doc.styled(style, doc), () -> Doc.codeBlock(
Language.Builtin.Aya,
err.problem().brief(options()).toDoc()
problem.brief(options()).toDoc()
));
}
case HighlightInfo.UserMeta meta -> new Doc.Tooltip(Doc.plain(raw),
() -> Doc.codeBlock(Language.Builtin.Aya, meta.hover().toDoc(options())));
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2023 Tesla (Yinsen) Zhang.
// 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.cli.literate;

Expand Down Expand Up @@ -88,4 +88,7 @@ record Err(

/** A literal */
record Lit(@NotNull SourcePos sourcePos, @NotNull LitKind kind) implements HighlightInfo { }

/** Usually metavariables */
record UserMeta(@NotNull SourcePos sourcePos, @NotNull AyaDocile hover) implements HighlightInfo { }
}
13 changes: 10 additions & 3 deletions cli-impl/src/main/java/org/aya/cli/literate/SyntaxHighlight.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import org.aya.syntax.concrete.stmt.ModuleName;
import org.aya.syntax.concrete.stmt.Stmt;
import org.aya.syntax.concrete.stmt.StmtVisitor;
import org.aya.syntax.concrete.stmt.decl.*;
import org.aya.syntax.concrete.stmt.decl.DataCon;
import org.aya.syntax.concrete.stmt.decl.DataDecl;
import org.aya.syntax.concrete.stmt.decl.FnDecl;
import org.aya.syntax.concrete.stmt.decl.PrimDecl;
import org.aya.syntax.core.def.ConDef;
import org.aya.syntax.core.def.DataDef;
import org.aya.syntax.core.def.FnDef;
Expand Down Expand Up @@ -80,14 +83,18 @@ else if (SPECIAL_SYMBOL.contains(tokenType))
return prettier.info.toImmutableSeq();
}

@Override
public void visitVarRef(@NotNull SourcePos pos, @NotNull AnyVar var, @NotNull LazyValue<@Nullable Term> type) {
@Override public void
visitVarRef(@NotNull SourcePos pos, @NotNull AnyVar var, @NotNull LazyValue<@Nullable Term> type) {
info.append(linkRef(pos, var, type.get()));
}
@Override public void visitExpr(@NotNull SourcePos pos, @NotNull Expr expr) {
switch (expr) {
case Expr.LitInt _ -> info.append(LitKind.Int.toLit(pos));
case Expr.LitString _ -> info.append(LitKind.String.toLit(pos));
case Expr.Hole hole when hole.filling() == null -> {
var hover = hole.solution().get();
if (hover != null) info.append(new HighlightInfo.UserMeta(pos, hover));
}
default -> StmtVisitor.super.visitExpr(pos, expr);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ open inductive infix << (Γ : Con) (Δ : Con) : Type
: (σ ∷ t) ∘ δ = (σ ∘ δ) ∷ transport (Tm _) SubAss (sub t)
| _, • => εη {δ : Γ << •} : δ = ε

// Incomplete
open inductive Tm (Γ : Con) (Ty Γ) : Type
| _, Π A B => λ (Tm (Γ ▷ A) B)
| Γ' ▷ A, B => app (Tm Γ' (Π A B))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ public record Symbol(
case Prim -> Option.some(Kind.PrimRef);
case Unknown -> Option.none();
};
case HighlightInfo.Lit _ -> Option.none(); // handled by client
case HighlightInfo.Lit _ -> Option.none(); // handled by client
case HighlightInfo.Err _ -> Option.none(); // handled by client
case HighlightInfo.UserMeta _ -> Option.none(); // handled by something else
};
}
}
Expand Down
7 changes: 4 additions & 3 deletions syntax/src/main/java/org/aya/syntax/concrete/Expr.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,15 @@ public Param(@NotNull SourcePos sourcePos, @NotNull LocalVar ref, @NotNull WithP
record Hole(
boolean explicit,
@Nullable WithPos<Expr> filling,
ImmutableSeq<LocalVar> accessibleLocal
@NotNull MutableValue<Term> solution,
@NotNull ImmutableSeq<LocalVar> accessibleLocal
) implements Expr {
public Hole(boolean explicit, @Nullable WithPos<Expr> filling) {
this(explicit, filling, ImmutableSeq.empty());
this(explicit, filling, MutableValue.create(), ImmutableSeq.empty());
}

public @NotNull Hole update(@Nullable WithPos<Expr> filling) {
return filling == filling() ? this : new Hole(explicit, filling, accessibleLocal);
return filling == filling() ? this : new Hole(explicit, filling, solution, accessibleLocal);
}

@Override public @NotNull Hole descent(@NotNull PosedUnaryOperator<@NotNull Expr> f) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ default void accept(@NotNull Stmt stmt) {
fn.body.forEach(this::visitExpr, cl -> cl.forEach(this::visitExpr,
this::visitPattern));
if (fn.body instanceof FnBody.BlockBody block) {
if (block.elims() != null) {
block.elims().forEachWith(block.rawElims(), (var, name) -> visitVar(name.sourcePos(), var, noType));
}
if (block.elims() != null) block.elims().forEachWith(block.rawElims(), (var, name) ->
visitVarRef(name.sourcePos(), var, noType));
}
}
case DataCon con -> con.patterns.forEach(cl -> visitPattern(cl.term()));
Expand Down
26 changes: 15 additions & 11 deletions syntax/src/main/java/org/aya/syntax/core/def/TyckDef.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import org.aya.generic.AyaDocile;
import org.aya.prettier.CorePrettier;
import org.aya.pretty.doc.Doc;
import org.aya.syntax.compile.JitDef;
import org.aya.syntax.concrete.stmt.decl.Decl;
import org.aya.syntax.core.Closure;
import org.aya.syntax.core.term.FreeTerm;
import org.aya.syntax.core.term.Param;
import org.aya.syntax.core.term.Term;
import org.aya.syntax.core.term.xtt.EqTerm;
import org.aya.syntax.ref.DefVar;
import org.aya.syntax.telescope.AbstractTele;
import org.aya.util.ForLSP;
import org.aya.util.prettier.PrettierOptions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -27,17 +30,18 @@ public sealed interface TyckDef extends AyaDocile permits SubLevelDef, TopLevelD
return new CorePrettier(options).def(this);
}

//region Pretty & IDE only APIs
static @Nullable Term defType(@NotNull AnyDef var) {
return switch (var) {
case TyckAnyDef<?> tyckDef -> {
var sig = tyckDef.ref.signature;
yield sig == null ? null : sig.result();
}
case JitDef jitDef -> jitDef.makePi();
};
@ForLSP static @Nullable Term defType(@NotNull AnyDef var) {
if (var instanceof TyckAnyDef<?> def && def.ref.signature == null) return null;
var sig = var.signature();
var names = sig.namesView().<Term>map(FreeTerm::new).toSeq();
var result = sig.result(names);
if (var instanceof ConDefLike con && con.hasEq()) result = new EqTerm(
Closure.mkConst(result),
con.equality(names, true),
con.equality(names, false)
);
return result;
}
//endregion

/**
* @see AnyDef#signature()
Expand Down
21 changes: 18 additions & 3 deletions syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.syntax.telescope;

import kala.collection.ArraySeq;
import kala.collection.Seq;
import kala.collection.immutable.ImmutableArray;
import kala.collection.SeqView;
import kala.collection.immutable.ImmutableSeq;
import kala.collection.immutable.primitive.ImmutableIntSeq;
import kala.range.primitive.IntRange;
import org.aya.syntax.core.Closure;
import org.aya.syntax.core.term.ErrorTerm;
import org.aya.syntax.core.term.Param;
Expand All @@ -17,7 +20,7 @@
* @param teleArgs the arguments before {@param i}, for constructor, it also contains the arguments to the data
*/
default @NotNull Term telescope(int i, Term[] teleArgs) {
return telescope(i, ImmutableArray.Unsafe.wrap(teleArgs));
return telescope(i, ArraySeq.wrap(teleArgs));
}

@NotNull Term telescope(int i, Seq<Term> teleArgs);
Expand All @@ -30,7 +33,12 @@
}

default @NotNull Term result(Term... teleArgs) {
return result(ImmutableArray.Unsafe.wrap(teleArgs));
return result(ArraySeq.wrap(teleArgs));
}

default @NotNull SeqView<String> namesView() {
return ImmutableIntSeq.from(IntRange.closedOpen(0, telescopeSize()))
.view().mapToObj(this::telescopeName);

Check warning on line 41 in syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java

View check run for this annotation

Codecov / codecov/patch

syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java#L40-L41

Added lines #L40 - L41 were not covered by tests
}

default @NotNull Term makePi() {
Expand Down Expand Up @@ -58,6 +66,7 @@
return signature.result(teleArgs).elevate(lift);
}
@Override public @NotNull AbstractTele lift(int i) { return new Lift(signature, lift + i); }
@Override public @NotNull SeqView<String> namesView() { return signature.namesView(); }

Check warning on line 69 in syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java

View check run for this annotation

Codecov / codecov/patch

syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java#L69

Added line #L69 was not covered by tests
}
record Locns(
@NotNull ImmutableSeq<Param> telescope,
Expand All @@ -73,6 +82,9 @@
assert teleArgs.size() == telescopeSize();
return result.instantiateTele(teleArgs.view());
}
@Override public @NotNull SeqView<String> namesView() {
return telescope.view().map(Param::name);
}
}
default @NotNull AbstractTele prefix(int i) {
return i == telescopeSize() ? this : new Slice(this, i);
Expand All @@ -92,5 +104,8 @@
@Override public @NotNull AbstractTele prefix(int i) {
return new Slice(signature, i);
}
@Override public @NotNull SeqView<String> namesView() {
return signature.namesView().sliceView(0, telescopeSize);

Check warning on line 108 in syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java

View check run for this annotation

Codecov / codecov/patch

syntax/src/main/java/org/aya/syntax/telescope/AbstractTele.java#L108

Added line #L108 was not covered by tests
}
}
}
5 changes: 5 additions & 0 deletions syntax/src/main/java/org/aya/syntax/telescope/JitTele.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.syntax.telescope;

import kala.collection.ArraySeq;
import kala.collection.SeqView;
import org.jetbrains.annotations.NotNull;

/**
Expand All @@ -21,4 +23,7 @@
@Override public int telescopeSize() { return telescopeSize; }
@Override public boolean telescopeLicit(int i) { return telescopeLicit[i]; }
@Override public @NotNull String telescopeName(int i) { return telescopeNames[i]; }
@Override public @NotNull SeqView<String> namesView() {
return ArraySeq.wrap(telescopeNames).view();

Check warning on line 27 in syntax/src/main/java/org/aya/syntax/telescope/JitTele.java

View check run for this annotation

Codecov / codecov/patch

syntax/src/main/java/org/aya/syntax/telescope/JitTele.java#L27

Added line #L27 was not covered by tests
}
}
Loading