internal override MSAst.Expression TransformSet(AstGenerator ag, SourceSpan span, MSAst.Expression right, PythonOperationKind op) { MSAst.Expression assignment; if (op != PythonOperationKind.None) { right = ag.Operation( typeof(object), op, Transform(ag, typeof(object)), right ); } if (_reference.PythonVariable != null) { assignment = ag.Globals.Assign( ag.Globals.GetVariable(_reference.PythonVariable), AstGenerator.ConvertIfNeeded(right, typeof(object)) ); } else { assignment = Ast.Call( null, typeof(ScriptingRuntimeHelpers).GetMethod("SetName"), new [] { ag.LocalContext, ag.Globals.GetSymbol(_name), AstUtils.Convert(right, typeof(object)) } ); } SourceSpan aspan = span.IsValid ? new SourceSpan(Span.Start, span.End) : SourceSpan.None; return ag.AddDebugInfoAndVoid(assignment, aspan); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { return ag.Operation( type, PythonOperatorToOperatorString(_op), ag.Transform(_expression) ); }
internal override MSAst.Expression Transform(AstGenerator ag, Type type) { MSAst.Expression res; if (Op == PythonOperator.Not) { Debug.Assert(type == typeof(object) || type == typeof(bool)); if (type == typeof(bool)) { res = ag.Operation(typeof(bool), PythonOperationKind.Not, ag.Transform(_expression)); } else { res = ag.Operation(typeof(object), PythonOperationKind.NotRetObject, ag.Transform(_expression)); } } else { res = ag.Operation( typeof(object), PythonOperatorToOperatorString(_op), ag.Transform(_expression) ); if (type != typeof(object)) { res = ag.Convert(type, Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, res); } } return res; }
private MSAst.Expression SetMemberOperator(AstGenerator ag, MSAst.Expression right, PythonOperationKind op, MSAst.ParameterExpression temp) { return ag.Set( typeof(object), _name, temp, ag.Operation( typeof(object), op, ag.Get( typeof(object), _name, temp ), right ) ); }
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() ); }
private static MSAst.Expression MakeBinaryOperation(AstGenerator ag, PythonOperator op, MSAst.Expression left, MSAst.Expression right, Type type, SourceSpan span) { if (op == PythonOperator.NotIn) { return AstUtils.Convert( Ast.Not( ag.Operation( typeof(bool), PythonOperationKind.Contains, left, right ) ), type ); } else if (op == PythonOperator.In) { return AstUtils.Convert( ag.Operation( typeof(bool), PythonOperationKind.Contains, left, right ), type ); } PythonOperationKind action = PythonOperatorToAction(op); if (action != PythonOperationKind.None) { // Create action expression if (CanEmitWarning(ag, op)) { MSAst.ParameterExpression tempLeft = ag.GetTemporary("left", left.Type); MSAst.ParameterExpression tempRight = ag.GetTemporary("right", right.Type); return Ast.Block( Ast.Call( AstGenerator.GetHelperMethod("WarnDivision"), ag.LocalContext, AstUtils.Constant(ag.DivisionOptions), AstUtils.Convert( Ast.Assign(tempLeft, left), typeof(object) ), AstUtils.Convert( Ast.Assign(tempRight, right), typeof(object) ) ), ag.Operation( type, action, tempLeft, tempRight ) ); } return ag.Operation( type, action, left, right ); } else { // Call helper method return Ast.Call( AstGenerator.GetHelperMethod(GetHelperName(op)), AstGenerator.ConvertIfNeeded(left, typeof(object)), AstGenerator.ConvertIfNeeded(right, typeof(object)) ); } }
/// <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> internal override MSAst.Expression Transform(AstGenerator ag) { MSAst.ParameterExpression lineUpdated = ag.GetTemporary("$lineUpdated_with", typeof(bool)); // Five statements in the result... MSAst.Expression[] statements = new MSAst.Expression[6]; //****************************************************************** // 1. mgr = (EXPR) //****************************************************************** MSAst.ParameterExpression manager = ag.GetTemporary("with_manager"); statements[0] = ag.MakeAssignment( manager, ag.Transform(_contextManager), new SourceSpan(Start, _header) ); //****************************************************************** // 2. exit = mgr.__exit__ # Not calling it yet //****************************************************************** MSAst.ParameterExpression exit = ag.GetTemporary("with_exit"); statements[1] = ag.MakeAssignment( exit, ag.Get( typeof(object), "__exit__", manager ) ); //****************************************************************** // 3. value = mgr.__enter__() //****************************************************************** MSAst.ParameterExpression value = ag.GetTemporary("with_value"); statements[2] = ag.AddDebugInfo( ag.MakeAssignment( value, ag.Invoke( typeof(object), new CallSignature(0), ag.Get( typeof(object), "__enter__", manager ) ) ), new SourceSpan(Start, _header) ); //****************************************************************** // 4. exc = True //****************************************************************** MSAst.ParameterExpression exc = ag.GetTemporary("with_exc", typeof(bool)); statements[3] = ag.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 = ag.GetTemporary("exception", typeof(Exception)); MSAst.ParameterExpression nestedFrames = ag.GetTemporary("$nestedFrames", typeof(List<DynamicStackFrame>)); statements[4] = // try: AstUtils.Try( AstUtils.Try(// try statement body ag.PushLineUpdated(false, lineUpdated), _var != null ? ag.AddDebugInfo( Ast.Block( // VAR = value _var.TransformSet(ag, SourceSpan.None, value, PythonOperationKind.None), // BLOCK ag.Transform(_body), AstUtils.Empty() ), _body.Span ) : // BLOCK ag.Transform(_body) // except:, // try statement location ).Catch(exception, // Python specific exception handling code TryStatement.GetTracebackHeader( ag, exception, ag.AddDebugInfo( Ast.Block( // exc = False ag.MakeAssignment( exc, AstUtils.Constant(false) ), Ast.Assign( nestedFrames, Ast.Call(AstGenerator.GetHelperMethod("GetAndClearDynamicStackFrames")) ), // if not exit(*sys.exc_info()): // raise AstUtils.IfThen( ag.Convert( typeof(bool), ConversionResultKind.ExplicitCast, ag.Operation( typeof(bool), PythonOperationKind.Not, MakeExitCall(ag, exit, exception) ) ), ag.UpdateLineUpdated(true), Ast.Call( AstGenerator.GetHelperMethod("SetDynamicStackFrames"), nestedFrames ), Ast.Rethrow() ) ), _body.Span ) ), Ast.Call( AstGenerator.GetHelperMethod("SetDynamicStackFrames"), nestedFrames ), ag.PopLineUpdated(lineUpdated), Ast.Empty() ) // finally: ).Finally( // if exc: // exit(None, None, None) AstUtils.IfThen( exc, ag.AddDebugInfo( Ast.Block( Ast.Dynamic( ag.BinderState.Invoke( new CallSignature(3) // signature doesn't include function ), typeof(object), new MSAst.Expression[] { ag.LocalContext, exit, AstUtils.Constant(null), AstUtils.Constant(null), AstUtils.Constant(null) } ), Ast.Empty() ), _contextManager.Span ) ) ); statements[4] = ag.AddDebugInfo(statements[4], Span); statements[5] = AstUtils.Empty(); return ag.AddDebugInfo(Ast.Block(statements), _body.Span); }
internal override MSAst.Expression TransformSet(AstGenerator ag, SourceSpan span, MSAst.Expression right, PythonOperationKind op) { if (op != PythonOperationKind.None) { right = ag.Operation( typeof(object), op, Transform(ag, typeof(object)), right ); } MSAst.Expression index; if (IsSlice) { index = ag.SetSlice(typeof(object), GetActionArgumentsForSet(ag, right)); } else { index = ag.SetIndex(typeof(object), GetActionArgumentsForSet(ag, right)); } return ag.AddDebugInfoAndVoid(index, Span); }