-
Notifications
You must be signed in to change notification settings - Fork 125
/
AstNodeData.scala
51 lines (41 loc) · 1.73 KB
/
AstNodeData.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package tip.ast
import tip.ast.AstPrinters._
import tip.types.Type
object AstNodeData {
/**
* Map from identifier node to corresponding declaration node.
* @see [[tip.analysis.DeclarationAnalysis]]
*/
type DeclarationData = Map[AIdentifier, ADeclaration]
/**
* Map from AST node to type, if available.
* @see [[tip.analysis.TypeAnalysis]]
*/
type TypeData = Map[AstNode, Option[Type]]
/**
* Implicitly make declaration data available on identifier AST nodes.
*
* To novice Scala programmers:
* This "implicit class" has the effect that every instance of `AIdentifier` effectively
* gets an extra field `declaration` (provided that this class has been imported).
* Note that the value of the field is obtained via the implicit parameter `data`.
* For more information about implicit classes in Scala, see [[https://docs.scala-lang.org/overviews/core/implicit-classes.html]].
*/
implicit class AstNodeWithDeclaration(n: AIdentifier)(implicit val data: DeclarationData) {
def declaration: ADeclaration = data(n)
}
/**
* Implicitly make type data available on AST nodes.
*
* (For information about Scala's implicit classes, see [[tip.ast.AstNodeData.AstNodeWithDeclaration]].)
*/
implicit class AstNodeWithType(n: AstNode)(implicit val data: TypeData) {
def theType: Option[Type] = data.getOrElse(n, None)
private def printer: PartialFunction[AstNode, String] = {
case id: AIdentifierDeclaration => s"${id.name}: ${id.theType.getOrElse("??")}"
case f: AFunDeclaration =>
s"${f.name}(${f.params.map(_.name).mkString(",")}): ${f.theType.getOrElse("??")}\n${f.stmts.print(printer)}"
}
def toTypedString: String = n.print(printer)
}
}