public ProcedureVariable AddVariable(string name, TypeReference type, SBExpressionData assignment, EntryModifiers modifiers) { var v = new ProcedureVariable(false, name, type, modifiers); v.Assignment = assignment; m_localVariables.Add(v); return(v); }
public override void ExitWhileStatement([NotNull] SBP.WhileStatementContext context) { var stack = m_expressionData.PopStackLevel(); var condition = stack.Pop(); var subStatements = m_scopeStack.Peek().GetSubExpressions(); var attributes = m_scopeStack.Peek().GetAttributes(); ProcedureVariable varLoopIndex = null; ProcedureVariable varEntryTime = null; ProcedureVariable varTimeoutTime = null; Expression timeout = null; var props = m_lastElementPropertyBlock; m_lastElementPropertyBlock = null; condition = this.ResolveForGetOperation(condition); var conditionExpression = condition.ExpressionCode; if (condition.IsValueType && condition.DataType.Type != typeof(bool)) { throw new NotImplementedException("Something wrong with the condition expression."); } var breakLabel = Expression.Label(); var isBlockSub = (subStatements[0].Type == ProcedureParsingScope.ScopeType.Block); if (isBlockSub) { breakLabel = m_scopeStack.Peek().BreakLabel; } var statementExpressions = new List <Expression>(); var loopExpressions = new List <Expression>(); loopExpressions.Add( Expression.IfThen( Expression.Not(conditionExpression), Expression.Break(breakLabel))); varLoopIndex = m_scopeStack.Peek().AddVariable( CreateStatementVariableName(context, "whileLoop_index"), TypeReference.TypeInt64, new SBExpressionData(Expression.Constant(0L)), EntryModifiers.Private); loopExpressions.Add(Expression.Increment(varLoopIndex.VariableExpression)); // index++; therefore index = 1 inside and after first iteration. // TODO: Add some logging, interactive break check, timeout and other stuff #region Attribute Handling if ((m_currentProcedure.Flags & ProcedureFlags.IsFunction) == ProcedureFlags.None && props != null) { foreach (var property in props) { if (property.Is("Timeout", PropertyBlockEntryType.Value)) { object toValue = (((PropertyBlockValue)property).Value); if (toValue is TimeSpan) { timeout = Expression.Constant((TimeSpan)toValue); } else { throw new NotImplementedException("Timeout data type or expression not implemented or supported."); } varEntryTime = m_scopeStack.Peek().AddVariable( CreateStatementVariableName(context, "whileLoop_EntryTime"), TypeReference.TypeDateTime, new SBExpressionData(Expression.Field(null, typeof(DateTime).GetField("MinValue"))), EntryModifiers.Private); varTimeoutTime = m_scopeStack.Peek().AddVariable( CreateStatementVariableName(context, "whileLoop_TimeoutTime"), TypeReference.TypeDateTime, new SBExpressionData(Expression.Field(null, typeof(DateTime).GetField("MinValue"))), EntryModifiers.Private); //loopExpressions.Add(Expression.Assign(varTimeoutTime.VariableExpression, // Expression.IfThen( // Expression.Not(conditionExpression), // Expression.Block( // Expression.Break(breakLabel)))); //new TSExpressionData(Expression.Property(null, typeof(DateTime).GetProperty("Now"))), } } } #endregion if (varEntryTime != null) { m_scopeStack.Peek().AddStatementCode( Expression.Assign(varEntryTime.VariableExpression, Expression.Property(null, typeof(DateTime).GetProperty("Now")))); } if (varTimeoutTime != null) { m_scopeStack.Peek().AddStatementCode( Expression.Assign(varTimeoutTime.VariableExpression, Expression.Add( varEntryTime.VariableExpression, timeout))); loopExpressions.Add( Expression.IfThen( Expression.Not(conditionExpression), Expression.Break(breakLabel))); loopExpressions.Add( Expression.IfThen( Expression.GreaterThan( Expression.Property(null, typeof(DateTime).GetProperty("Now")), varTimeoutTime.VariableExpression), Expression.Block( // TODO: log timeout Expression.Break(breakLabel)))); //new TSExpressionData(Expression.Property(null, typeof(DateTime).GetProperty("Now"))), } if (isBlockSub) { statementExpressions.Add( Expression.Loop( subStatements[0].GetBlockCode(loopExpressions, null), breakLabel, subStatements[0].ContinueLabel)); } else { loopExpressions.Add(subStatements[0].GetOnlyStatementCode()); statementExpressions.Add( Expression.Loop( Expression.Block(loopExpressions), breakLabel)); } m_scopeStack.Peek().AddStatementCode(statementExpressions.ToArray()); }