package org.glassfish.pfl.dynamic.codegen.impl;
import org.glassfish.pfl.dynamic.codegen.spi.Expression;
import java.util.List ;
import java.util.ArrayList ;
import java.util.Map ;
import java.util.HashMap ;
import org.glassfish.pfl.dynamic.codegen.spi.Type ;
import org.glassfish.pfl.dynamic.codegen.spi.Variable ;
public class BlockStatement extends StatementBase {
private List<Statement> body ;
private ExpressionFactory efactory ;
private Map<String,DefinitionStatement> definitions ;
BlockStatement( Node parent ) {
super( parent ) ;
body = new ArrayList<Statement>() ;
efactory = new ExpressionFactory( this ) ;
definitions = new HashMap<String,DefinitionStatement>() ;
}
public Variable getVar( String ident ) {
Variable result = null ;
DefinitionStatement ds = definitions.get( ident ) ;
if (ds != null)
result = ds.var() ;
return result ;
}
public boolean isEmpty() {
return body.isEmpty() ;
}
public List<Statement> body() {
return body ;
}
public ExpressionFactory exprFactory() {
return efactory ;
}
public void addBreak() {
body.add( new BreakStatement( this )) ;
}
public void addReturn() {
body.add( new ReturnStatement( this )) ;
}
public void addReturn( Expression expr ) {
body.add( new ReturnStatement( this,
((ExpressionInternal)expr).copy(this, ExpressionInternal.class) )) ;
}
public IfStatement addIf( Expression cond ) {
IfStatement result = new IfStatement( this,
((ExpressionInternal)cond).copy(this, ExpressionInternal.class) ) ;
body.add( result ) ;
return result ;
}
public TryStatement addTry() {
TryStatement result = new TryStatement( this ) ;
body.add( result ) ;
return result ;
}
public void addThrow( Expression expr ) {
body.add( new ThrowStatement( this,
((ExpressionInternal)expr).copy(this, ExpressionInternal.class) )) ;
}
private void checkSwitchExpressionType( Type type ) {
if ((type.size() != 1) || type.equals( Type._boolean()))
throw new IllegalArgumentException(
"A switch expression must have type char, byte, short, or int" ) ;
}
public SwitchStatement addSwitch( Expression value ) {
checkSwitchExpressionType( ((ExpressionInternal)value).type() ) ;
SwitchStatement result = new SwitchStatement( this,
((ExpressionInternal)value).copy(this, ExpressionInternal.class) ) ;
body.add( result ) ;
return result ;
}
public WhileStatement addWhile( Expression expr ) {
WhileStatement result = new WhileStatement( this,
((ExpressionInternal)expr).copy(this, ExpressionInternal.class) ) ;
body.add( result ) ;
return result ;
}
public void addExpression( Expression expr ) {
body.add( ((ExpressionInternal)expr).copy(this,
ExpressionInternal.class) ) ;
}
public void addAssign( Expression left, Expression right ) {
body.add(new AssignmentStatement( this,
((ExpressionInternal)left).copy(this, ExpressionInternal.class),
((ExpressionInternal)right).copy(this, ExpressionInternal.class))) ;
}
public Expression addDefinition( Type type, String ident,
Expression value ) {
if (definitions.containsKey( ident ))
throw new IllegalArgumentException(
"This scope already contains a variable named " + ident ) ;
Variable var = efactory.variable( type, ident ) ;
DefinitionStatement ds = new DefinitionStatement( this, var,
((ExpressionInternal)value).copy(this, ExpressionInternal.class) ) ;
body.add( ds ) ;
definitions.put( ident, ds ) ;
return var ;
}
@Override
public void accept( Visitor visitor ) {
visitor.visitBlockStatement( this ) ;
}
}