@Override public SStmCG caseAClassInvariantStm(AClassInvariantStm node, IRInfo question) throws AnalysisException { List<PExp> exps = new LinkedList<PExp>(); for (PDefinition d : node.getInvDefs()) { if (!(d instanceof AClassInvariantDefinition)) { Logger.getLog() .printErrorln( "Expected class invariant definition in '" + this.getClass().getName() + "'. Got: " + d); return null; } AClassInvariantDefinition invDef = (AClassInvariantDefinition) d; exps.add(invDef.getExpression()); } AReturnStmCG returnStmCg = new AReturnStmCG(); if (exps.isEmpty()) { // Should not really be necessary returnStmCg.setExp(question.getExpAssistant().consBoolLiteral(true)); } else if (exps.size() == 1) { SExpCG expCg = exps.get(0).apply(question.getExpVisitor(), question); returnStmCg.setExp(expCg); } else { // We have more than one expressions from which we will build an 'and chain' AAndBoolBinaryExpCG andExpTopCg = new AAndBoolBinaryExpCG(); andExpTopCg.setType(new ABoolBasicTypeCG()); andExpTopCg.setLeft(exps.get(0).apply(question.getExpVisitor(), question)); AAndBoolBinaryExpCG previousAndExpCg = andExpTopCg; // The remaining ones except the last for (int i = 1; i < exps.size() - 1; i++) { SExpCG nextExpCg = exps.get(i).apply(question.getExpVisitor(), question); AAndBoolBinaryExpCG nextAndExpCg = new AAndBoolBinaryExpCG(); nextAndExpCg.setType(new ABoolBasicTypeCG()); nextAndExpCg.setLeft(nextExpCg); previousAndExpCg.setRight(nextAndExpCg); previousAndExpCg = nextAndExpCg; } previousAndExpCg.setRight( exps.get(exps.size() - 1).apply(question.getExpVisitor(), question)); returnStmCg.setExp(andExpTopCg); } return returnStmCg; }
@Override public SStmCG caseACallObjectStm(ACallObjectStm node, IRInfo question) throws AnalysisException { PType type = node.getType(); PObjectDesignator objectDesignator = node.getDesignator(); ILexNameToken field = node.getField(); LinkedList<PExp> args = node.getArgs(); STypeCG typeCg = type.apply(question.getTypeVisitor(), question); SObjectDesignatorCG objectDesignatorCg = objectDesignator.apply(question.getObjectDesignatorVisitor(), question); if (node.getExplicit()) { SClassDefinition enclosingClass = node.getAncestor(SClassDefinition.class); if (enclosingClass != null) { if (!field.getModule().equals(enclosingClass.getName().getName())) { // A quoted method call is only supported if the explicit // module name is equal to that of the enclosing class. Say A // is a sub class of S and 'a' is an instance of A then a.A`op(); // is allowed (although it is the same as a.op()). However, // a.S`op(); is not allowed. question.addUnsupportedNode( node, "A quoted object call statement is only supported if the explicit module name is equal to that of the enclosing class"); } } else { Logger.getLog() .printErrorln( "Could not find enclosing the statement of call a call object statement."); } } String fieldNameCg = field.getName(); ACallObjectStmCG callObject = new ACallObjectStmCG(); callObject.setType(typeCg); callObject.setDesignator(objectDesignatorCg); callObject.setFieldName(fieldNameCg); for (PExp arg : args) { SExpCG argCg = arg.apply(question.getExpVisitor(), question); if (argCg != null) { callObject.getArgs().add(argCg); } else { return null; } } return callObject; }
public STypeCG toIrType(IRInfo info) { try { STypeCG irType = type.apply(info.getTypeVisitor(), info); if (irType != null) { irType.setOptional(optional); } return irType; } catch (AnalysisException e) { Logger.getLog() .printErrorln( "Problems encountered while attempting " + "to construct the IR type from a VDM type: " + e.getMessage() + " in '" + this.getClass().getSimpleName() + "'"); e.printStackTrace(); } return null; }