public AddLocal ( string name, |
||
name | string | |
type | ||
return | System.Linq.Expressions.ParameterExpression |
Expr IStatementVisitor <Expr> .Visit(Statement.LocalAssign statement) { var values = WrapWithVarargsFirst(statement.Values); var locals = statement.Identifiers.Select(v => scope.AddLocal(v)).ToList(); if (statement.Values.Last().IsVarargs() || statement.Values.Last().IsFunctionCall()) { return(VarargsExpandAssignment(locals, values)); } return(AssignWithTemporaries(locals, values, Expr.Assign)); }
Expr IStatementVisitor <Expr> .Visit(Statement.ForIn statement) { var iterFuncVar = Expr.Variable(typeof(object)); var iterStateVar = Expr.Variable(typeof(object)); var iterableVar = Expr.Variable(typeof(object)); var iterVars = new[] { iterFuncVar, iterStateVar, iterableVar }; var valueExprs = statement.Values.Select(v => Expr.Convert(v.Visit(this), typeof(object))); var assignIterVars = VarargsExpandAssignment(iterVars, valueExprs); var parentScope = scope; scope = Scope.CreateChild(scope); var locals = statement.Identifiers.Select(id => scope.AddLocal(id)).ToList(); var invokeIterFunc = Expr.Dynamic(Context.DynamicCache.GetInvokeBinder(new CallInfo(2)), typeof(object), iterFuncVar, iterStateVar, iterableVar); var loop = Expr.Loop( Expr.Block( locals, VarargsExpandAssignment( locals, new[] { invokeIterFunc }), Expr.IfThen(Expr.Equal(locals[0], Expr.Constant(null)), Expr.Break(scope.BreakLabel())), Visit(statement.Body)), scope.BreakLabel()); var expr = Expr.Block(iterVars, assignIterVars, loop); scope = parentScope; return(expr); }
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); }
Expr Visit(string name, FunctionBody function) { var parentScope = scope; scope = Scope.CreateFunctionChild(scope); var parameters = function.Parameters.Select(p => scope.AddLocal(p)).ToList(); if (function.Varargs) { parameters.Add(scope.AddLocal(Constant.VARARGS, typeof(Varargs))); } var bodyExpr = Expr.Block(Visit(function.Body), Expr.Label(scope.GetReturnLabel(), Expr.Constant(null))); var lambdaExpr = Expr.Lambda(bodyExpr, Constant.FUNCTION_PREFIX + name, parameters); scope = parentScope; return(lambdaExpr); }