public override MSAst.Expression Reduce() { return(GlobalParent.Operation( typeof(object), PythonOperatorToOperatorString(_op), _expression )); }
private MSAst.Expression MakeBinaryOperation(PythonOperator op, MSAst.Expression left, MSAst.Expression right, SourceSpan span) { if (op == PythonOperator.NotIn) { return(AstUtils.Convert( Ast.Not( GlobalParent.Operation( typeof(bool), PythonOperationKind.Contains, left, right ) ), typeof(object) )); } else if (op == PythonOperator.In) { return(AstUtils.Convert( GlobalParent.Operation( typeof(bool), PythonOperationKind.Contains, left, right ), typeof(object) )); } PythonOperationKind action = PythonOperatorToAction(op); if (action != PythonOperationKind.None) { return(GlobalParent.Operation( typeof(object), action, left, right )); } else { // Call helper method return(Ast.Call( GetHelperMethod(op), ConvertIfNeeded(left, typeof(object)), ConvertIfNeeded(right, typeof(object)) )); } }
private MSAst.Expression SetMemberOperator(MSAst.Expression right, PythonOperationKind op, MSAst.ParameterExpression temp) { return(GlobalParent.Set( _name, temp, GlobalParent.Operation( typeof(object), op, GlobalParent.Get( _name, temp ), right ) )); }
internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op) { if (op != PythonOperationKind.None) { right = GlobalParent.Operation( typeof(object), op, this, right ); } MSAst.Expression index = IsSlice ? GlobalParent.SetSlice(GetActionArgumentsForSet(right)) : GlobalParent.SetIndex(GetActionArgumentsForSet(right)); return(GlobalParent.AddDebugInfoAndVoid(index, Span)); }
internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op) { MSAst.Expression assignment; if (op != PythonOperationKind.None) { right = GlobalParent.Operation( typeof(object), op, this, right ); } SourceSpan aspan = span.IsValid ? new SourceSpan(Span.Start, span.End) : SourceSpan.None; if (Reference.PythonVariable != null) { assignment = AssignValue( Parent.GetVariableExpression(Reference.PythonVariable), ConvertIfNeeded(right, typeof(object)) ); } else { assignment = Ast.Call( null, AstMethods.SetName, Parent.LocalContext, Ast.Constant(Name), AstUtils.Convert(right, typeof(object)) ); } return(GlobalParent.AddDebugInfoAndVoid(assignment, aspan)); }
/// <summary> /// WithStatement is translated to the DLR AST equivalent to /// the following Python code snippet (from with statement spec): /// /// mgr = (EXPR) /// exit = mgr.__exit__ # Not calling it yet /// value = mgr.__enter__() /// exc = True /// try: /// VAR = value # Only if "as VAR" is present /// BLOCK /// except: /// # The exceptional case is handled here /// exc = False /// if not exit(*sys.exc_info()): /// raise /// # The exception is swallowed if exit() returns true /// finally: /// # The normal and non-local-goto cases are handled here /// if exc: /// exit(None, None, None) /// /// </summary> public override MSAst.Expression Reduce() { // Five statements in the result... ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(6); ReadOnlyCollectionBuilder <MSAst.ParameterExpression> variables = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(6); MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with"); variables.Add(lineUpdated); //****************************************************************** // 1. mgr = (EXPR) //****************************************************************** MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager"); variables.Add(manager); statements.Add( GlobalParent.AddDebugInfo( Ast.Assign( manager, _contextManager ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 2. exit = mgr.__exit__ # Not calling it yet //****************************************************************** MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit"); variables.Add(exit); statements.Add( MakeAssignment( exit, GlobalParent.Get( "__exit__", manager ) ) ); //****************************************************************** // 3. value = mgr.__enter__() //****************************************************************** MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value"); variables.Add(value); statements.Add( GlobalParent.AddDebugInfoAndVoid( MakeAssignment( value, Parent.Invoke( new CallSignature(0), Parent.LocalContext, GlobalParent.Get( "__enter__", manager ) ) ), new SourceSpan(Start, _header) ) ); //****************************************************************** // 4. exc = True //****************************************************************** MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc"); variables.Add(exc); statements.Add( MakeAssignment( exc, AstUtils.Constant(true) ) ); //****************************************************************** // 5. The final try statement: // // try: // VAR = value # Only if "as VAR" is present // BLOCK // except: // # The exceptional case is handled here // exc = False // if not exit(*sys.exc_info()): // raise // # The exception is swallowed if exit() returns true // finally: // # The normal and non-local-goto cases are handled here // if exc: // exit(None, None, None) //****************************************************************** MSAst.ParameterExpression exception; MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List <DynamicStackFrame>), "$nestedFrames"); variables.Add(nestedFrames); statements.Add( // try: AstUtils.Try( AstUtils.Try(// try statement body PushLineUpdated(false, lineUpdated), _var != null ? (MSAst.Expression)Ast.Block( // VAR = value _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None), // BLOCK _body, AstUtils.Empty() ) : // BLOCK (MSAst.Expression)_body // except:, // try statement location ).Catch(exception = Ast.Variable(typeof(Exception), "exception"), // Python specific exception handling code TryStatement.GetTracebackHeader( this, exception, GlobalParent.AddDebugInfoAndVoid( Ast.Block( // exc = False MakeAssignment( exc, AstUtils.Constant(false) ), Ast.Assign( nestedFrames, Ast.Call(AstMethods.GetAndClearDynamicStackFrames) ), // if not exit(*sys.exc_info()): // raise AstUtils.IfThen( GlobalParent.Convert( typeof(bool), ConversionResultKind.ExplicitCast, GlobalParent.Operation( typeof(bool), PythonOperationKind.IsFalse, MakeExitCall(exit, exception) ) ), UpdateLineUpdated(true), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), Ast.Throw( Ast.Call( AstMethods.MakeRethrowExceptionWorker, exception ) ) ) ), _body.Span ) ), Ast.Call( AstMethods.SetDynamicStackFrames, nestedFrames ), PopLineUpdated(lineUpdated), Ast.Empty() ) // finally: ).Finally( // if exc: // exit(None, None, None) AstUtils.IfThen( exc, GlobalParent.AddDebugInfoAndVoid( Ast.Block( Ast.Dynamic( GlobalParent.PyContext.Invoke( new CallSignature(3) // signature doesn't include function ), typeof(object), new MSAst.Expression[] { Parent.LocalContext, exit, AstUtils.Constant(null), AstUtils.Constant(null), AstUtils.Constant(null) } ), Ast.Empty() ), _contextManager.Span ) ) ) ); statements.Add(AstUtils.Empty()); return(Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection())); }
private MSAst.Expression MakeBinaryOperation(PythonOperator op, MSAst.Expression left, MSAst.Expression right, SourceSpan span) { if (op == PythonOperator.NotIn) { return(AstUtils.Convert( Ast.Not( GlobalParent.Operation( typeof(bool), PythonOperationKind.Contains, left, right ) ), typeof(object) )); } else if (op == PythonOperator.In) { return(AstUtils.Convert( GlobalParent.Operation( typeof(bool), PythonOperationKind.Contains, left, right ), typeof(object) )); } PythonOperationKind action = PythonOperatorToAction(op); if (action != PythonOperationKind.None) { // Create action expression if (CanEmitWarning(op)) { MSAst.ParameterExpression tempLeft = Ast.Parameter(left.Type, "left"); MSAst.ParameterExpression tempRight = Ast.Parameter(right.Type, "right"); return(Ast.Block( new[] { tempLeft, tempRight }, Ast.Call( AstMethods.WarnDivision, Parent.LocalContext, AstUtils.Constant(GlobalParent.DivisionOptions), AstUtils.Convert( Ast.Assign(tempLeft, left), typeof(object) ), AstUtils.Convert( Ast.Assign(tempRight, right), typeof(object) ) ), GlobalParent.Operation( typeof(object), action, tempLeft, tempRight ) )); } return(GlobalParent.Operation( typeof(object), action, left, right )); } else { // Call helper method return(Ast.Call( GetHelperMethod(op), ConvertIfNeeded(left, typeof(object)), ConvertIfNeeded(right, typeof(object)) )); } }