/*
* #%~
* VDM Code Generator
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.codegen.assistant;
import java.util.List;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.definitions.SOperationDefinition;
import org.overture.ast.expressions.PExp;
import org.overture.ast.statements.ABlockSimpleBlockStm;
import org.overture.ast.statements.ACaseAlternativeStm;
import org.overture.ast.statements.AElseIfStm;
import org.overture.ast.statements.AForAllStm;
import org.overture.ast.statements.AForIndexStm;
import org.overture.ast.statements.AIfStm;
import org.overture.ast.statements.ALetStm;
import org.overture.ast.statements.PStm;
import org.overture.ast.types.AUnionType;
import org.overture.ast.types.PType;
import org.overture.codegen.ir.IRInfo;
import org.overture.codegen.ir.SStmIR;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.declarations.ADefaultClassDeclIR;
import org.overture.codegen.ir.declarations.AMethodDeclIR;
import org.overture.codegen.ir.declarations.AVarDeclIR;
import org.overture.codegen.ir.statements.AAtomicStmIR;
import org.overture.codegen.ir.statements.ABlockStmIR;
import org.overture.codegen.ir.statements.ACaseAltStmStmIR;
import org.overture.codegen.ir.statements.AElseIfStmIR;
import org.overture.codegen.ir.statements.AForAllStmIR;
import org.overture.codegen.ir.statements.AForIndexStmIR;
import org.overture.codegen.ir.statements.AForLoopStmIR;
import org.overture.codegen.ir.statements.AIfStmIR;
import org.overture.codegen.ir.statements.AMetaStmIR;
import org.overture.codegen.ir.statements.ASuperCallStmIR;
public class StmAssistantIR extends AssistantBase
{
public StmAssistantIR(AssistantManager assistantManager)
{
super(assistantManager);
}
public void injectDeclAsStm(ABlockStmIR block, AVarDeclIR decl)
{
ABlockStmIR wrappingBlock = new ABlockStmIR();
wrappingBlock.getLocalDefs().add(decl);
block.getStatements().add(wrappingBlock);
}
public void handleAlternativesCasesStm(IRInfo question, PExp exp,
List<ACaseAlternativeStm> cases, List<ACaseAltStmStmIR> casesCg)
throws AnalysisException
{
for (ACaseAlternativeStm alt : cases)
{
SStmIR altCg = alt.apply(question.getStmVisitor(), question);
casesCg.add((ACaseAltStmStmIR) altCg);
}
PType expType = question.getTypeAssistant().resolve(exp.getType());
if (expType instanceof AUnionType)
{
AUnionType unionType = ((AUnionType) expType).clone();
question.getTcFactory().createAUnionTypeAssistant().expand(unionType);
for (int i = 0; i < cases.size(); i++)
{
ACaseAlternativeStm vdmCase = cases.get(i);
ACaseAltStmStmIR cgCase = casesCg.get(i);
PType patternType = question.getAssistantManager().getTypeAssistant().getType(question, unionType, vdmCase.getPattern());
STypeIR patternTypeCg = patternType.apply(question.getTypeVisitor(), question);
cgCase.setPatternType(patternTypeCg);
}
} else
{
STypeIR expTypeCg = expType.apply(question.getTypeVisitor(), question);
for (ACaseAltStmStmIR altCg : casesCg)
{
altCg.setPatternType(expTypeCg.clone());
}
}
}
public boolean inAtomic(SStmIR stm)
{
return stm.getAncestor(AAtomicStmIR.class) != null;
}
public String getSuperClassName(ASuperCallStmIR stm)
{
ADefaultClassDeclIR enclosingClass = stm.getAncestor(ADefaultClassDeclIR.class);
return enclosingClass.getName();
}
public boolean isScoped(ABlockSimpleBlockStm block)
{
return appearsInRightContext(block);
}
public boolean isScoped(ALetStm let)
{
return appearsInRightContext(let);
}
private boolean appearsInRightContext(PStm block)
{
return !(block.parent() instanceof SOperationDefinition)
&& !(block.parent() instanceof AElseIfStm)
&& !(block.parent() instanceof AIfStm)
&& !(block.parent() instanceof AForAllStm)
&& !(block.parent() instanceof AForIndexStm);
}
public boolean isScoped(ABlockStmIR block)
{
return !(block.parent() instanceof AMethodDeclIR)
&& !(block.parent() instanceof AElseIfStmIR)
&& !(block.parent() instanceof AIfStmIR)
&& !(block.parent() instanceof AForAllStmIR)
&& !(block.parent() instanceof AForIndexStmIR)
&& !(block.parent() instanceof AForLoopStmIR);
}
public boolean equal(AMetaStmIR left, AMetaStmIR right)
{
if (left.getMetaData().size() != right.getMetaData().size())
{
return false;
}
for (int i = 0; i < left.getMetaData().size(); i++)
{
String currentLeft = left.getMetaData().get(i).value;
String currentRight = right.getMetaData().get(i).value;
if (!currentLeft.equals(currentRight))
{
return false;
}
}
return true;
}
}