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

Reorder simple classes and require let class on the others #278

Open
LPTK opened this issue Feb 12, 2025 · 0 comments
Open

Reorder simple classes and require let class on the others #278

LPTK opened this issue Feb 12, 2025 · 0 comments

Comments

@LPTK
Copy link
Contributor

LPTK commented Feb 12, 2025

Basically we should distinguish two kinds of classes

  • Simple/classical classes, similar to what one would define in Java. These can generally be moved around and lifted.
  • Complex/first-class classes, which can extend arbitrary expressions and whose extension clauses can refer to local variables

We should reorder the former and place them at the top according to the inheritance topology, avoiding forward reference/initialization problems.
Relevant code from the old compiler:

/**
* Resolve inheritance of all declared classes.
*
* @return sorted class symbols with their base classes
*/
protected def sortClassSymbols(classSymbols: Ls[ClassSymbol]): Iterable[(ClassSymbol, Opt[ClassSymbol])] = {
// Cache base classes for class symbols.
val baseClasses = Map.from(classSymbols.iterator.flatMap { derivedClass =>
topLevelScope.resolveBaseClass(derivedClass.body).map(derivedClass -> _)
})
val sorted = try topologicalSort(baseClasses, classSymbols) catch {
case e: CyclicGraphError => throw CodeGenError("cyclic inheritance detected")
}
// Their base classes might be class symbols defined in previous translation
// units. So we filter them out here.
sorted.flatMap(sym => if (classSymbols.contains(sym)) S(sym -> baseClasses.get(sym)) else N)
}

Example of the latter, which we would require to use the let class construct, would be:

let c = ... // some computation
let class Foo extends c

let x = ... // eg Console.readInt
let class Bar extends Base(x)

The distinction between these two kinds of classes is notably important in the context of the class lifer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant