/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser.statements; import gw.internal.gosu.parser.CannotExecuteGosuException; import gw.internal.gosu.parser.Expression; import gw.internal.gosu.parser.Statement; import gw.lang.parser.statements.IAssertStatement; import gw.lang.parser.statements.IBreakStatement; import gw.lang.parser.statements.IDoWhileStatement; import gw.lang.parser.statements.ILoopStatement; import gw.lang.parser.statements.IReturnStatement; import gw.lang.parser.statements.ITerminalStatement; import gw.lang.parser.statements.IThrowStatement; import gw.lang.parser.statements.TerminalType; /** * Represents an do-while-statement as specified in the Gosu grammar: * <pre> * <i>do-while-statement</i> * <b>while</b> <b>(</b> <expression> <b>)</b> <statement> * </pre> * <p/> * * @see gw.lang.parser.IGosuParser */ public final class DoWhileStatement extends LoopStatement implements IDoWhileStatement { protected Expression _expression; protected Statement _statement; /** * @return The conditional expression. */ public Expression getExpression() { return _expression; } /** * @param expression The conditional expression. */ public void setExpression( Expression expression ) { _expression = expression; } /** * @return The statement to execute while the conditional expression evaluates * to true. */ public Statement getStatement() { return _statement; } /** * @param statement The statement to execute while the conditional expression * evaluates to true. */ public void setStatement( Statement statement ) { _statement = statement; } /** * Execute the do...while statement */ public Object execute() { if( !isCompileTimeConstant() ) { return super.execute(); } throw new CannotExecuteGosuException(); } @Override protected ITerminalStatement getLeastSignificantTerminalStatement_internal( boolean[] bAbsolute ) { Statement statement = getStatement(); if( statement != null ) { ITerminalStatement terminalStmt = statement.getLeastSignificantTerminalStatement( bAbsolute ); if( terminalStmt instanceof IReturnStatement || terminalStmt instanceof IAssertStatement || terminalStmt instanceof IThrowStatement || terminalStmt instanceof ILoopStatement ) { if( !bAbsolute[0] ) { if( isConditionLiteralTrue() ) { bAbsolute[0] = true; return this; } } return terminalStmt; } else if( !(terminalStmt instanceof IBreakStatement) && isConditionLiteralTrue() ) { bAbsolute[0] = true; return this; } } return null; } @Override public TerminalType getTerminalType() { boolean[] bAbsolute = {false}; ITerminalStatement lst = getLeastSignificantTerminalStatement( bAbsolute ); return lst == this ? TerminalType.ForeverLoop : null; // a loop can be a terminal if and only if it is a forever loop } @Override public String toString() { return "do\n" + (getStatement() == null ? "" : getStatement().toString()) + "\nwhile( " + (getExpression() == null ? "" : getExpression().toString()) + " )"; } }