Skip to content
Snippets Groups Projects
Commit fcc1c05a authored by Jan Gruteser's avatar Jan Gruteser
Browse files

minor simplifications in Typechecker

parent 346b1111
Branches
No related tags found
No related merge requests found
Pipeline #148577 passed
...@@ -13,7 +13,7 @@ import tlc2.tool.BuiltInOPs; ...@@ -13,7 +13,7 @@ import tlc2.tool.BuiltInOPs;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, TranslationGlobals { public class TypeChecker extends BuiltInOPs implements BBuildIns, TranslationGlobals {
private static final int TEMP_TYPE_ID = 6; private static final int TEMP_TYPE_ID = 6;
private int paramId; private int paramId;
...@@ -34,6 +34,9 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -34,6 +34,9 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
private ConfigfileEvaluator conEval; private ConfigfileEvaluator conEval;
/**
* for module translation
*/
public TypeChecker(ModuleNode moduleNode, ConfigfileEvaluator conEval, SpecAnalyser specAnalyser) { public TypeChecker(ModuleNode moduleNode, ConfigfileEvaluator conEval, SpecAnalyser specAnalyser) {
this.moduleNode = moduleNode; this.moduleNode = moduleNode;
this.specAnalyser = specAnalyser; this.specAnalyser = specAnalyser;
...@@ -44,52 +47,39 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -44,52 +47,39 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
} }
this.inits = specAnalyser.getInits(); this.inits = specAnalyser.getInits();
this.nextExpr = specAnalyser.getNext(); this.nextExpr = specAnalyser.getNext();
usedDefinitions = specAnalyser.getUsedDefinitions(); this.usedDefinitions = specAnalyser.getUsedDefinitions();
this.bDefinitions = specAnalyser.getBDefinitions(); this.bDefinitions = specAnalyser.getBDefinitions();
this.paramId = TYPE_ID;
paramId = TYPE_ID;
} }
/**
* for expression translation
*/
public TypeChecker(ModuleNode moduleNode, SpecAnalyser specAnalyser) { public TypeChecker(ModuleNode moduleNode, SpecAnalyser specAnalyser) {
this.moduleNode = moduleNode; this.moduleNode = moduleNode;
this.specAnalyser = specAnalyser; this.specAnalyser = specAnalyser;
Set<OpDefNode> usedDefinitions = new HashSet<>();
OpDefNode[] defs = moduleNode.getOpDefs(); OpDefNode[] defs = moduleNode.getOpDefs();
// used the last definition of the module // use the last definition of the module
usedDefinitions.add(defs[defs.length - 1]); this.usedDefinitions = Collections.singleton(defs[defs.length - 1]);
this.usedDefinitions = usedDefinitions;
this.bDefinitions = specAnalyser.getBDefinitions(); this.bDefinitions = specAnalyser.getBDefinitions();
paramId = TYPE_ID; this.paramId = TYPE_ID;
} }
public void start() throws TLA2BException { public void start() throws TLA2BException {
OpDeclNode[] cons = moduleNode.getConstantDecls(); for (OpDeclNode con : moduleNode.getConstantDecls()) {
for (OpDeclNode con : cons) {
if (constantAssignments != null && constantAssignments.containsKey(con)) { if (constantAssignments != null && constantAssignments.containsKey(con)) {
setType(con, constantAssignments.get(con).getType());
TLAType t = constantAssignments.get(con).getType();
con.setToolObject(TYPE_ID, t);
if (t instanceof AbstractHasFollowers) {
((AbstractHasFollowers) t).addFollower(con);
}
} else { } else {
// if constant already has a type: keep type; otherwise add an untyped type // if constant already has a type: keep type; otherwise add an untyped type
if (con.getToolObject(TYPE_ID) == null) { if (con.getToolObject(TYPE_ID) == null)
UntypedType u = new UntypedType(); setType(con, new UntypedType());
con.setToolObject(TYPE_ID, u);
u.addFollower(con);
}
} }
} }
OpDeclNode[] vars = moduleNode.getVariableDecls(); for (OpDeclNode var : moduleNode.getVariableDecls()) {
for (OpDeclNode var : vars) {
// if variable already has a type: keep type; otherwise add an untyped type // if variable already has a type: keep type; otherwise add an untyped type
if (var.getToolObject(TYPE_ID) == null) { if (var.getToolObject(TYPE_ID) == null)
UntypedType u = new UntypedType(); setType(var, new UntypedType());
var.setToolObject(TYPE_ID, u);
u.addFollower(var);
}
} }
evalDefinitions(moduleNode.getOpDefs()); evalDefinitions(moduleNode.getOpDefs());
...@@ -97,16 +87,13 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -97,16 +87,13 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
if (conEval != null) { if (conEval != null) {
for (Entry<OpDeclNode, OpDefNode> entry : conEval.getConstantOverrides().entrySet()) { for (Entry<OpDeclNode, OpDefNode> entry : conEval.getConstantOverrides().entrySet()) {
OpDeclNode con = entry.getKey(); OpDeclNode con = entry.getKey();
if (!bConstList.contains(con)) { if (!bConstList.contains(con))
continue; continue;
}
OpDefNode def = entry.getValue();
TLAType defType = (TLAType) def.getToolObject(TYPE_ID);
TLAType conType = (TLAType) con.getToolObject(TYPE_ID);
TLAType defType = (TLAType) entry.getValue().getToolObject(TYPE_ID);
TLAType conType = (TLAType) con.getToolObject(TYPE_ID);
try { try {
TLAType result = defType.unify(conType); setType(con, defType.unify(conType));
con.setToolObject(TYPE_ID, result);
} catch (UnificationException e) { } catch (UnificationException e) {
throw new TypeErrorException( throw new TypeErrorException(
String.format("Expected %s, found %s at constant '%s'.", defType, conType, con.getName())); String.format("Expected %s, found %s at constant '%s'.", defType, conType, con.getName()));
...@@ -127,14 +114,12 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -127,14 +114,12 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
} }
checkIfAllIdentifiersHaveAType(); checkIfAllIdentifiersHaveAType();
} }
private void checkIfAllIdentifiersHaveAType() throws TypeErrorException { private void checkIfAllIdentifiersHaveAType() throws TypeErrorException {
// check if a variable has no type // check if a variable has no type
OpDeclNode[] vars = moduleNode.getVariableDecls(); for (OpDeclNode var : moduleNode.getVariableDecls()) {
for (OpDeclNode var : vars) { TLAType varType = getType(var);
TLAType varType = (TLAType) var.getToolObject(TYPE_ID);
if (varType.isUntyped()) { if (varType.isUntyped()) {
throw new TypeErrorException( throw new TypeErrorException(
"The type of the variable '" + var.getName() + "' can not be inferred: " + varType); "The type of the variable '" + var.getName() + "' can not be inferred: " + varType);
...@@ -143,10 +128,9 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -143,10 +128,9 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
// check if a constant has no type, only constants which will appear in // check if a constant has no type, only constants which will appear in
// the resulting B Machine are considered // the resulting B Machine are considered
OpDeclNode[] cons = moduleNode.getConstantDecls(); for (OpDeclNode con : moduleNode.getConstantDecls()) {
for (OpDeclNode con : cons) {
if (bConstList == null || bConstList.contains(con)) { if (bConstList == null || bConstList.contains(con)) {
TLAType conType = (TLAType) con.getToolObject(TYPE_ID); TLAType conType = getType(con);
if (conType.isUntyped()) { if (conType.isUntyped()) {
throw new TypeErrorException( throw new TypeErrorException(
"The type of constant " + con.getName() + " is still untyped: " + conType); "The type of constant " + con.getName() + " is still untyped: " + conType);
...@@ -155,20 +139,19 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -155,20 +139,19 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
} }
for (SymbolNode symbol : symbolNodeList) { for (SymbolNode symbol : symbolNodeList) {
TLAType type = (TLAType) symbol.getToolObject(TYPE_ID); TLAType type = getType(symbol);
if (type.isUntyped()) { if (type.isUntyped()) {
throw new TypeErrorException("Symbol '" + symbol.getName() + "' has no type.\n" + symbol.getLocation()); throw new TypeErrorException("Symbol '" + symbol.getName() + "' has no type.\n" + symbol.getLocation());
} }
} }
for (SemanticNode tuple : tupleNodeList) { for (SemanticNode tuple : tupleNodeList) {
TLAType type = (TLAType) tuple.getToolObject(TYPE_ID); TLAType type = getType(tuple);
if (type instanceof TupleOrFunction) { if (type instanceof TupleOrFunction) {
TupleOrFunction tOrF = (TupleOrFunction) type; ((TupleOrFunction) type).getFinalType();
tOrF.getFinalType();
} }
// TODO: does this do anything?
} }
} }
private void evalDefinitions(OpDefNode[] opDefs) throws TLA2BException { private void evalDefinitions(OpDefNode[] opDefs) throws TLA2BException {
...@@ -183,29 +166,21 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -183,29 +166,21 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
if (usedDefinitions.contains(def) || bDefinitions.contains(def)) if (usedDefinitions.contains(def) || bDefinitions.contains(def))
visitOpDefNode(def); visitOpDefNode(def);
} }
} }
public void visitOpDefNode(OpDefNode def) throws TLA2BException { public void visitOpDefNode(OpDefNode def) throws TLA2BException {
FormalParamNode[] params = def.getParams(); for (FormalParamNode p : def.getParams()) {
for (FormalParamNode p : params) {
if (p.getArity() > 0) { if (p.getArity() > 0) {
throw new TLA2BFrontEndException(String.format("TLA2B do not support 2nd-order operators: '%s'%n %s ", throw new TLA2BFrontEndException(String.format("TLA2B do not support 2nd-order operators: '%s'%n %s ",
def.getName(), def.getLocation())); def.getName(), def.getLocation()));
} }
UntypedType u = new UntypedType(); setType(p, new UntypedType(), paramId);
p.setToolObject(paramId, u);
u.addFollower(p);
} }
UntypedType u = new UntypedType(); UntypedType u = new UntypedType();
// TODO: check this
// def.setToolObject(TYPE_ID, u); // def.setToolObject(TYPE_ID, u);
// u.addFollower(def); // u.addFollower(def);
TLAType defType = visitExprNode(def.getBody(), u); setType(def, visitExprNode(def.getBody(), u));
def.setToolObject(TYPE_ID, defType);
if (defType instanceof AbstractHasFollowers) {
((AbstractHasFollowers) defType).addFollower(def);
}
} }
private void evalAssumptions(AssumeNode[] assumptions) throws TLA2BException { private void evalAssumptions(AssumeNode[] assumptions) throws TLA2BException {
...@@ -218,13 +193,11 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -218,13 +193,11 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
if (n instanceof ExprNode) { if (n instanceof ExprNode) {
return visitExprNode((ExprNode) n, expected); return visitExprNode((ExprNode) n, expected);
} else { } else {
throw new NotImplementedException("OpArgNode not implemented jet"); throw new NotImplementedException("OpArgNode not implemented yet");
} }
} }
private TLAType visitExprNode(ExprNode exprNode, TLAType expected) throws TLA2BException { private TLAType visitExprNode(ExprNode exprNode, TLAType expected) throws TLA2BException {
switch (exprNode.getKind()) { switch (exprNode.getKind()) {
case TLCValueKind: { case TLCValueKind: {
TLCValueNode valueNode = (TLCValueNode) exprNode; TLCValueNode valueNode = (TLCValueNode) exprNode;
...@@ -235,7 +208,6 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -235,7 +208,6 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
String.format("Expected %s, found %s at '%s'(assigned in the configuration file),%n%s ", String.format("Expected %s, found %s at '%s'(assigned in the configuration file),%n%s ",
expected, valueNode.getType(), valueNode.getValue(), exprNode.getLocation())); expected, valueNode.getType(), valueNode.getValue(), exprNode.getLocation()));
} }
} }
case OpApplKind: case OpApplKind:
...@@ -277,7 +249,6 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -277,7 +249,6 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
throw new TypeErrorException( throw new TypeErrorException(
String.format("Expected %s, found %s at '@',%n%s ", expected, type, exprNode.getLocation())); String.format("Expected %s, found %s at '@',%n%s ", expected, type, exprNode.getLocation()));
} }
} }
case LetInKind: { case LetInKind: {
...@@ -291,21 +262,22 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns, ...@@ -291,21 +262,22 @@ public class TypeChecker extends BuiltInOPs implements ASTConstants, BBuildIns,
case SubstInKind: { case SubstInKind: {
throw new RuntimeException("SubstInKind should never occur after InstanceTransformation"); throw new RuntimeException("SubstInKind should never occur after InstanceTransformation");
} }
} }
throw new NotImplementedException(exprNode.toString(2)); throw new NotImplementedException(exprNode.toString(2));
} }
private void setType(SemanticNode node, TLAType type) { private void setType(SemanticNode node, TLAType type, int paramId) {
node.setToolObject(TYPE_ID, type); node.setToolObject(paramId, type);
if (type instanceof AbstractHasFollowers) { if (type instanceof AbstractHasFollowers) {
((AbstractHasFollowers) type).addFollower(node); ((AbstractHasFollowers) type).addFollower(node);
} }
} }
private TLAType getType(OpApplNode n) { private void setType(SemanticNode node, TLAType type) {
setType(node, type, TYPE_ID);
}
private TLAType getType(SemanticNode n) {
return (TLAType) n.getToolObject(TYPE_ID); return (TLAType) n.getToolObject(TYPE_ID);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment