Used to denote the target of a GotoExpression.
 internal ForCSharpStatement(ReadOnlyCollection<ParameterExpression> variables, ReadOnlyCollection<Expression> initializers, Expression test, ReadOnlyCollection<Expression> iterators, Expression body, LabelTarget breakLabel, LabelTarget continueLabel)
     : base(test, body, breakLabel, continueLabel)
 {
     Variables = variables;
     Initializers = initializers;
     Iterators = iterators;
 }
        public Expression Update(LabelTarget label, Type type) {
            if (LabelTarget.Equals(label) && Type.Equals(type)) {
                return this;
            }

            return AstExpression.Continue(_continueStatement, this as IScope, Visitor);
        }
예제 #3
0
 public override void BeforeVisit(Function node)
 {
     base.BeforeVisit(node);
     //_currentOutputExp = Expression.Parameter(typeof (TextWriter), CurrentOutputIdentifier);
     //Create return target
     _returnLabelTarget = Expression.Label(typeof(object), "lambdaReturn");
 }
		internal DoWhileExpression (Expression test,  Expression body, LabelTarget breakTarget, LabelTarget continueTarget)
		{
			this.test = test;
			this.body = body;
			this.break_target = breakTarget;
			this.continue_target = continueTarget;
		}
예제 #5
0
 public override Expression Compile(ParameterExpression stateParameterExpression, LabelTarget returnTarget)
 {
     return Expression.IfThenElse(
         Expression.Convert(this.Condition.Compile(stateParameterExpression, returnTarget), typeof(bool)),
         this.Statement.Compile(stateParameterExpression, returnTarget),
         this.ElseStatement.Compile(stateParameterExpression, returnTarget));
 }
		public DoWhileExpression Update (Expression test, Expression body, LabelTarget breakTarget, LabelTarget continueTarget)
		{
			if (this.test == test && this.body == body && this.break_target == breakTarget && this.continue_target == continueTarget)
				return this;

			return CustomExpression.DoWhile (test, body, breakTarget, continueTarget);
		}
예제 #7
0
        public Expression Update(LabelTarget labelTarget, Type type) {
            if (LabelTarget.Equals(labelTarget) && Type.Equals(type)) {
                return this;
            }

            return AstExpression.Goto(_gotoStatement, this as IScope, Visitor);
        }
예제 #8
0
        public static SwitchExpression Switch(Expression value, LabelTarget label, IEnumerable<SwitchCase> cases) {
            RequiresCanRead(value, "value");
            ContractUtils.Requires(value.Type == typeof(int), "value", Strings.ValueMustBeInt);
            ContractUtils.RequiresNotNull(cases, "cases");
            var caseList = cases.ToReadOnly();
            ContractUtils.RequiresNotEmpty(caseList, "cases");
            ContractUtils.RequiresNotNullItems(caseList, "cases");
            // TODO: does it make sense for switch to have non-void type?
            ContractUtils.Requires(label == null || label.Type == typeof(void), "label", Strings.LabelTypeMustBeVoid);

            bool @default = false;
            int max = Int32.MinValue;
            int min = Int32.MaxValue;
            foreach (SwitchCase sc in caseList) {
                if (sc.IsDefault) {
                    ContractUtils.Requires(@default == false, "cases", Strings.OnlyDefaultIsAllowed);
                    @default = true;
                } else {
                    int val = sc.Value;
                    if (val > max) max = val;
                    if (val < min) min = val;
                }
            }

            ContractUtils.Requires(UniqueCaseValues(caseList, min, max), "cases", Strings.CaseValuesMustBeUnique);

            return new SwitchExpression(value, label, caseList);
        }
예제 #9
0
        public sealed override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel) {
            if (args.Length == 0) {
                throw new InvalidOperationException();
            }

            MetaObject[] mos;
            if (args.Length != 1) {
                mos = new MetaObject[args.Length - 1];
                for (int i = 1; i < args.Length; i++) {
                    mos[i - 1] = MetaObject.ObjectToMetaObject(args[i], parameters[i]);
                }
            } else {
                mos = MetaObject.EmptyMetaObjects;
            }

            MetaObject binding = Bind(
                MetaObject.ObjectToMetaObject(args[0], parameters[0]),
                mos
            );

            if (binding == null) {
                throw Error.BindingCannotBeNull();
            }

            return GetMetaObjectRule(binding, returnLabel);
        }
        public Expression Update(LabelTarget target, Expression defaultValue) {
            if (Target.Equals(target) && DefaultValue == defaultValue) {
                return this;
            }

            return AstExpression.Label(_caseLabel, ParentScope, Visitor);
        }
예제 #11
0
        public Expression Update(GotoExpressionKind kind, LabelTarget target, Expression value) {
            if (Target.Equals(target) && ReferenceEquals(Value, value) && Kind == kind) {
                return this;
            }

            return AstExpression.Return(_returnStatement, ParentScope, Visitor);
        }
예제 #12
0
        public Expression Update(LabelTarget labelTarget, Type type) {
            if (LabelTarget.Equals(labelTarget) && Type.Equals(type)) {
                return this;
            }

            return AstExpression.Label(_labelStatement, ParentScope, Visitor);
        }
 internal SwitchCSharpStatement(Expression switchValue, LabelTarget breakLabel, ReadOnlyCollection<ParameterExpression> variables, ReadOnlyCollection<CSharpSwitchCase> cases)
 {
     SwitchValue = switchValue;
     BreakLabel = breakLabel;
     Variables = variables;
     Cases = cases;
 }
예제 #14
0
        // Just splat the args and dispatch through a nested site
        public override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel) {
            Debug.Assert(args.Length == 2);

            int count = ((object[])args[1]).Length;
            ParameterExpression array = parameters[1];

            var nestedArgs = new ReadOnlyCollectionBuilder<Expression>(count + 1);
            var delegateArgs = new Type[count + 3]; // args + target + returnType + CallSite
            nestedArgs.Add(parameters[0]);
            delegateArgs[0] = typeof(CallSite);
            delegateArgs[1] = typeof(object);
            for (int i = 0; i < count; i++) {
                nestedArgs.Add(Expression.ArrayAccess(array, Expression.Constant(i)));
                delegateArgs[i + 2] = typeof(object).MakeByRefType();
            }
            delegateArgs[delegateArgs.Length - 1] = typeof(object);

            return Expression.IfThen(
                Expression.Equal(Expression.ArrayLength(array), Expression.Constant(count)),
                Expression.Return(
                    returnLabel,
                    Expression.MakeDynamic(
                        Expression.GetDelegateType(delegateArgs),
                        new ComInvokeAction(new CallInfo(count)),
                        nestedArgs
                    )
                )
            );
        }
예제 #15
0
        internal SwitchExpression(Expression testValue, LabelTarget label, ReadOnlyCollection<SwitchCase> cases) {
            Assert.NotNullItems(cases);

            _label = label;
            _testValue = testValue;
            _cases = cases;
        }
예제 #16
0
        public ComplexFunctionBuilder(Type targetType)
        {
            _targetType = targetType;
            _delegateType = typeof(Combine<>).MakeGenericType(_targetType);

            _pCombiner = Expression.Parameter(typeof(ICombiner));
            _pPrev = Expression.Parameter(_targetType);
            _pNext = Expression.Parameter(_targetType);
            _vResult = Expression.Variable(_targetType);

            _lbReturn = Expression.Label(_targetType);

            if (!_targetType.IsValueType)
            {
                _bodyList.Add(Expression.IfThen(Expression.Equal(_pNext, Expression.Constant(null)), Expression.Return(_lbReturn, _pPrev)));
                _bodyList.Add(Expression.IfThen(Expression.Equal(_pPrev, Expression.Constant(null)), Expression.Return(_lbReturn, _pNext)));
            }

            var ci = _targetType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(_ => _.GetParameters().Length == 0);
            Expression resultInstance;

            if (ci == null)
            {
                resultInstance = Expression.Call(typeof(FormatterServices).GetMethod("GetUninitializedObject"), Expression.Constant(_targetType));
                resultInstance = Expression.Convert(resultInstance, _targetType);
            }
            else
                resultInstance = Expression.New(ci);

            _bodyList.Add(Expression.Assign(_vResult, resultInstance));
        }
예제 #17
0
 public static LoopExpression Loop(Expression body, LabelTarget @break, LabelTarget @continue) {
     RequiresCanRead(body, "body");
     // TODO: lift the restriction on break, and allow loops to have non-void type
     ContractUtils.Requires(@break == null || @break.Type == typeof(void), "break", Strings.LabelTypeMustBeVoid);
     ContractUtils.Requires(@continue == null || @continue.Type == typeof(void), "continue", Strings.LabelTypeMustBeVoid);
     return new LoopExpression(body, @break, @continue);
 }
        public override Expression Compile(ParameterExpression stateParameterExpression, LabelTarget returnTarget, LogicExpression valueExpression)
        {
            var value = this.Target.Compile(stateParameterExpression, returnTarget);
            var convertedValue = Expression.Convert(value, typeof(LogicStructureInstance));

            var valueVariable = Expression.Variable(typeof(LogicStructureInstance), "value");
            var field = Expression.Variable(typeof(LogicField), "field");

            Expression<Func<LogicStructureInstance, string, LogicField>> lookupField =
                (x, z) => x.Fields.Keys.First(y => y.Name == z);

            var assignValue = Expression.Assign(valueVariable, convertedValue);
            var assignFieldName = Expression.Assign(
                field,
                Expression.Invoke(lookupField, valueVariable, Expression.Constant(this.Field)));
            var assignField =
                Expression.Assign(
                    Expression.Property(Expression.Property(valueVariable, "Fields"), "Item", field),
                    Expression.Convert(valueExpression.Compile(stateParameterExpression, returnTarget), typeof(object)));
            var assignFieldSet =
                Expression.Assign(
                    Expression.Property(Expression.Property(valueVariable, "FieldsSet"), "Item", field),
                    Expression.Constant(true));

            return Expression.Block(
                new[] { valueVariable, field },
                assignValue,
                assignFieldName,
                assignField,
                assignFieldSet);
        }
 public LoopExpression Update (LabelTarget breakLabel, LabelTarget continueLabel, Expression body)
 {
   Contract.Requires(body != null);
   Contract.Requires(continueLabel == null || continueLabel.Type == typeof(void), "Continue label type must be void");
   Contract.Ensures(Contract.Result<LoopExpression>() != null);
   return default(LoopExpression);
 }
 public GotoExpression Update (LabelTarget target, Expression value)
 {
   Contract.Requires(target != null);
   Contract.Requires(value != null || target.Type == typeof(void), "Label type must be void when no value is provided");
   Contract.Ensures(Contract.Result<GotoExpression>() != null);
   return default(GotoExpression);
 }
예제 #21
0
        public ForExpression Update(ParameterExpression variable, Expression initializer, Expression test, Expression step, Expression body, LabelTarget breakTarget, LabelTarget continueTarget)
        {
            if (this.variable == variable && this.initializer == initializer && this.test == test && this.step == step && this.body == body && this.break_target == breakTarget && this.continue_target == continueTarget)
                return this;

            return CustomExpression.For(variable, initializer, test, step, body, breakTarget, continueTarget);
        }
예제 #22
0
        public ForEachExpression Update(ParameterExpression variable, Expression enumerable, Expression body, LabelTarget breakTarget, LabelTarget continueTarget)
        {
            if (this.variable == variable && this.enumerable == enumerable && this.body == body && break_target == breakTarget && continue_target == continueTarget)
                return this;

            return CustomExpression.ForEach(variable, enumerable, body, continueTarget, breakTarget);
        }
예제 #23
0
        public Expression Update(LabelTarget target, Type type, Expression value) {
            if (Target.Equals(target) && Type.Equals(type) && Value.Equals(value)) {
                return this;
            }

            return AstExpression.Init(_variableInitializer, ParentScope, Visitor);
        }
예제 #24
0
        public Expression Update(LabelTarget target, Type type, Expression value) {
            if (Target.Equals(target) && Type.Equals(type) && Value.Equals(value)) {
                return this;
            }

            return AstExpression.Break(_breakStatement, ParentScope, Visitor);
        }
예제 #25
0
        public AplusScope(AplusScope parent,
            string name,
            Aplus runtime = null,
            DLR.ParameterExpression runtimeParam = null,
            DLR.ParameterExpression moduleParam = null,
            DLR.LabelTarget returnTarget = null,
            bool isEval = false,
            bool isMethod = false,
            bool isAssignment = false)
        {
            this.parent = parent;
            this.name = name;
            this.runtime = runtime;
            this.runtimeParam = runtimeParam;
            this.moduleParam = moduleParam;

            this.returnTarget = returnTarget;

            this.variables = new Dictionary<string, DLR.ParameterExpression>();

            this.callbackInfo = new CallbackInfoStorage();

            this.iseval = isEval;

            this.ismethod = isMethod;
            this.isAssignment = isAssignment;

            InheritProperties(parent);
        }
예제 #26
0
 internal GotoExpression(GotoExpressionKind kind, LabelTarget target, Expression value, Type type)
 {
     _kind = kind;
     _value = value;
     _target = target;
     _type = type;
 }
 public override Expression Compile(ParameterExpression stateParameterExpression, LabelTarget returnTarget)
 {
     return Expression.Property(
         Expression.Property(stateParameterExpression, "Variables"),
         "Item",
         Expression.Constant(this.Identifier));
 }
예제 #28
0
 internal void AddLabelInfo(LabelTarget target, LabelInfo info)
 {
     if (this.Labels == null)
     {
         this.Labels = new HybridReferenceDictionary<LabelTarget, LabelInfo>();
     }
     this.Labels[target] = info;
 }
예제 #29
0
 internal bool ContainsTarget(LabelTarget target)
 {
     if (this.Labels == null)
     {
         return false;
     }
     return this.Labels.ContainsKey(target);
 }
예제 #30
0
 /// <summary>
 /// Creates a new expression that is like this one, but using the
 /// supplied children. If all of the children are the same, it will
 /// return this expression.
 /// </summary>
 /// <param name="breakLabel">The <see cref="BreakLabel"/> property of the result.</param>
 /// <param name="continueLabel">The <see cref="ContinueLabel"/> property of the result.</param>
 /// <param name="body">The <see cref="Body"/> property of the result.</param>
 /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
 public LoopExpression Update(LabelTarget breakLabel, LabelTarget continueLabel, Expression body)
 {
     if (breakLabel == BreakLabel && continueLabel == ContinueLabel && body == Body)
     {
         return this;
     }
     return Expression.Loop(body, breakLabel, continueLabel);
 }
예제 #31
0
        private MSAst.LambdaExpression CreateOuterGeneratorFactory(Type lambdaType)
        {
            MSAst.LabelTarget returnLabelTarget = Ast.Label(lambdaType.GetMethod("Invoke").ReturnType);

            MSAst.Expression body = Ast.Return(
                returnLabelTarget,
                Ast.Call(
                    typeof(RuntimeOps),
                    "CreateDebugGenerator",
                    new[] { _generatorLabelTarget.Type },
                    Ast.Call(
                        typeof(RuntimeOps).GetMethod("CreateFrameForGenerator"),
                        _debugContextExpression,
                        _functionInfo
                        )
                    )
                );

            MSAst.LabelExpression returnLabel = null;
            if (returnLabelTarget.Type == typeof(void))
            {
                returnLabel = Ast.Label(returnLabelTarget, AstUtils.Void(body));
            }
            else
            {
                returnLabel = Ast.Label(returnLabelTarget, AstUtils.Convert(body, returnLabelTarget.Type));
            }

            return(Ast.Lambda(
                       lambdaType,
                       Ast.Block(
                           _lambdaVars,
                           returnLabel
                           ),
                       _alias,
                       _lambdaParams));
        }
        internal override lambda.Expression CompileArrayBlock(lambda.ParameterExpression paramArray1, lambda.LabelTarget fault)
        {
            lambda.ParameterExpression counter   = lambda.Expression.Variable(typeof(int), "counter");
            lambda.ParameterExpression countitem = lambda.Expression.Variable(typeof(int), "countitem");

            lambda.LabelTarget label = lambda.Expression.Label(typeof(object));

            lambda.BlockExpression block = lambda.Expression.Block(
                new[] { counter, countitem },
                lambda.Expression.Assign(counter, lambda.Expression.Constant(0)),
                lambda.Expression.Assign(countitem, lambda.Expression.Constant(0)),
                lambda.Expression.Loop(
                    lambda.Expression.IfThenElse(
                        lambda.Expression.LessThan(counter, lambda.Expression.ArrayLength(paramArray1)),
                        lambda.Expression.Block(
                            lambda.Expression.TryCatch(lambda.Expression.Block(
                                                           lambda.Expression.IfThen(lambda.Expression.IsTrue(lambda.Expression.Convert(lambda.Expression.ArrayIndex(paramArray1, counter), typeof(bool))),
                                                                                    lambda.Expression.PostIncrementAssign(countitem)), countitem),
                                                       lambda.Expression.Catch(typeof(Exception), countitem)),
                            lambda.Expression.PostIncrementAssign(counter)),
                        lambda.Expression.Break(label, lambda.Expression.Convert(countitem, typeof(object)))
                        ), label));
            return(block);
        }
예제 #33
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            // This parameter will store the return value
            DLR.ParameterExpression returnValue = DLR.ParameterExpression.Parameter(typeof(AType), "RETURN_VALUE");
            DLR.LabelTarget         breakLabel  = DLR.Expression.Label(typeof(AType), "BREAK");

            DLR.Expression result = DLR.Expression.Block(
                new DLR.ParameterExpression[] { returnValue },
                // Assign the default return value: ANull
                DLR.Expression.Assign(returnValue, DLR.Expression.Constant(Utils.ANull())),
                DLR.Expression.Loop(
                    DLR.Expression.Block(
                        DLR.Expression.IfThen(
                            // Test if the condition is equal to 0
                            // Invert the inner test's result
                            DLR.Expression.Not(
                                // This part will test if the condition is true (this means it is not 0)
                                DLR.Expression.IsTrue(
                                    this.expression.Generate(scope),
                                    typeof(Helpers).GetMethod("BooleanTest")
                                    )
                                ),
                            // Break out from the loop with the last computed value
                            DLR.Expression.Break(breakLabel, returnValue)
                            ),
                        // Compute & assign the value
                        DLR.Expression.Assign(returnValue, this.codeBlock.Generate(scope))
                        ),
                    // The label where to jump in case of break
                    breakLabel
                    )
                );


            return(result);
        }
예제 #34
0
        public void EnterBlockDefinition(
            ScopeBuilder /*!*/ locals,
            MSA.Expression /*!*/ bfcVariable,
            MSA.Expression /*!*/ selfVariable,
            MSA.ParameterExpression /*!*/ runtimeScopeVariable,
            MSA.LabelTarget /*!*/ redoLabel)
        {
            Assert.NotNull(locals, bfcVariable, selfVariable);
            Assert.NotNull(redoLabel);

            BlockScope block = new BlockScope(locals, selfVariable, runtimeScopeVariable, bfcVariable, redoLabel);

            block.Parent              = _currentElement;
            block.ParentRescue        = _currentRescue;
            block.ParentLoop          = _currentLoop;
            block.ParentBlock         = _currentBlock;
            block.ParentVariableScope = _currentVariableScope;

            _currentElement       = block;
            _currentRescue        = null;
            _currentLoop          = null;
            _currentBlock         = block;
            _currentVariableScope = block;
        }
예제 #35
0
        internal MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen, bool isLambda)
        {
            ScopeBuilder scope = DefineLocals(gen.CurrentScope);

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.ParameterExpression blockParameter, selfParameter;
            var parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.ParameterExpression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget         redoLabel     = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
                );

            MSA.Expression          paramInit = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder, filterVariable;

            MSA.Expression traceCall, traceReturn;
            if (gen.TraceEnabled)
            {
                int firstStatementLine = _body.Count > 0 ? _body.First.Location.Start.Line : Location.End.Line;
                int lastStatementLine  = _body.Count > 0 ? _body.Last.Location.End.Line : Location.End.Line;

                traceCall   = Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, gen.SourcePathConstant, AstUtils.Constant(firstStatementLine));
                traceReturn = Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, gen.SourcePathConstant, AstUtils.Constant(lastStatementLine));
            }
            else
            {
                traceCall = traceReturn = Ast.Empty();
            }

            MSA.Expression body = AstUtils.Try(
                paramInit,
                traceCall,
                Ast.Label(redoLabel),
                AstUtils.Try(
                    gen.TransformStatements(_body, ResultOperation.Return)
                    ).Catch(blockUnwinder = Ast.Parameter(typeof(BlockUnwinder), "#u"),
                            // redo:
                            AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Goto(redoLabel)),

                            // next:
                            gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                            )
                ).Filter(filterVariable = Ast.Parameter(typeof(Exception), "#e"),
                         Methods.FilterBlockException.OpCall(scopeVariable, filterVariable)
                         ).Finally(
                traceReturn,
                Ast.Empty()
                );

            body = gen.AddReturnTarget(
                scope.CreateScope(
                    scopeVariable,
                    Methods.CreateBlockScope.OpCall(new AstExpressions {
                scope.MakeLocalsStorage(),
                scope.GetVariableNamesExpression(),
                blockParameter,
                selfParameter,
                EnterInterpretedFrameExpression.Instance
            }),
                    body
                    )
                );

            gen.LeaveBlockDefinition();

            int parameterCount = ParameterCount;
            var attributes = _parameters.GetBlockSignatureAttributes();

            var dispatcher = Ast.Constant(
                BlockDispatcher.Create(parameterCount, attributes, gen.SourcePath, Location.Start.Line), typeof(BlockDispatcher)
                );

            return(Ast.Coalesce(
                       (isLambda ? Methods.InstantiateLambda : Methods.InstantiateBlock).OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher),
                       (isLambda ? Methods.DefineLambda : Methods.DefineBlock).OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher,
                                                                                      BlockDispatcher.CreateLambda(
                                                                                          body,
                                                                                          RubyStackTraceBuilder.EncodeMethodName(gen.CurrentMethod.MethodName, gen.SourcePath, Location, gen.DebugMode),
                                                                                          parameters,
                                                                                          parameterCount,
                                                                                          attributes
                                                                                          )
                                                                                      )
                       ));
        }
예제 #36
0
 /// <summary>
 /// Gets the debug view for the specified label.
 /// </summary>
 /// <param name="label">The label to get a debug view for.</param>
 /// <returns>Debug view for the specified label.</returns>
 public XNode GetDebugView(LabelTarget label)
 {
     return(Visit(label));
 }
예제 #37
0
 /// <summary>
 ///     Creates a <see cref="LabelExpression" /> representing a label with no default value.
 /// </summary>
 /// <param name="target">The <see cref="LabelTarget" /> which this <see cref="LabelExpression" /> will be associated with.</param>
 /// <returns>A <see cref="LabelExpression" /> with no default value.</returns>
 public static LabelExpression Label(LabelTarget target)
 {
     return(Label(target, null));
 }
예제 #38
0
 internal LabelExpression(LabelTarget label, Expression defaultValue)
 {
     Target       = label;
     DefaultValue = defaultValue;
 }
예제 #39
0
 private int GetLabelTargetId(LabelTarget target)
 {
     Debug.Assert(string.IsNullOrEmpty(target.Name));
     return(GetId(target, ref _labelIds));
 }
예제 #40
0
 /// <summary>
 /// Creates a <see cref="LoopExpression"/> with the given body and break target.
 /// </summary>
 /// <param name="body">The body of the loop.</param>
 /// <param name="break">The break target used by the loop body.</param>
 /// <returns>The created <see cref="LoopExpression"/>.</returns>
 public static LoopExpression Loop(Expression body, LabelTarget @break)
 {
     return(Loop(body, @break, null));
 }
예제 #41
0
        public void EnterLoop(MSA.Expression /*!*/ redoVariable, MSA.Expression /*!*/ resultVariable, MSA.LabelTarget /*!*/ breakLabel, MSA.LabelTarget /*!*/ continueLabel)
        {
            Assert.NotNull(redoVariable, resultVariable, breakLabel, continueLabel);

            LoopScope loop = new LoopScope(redoVariable, resultVariable, breakLabel, continueLabel);

            loop.Parent     = _currentElement;
            loop.ParentLoop = _currentLoop;

            _currentElement = _currentLoop = loop;
        }
예제 #42
0
 public LoopExpression Update(LabelTarget breakLabel, LabelTarget continueLabel, Expression body)
 {
     throw new NotImplementedException();
 }
예제 #43
0
        internal static MSA.Expression /*!*/ MakeUserMethodBody(AstGenerator gen, int lastLine,
                                                                MSA.Expression /*!*/ blockParameter, MSA.Expression /*!*/ rfcVariable,
                                                                MSA.ParameterExpression /*!*/ methodUnwinder, MSA.Expression /*!*/ bodyStatement, ResultOperation resultOperation,
                                                                int profileTickIndex, MSA.ParameterExpression stampVariable, MSA.LabelTarget returnLabel)
        {
            Assert.NotNull(blockParameter, rfcVariable, bodyStatement, methodUnwinder);
            Debug.Assert(!resultOperation.IsIgnore, "return value should not be ignored");
            Debug.Assert(returnLabel != null || resultOperation.Variable != null, "return label needed");

            MSA.Expression resultExpression = Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField);
            if (resultOperation.Variable != null)
            {
                resultExpression = Ast.Assign(resultOperation.Variable, resultExpression);
            }
            else
            {
                resultExpression = Ast.Return(returnLabel, resultExpression);
            }

            // TODO: move this to the caller:
            MSA.Expression profileStart, profileEnd;
            if (stampVariable != null)
            {
                profileStart = Ast.Assign(stampVariable, Methods.Stopwatch_GetTimestamp.OpCall());
                profileEnd   = Methods.UpdateProfileTicks.OpCall(Ast.Constant(profileTickIndex), stampVariable);
            }
            else
            {
                profileStart = profileEnd = Ast.Empty();
            }

            return(AstUtils.Try(
                       // initialize frame (RFC):
                       profileStart,
                       Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(blockParameter, typeof(Proc)))),
                       bodyStatement
                       ).Filter(methodUnwinder, Ast.Equal(Ast.Field(methodUnwinder, MethodUnwinder.TargetFrameField), rfcVariable),

                                // return unwinder.ReturnValue;
                                resultExpression

                                ).Finally(
                       Ast.Assign(Ast.Field(rfcVariable, RuntimeFlowControl.IsActiveMethodField), Ast.Constant(false)),
                       profileEnd,
                       gen != null && gen.TraceEnabled ? Methods.TraceMethodReturn.OpCall(
                           gen.CurrentScopeVariable,
                           Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)),
                           Ast.Constant(lastLine)
                           ) : Ast.Empty()
                       ));
        }
예제 #44
0
        // see Ruby Language.doc/Runtime/Control Flow Implementation/While-Until
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            MSA.Expression          resultVariable = gen.CurrentScope.DefineHiddenVariable("#loop-result", typeof(object));
            MSA.Expression          redoVariable   = gen.CurrentScope.DefineHiddenVariable("#skip-condition", typeof(bool));
            MSA.ParameterExpression unwinder;

            bool isInnerLoop = gen.CurrentLoop != null;

            MSA.LabelTarget breakLabel    = Ast.Label();
            MSA.LabelTarget continueLabel = Ast.Label();

            gen.EnterLoop(redoVariable, resultVariable, breakLabel, continueLabel);
            MSA.Expression transformedBody      = gen.TransformStatements(_statements, ResultOperation.Ignore);
            MSA.Expression transformedCondition = _condition.TransformCondition(gen, true);
            gen.LeaveLoop();

            MSA.Expression conditionPositiveStmt, conditionNegativeStmt;
            if (_isWhileLoop)
            {
                conditionPositiveStmt = AstUtils.Empty();
                conditionNegativeStmt = Ast.Break(breakLabel);
            }
            else
            {
                conditionPositiveStmt = Ast.Break(breakLabel);
                conditionNegativeStmt = AstUtils.Empty();
            }

            // make the loop first:
            MSA.Expression loop = new AstBlock {
                gen.ClearDebugInfo(),
                           Ast.Assign(redoVariable, AstUtils.Constant(_isPostTest)),

                AstFactory.Infinite(breakLabel, continueLabel,
                                    AstUtils.Try(

                                        AstUtils.If(redoVariable,
                                                    Ast.Assign(redoVariable, AstUtils.Constant(false))
                                                    ).ElseIf(transformedCondition,
                                                             conditionPositiveStmt
                                                             ).Else(
                                            conditionNegativeStmt
                                            ),

                                        transformedBody,
                                        AstUtils.Empty()

                                        ).Catch(unwinder = Ast.Parameter(typeof(BlockUnwinder), "#u"),
                                                // redo = u.IsRedo
                                                Ast.Assign(redoVariable, Ast.Field(unwinder, BlockUnwinder.IsRedoField)),
                                                AstUtils.Empty()

                                                ).Filter(unwinder = Ast.Parameter(typeof(EvalUnwinder), "#u"),
                                                         Ast.Equal(Ast.Field(unwinder, EvalUnwinder.ReasonField), AstFactory.BlockReturnReasonBreak),

                                                         // result = unwinder.ReturnValue
                                                         Ast.Assign(resultVariable, Ast.Field(unwinder, EvalUnwinder.ReturnValueField)),
                                                         Ast.Break(breakLabel)
                                                         )
                                    ),
                gen.ClearDebugInfo(),
                AstUtils.Empty(),
            };

            // wrap it to try finally that updates RFC state:
            if (!isInnerLoop)
            {
                loop = AstUtils.Try(
                    Methods.EnterLoop.OpCall(gen.CurrentScopeVariable),
                    loop
                    ).Finally(
                    Methods.LeaveLoop.OpCall(gen.CurrentScopeVariable)
                    );
            }

            return(Ast.Block(loop, resultVariable));
        }
예제 #45
0
        internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen)
        {
            MSA.Expression parentScope = gen.CurrentScopeVariable;
            ScopeBuilder   scope       = new ScopeBuilder();

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.Expression            blockParameter, selfParameter;
            MSA.ParameterExpression[] parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.Expression  scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget redoLabel     = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
                );

            if (_definedScope != null)
            {
                _definedScope.TransformLocals(scope);
            }

            MSA.Expression          paramInit     = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder = scope.DefineHiddenVariable("#unwinder", typeof(BlockUnwinder));

            MSA.Expression loop = AstFactory.Infinite(null, redoLabel,
                                                      AstUtils.Try(
                                                          gen.TransformStatements(_body, ResultOperation.Return)
                                                          ).Catch(blockUnwinder,
                                                                  // redo:
                                                                  AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Continue(redoLabel)),

                                                                  // next:
                                                                  gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                                                                  )
                                                      );

            if (gen.TraceEnabled)
            {
                int firstStatementLine = _body.Count > 0 ? _body[0].Location.Start.Line : Location.End.Line;
                int lastStatementLine  = _body.Count > 0 ? _body[_body.Count - 1].Location.End.Line : Location.End.Line;

                loop = Ast.TryFinally(
                    Ast.Block(
                        Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(firstStatementLine)),
                        loop
                        ),
                    Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(lastStatementLine))
                    );
            }

            MSA.Expression body = Ast.Block(
                Ast.Assign(scopeVariable,
                           Methods.CreateBlockScope.OpCall(scope.VisibleVariables(), parentScope, blockParameter, selfParameter)
                           ),

                paramInit,

                loop,

                Ast.Empty()
                );

            body = gen.AddReturnTarget(scope.CreateScope(body));
            gen.LeaveBlockDefinition();

            int parameterCount = _parameters.LeftValues.Count;

            var attributes = _parameters.GetBlockSignatureAttributes();

            return(Methods.DefineBlock.OpCall(
                       gen.CurrentScopeVariable,
                       gen.CurrentRfcVariable,
                       gen.CurrentSelfVariable,
                       Ast.Lambda(
                           BlockDispatcher.GetDelegateType(parameterCount, attributes),
                           body,
                           gen.EncodeMethodName(gen.CurrentMethod.MethodName, Location),
                           new ReadOnlyCollection <MSA.ParameterExpression>(parameters)
                           ),
                       Ast.Constant(parameterCount),
                       Ast.Constant(attributes)
                       ));
        }
        internal override lambda.Expression CompileArrayBlock(lambda.ParameterExpression paramArray1, lambda.LabelTarget fault)
        {
            lambda.ParameterExpression counter      = lambda.Expression.Variable(typeof(int), "counter");
            lambda.ParameterExpression exc          = lambda.Expression.Variable(typeof(bool), "exc");
            lambda.ParameterExpression row          = lambda.Expression.Variable(typeof(object[]), "row");
            lambda.ParameterExpression ret          = lambda.Expression.Variable(typeof(object[]), "ret");
            lambda.LabelTarget         label        = lambda.Expression.Label(typeof(object));
            lambda.LabelTarget         loclalfault  = lambda.Expression.Label();
            lambda.LabelTarget         loclalsucces = lambda.Expression.Label();

            lambda.BlockExpression foorEachBlock = lambda.Expression.Block(
                new[] { counter, ret, exc },
                lambda.Expression.Assign(exc, lambda.Expression.Constant(false)),
                lambda.Expression.Assign(counter, lambda.Expression.Constant(0)),
                lambda.Expression.Assign(ret, lambda.Expression.Convert(lambda.Expression.ArrayIndex(paramArray1, lambda.Expression.Subtract(lambda.Expression.ArrayLength(paramArray1), lambda.Expression.Constant(1))), typeof(object[]))), // lambda.Expression.NewArrayBounds(typeof(object), lambda.Expression.ArrayLength(paramArray1))),
                lambda.Expression.Loop(lambda.Expression.IfThenElse(
                                           lambda.Expression.LessThan(counter, lambda.Expression.Subtract(lambda.Expression.ArrayLength(paramArray1), lambda.Expression.Constant(1))),
                                           lambda.Expression.Block(
                                               new[] { row },
                                               lambda.Expression.TryCatch(
                                                   lambda.Expression.Block(
                                                       lambda.Expression.Assign(row, lambda.Expression.Convert(lambda.Expression.ArrayIndex(paramArray1, counter), typeof(object[]))),
                                                       lambda.Expression.Assign(lambda.Expression.ArrayAccess(ret, counter), lambda.Expression.Convert(base.Compile(row, loclalfault), typeof(object))),
                                                       lambda.Expression.Goto(loclalsucces),
                                                       lambda.Expression.Label(loclalfault),
                                                       lambda.Expression.Assign(lambda.Expression.ArrayAccess(ret, counter), lambda.Expression.Constant(null)),
                                                       lambda.Expression.Label(loclalsucces),
                                                       ret)
                                                   , lambda.Expression.Catch(typeof(Exception), lambda.Expression.Block(
                                                                                 lambda.Expression.Assign(counter, lambda.Expression.Subtract(lambda.Expression.ArrayLength(paramArray1), lambda.Expression.Constant(1))),
                                                                                 lambda.Expression.Assign(exc, lambda.Expression.Constant(true)),
                                                                                 ret)))
                                               , lambda.Expression.PostIncrementAssign(counter)
                                               ),
                                           lambda.Expression.IfThenElse(exc, lambda.Expression.Goto(fault),
                                                                        lambda.Expression.Break(label, lambda.Expression.Convert(ret, typeof(object))))
                                           ), label)
                );
            return(foorEachBlock);
        }
예제 #47
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            // TODO: Add usage of Protected Execute Flag

            // Save the previous return target
            DLR.LabelTarget oldTarget = scope.ReturnTarget;
            scope.ReturnTarget = DLR.Expression.Label(typeof(AType), "EXIT");

            DLR.Expression protectedCode = DLR.Expression.Label(
                scope.ReturnTarget,
                this.codeblock.Generate(scope)
                );

            // Restore the return target;
            scope.ReturnTarget = oldTarget;

            // Code block contining the strandard execution's result
            // wrapped in a strand
            DLR.Expression block =
                DLR.Expression.Call(
                    typeof(Runtime.Helpers).GetMethod("BuildStrand"),
                    DLR.Expression.NewArrayInit(
                        typeof(AType),
                        // We need to pass in reverse order
                        protectedCode,
                        DLR.Expression.Constant(AInteger.Create(0), typeof(AType))
                        )
                    );

            // Parameter for Catch block
            DLR.ParameterExpression errorVariable = DLR.Expression.Parameter(typeof(Error), "error");

            // Catch block, returns the ([errorcode]; [errortext]) strand
            DLR.CatchBlock catchBlock = DLR.Expression.Catch(
                errorVariable,
                DLR.Expression.Call(
                    typeof(Runtime.Helpers).GetMethod("BuildStrand"),
                    DLR.Expression.NewArrayInit(
                        typeof(AType),
                        // We need to pass in reverse order
                        // Error Text
                        DLR.Expression.Call(
                            typeof(Runtime.Helpers).GetMethod("BuildString"),
                            DLR.Expression.Property(errorVariable, "ErrorText")
                            ),
                        // Error Code
                        DLR.Expression.Call(
                            typeof(AInteger).GetMethod("Create", new Type[] { typeof(int) }),
                            DLR.Expression.Convert(
                                DLR.Expression.Property(errorVariable, "ErrorType"),
                                typeof(int)
                                )
                            )
                        )
                    )
                );

            DLR.Expression result = DLR.Expression.TryCatch(
                block,
                catchBlock
                );

            return(result);
        }
