internal override MSAst.Expression Transform(AstGenerator ag) { MSAst.MethodCallExpression call; if (_locals == null && _globals == null) { // exec code call = Ast.Call( AstGenerator.GetHelperMethod("UnqualifiedExec"), AstUtils.CodeContext(), ag.TransformAsObject(_code) ); } else { // exec code in globals [ , locals ] // We must have globals now (locals is last and may be absent) Debug.Assert(_globals != null); call = Ast.Call( AstGenerator.GetHelperMethod("QualifiedExec"), AstUtils.CodeContext(), ag.TransformAsObject(_code), ag.TransformAndDynamicConvert(_globals, typeof(IAttributesCollection)), ag.TransformOrConstantNull(_locals, typeof(object)) ); } return ag.AddDebugInfo(call, Span); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { return Ast.Call( AstGenerator.GetHelperMethod("Repr"), // method Microsoft.Scripting.Ast.Utils.CodeContext(), ag.TransformAsObject(_expression) // args ); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { MSAst.ParameterExpression list = ag.GetTemporary("list_comprehension_list", typeof(List)); // 1. Initialization code - create list and store it in the temp variable MSAst.Expression initialize = Ast.Assign( list, Ast.Call( AstGenerator.GetHelperMethod("MakeList", Type.EmptyTypes) // method ) ); // 2. Create body from _item: list.Append(_item) MSAst.Expression body = ag.AddDebugInfo( Ast.Call( AstGenerator.GetHelperMethod("ListAddForComprehension"), list, ag.TransformAsObject(_item) ), _item.Span ); // 3. Transform all iterators in reverse order, building the true body: int current = _iterators.Length; while (current-- > 0) { ListComprehensionIterator iterator = _iterators[current]; body = iterator.Transform(ag, body); } return Ast.Block( initialize, body, list // result ); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { return Ast.Call( AstGenerator.GetHelperMethod("Repr"), // method ag.LocalContext, ag.TransformAsObject(_expression) // args ); }
internal override MSAst.Expression Transform(AstGenerator ag) { MSAst.Expression destination = ag.TransformAsObject(_dest); if (_expressions.Length == 0) { MSAst.Expression result; if (destination != null) { result = Ast.Call( AstGenerator.GetHelperMethod("PrintNewlineWithDest"), ag.LocalContext, destination ); } else { result = Ast.Call( AstGenerator.GetHelperMethod("PrintNewline"), ag.LocalContext ); } return ag.AddDebugInfo(result, Span); } else { // Create list for the individual statements List<MSAst.Expression> statements = new List<MSAst.Expression>(); // Store destination in a temp, if we have one if (destination != null) { MSAst.ParameterExpression temp = ag.GetTemporary("destination"); statements.Add( ag.MakeAssignment(temp, destination) ); destination = temp; } for (int i = 0; i < _expressions.Length; i++) { string method = (i < _expressions.Length - 1 || _trailingComma) ? "PrintComma" : "Print"; Expression current = _expressions[i]; MSAst.MethodCallExpression mce; if (destination != null) { mce = Ast.Call( AstGenerator.GetHelperMethod(method + "WithDest"), ag.LocalContext, destination, ag.TransformAsObject(current) ); } else { mce = Ast.Call( AstGenerator.GetHelperMethod(method), ag.LocalContext, ag.TransformAsObject(current) ); } statements.Add(mce); } statements.Add(AstUtils.Empty()); return ag.AddDebugInfo(Ast.Block(statements.ToArray()), Span); } }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { MSAst.Expression func = _function.TransformToFunctionExpression(ag); return Ast.Call( AstGenerator.GetHelperMethod("MakeGeneratorExpression"), func, ag.TransformAsObject(_iterable) ); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { MSAst.Expression func = _function.TransformToFunctionExpression(ag); return ag.Invoke( typeof(object), new CallSignature(1), func, ag.TransformAsObject(_iterable) ); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { MSAst.Expression func = _function.TransformToFunctionExpression(ag); Debug.Assert(func.Type == typeof(PythonFunction)); // Generator expressions always return functions. We could do even better here when all PythonFunction's are in the same class. return Binders.Invoke( ag.BinderState, typeof(object), new CallSignature(1), func, ag.TransformAsObject(_iterable) ); }
internal static MSAst.Expression TransformForStatement(AstGenerator ag, MSAst.ParameterExpression enumerator, Expression list, Expression left, MSAst.Expression body, Statement else_, SourceSpan span, SourceLocation header, MSAst.LabelTarget breakLabel, MSAst.LabelTarget continueLabel) { // enumerator = PythonOps.GetEnumeratorForIteration(list) MSAst.Expression init = Ast.Assign( enumerator, ag.Operation( typeof(IEnumerator), PythonOperationKind.GetEnumeratorForIteration, ag.TransformAsObject(list) ) ); // while enumerator.MoveNext(): // left = enumerator.Current // body // else: // else MSAst.Expression ls = AstUtils.Loop( ag.AddDebugInfo(Ast.Call( enumerator, typeof(IEnumerator).GetMethod("MoveNext") ), left.Span), null, Ast.Block( left.TransformSet( ag, SourceSpan.None, Ast.Call( enumerator, typeof(IEnumerator).GetProperty("Current").GetGetMethod() ), PythonOperationKind.None ), body, ag.UpdateLineNumber(list.Start.Line), AstUtils.Empty() ), ag.Transform(else_), breakLabel, continueLabel ); return Ast.Block( init, ls, AstUtils.Empty() ); }
/// <summary> /// Transform multiple python except handlers for a try block into a single catch body. /// </summary> /// <param name="ag"></param> /// <param name="variable">The variable for the exception in the catch block.</param> /// <returns>Null if there are no except handlers. Else the statement to go inside the catch handler</returns> private MSAst.Expression TransformHandlers(AstGenerator ag, out MSAst.ParameterExpression variable) { if (_handlers == null || _handlers.Length == 0) { variable = null; return null; } MSAst.ParameterExpression exception = ag.GetTemporary("exception", typeof(Exception)); MSAst.ParameterExpression extracted = ag.GetTemporary("extracted", typeof(object)); // The variable where the runtime will store the exception. variable = exception; var tests = new List<Microsoft.Scripting.Ast.IfStatementTest>(_handlers.Length); MSAst.ParameterExpression converted = null; MSAst.Expression catchAll = null; for (int index = 0; index < _handlers.Length; index++) { TryStatementHandler tsh = _handlers[index]; if (tsh.Test != null) { Microsoft.Scripting.Ast.IfStatementTest ist; // translating: // except Test ... // // generate following AST for the Test (common part): // CheckException(exception, Test) MSAst.Expression test = Ast.Call( AstGenerator.GetHelperMethod("CheckException"), extracted, ag.TransformAsObject(tsh.Test) ); if (tsh.Target != null) { // translating: // except Test, Target: // <body> // into: // if ((converted = CheckException(exception, Test)) != null) { // Target = converted; // traceback-header // <body> // } if (converted == null) { converted = ag.GetTemporary("converted"); } ist = AstUtils.IfCondition( Ast.NotEqual( Ast.Assign(converted, test), Ast.Constant(null) ), Ast.Block( tsh.Target.TransformSet(ag, SourceSpan.None, converted, Operators.None), GetTracebackHeader( new SourceSpan(tsh.Start, tsh.Header), ag, exception, ag.Transform(tsh.Body) ), Ast.Empty() ) ); } else { // translating: // except Test: // <body> // into: // if (CheckException(exception, Test) != null) { // traceback-header // <body> // } ist = AstUtils.IfCondition( Ast.NotEqual( test, Ast.Constant(null) ), GetTracebackHeader( new SourceSpan(tsh.Start, tsh.Header), ag, exception, ag.Transform(tsh.Body) ) ); } // Add the test to the if statement test cascade tests.Add(ist); } else { Debug.Assert(index == _handlers.Length - 1); Debug.Assert(catchAll == null); // translating: // except: // <body> // into: // { // traceback-header // <body> // } catchAll = GetTracebackHeader(new SourceSpan(tsh.Start, tsh.Header), ag, exception, ag.Transform(tsh.Body)); } } MSAst.Expression body = null; if (tests.Count > 0) { // rethrow the exception if we have no catch-all block if (catchAll == null) { catchAll = Ast.Throw(exception); } body = AstUtils.If( tests.ToArray(), catchAll ); } else { Debug.Assert(catchAll != null); body = catchAll; } if (converted != null) { ag.FreeTemp(converted); } ag.FreeTemp(exception); ag.FreeTemp(extracted); // Codegen becomes: // extracted = PythonOps.SetCurrentException(exception) // < dynamic exception analysis > return Ast.Block( Ast.Assign( extracted, Ast.Call( AstGenerator.GetHelperMethod("SetCurrentException"), AstUtils.CodeContext(), exception ) ), body, Ast.Empty() ); }