Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
    }
Beispiel #4
0
    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);
    }