internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op) { if (op == PythonOperationKind.None) { return(GlobalParent.AddDebugInfoAndVoid( GlobalParent.Set( _name, _target, right ), span )); } else { MSAst.ParameterExpression temp = Ast.Variable(typeof(object), "inplace"); return(GlobalParent.AddDebugInfo( Ast.Block( new[] { temp }, Ast.Assign(temp, _target), SetMemberOperator(right, op, temp), AstUtils.Empty() ), Span.Start, span.End )); } }
public override MSAst.Expression Reduce() { // If debugging is off, return empty statement if (Optimize) { return(AstUtils.Empty()); } // Transform into: // if (_test) { // } else { // RaiseAssertionError(_message); // } return(GlobalParent.AddDebugInfoAndVoid( AstUtils.Unless( // if TransformAndDynamicConvert(_test, typeof(bool)), // _test Ast.Call( // else branch AstMethods.RaiseAssertionError, Parent.LocalContext, TransformOrConstantNull(_message, typeof(object)) ) ), Span )); }
public override MSAst.Expression Reduce() { ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); for (int i = 0; i < _names.Length; i++) { statements.Add( // _references[i] = PythonOps.Import(<code context>, _names[i]) GlobalParent.AddDebugInfoAndVoid( AssignValue( Parent.GetVariableExpression(_variables[i]), LightExceptions.CheckAndThrow( Expression.Call( _asNames[i] == null ? AstMethods.ImportTop : AstMethods.ImportBottom, Parent.LocalContext, // 1st arg - code context AstUtils.Constant(_names[i].MakeString()), // 2nd arg - module name AstUtils.Constant(_forceAbsolute ? 0 : -1) // 3rd arg - absolute or relative imports ) ) ), _names[i].Span ) ); } statements.Add(AstUtils.Empty()); return(GlobalParent.AddDebugInfo(Ast.Block(statements.ToReadOnlyCollection()), Span)); }
public override MSAst.Expression Reduce() { if (_statements.Length == 0) { return(GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span)); } ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); int curStart = -1; foreach (var statement in _statements) { // CPython debugging treats multiple statements on the same line as a single step, we // match that behavior here. int newline = GlobalParent.IndexToLocation(statement.StartIndex).Line; if (newline == curStart) { statements.Add(new DebugInfoRemovalExpression(statement, curStart)); } else { if (statement.CanThrow && newline != -1) { statements.Add(UpdateLineNumber(newline)); } statements.Add(statement); } curStart = newline; } return(Ast.Block(statements.ToReadOnlyCollection())); }
private MSAst.Expression ReduceWorker(bool optimizeDynamicConvert) { MSAst.Expression result; if (_else != null) { result = _else; } else { result = AstUtils.Empty(); } // Now build from the inside out int i = _tests.Length; while (i-- > 0) { IfStatementTest ist = _tests[i]; result = GlobalParent.AddDebugInfoAndVoid( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), TransformMaybeSingleLineSuite(ist.Body, ist.Test.Start), result ), new SourceSpan(ist.Start, ist.Header) ); } return(result); }
public override MSAst.Expression Reduce() { Debug.Assert(_variable != null, "Shouldn't be called by lambda expression"); MSAst.Expression function = MakeFunctionExpression(); return(GlobalParent.AddDebugInfoAndVoid(AssignValue(Parent.GetVariableExpression(_variable), function), new SourceSpan(Start, Header))); }
internal override MSAst.Expression Transform(MSAst.Expression body) { return(GlobalParent.AddDebugInfoAndVoid( AstUtils.If( GlobalParent.Convert(typeof(bool), ConversionResultKind.ExplicitCast, _test), body ), Span )); }
private MSAst.Expression ReduceWorker(bool optimizeDynamicConvert) { // Only the body is "in the loop" for the purposes of break/continue // The "else" clause is outside ConstantExpression constTest = _test as ConstantExpression; if (constTest != null && constTest.Value is int) { // while 0: / while 1: int val = (int)constTest.Value; if (val == 0) { // completely optimize the loop away if (_else == null) { return(MSAst.Expression.Empty()); } else { return(_else); } } MSAst.Expression test = MSAst.Expression.Constant(true); MSAst.Expression res = AstUtils.While( test, _body, _else, _break, _continue ); if (GlobalParent.IndexToLocation(_test.StartIndex).Line != GlobalParent.IndexToLocation(_body.StartIndex).Line) { res = GlobalParent.AddDebugInfoAndVoid(res, _test.Span); } return(res); } return(AstUtils.While( GlobalParent.AddDebugInfo( optimizeDynamicConvert ? TransformAndDynamicConvert(_test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, _test), Header ), _body, _else, _break, _continue )); }
private MSAst.Expression ReduceWorker(MSAst.Expression expression) { if (Parent.PrintExpressions) { expression = Ast.Call( AstMethods.PrintExpressionValue, Parent.LocalContext, ConvertIfNeeded(expression, typeof(object)) ); } return(GlobalParent.AddDebugInfoAndVoid(expression, _expression.Span)); }
internal override MSAst.Expression TransformDelete() { MSAst.Expression index; if (IsSlice) { index = GlobalParent.DeleteSlice(GetActionArgumentsForGetOrDelete()); } else { index = GlobalParent.DeleteIndex(GetActionArgumentsForGetOrDelete()); } return(GlobalParent.AddDebugInfoAndVoid(index, Span)); }
private MSAst.Expression AssignOne() { Debug.Assert(_left.Length == 1); SequenceExpression seLeft = _left[0] as SequenceExpression; SequenceExpression seRight = _right as SequenceExpression; bool isStarred = seLeft != null && seLeft.Items.OfType <StarredExpression>().Any(); if (!isStarred && seLeft != null && seRight != null && seLeft.Items.Count == seRight.Items.Count) { int cnt = seLeft.Items.Count; // a, b = 1, 2, or [a,b] = 1,2 - not something like a, b = range(2) // we can do a fast parallel assignment MSAst.ParameterExpression[] tmps = new MSAst.ParameterExpression[cnt]; MSAst.Expression[] body = new MSAst.Expression[cnt * 2 + 1]; // generate the body, the 1st n are the temporary assigns, the // last n are the assignments to the left hand side // 0: tmp0 = right[0] // ... // n-1: tmpn-1 = right[n-1] // n: right[0] = tmp0 // ... // n+n-1: right[n-1] = tmpn-1 // allocate the temps first before transforming so we don't pick up a bad temp... for (int i = 0; i < cnt; i++) { MSAst.Expression tmpVal = seRight.Items[i]; tmps[i] = Ast.Variable(tmpVal.Type, "parallelAssign"); body[i] = Ast.Assign(tmps[i], tmpVal); } // then transform which can allocate more temps for (int i = 0; i < cnt; i++) { body[i + cnt] = seLeft.Items[i].TransformSet(SourceSpan.None, tmps[i], PythonOperationKind.None); } // 4. Create and return the resulting suite body[cnt * 2] = AstUtils.Empty(); return(GlobalParent.AddDebugInfoAndVoid(Ast.Block(tmps, body), Span)); } return(_left[0].TransformSet(Span, _right, PythonOperationKind.None)); }
public override MSAst.Expression Reduce() { var codeObj = GetOrMakeFunctionCode(); var funcCode = GlobalParent.Constant(codeObj); FuncCodeExpr = funcCode; MSAst.Expression lambda; if (EmitDebugSymbols) { lambda = GetLambda(); } else { lambda = NullLambda; ThreadPool.QueueUserWorkItem((x) => { // class defs are almost always run, so start // compiling the code now so it might be ready // when we actually go and execute it codeObj.UpdateDelegate(PyContext, true); }); } MSAst.Expression classDef = Ast.Call( AstMethods.MakeClass, funcCode, lambda, Parent.LocalContext, AstUtils.Constant(_name), Ast.NewArrayInit( typeof(object), ToObjectArray(_bases) ), Metaclass is null ? AstUtils.Constant(null, typeof(object)) : AstUtils.Convert(Metaclass, typeof(object)), AstUtils.Constant(FindSelfNames()) ); classDef = AddDecorators(classDef, Decorators); return(GlobalParent.AddDebugInfoAndVoid( AssignValue(Parent.GetVariableExpression(PythonVariable), classDef), new SourceSpan( GlobalParent.IndexToLocation(StartIndex), GlobalParent.IndexToLocation(HeaderIndex) ) )); }
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)); }
private MSAst.Expression AssignComplex(MSAst.Expression right) { // Python assignment semantics: // - only evaluate RHS once. // - evaluates assignment from left to right // - does not evaluate getters. // // So // a=b[c]=d=f() // should be: // $temp = f() // a = $temp // b[c] = $temp // d = $temp List <MSAst.Expression> statements = new List <MSAst.Expression>(); // 1. Create temp variable for the right value MSAst.ParameterExpression right_temp = Expression.Variable(typeof(object), "assignment"); // 2. right_temp = right statements.Add(MakeAssignment(right_temp, right)); // Do left to right assignment foreach (Expression e in _left) { if (e == null) { continue; } // 3. e = right_temp MSAst.Expression transformed = e.TransformSet(Span, right_temp, PythonOperationKind.None); statements.Add(transformed); } // 4. Create and return the resulting suite statements.Add(AstUtils.Empty()); return(GlobalParent.AddDebugInfoAndVoid( Ast.Block(new[] { right_temp }, statements.ToArray()), 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)); }
private MSAst.Expression ReduceWorker(bool optimizeDynamicConvert) { MSAst.Expression result; if (_tests.Length > 100) { // generate: // if(x) { // body // goto end // } else { // } // elseBody // end: // // to avoid deeply recursive trees which can stack overflow. var builder = new ReadOnlyCollectionBuilder <MSAst.Expression>(); var label = Ast.Label(); for (int i = 0; i < _tests.Length; i++) { IfStatementTest ist = _tests[i]; builder.Add( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), Ast.Block( TransformMaybeSingleLineSuite(ist.Body, ist.Test.Start), Ast.Goto(label) ), AstUtils.Empty() ) ); } if (_else != null) { builder.Add(_else); } builder.Add(Ast.Label(label)); result = Ast.Block(builder); } else { // Now build from the inside out if (_else != null) { result = _else; } else { result = AstUtils.Empty(); } int i = _tests.Length; while (i-- > 0) { IfStatementTest ist = _tests[i]; result = GlobalParent.AddDebugInfoAndVoid( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), TransformMaybeSingleLineSuite(ist.Body, ist.Test.Start), result ), new SourceSpan(ist.Start, ist.Header) ); } } return(result); }
/// <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())); }
public override MSAst.Expression Reduce() { if (_names == _star) { // from a[.b] import * return(GlobalParent.AddDebugInfo( Ast.Call( AstMethods.ImportStar, Parent.LocalContext, AstUtils.Constant(_root.MakeString()), AstUtils.Constant(GetLevel()) ), Span )); } else { // from a[.b] import x [as xx], [ y [ as yy] ] [ , ... ] ReadOnlyCollectionBuilder <MSAst.Expression> statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(); MSAst.ParameterExpression module = Ast.Variable(typeof(object), "module"); // Create initializer of the array of names being passed to ImportWithNames MSAst.Expression[] names = new MSAst.Expression[_names.Length]; for (int i = 0; i < names.Length; i++) { names[i] = AstUtils.Constant(_names[i]); } // module = PythonOps.ImportWithNames(<context>, _root, make_array(_names)) statements.Add( GlobalParent.AddDebugInfoAndVoid( AssignValue( module, LightExceptions.CheckAndThrow( Expression.Call( AstMethods.ImportWithNames, Parent.LocalContext, AstUtils.Constant(_root.MakeString()), Ast.NewArrayInit(typeof(string), names), AstUtils.Constant(GetLevel()) ) ) ), _root.Span ) ); // now load all the names being imported and assign the variables for (int i = 0; i < names.Length; i++) { statements.Add( GlobalParent.AddDebugInfoAndVoid( AssignValue( Parent.GetVariableExpression(_variables[i]), Ast.Call( AstMethods.ImportFrom, Parent.LocalContext, module, names[i] ) ), Span ) ); } statements.Add(AstUtils.Empty()); return(GlobalParent.AddDebugInfo(Ast.Block(new[] { module }, statements.ToArray()), Span)); } }
public override MSAst.Expression Reduce() { return(GlobalParent.AddDebugInfoAndVoid(AstUtils.Empty(), Span)); }
internal MSAst.Expression MakeAssignment(MSAst.ParameterExpression variable, MSAst.Expression right, SourceSpan span) { return(GlobalParent.AddDebugInfoAndVoid(Ast.Assign(variable, AstUtils.Convert(right, variable.Type)), span)); }