Skip to content
Draft
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
4 changes: 2 additions & 2 deletions hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
if usesResTmp then k(Value.Ref(l))
else k(unit) // * it seems this currently never happens
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎


case sel @ Sel(prefix, nme) =>
setupSelection(prefix, nme, sel.sym)(k)

Expand Down Expand Up @@ -791,7 +791,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
msg"Cannot compile ${t.describe} term that was not elaborated (maybe elaboration was one in 'lightweight' mode?)" ->
t.toLoc :: Nil,
source = Diagnostic.Source.Compilation)
case _: CompType | _: Neg | _: Term.FunTy | _: Term.Forall | _: Term.WildcardTy | _: Term.Unquoted
case _: CompType | _: Neg | _: Term.FunTy | _: Term.Forall | _: Term.WildcardTy | _: Term.Unquoted | LeadingDotTarget
=> fail:
ErrorReport(
msg"Unexpected term form in expression position (${t.describe})" ->
Expand Down
4 changes: 3 additions & 1 deletion hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Keyword.{`let`, `set`}
object Elaborator:

val binaryOps = Set(
",",
",", // * Not currently used directly; but `;` (below) maps to it
"+", "-", "*", "/", "%",
"==", "!=", "<", "<=", ">", ">=",
"===", "!==",
Expand Down Expand Up @@ -564,6 +564,8 @@ extends Importer:
val preTrm = subterm(pre)
val sym = resolveField(nme, preTrm.symbol, nme)
Term.SynthSel(preTrm, nme)(sym, N)
case Sel(Empty(), nme) =>
Term.Sel(Term.LeadingDotTarget, nme)(N, N, S(ctx))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to add a new term, it should be Term.LeadingDotSel(nme), tro reduce the amount of illegal states that are representable.

case Sel(pre, nme) =>
val preTrm = subterm(pre)
val sym = resolveField(nme, preTrm.symbol, nme)
Expand Down
22 changes: 22 additions & 0 deletions hkmc2/shared/src/main/scala/hkmc2/semantics/Symbol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import hkmc2.utils.*
import Elaborator.State
import Tree.Ident
import hkmc2.utils.SymbolSubst
import hkmc2.typing.Type


abstract class Symbol(using State) extends Located:
Expand Down Expand Up @@ -203,6 +204,27 @@ class BuiltinSymbol

def subst(using sub: SymbolSubst): BuiltinSymbol = sub.mapBuiltInSym(this)

def signature : semantics.flow.Producer =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make this a lazy val?

import Type.*
val binaryType : Type = Fun(args = Ls(Top, Top), ret = Top, eff = N)
val unaryType : Type = Fun(args = Ls(Top), ret = Top, eff = N)
val nullaryType : Type = Top
val typ =
Union(
Union(
if (binary) then binaryType else Bot,
if (unary) then unaryType else Bot,
),
if (nullary) then nullaryType else Bot,
)
// (binary, unary, nullary) match
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually prefer this version.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are you referring to? The pattern match or the if block? if it's the latter, do you mean that we should assign the signature only based on the nullary flag?

// case (true, true, true) => Union()
// case (true, _, _) => Fun(args = Ls(Top, Top), ret = Top, eff = N)
// case (_, true, _) => Fun(args = Ls(Top), ret = Top, eff = N)
// case (_, _, true) => Top
// case _ => Bot
semantics.flow.Producer.Typ(typ)


/** This is the outside-facing symbol associated to a possibly-overloaded
* definition living in a block – e.g., a module or class.
Expand Down
14 changes: 11 additions & 3 deletions hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ enum Term extends Statement:
case Annotated(annot: Annot, target: Term)
case Handle(lhs: LocalSymbol, rhs: Term, args: List[Term],
derivedClsSym: ClassSymbol, defs: Ls[HandlerTermDefinition], body: Term)
case LeadingDotTarget

def expanded: Term = this match
case t: Resolvable => t.expansion match
Expand Down Expand Up @@ -422,6 +423,8 @@ sealed trait Statement extends AutoLocated, ProductWithExtraInfo:
case Annotated(annotation, target) => "annotation"
case Ret(res) => "return"
case Try(body, finallyDo) => "try expression"
case Missing => "missing"
case LeadingDotTarget => "leading dot placeholder"
case s => TODO(s)
this match
case self: Resolvable => self.resolvedTyp match
Expand Down Expand Up @@ -491,6 +494,7 @@ sealed trait Statement extends AutoLocated, ProductWithExtraInfo:
case Handle(lhs, rhs, args, derivedClsSym, defs, bod) => rhs :: args ::: defs.flatMap(_.td.subTerms) ::: bod :: Nil
case Neg(e) => e :: Nil
case Annotated(ann, target) => ann.subTerms ::: target :: Nil
case LeadingDotTarget => Nil

// private def treeOrSubterms(t: Tree, t: Term): Ls[Located] = t match
private def treeOrSubterms(t: Tree): Ls[Located] = t match
Expand Down Expand Up @@ -539,9 +543,11 @@ sealed trait Statement extends AutoLocated, ProductWithExtraInfo:
case tup: Tup => bracketed("[", "]", insertBreak = true):
tup.fields.map(_.show).mkDocument(doc", # ")
case blk: Blk => braced:
doc" # " :: blk.stats.map(_.show).mkDocument(doc", # ") :: blk.res.match
case Lit(Tree.UnitLit(false)) => doc""
case res => res.show
doc" # " :: (blk.stats :::
blk.res.match
case Lit(Tree.UnitLit(false)) => Nil
case res => res :: Nil
).map(_.show).mkDocument(doc", # ")
case ld: LetDecl =>
(ld.annotations.map(_.show) ::: doc"let ${ld.sym.showName}" :: Nil).mkDocument()
case df: DefineVar =>
Expand All @@ -565,6 +571,7 @@ sealed trait Statement extends AutoLocated, ProductWithExtraInfo:
:: doc" ${cld.body.blk.show}"
case imp: Import =>
doc"import ${"\""}.../${imp.file.lastOpt.getOrElse("")}${"\""} as ${imp.sym.showName}"
case LeadingDotTarget => doc"${this.showDbg}"
case _ =>
doc"TODO[show:${getClass.getSimpleName}]($showDbg)"
this match
Expand Down Expand Up @@ -668,6 +675,7 @@ sealed trait Statement extends AutoLocated, ProductWithExtraInfo:
case TypeDef(sym, _, tparams, rhs, _, _) =>
s"type ${sym}${tparams.mkStringOr(", ", "[", "]")} = ${rhs.fold("")(x => x.showDbg)}"
case Missing => "missing"
case LeadingDotTarget => "_?_"

final case class LetDecl(sym: LocalSymbol, annotations: Ls[Annot]) extends Statement

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ case class Constraint(lhs: Producer, rhs: Consumer):
enum Producer:
case Flow(sym: FlowSymbol)
case Fun(lhs: Consumer, rhs: Producer, captures: Ls[(Producer, Consumer)])
case Tup(elems: Ls[Opt[SpreadKind] -> Producer])
case Tup(elems: Ls[(Opt[SpreadKind], Producer)])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the -> version easier to read?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, -> looks to me like a function type, so (,) is much more readable. But the call is entirely yours of course, I will follow the project style

case Ctor(sym: CtorSymbol, args: List[Producer])(val trm: Term) extends Producer, CtorImpl
case LeadingDotSel(nme: Ident)(val trm: Term.Sel) // Note: trm.prefix is Missing
case Typ(typ: Type)
case Unknown(t: Statement)
case Unknown(s: Statement) // `s` is just for error reporting/debugging purposes


def toLoc: Opt[Loc] = this match
Expand All @@ -41,6 +42,7 @@ enum Producer:
case tup: Tup => Document.bracketed("[", "]")(showTupElems(tup))
case Ctor(LitSymbol(UnitLit(false)), Nil) => "()"
case Ctor(sym, args) => doc"${sym.nme}${args.map(_.showAsParams).mkDocument()}"
case LeadingDotSel(nme) => doc"_?_.${nme.showDbg}"
case Typ(typ) => doc"type ${typ.show}"
case Unknown(t) => doc"¿${t.showDbg}?"

Expand All @@ -62,6 +64,7 @@ enum Producer:
case Ctor(sym, Nil) => sym.nme
case Tup(args) => s"[${args.map((spd, a) => spd.fold("")(_.str) + a.showDbg).mkString(", ")}]"
case Ctor(sym, args) => s"${sym.nme}${args.map(_.showDbgAsParams).mkString}"
case sel @ LeadingDotSel(nme) => s"_?_.${nme}"
case Typ(typ) => s"type ${typ.showDbg}"
case Unknown(t) => s"¿${t.showDbg}?"

Expand Down
Loading
Loading