Type Checking¶
Overview¶
TypeCheckEASTVisitor traverses the Enriched AST and verifies that every expression has a well-formed type. It returns a TypeNode for each node, propagating types bottom-up through the tree.
Subtype Relations¶
Type compatibility is determined by TypeRels.isSubtype(a, b):
BoolTypeNodeis a subtype ofIntTypeNode(booleans can be used as integers).- A class type
Cis a subtype ofDifCextendsD(directly or transitively). EmptyTypeNode(null) is a subtype of anyRefTypeNode.
Key Rules¶
| Construct | Type Rule |
|---|---|
IntNode |
IntTypeNode |
BoolNode |
BoolTypeNode |
PlusNode, MinusNode, TimesNode, DivNode |
Both operands must be int; result is IntTypeNode |
AndNode, OrNode |
Both operands must be bool; result is BoolTypeNode |
NotNode |
Operand must be bool; result is BoolTypeNode |
EqualNode |
Operands must share a common subtype |
GreaterEqualNode, LessEqualNode |
Both operands must be int; result is BoolTypeNode |
IfNode |
Condition must be bool; result is the lowest common ancestor of the two branch types |
CallNode |
Argument types must be subtypes of the declared parameter types; result is the function's return type |
NewNode |
Argument types must match class field types; result is RefTypeNode(classID) |
ClassCallNode |
Like CallNode but resolves through the virtual table |
VarNode |
Declared type must be a supertype of the initialiser type |
FunNode / MethodNode |
Body type must be a subtype of the declared return type |
Lowest Common Ancestor¶
For if / then / else, the result type is the lowest common ancestor (LCA) of the two branch types in the subtype hierarchy. For example, if one branch has type C and another has type D where both extend Base, the result type is Base.
Error Reporting¶
Type errors are printed to standard error and counted. Compilation continues after a type error so that further errors can be reported in the same run.