Expr IStatementVisitor <Expr> .Visit(Statement.For statement) { var parentScope = scope; scope = Scope.CreateChild(parentScope); var step = statement.Step == null ? new Expression.Number(1.0).Visit(this) : ExprHelpers.ConvertToNumber(context, statement.Step.Visit(this)); var loopVariable = scope.AddLocal(statement.Identifier); var varVar = Expr.Variable(typeof(double)); var limitVar = Expr.Variable(typeof(double)); var stepVar = Expr.Variable(typeof(double)); var breakConditionExpr = ForLoopBreakCondition(limitVar, stepVar, varVar); var expr = Expr.Block( new[] { loopVariable, varVar, limitVar, stepVar }, Expr.Assign(varVar, ExprHelpers.ConvertToNumber(context, statement.Var.Visit(this))), Expr.Assign(limitVar, ExprHelpers.ConvertToNumber(context, statement.Limit.Visit(this))), Expr.Assign(stepVar, step), ExprHelpers.CheckNumberForNan(varVar, String.Format(ExceptionMessage.FOR_VALUE_NOT_NUMBER, "inital value")), ExprHelpers.CheckNumberForNan(limitVar, String.Format(ExceptionMessage.FOR_VALUE_NOT_NUMBER, "limit")), ExprHelpers.CheckNumberForNan(stepVar, String.Format(ExceptionMessage.FOR_VALUE_NOT_NUMBER, "step")), ForLoop(statement, stepVar, loopVariable, varVar, breakConditionExpr)); scope = parentScope; return(expr); }
LoopExpression ForLoop(Statement.For statement, ParameterExpression stepVar, ParameterExpression loopVariable, ParameterExpression varVar, BinaryExpression breakConditionExpr) { var loopExpr = Expr.Loop( Expr.Block( Expr.IfThen(breakConditionExpr, Expr.Break(scope.BreakLabel())), Expr.Assign(loopVariable, Expr.Convert(varVar, typeof(object))), Visit(statement.Body), Expr.AddAssign(varVar, stepVar)), scope.BreakLabel()); return(loopExpr); }
public object visitForStmt(Statement.For stmt) { var counter = (int)stmt.RangeStart.Accept(this); var end = (int)stmt.RangeEnd.Accept(this); while (counter <= end) { environment.Assign(stmt.Identifier.Name, counter); foreach (var statement in stmt.Block) { statement.Accept(this); } counter++; } return(null); }
public bool visitForStmt(Statement.For stmt) { var identifier = stmt.Identifier; if (!environment.Contains(identifier.Name)) { ErrorWriter.Write(identifier, "Usage of uninitialized variable '{0}'", identifier.Name); return(false); } if (environment.GetType(identifier.Name) != "int") { ErrorWriter.Write(identifier, "Loop variable '{0}' must be of type 'int'", identifier.Name); return(false); } var startType = stmt.RangeStart.Accept(expressionAnalyzer); if (startType != "int") { ErrorWriter.Write(stmt.RangeStart, "Range start must be a number"); return(false); } var endType = stmt.RangeEnd.Accept(expressionAnalyzer); if (endType != "int") { ErrorWriter.Write(stmt.RangeEnd, "Range end must be a number"); return(false); } var valid = true; // lock the variable so it can't be modified during the loop environment.setLock(identifier.Name, true); foreach (var statement in stmt.Block) { valid = statement.Accept(this) && valid; } environment.setLock(identifier.Name, false); return(valid); }