예제 #48
0
 public LoopScope(MSA.Expression /*!*/ redoVariable, MSA.Expression /*!*/ resultVariable, MSA.LabelTarget /*!*/ breakLabel, MSA.LabelTarget /*!*/ continueLabel)
 {
     Assert.NotNull(redoVariable, resultVariable, breakLabel, continueLabel);
     _redoVariable   = redoVariable;
     _resultVariable = resultVariable;
     _breakLabel     = breakLabel;
     _continueLabel  = continueLabel;
 }
예제 #49
0
 public RescueScope(MSA.Expression /*!*/ retryingVariable, MSA.LabelTarget /*!*/ retryLabel)
 {
     Assert.NotNull(retryingVariable, retryLabel);
     _retryingVariable = retryingVariable;
     _retryLabel       = retryLabel;
 }
예제 #50
0
 private static Ex enumeratorConversion(Type to, Ex enumerator, Type eType, LambdaExpression[] converters, Ex[] res, System.Linq.Expressions.LabelTarget end)
 {
     return(Ex.Block(res.Zip(converters, (r, con) =>
                             Ex.Block(
                                 Ex.IfThenElse(
                                     enumerator.Type.GetTypeInfo().GetDeclaredMethod(nameof(IEnumerator.MoveNext)) == null
                         ? Ex.Call(Ex.Convert(enumerator, typeof(IEnumerator)), nameof(IEnumerator.MoveNext), Type.EmptyTypes)
                         : Ex.Call(enumerator, enumerator.Type.GetTypeInfo().GetDeclaredMethod(nameof(IEnumerator.MoveNext))),
                                     Ex.Assign(r, con.ApplyTo(Ex.Property(enumerator, nameof(IEnumerator.Current)))),
                                     Ex.Goto(end, NoResult(to))),
                                 Ex.IfThen(Ex.Not(Ex.Property(r, nameof(IConversionResult.IsSuccessful))),
                                           Ex.Goto(end, NoResult(to)))))));
 }
예제 #51
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            Aplus runtime = scope.GetRuntime();

            LinkedList <DLR.Expression> result = new LinkedList <DLR.Expression>();

            DLR.ParameterExpression scalar    = DLR.Expression.Parameter(typeof(AType), "_ScalarResult_");
            DLR.ParameterExpression counter   = DLR.Expression.Parameter(typeof(int), "COUNTER");
            DLR.ParameterExpression exitValue = DLR.Expression.Parameter(typeof(int), "EXITVALUE");

            DLR.LabelTarget         exitLabel   = DLR.Expression.Label(typeof(AType), "EXIT");
            DLR.ParameterExpression returnValue = DLR.Expression.Parameter(typeof(AType), "RETURN");

            bool incrementMode = true;

            if (this.expression is MonadicFunction &&
                ((MonadicFunction)this.expression).Token.Type == Tokens.EXPONENTIAL)
            {
                // Change the counter's 'way'
                incrementMode = false;
                // Remove the Exponential function
                this.expression = ((MonadicFunction)this.expression).Expression;
            }

            if (this.expression is Assign && ((Assign)this.expression).Target is Identifier)
            {
                scope.IsAssignment = true;
                result.AddFirst(this.expression.Generate(scope));
                scope.IsAssignment = false;

                // Remove the assignment and leave the identifier only
                this.expression = ((Assign)this.expression).Target;
            }

            // Save the previous return target
            DLR.LabelTarget oldTarget = scope.ReturnTarget;

            // Add an return target for the scope
            // this will allow the usage of the Result monadic function
            scope.ReturnTarget = exitLabel;

            if (this.expression is Identifier)
            {
                // Found a case like: VAR do { ... }

                Identifier variable = (Identifier)this.expression;
                // Generate a .Dynamic.Get DLR tree (used multiple times so this saves time)
                DLR.Expression variableGenerated = variable.Generate(scope);
                DLR.Expression variableAsFloat   = DLR.Expression.Property(scalar, "asFloat");

                result.AddLast(DLR.Expression.Block(
                                   new DLR.ParameterExpression[] { counter, exitValue, returnValue, scalar },
                                   // Test if the constant is an integer
                                   DomainTest(variableGenerated, scalar),

                                   DLR.Expression.Assign(exitValue,
                                                         (incrementMode ?
                                                          // EXITVALUE = round(variable.asFloat)
                                                          (DLR.Expression)FloatRounding(variableAsFloat) :
                                                          // EXITVALUE = 0
                                                          (DLR.Expression)DLR.Expression.Constant(0, typeof(int))
                                                         )
                                                         ),
                                   DLR.Expression.Assign(
                                       counter,
                                       (incrementMode ?
                                        (DLR.Expression)DLR.Expression.Constant(0, typeof(int)) :
                                        (DLR.Expression)DLR.Expression.Decrement(FloatRounding(variableAsFloat))
                                       )
                                       ),

                                   // Start the loop
                                   DLR.Expression.Loop(
                                       DLR.Expression.Block(
                                           AST.Assign.GenerateIdentifierAssign(
                                               scope,
                                               variable,
                                               DLR.Expression.Call(typeof(LocalAInteger).GetMethod("Create"), counter),
                                               false,
                                               false
                                               ),
                                           DLR.Expression.IfThen(
                                               (incrementMode ?
                                                // Check if  variable >= EXITVALUE  is true
                                                DLR.Expression.GreaterThanOrEqual(
                                                    counter,
                                                    //DLR.Expression.Property(variableGenerated, "asInteger"),
                                                    exitValue
                                                    ) :
                                                // Check if  EXITVALUE(0) > variable  is true
                                                DLR.Expression.GreaterThan(
                                                    exitValue,
                                                    //DLR.Expression.Property(variableGenerated, "asInteger")
                                                    counter
                                                    )
                                               ),
                                               // The expression was true, exit from the loop with the last value of the expression block
                                               DLR.Expression.Break(exitLabel, returnValue)
                                               ),

                                           // Otherwise run the inner codeblock
                                           DLR.Expression.Assign(returnValue, this.codeblock.Generate(scope)),

                                           // Update counter
                                           (incrementMode ?
                                            // ++counter
                                            DLR.Expression.PreIncrementAssign(counter) :
                                            // --counter
                                            DLR.Expression.PreDecrementAssign(counter)
                                           )

                                           ),
                                       exitLabel
                                       )
                                   ));
            }
            else
            {
                // Simple Iteration
                DLR.ParameterExpression temp = DLR.Expression.Parameter(typeof(AType), "TMP");

                result.AddLast(DLR.Expression.Block(
                                   new DLR.ParameterExpression[] { temp, counter, exitValue, returnValue, scalar },
                                   // Save the iteration count into a temporaly variable
                                   DLR.Expression.Assign(temp, this.expression.Generate(scope)),
                                   // Test if the constant is an integer
                                   DomainTest(temp, scalar),
                                   // MAXVALUE = temp.asInteger
                                   DLR.Expression.Assign(exitValue, FloatRounding(DLR.Expression.Property(scalar, "asFloat"))),
                                   // counter = 0
                                   DLR.Expression.Assign(counter, DLR.Expression.Constant(0, typeof(int))),
                                   // Start the loop
                                   DLR.Expression.Loop(
                                       DLR.Expression.Block(
                                           // Check if  counter >= MAXVALUE  is true
                                           DLR.Expression.IfThen(
                                               DLR.Expression.GreaterThanOrEqual(counter, exitValue),
                                               // The expression was true, exit from the loop with the last calculated value
                                               DLR.Expression.Break(exitLabel, returnValue)
                                               ),
                                           // Otherwise run the inner codeblock, save the block's result
                                           DLR.Expression.Assign(returnValue, this.codeblock.Generate(scope)),
                                           // Increment the counter
                                           DLR.Expression.PreIncrementAssign(counter)
                                           ),
                                       exitLabel
                                       )
                                   ));
            }

            // Restore the return target
            scope.ReturnTarget = oldTarget;

            return(DLR.Expression.Block(result));
        }
 public LoopExpression Update(LabelTarget breakLabel, LabelTarget continueLabel, Expression body)
 {
     return(default(LoopExpression));
 }
