/*
* #%~
* 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.trans.let;
import java.util.LinkedList;
import java.util.List;
import org.overture.codegen.ir.ITempVarGen;
import org.overture.codegen.ir.SExpIR;
import org.overture.codegen.ir.SPatternIR;
import org.overture.codegen.ir.SStmIR;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.analysis.AnalysisException;
import org.overture.codegen.ir.declarations.AVarDeclIR;
import org.overture.codegen.ir.expressions.AIdentifierVarExpIR;
import org.overture.codegen.ir.expressions.ALetBeStNoBindingRuntimeErrorExpIR;
import org.overture.codegen.ir.statements.AAssignToExpStmIR;
import org.overture.codegen.ir.statements.AIfStmIR;
import org.overture.codegen.ir.statements.ALocalPatternAssignmentStmIR;
import org.overture.codegen.ir.statements.ARaiseErrorStmIR;
import org.overture.codegen.ir.types.AErrorTypeIR;
import org.overture.codegen.trans.AbstractIterationStrategy;
import org.overture.codegen.trans.DeclarationTag;
import org.overture.codegen.trans.IterationVarPrefixes;
import org.overture.codegen.trans.assistants.TransAssistantIR;
import org.overture.codegen.trans.iterator.ILanguageIterator;
public class LetBeStStrategy extends AbstractIterationStrategy
{
protected String successVarName;
protected SExpIR suchThat;
protected STypeIR setSeqType;
protected int count = 0;
protected List<AVarDeclIR> decls = new LinkedList<AVarDeclIR>();
public LetBeStStrategy(TransAssistantIR transformationAssistant,
SExpIR suchThat, STypeIR setSeqType, ILanguageIterator langIterator,
ITempVarGen tempGen, IterationVarPrefixes iteVarPrefixes)
{
super(transformationAssistant, langIterator, tempGen, iteVarPrefixes);
String successVarNamePrefix = iteVarPrefixes.success();
ITempVarGen tempVarNameGen = transformationAssistant.getInfo().getTempVarNameGen();
this.successVarName = tempVarNameGen.nextVarName(successVarNamePrefix);
this.suchThat = suchThat;
this.setSeqType = setSeqType;
}
@Override
public List<AVarDeclIR> getOuterBlockDecls(AIdentifierVarExpIR setVar,
List<SPatternIR> patterns) throws AnalysisException
{
List<AVarDeclIR> outerBlockDecls = new LinkedList<AVarDeclIR>();
STypeIR elementType = transAssist.getElementType(setSeqType);
for (SPatternIR id : patterns)
{
AVarDeclIR decl = transAssist.getInfo().getDeclAssistant().consLocalVarDecl(elementType.clone(), id.clone(), transAssist.getInfo().getExpAssistant().consUndefinedExp());
decls.add(decl);
outerBlockDecls.add(decl);
}
successVarDecl = transAssist.consBoolVarDecl(successVarName, false);
outerBlockDecls.add(successVarDecl);
return outerBlockDecls;
}
@Override
public List<SStmIR> getPreForLoopStms(AIdentifierVarExpIR setVar,
List<SPatternIR> patterns, SPatternIR pattern)
{
if (count > 0)
{
AAssignToExpStmIR successAssignment = new AAssignToExpStmIR();
successAssignment.setExp(transAssist.getInfo().getExpAssistant().consBoolLiteral(false));
successAssignment.setTarget(transAssist.consSuccessVar(successVarName));
return packStm(successAssignment);
} else
{
return null;
}
}
@Override
public SExpIR getForLoopCond(AIdentifierVarExpIR setVar,
List<SPatternIR> patterns, SPatternIR pattern)
throws AnalysisException
{
SExpIR left = langIterator.getForLoopCond(setVar, patterns, pattern);
SExpIR right = transAssist.consBoolCheck(successVarName, true);
return transAssist.consAndExp(left, right);
}
@Override
public DeclarationTag consDeclarationTag()
{
return new DeclarationTag(true, successVarDecl);
}
@Override
public AVarDeclIR getNextElementDeclared(AIdentifierVarExpIR setVar,
List<SPatternIR> patterns, SPatternIR pattern)
throws AnalysisException
{
AVarDeclIR nextElementDecl = decls.get(count++);
tagNextElementDeclared(nextElementDecl);
return null;
}
@Override
public ALocalPatternAssignmentStmIR getNextElementAssigned(
AIdentifierVarExpIR setVar, List<SPatternIR> patterns,
SPatternIR pattern) throws AnalysisException
{
return langIterator.getNextElementAssigned(setVar, patterns, pattern, successVarDecl, this.nextElementDeclared);
}
@Override
public List<SStmIR> getForLoopStms(AIdentifierVarExpIR setVar,
List<SPatternIR> patterns, SPatternIR pattern)
{
return packStm(transAssist.consBoolVarAssignment(suchThat, successVarName));
}
@Override
public List<SStmIR> getPostOuterBlockStms(AIdentifierVarExpIR setVar,
List<SPatternIR> patterns)
{
ALetBeStNoBindingRuntimeErrorExpIR noBinding = new ALetBeStNoBindingRuntimeErrorExpIR();
noBinding.setType(new AErrorTypeIR());
ARaiseErrorStmIR raise = new ARaiseErrorStmIR();
raise.setError(noBinding);
AIfStmIR ifStm = new AIfStmIR();
ifStm.setIfExp(transAssist.consBoolCheck(successVarName, true));
ifStm.setThenStm(raise);
return packStm(ifStm);
}
}