/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.ir.transform.expression;
import gw.internal.gosu.parser.expressions.ExistsExpression;
import gw.internal.gosu.parser.Expression;
import gw.lang.ir.IRExpression;
import gw.lang.ir.IRSymbol;
import gw.lang.ir.IRTypeConstants;
import gw.lang.ir.expression.IRCompositeExpression;
import gw.lang.ir.statement.IRAssignmentStatement;
import gw.lang.ir.statement.IRBreakStatement;
import gw.lang.ir.statement.IRForEachStatement;
import gw.lang.ir.statement.IRStatementList;
import gw.internal.gosu.ir.transform.ExpressionTransformer;
import gw.internal.gosu.ir.transform.TopLevelTransformationContext;
import gw.internal.gosu.ir.transform.statement.ForEachStatementTransformer;
public class ExistsExpressionTransformer extends AbstractExpressionTransformer<ExistsExpression>
{
public static IRExpression compile( TopLevelTransformationContext cc, ExistsExpression expr )
{
ExistsExpressionTransformer compiler = new ExistsExpressionTransformer( cc, expr );
return compiler.compile();
}
private ExistsExpressionTransformer( TopLevelTransformationContext cc, ExistsExpression expr )
{
super( cc, expr );
}
protected IRExpression compile_impl()
{
_cc().pushScope( false );
try
{
// boolean to hold if an element matches
IRSymbol booleanVal = _cc().makeAndIndexTempSymbol(IRTypeConstants.pBOOLEAN());
IRAssignmentStatement initBoolean = buildAssignment( booleanVal, booleanLiteral( false ) );
// construct for loop
Expression inExpression = _expr().getInExpression();
IRForEachStatement loop = ForEachStatementTransformer.makeLoop( _cc(),
ExpressionTransformer.compile( inExpression, _cc() ),
inExpression.getType(),
_expr().getIdentifier(),
_expr().getIndexIdentifier() );
// body of loop: if the value matches, set boolean to true and break
loop.setBody( buildIf( ExpressionTransformer.compile( _expr().getWhereExpression(), _cc() ),
new IRStatementList( false, buildAssignment( booleanVal, booleanLiteral( true ) ),
new IRBreakStatement() ) ) );
//Tie it all up in a Composite expression
IRCompositeExpression expression = new IRCompositeExpression();
expression.addElement( initBoolean );
expression.addElement( loop );
expression.addElement( identifier( booleanVal ) ); // the return value is the value of the boolean after the loop has executed
return expression;
}
finally
{
_cc().popScope();
}
}
}