예제 #53
0
 private void DumpLabel(LabelTarget target)
 {
     Out(string.Format(CultureInfo.CurrentCulture, ".LabelTarget {0}:", GetLabelTargetName(target)));
 }
예제 #54
0
        internal static MSAst.Expression TransformFor(ScopeStatement parent, MSAst.ParameterExpression enumerator,
                                                      Expression list, Expression left, MSAst.Expression body,
                                                      Statement else_, SourceSpan span, SourceLocation header,
                                                      MSAst.LabelTarget breakLabel, MSAst.LabelTarget continueLabel, bool isStatement)
        {
            // enumerator, isDisposable = Dynamic(GetEnumeratorBinder, list)
            MSAst.Expression init = Ast.Assign(
                enumerator,
                new PythonDynamicExpression1 <KeyValuePair <IEnumerator, IDisposable> >(
                    Binders.UnaryOperationBinder(
                        parent.GlobalParent.PyContext,
                        PythonOperationKind.GetEnumeratorForIteration
                        ),
                    parent.GlobalParent.CompilationMode,
                    AstUtils.Convert(list, typeof(object))
                    )
                );

            // while enumerator.MoveNext():
            //    left = enumerator.Current
            //    body
            // else:
            //    else
            MSAst.Expression ls = AstUtils.Loop(
                parent.GlobalParent.AddDebugInfo(
                    Ast.Call(
                        Ast.Property(
                            enumerator,
                            typeof(KeyValuePair <IEnumerator, IDisposable>).GetProperty("Key")
                            ),
                        typeof(IEnumerator).GetMethod("MoveNext")
                        ),
                    left.Span
                    ),
                null,
                Ast.Block(
                    left.TransformSet(
                        SourceSpan.None,
                        Ast.Call(
                            Ast.Property(
                                enumerator,
                                typeof(KeyValuePair <IEnumerator, IDisposable>).GetProperty("Key")
                                ),
                            typeof(IEnumerator).GetProperty("Current").GetGetMethod()
                            ),
                        PythonOperationKind.None
                        ),
                    body,
                    isStatement ? UpdateLineNumber(parent.GlobalParent.IndexToLocation(list.StartIndex).Line) : AstUtils.Empty(),
                    AstUtils.Empty()
                    ),
                else_,
                breakLabel,
                continueLabel
                );

            return(Ast.Block(
                       init,
                       Ast.TryFinally(
                           ls,
                           Ast.Block(
                               Ast.Call(AstMethods.ForLoopDispose, enumerator),
                               Ast.Assign(enumerator, Ast.New(typeof(KeyValuePair <IEnumerator, IDisposable>)))
                               )
                           )
                       ));
        }
예제 #55
0
        private MSAst.LambdaExpression CreateOuterLambda(Type lambdaType, MSAst.Expression debuggableBody)
        {
            List <MSAst.Expression> bodyExpressions    = new List <MSAst.Expression>();
            List <MSAst.Expression> tryExpressions     = new List <MSAst.Expression>();
            List <MSAst.Expression> finallyExpressions = new List <MSAst.Expression>();

            Type returnType = lambdaType.GetMethod("Invoke").ReturnType;

            MSAst.LabelTarget returnLabelTarget = Ast.Label(returnType);

            // Init $funcInfo
            tryExpressions.Add(
                Ast.Assign(
                    _funcInfo,
                    Ast.Convert(_functionInfo, typeof(FunctionInfo))
                    )
                );

            // Init $traceLocations
            // $TODO: only do this if we're in TracePoints mode
            tryExpressions.Add(
                Ast.Assign(
                    _traceLocations,
                    Ast.Call(typeof(RuntimeOps).GetMethod("GetTraceLocations"), _funcInfo)
                    )
                );

            // Init sourceFile locals
            foreach (var entry in _sourceFilesMap)
            {
                tryExpressions.Add(
                    Ast.Assign(
                        entry.Value,
                        Ast.Constant(entry.Key, typeof(DebugSourceFile))
                        )
                    );
            }

            if (_noPushFrameOptimization)
            {
                tryExpressions.Add(_pushFrame);
            }

            tryExpressions.Add(Ast.Call(
                                   typeof(RuntimeOps).GetMethod("OnFrameEnterTraceEvent"),
                                   _thread
                                   ));

            var frameExit = AstUtils.If(
                Ast.Equal(
                    _debugMarkerLocationMap.Length > 0 ?
                    Ast.Property(_sourceFilesMap[_debugMarkerLocationMap[0].SourceFile], "Mode") :
                    _globalDebugMode,
                    AstUtils.Constant((int)DebugMode.FullyEnabled)
                    ),
                Ast.Call(
                    typeof(RuntimeOps).GetMethod("OnFrameExitTraceEvent"),
                    _thread,
                    _debugMarker,
                    _retVal != null ? (MSAst.Expression)Ast.Convert(_retVal, typeof(object)) : Ast.Constant(null)
                    )
                );

            // normal exit
            tryExpressions.Add(
                Ast.Block(
                    _retVal != null ? Ast.Assign(_retVal, debuggableBody) : debuggableBody,
                    Ast.Assign(_frameExitException, Ast.Constant(true)),
                    frameExit)
                );

            tryExpressions.Add(
                _retVal != null ? (MSAst.Expression)Ast.Return(returnLabelTarget, _retVal) : Ast.Empty()
                );

            MSAst.Expression[] popFrame = new MSAst.Expression[] {
                AstUtils.If(
                    // Fire thead-exit event if PopFrame returns true
                    Ast.AndAlso(
                        Ast.Equal(Ast.Call(typeof(RuntimeOps).GetMethod("PopFrame"), _thread), Ast.Constant(true)),
                        Ast.Equal(_globalDebugMode, AstUtils.Constant((int)DebugMode.FullyEnabled))
                        ),
                    Ast.Call(
                        typeof(RuntimeOps).GetMethod("OnThreadExitEvent"),
                        _thread
                        )
                    )
            };

            if (_noPushFrameOptimization)
            {
                finallyExpressions.AddRange(popFrame);
            }
            else
            {
                finallyExpressions.Add(
                    AstUtils.If(
                        Ast.Equal(_framePushed, Ast.Constant(true)),
                        popFrame
                        )
                    );
            }

            MSAst.ParameterExpression caughtException;

            // Run the function body
            bodyExpressions.Add(Ast.TryCatchFinally(
                                    Ast.TryCatch(
                                        Ast.Block(
                                            ArrayUtils.Append(tryExpressions.ToArray(), Ast.Default(returnType))
                                            ),
                                        Ast.Catch(
                                            caughtException = Ast.Variable(typeof(Exception), "$caughtException"),
                                            Ast.Block(
                                                // The expressions below will always throw.
                                                // If the exception needs to be cancelled then OnTraceEvent will throw ForceToGeneratorLoopException.
                                                // If the exception is not being cancelled then we'll just rethrow at the end of the catch block.
                                                AstUtils.If(
                                                    Ast.Not(
                                                        Ast.TypeIs(
                                                            caughtException,
                                                            typeof(ForceToGeneratorLoopException)
                                                            )
                                                        ),
                                                    AstUtils.If(
                                                        Ast.NotEqual(_globalDebugMode, AstUtils.Constant((int)DebugMode.Disabled)),
                                                        _noPushFrameOptimization ? Ast.Empty() : _conditionalPushFrame,
                                                        Ast.Call(
                                                            typeof(RuntimeOps).GetMethod("OnTraceEventUnwind"),
                                                            _thread,
                                                            _debugMarker,
                                                            caughtException
                                                            )
                                                        ),
                                                    // exception exit
                                                    AstUtils.If(
                                                        Ast.Not(_frameExitException),
                                                        frameExit
                                                        )
                                                    ),

                                                Ast.Rethrow(),

                                                // Ensuring that the catch block is of the same type as the try block
                                                Ast.Default(returnType)
                                                )
                                            )
                                        ),
                                    Ast.Block(finallyExpressions),
                                    Ast.Catch(
                                        typeof(ForceToGeneratorLoopException),
                                        Ast.TryFinally(
                                            // Handle ForceToGeneratorLoopException
                                            Ast.Block(
                                                returnType != typeof(void) ? Ast.Block(
                                                    Ast.Assign(
                                                        _retValFromGeneratorLoop,
                                                        Ast.Call(
                                                            typeof(RuntimeOps).GetMethod("GeneratorLoopProc"),
                                                            _thread
                                                            )
                                                        ),
                                                    AstUtils.If(
                                                        Ast.NotEqual(
                                                            _retValFromGeneratorLoop,
                                                            Ast.Constant(null)
                                                            ),
                                                        Ast.Assign(_retVal, Ast.Convert(_retValFromGeneratorLoop, returnType)),
                                                        Ast.Return(
                                                            returnLabelTarget,
                                                            Ast.Convert(_retValFromGeneratorLoop, returnType)
                                                            )
                                                        ).Else(
                                                        Ast.Assign(_retVal, Ast.Default(returnType)),
                                                        Ast.Return(
                                                            returnLabelTarget,
                                                            Ast.Default(returnType)
                                                            )
                                                        )
                                                    ) :
                                                Ast.Block(
                                                    Ast.Call(
                                                        typeof(RuntimeOps).GetMethod("GeneratorLoopProc"),
                                                        _thread
                                                        ),
                                                    Ast.Return(returnLabelTarget)
                                                    )
                                                ,
                                                // Ensuring that the catch block is of the same type as the try block
                                                Ast.Default(returnType)
                                                ),
                                            // Make sure that the debugMarker is up-to-date after the generator loop
                                            Ast.Assign(
                                                _debugMarker,
                                                Ast.Call(
                                                    typeof(RuntimeOps).GetMethod("GetCurrentSequencePointForLeafGeneratorFrame"),
                                                    _thread
                                                    )
                                                )
                                            )
                                        )
                                    ));

            MSAst.Expression body = Ast.Block(bodyExpressions);

            if (body.Type == typeof(void) && returnType != typeof(void))
            {
                body = Ast.Block(body, Ast.Default(returnType));
            }

            return(Ast.Lambda(
                       lambdaType,
                       Ast.Block(
                           _lambdaVars,
                           Ast.Label(returnLabelTarget, body)
                           ),
                       _alias,
                       _lambdaParams));
        }
예제 #56
0
        private static DLR.Expression BuildDyadicCase(
            Token functionToken,
            DLR.LabelTarget returnTarget,
            DLR.Expression environment,
            DLR.Expression rightParam,
            DLR.Expression leftParam)
        {
            DLR.Expression result;
            MethodInfo     method = typeof(AbstractDyadicFunction).GetMethod("Execute");

            if (functionToken.Type == Tokens.TYPE)
            {
                result = DLR.Expression.IfThenElse(
                    // $left.IsNumber || ($left.Type == ATypes.ANull)
                    DLR.Expression.OrElse(
                        DLR.Expression.IsTrue(
                            DLR.Expression.PropertyOrField(leftParam, "IsNumber")
                            ),
                        DLR.Expression.Equal(
                            DLR.Expression.PropertyOrField(leftParam, "Type"),
                            DLR.Expression.Constant(ATypes.ANull)
                            )
                        ),
                    // Or($right, $left)
                    DLR.Expression.Goto(
                        returnTarget,
                        DLR.Expression.Call(
                            DLR.Expression.Constant(DyadicFunctionInstance.Or),
                            method,
                            rightParam, leftParam, environment
                            )
                        ),
                    // Cast($right, $left)
                    DLR.Expression.Goto(
                        returnTarget,
                        DLR.Expression.Call(
                            DLR.Expression.Constant(DyadicFunctionInstance.Cast),
                            method,
                            rightParam, leftParam, environment
                            )
                        )
                    );
            }
            else
            {
                MethodChooser.ConvertToDyadicToken(functionToken);
                AbstractDyadicFunction dyadic = MethodChooser.GetDyadicMethod(functionToken);

                if (dyadic != null)
                {
                    result =
                        DLR.Expression.Goto(
                            returnTarget,
                            DLR.Expression.Call(
                                DLR.Expression.Constant(dyadic),
                                method,
                                rightParam,
                                leftParam,
                                environment
                                )
                            );
                }
                else
                {
                    result =
                        DLR.Expression.Throw(
                            DLR.Expression.New(
                                typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }),
                                DLR.Expression.Constant(functionToken.Text)
                                )
                            );
                }
            }

            return(result);
        }
예제 #57
0
 /// <summary>
 ///     Creates a <see cref="LabelExpression" /> representing a label with the given default value.
 /// </summary>
 /// <param name="target">The <see cref="LabelTarget" /> which this <see cref="LabelExpression" /> will be associated with.</param>
 /// <param name="defaultValue">
 ///     The value of this <see cref="LabelExpression" /> when the label is reached through normal
 ///     control flow.
 /// </param>
 /// <returns>A <see cref="LabelExpression" /> with the given default value.</returns>
 public static LabelExpression Label(LabelTarget target, Expression defaultValue)
 {
     ValidateGoto(target, ref defaultValue, nameof(target), nameof(defaultValue), null);
     return(new LabelExpression(target, defaultValue));
 }
예제 #58
0
 internal LoopExpression(Expression body, LabelTarget @break, LabelTarget @continue)
 {
     _body     = body;
     _break    = @break;
     _continue = @continue;
 }
예제 #59
0
 public static MSA.Expression /*!*/ Infinite(MSA.LabelTarget @break, MSA.LabelTarget @continue, params MSA.Expression[] /*!*/ body)
 {
     return(AstUtils.Infinite(Ast.Block(body), @break, @continue));
 }
예제 #60
0
 internal virtual lambda.Expression Compile(lambda.Expression[] param, lambda.LabelTarget fault)
 {
     throw new EvaluateException("Syntax Error");
 }