コード例 #1
0
ファイル: AndExpression.cs プロジェクト: octavioh/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag, Type type) {
            MSAst.Expression left = ag.Transform(_left);
            MSAst.Expression right = ag.Transform(_right);

            Type t = left.Type == right.Type ? left.Type : typeof(object);
            MSAst.ParameterExpression tmp = ag.GetTemporary("__all__", t);
            
            return Ast.Condition(
                Binders.Convert(
                    ag.BinderState,
                    typeof(bool),
                    ConversionResultKind.ExplicitCast,
                    AstUtils.Assign(
                        tmp,
                        AstUtils.Convert(
                            left,
                            t
                        )
                    )
                ),
                AstUtils.Convert(
                    right,
                    t
                ),
                tmp
            );            
        }
コード例 #2
0
ファイル: IfStatement.cs プロジェクト: octavioh/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            MSAst.Expression result;

            if (_else != null) {
                result = ag.Transform(_else);
            } else {
                result = Ast.Empty();
            }

            // Now build from the inside out
            int i = _tests.Length;
            while (i-- > 0) {
                IfStatementTest ist = _tests[i];

                result = ag.AddDebugInfo(
                    Ast.Condition(
                        ag.TransformAndDynamicConvert(ist.Test, typeof(bool)), 
                        ag.Transform(ist.Body), 
                        result
                    ),
                    new SourceSpan(ist.Start, ist.Header)
                );
            }

            return result;
        }
コード例 #3
0
ファイル: MemberExpression.cs プロジェクト: octavioh/ironruby
 internal override MSAst.Expression TransformSet(AstGenerator ag, SourceSpan span, MSAst.Expression right, Operators op) {
     if (op == Operators.None) {
         return ag.AddDebugInfoAndVoid(
             Binders.Set(
                 ag.BinderState,
                 typeof(object),
                 SymbolTable.IdToString(_name),
                 ag.Transform(_target),
                 right
             ),
             span
         );
     } else {
         MSAst.ParameterExpression temp = ag.GetTemporary("inplace");
         return ag.AddDebugInfo(
             Ast.Block(
                 Ast.Assign(temp, ag.Transform(_target)),
                 SetMemberOperator(ag, right, op, temp),
                 Ast.Empty()
             ),
             Span.Start,
             span.End
         );
     }
 }
コード例 #4
0
ファイル: MemberExpression.cs プロジェクト: jcteague/ironruby
 internal override MSAst.Expression Transform(AstGenerator ag, Type type) {
     return ag.Get(
         type,
         SymbolTable.IdToString(_name),
         ag.Transform(_target)
     );
 }
コード例 #5
0
ファイル: IndexExpression.cs プロジェクト: octavioh/ironruby
        private static MSAst.Expression GetSliceValue(AstGenerator ag, Expression expr) {
            if (expr != null) {
                return ag.Transform(expr);
            }

            return Ast.Field(null, typeof(MissingParameter).GetField("Value"));
        }
コード例 #6
0
ファイル: UnaryExpression.cs プロジェクト: jcteague/ironruby
 internal override MSAst.Expression Transform(AstGenerator ag, Type type) {
     return ag.Operation(
         type,
         PythonOperatorToOperatorString(_op),
         ag.Transform(_expression)
     );
 }
コード例 #7
0
ファイル: MemberExpression.cs プロジェクト: techarch/ironruby
 internal override MSAst.Expression Transform(AstGenerator ag, Type type) {
     return ag.Get(
         type,
         _name,
         ag.Transform(_target)
     );
 }
コード例 #8
0
 internal override MSAst.Expression Transform(AstGenerator ag) {
     if (_left.Length == 1) {
         // Do not need temps for simple assignment
         return AssignOne(ag);
     } else {
         return AssignComplex(ag, ag.Transform(_right));
     }
 }
コード例 #9
0
ファイル: WhileStatement.cs プロジェクト: joshholmes/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            // Only the body is "in the loop" for the purposes of break/continue
            // The "else" clause is outside
            MSAst.LabelTarget breakLabel, continueLabel;

            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 ag.Transform(_else);
                    }
                }

                MSAst.Expression test = MSAst.Expression.Constant(true);
                MSAst.Expression res = AstUtils.While(
                    test,
                    ag.TransformLoopBody(_body, SourceLocation.Invalid, out breakLabel, out continueLabel),
                    ag.Transform(_else),
                    breakLabel,
                    continueLabel
                );

                if (_test.Start.Line != _body.Start.Line) {
                    res = ag.AddDebugInfo(res, _test.Span);
                }

                return res;
            }

            return AstUtils.While(
                ag.AddDebugInfo(
                    ag.TransformAndDynamicConvert(_test, typeof(bool)),
                    Header
                ),
                ag.TransformLoopBody(_body, _test.Start, out breakLabel, out continueLabel), 
                ag.Transform(_else),
                breakLabel,
                continueLabel
            );
        }
コード例 #10
0
ファイル: IndexExpression.cs プロジェクト: octavioh/ironruby
        private MSAst.Expression[] GetActionArgumentsForGetOrDelete(AstGenerator ag) {
            TupleExpression te = _index as TupleExpression;
            if (te != null && te.IsExpandable) {
                return ArrayUtils.Insert(AstUtils.CodeContext(), ag.Transform(_target), ag.Transform(te.Items));
            }

            SliceExpression se = _index as SliceExpression;
            if (se != null) {
                if (se.StepProvided) {
                    return new MSAst.Expression[] { 
                        AstUtils.CodeContext(),
                        ag.Transform(_target),
                        GetSliceValue(ag, se.SliceStart),
                        GetSliceValue(ag, se.SliceStop),
                        GetSliceValue(ag, se.SliceStep) 
                    };
                }

                return new MSAst.Expression[] { 
                    AstUtils.CodeContext(),
                    ag.Transform(_target),
                    GetSliceValue(ag, se.SliceStart),
                    GetSliceValue(ag, se.SliceStop)
                };
            }

            return new MSAst.Expression[] { AstUtils.CodeContext(), ag.Transform(_target), ag.Transform(_index) };
        }
コード例 #11
0
ファイル: Arg.cs プロジェクト: jcteague/ironruby
        internal Argument Transform(AstGenerator ag, out MSAst.Expression expression) {
            expression = ag.Transform(_expression);

            if (_name == null) {
                return Argument.Simple;
            } else if (_name == "*") {
                return new Argument(ArgumentType.List);
            } else if (_name == "**") {
                return new Argument(ArgumentType.Dictionary);
            } else {
                return new Argument(_name);
            }
        }
コード例 #12
0
        internal override MSAst.Expression Transform(AstGenerator ag) {
            MSAst.Expression expression = ag.Transform(_expression);

            if (ag.PrintExpressions) {
                expression = Ast.Call(
                    AstGenerator.GetHelperMethod("PrintExpressionValue"),
                    ag.LocalContext,
                    AstGenerator.ConvertIfNeeded(expression, typeof(object))
                );
            }

            return ag.AddDebugInfoAndVoid(expression, _expression.Span);
        }
コード例 #13
0
ファイル: Arg.cs プロジェクト: octavioh/ironruby
        internal Argument Transform(AstGenerator ag, out MSAst.Expression expression) {
            expression = ag.Transform(_expression);

            if (_name == SymbolId.Empty) {
                return Argument.Simple;
            } else if (_name == Symbols.Star) {
                return new Argument(ArgumentType.List);
            } else if (_name == Symbols.StarStar) {
                return new Argument(ArgumentType.Dictionary);
            } else {
                return new Argument(_name);
            }
        }
コード例 #14
0
ファイル: MemberExpression.cs プロジェクト: techarch/ironruby
 internal override MSAst.Expression TransformSet(AstGenerator ag, SourceSpan span, MSAst.Expression right, PythonOperationKind op) {
     if (op == PythonOperationKind.None) {
         return ag.AddDebugInfoAndVoid(
             ag.Set(
                 typeof(object),
                 _name,
                 ag.Transform(_target),
                 right
             ),
             span
         );
     } else {
         MSAst.ParameterExpression temp = ag.GetTemporary("inplace");
         return ag.AddDebugInfo(
             Ast.Block(
                 Ast.Assign(temp, ag.Transform(_target)),
                 SetMemberOperator(ag, right, op, temp),
                 AstUtils.Empty()
             ),
             Span.Start,
             span.End
         );
     }
 }
コード例 #15
0
ファイル: UnaryExpression.cs プロジェクト: jxnmaomao/ironruby
        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;
        }
コード例 #16
0
ファイル: SuiteStatement.cs プロジェクト: techarch/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            if (_statements.Length == 0) {
                return AstGenerator.EmptyBlock;
            }

            var stmts = ag.Transform(_statements);

            foreach (MSAst.Expression stmt in stmts) {
                if (stmt == null) {
                    // error was encountered and added to sync, 
                    // don't return any of the block
                    return null;
                }
            }
            return Ast.Block(stmts);
        }
コード例 #17
0
ファイル: WhileStatement.cs プロジェクト: jcteague/ironruby
 internal override MSAst.Expression Transform(AstGenerator ag) {
     // Only the body is "in the loop" for the purposes of break/continue
     // The "else" clause is outside
     MSAst.LabelTarget breakLabel, continueLabel;
     MSAst.Expression body = ag.TransformLoopBody(_body, out breakLabel, out continueLabel);
     return AstUtils.While(
         ag.AddDebugInfo(
             ag.TransformAndDynamicConvert(_test, typeof(bool)),
             Header
         ),
         body, 
         ag.Transform(_else),
         breakLabel,
         continueLabel
     );
 }
コード例 #18
0
ファイル: CallExpression.cs プロジェクト: Hank923/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag, Type type) {
            MSAst.Expression[] values = new MSAst.Expression[_args.Length + 2];
            Argument[] kinds = new Argument[_args.Length];

            values[0] = ag.LocalContext;
            values[1] = ag.Transform(_target);

            for (int i = 0; i < _args.Length; i++) {
                kinds[i] = _args[i].Transform(ag, out values[i + 2]);
            }

            return ag.Invoke(
                type,
                new CallSignature(kinds),
                ArrayUtils.RemoveFirst(values)
            );
        }
コード例 #19
0
ファイル: YieldExpression.cs プロジェクト: jcteague/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag, Type type) {
            // (yield z) becomes:
            // .comma (1) {
            //    .void ( .yield_statement (_expression) ),
            //    $gen.CheckThrowable() // <-- has return result from send            
            //  }

            return Ast.Block(
                ag.AddDebugInfo(
                    AstUtils.YieldReturn(
                        ag.GeneratorLabel,
                        AstUtils.Convert(ag.Transform(_expression), typeof(object))
                    ),
                    Span
                ),
                CreateCheckThrowExpression(ag, Span) // emits ($gen.CheckThrowable())
            );
        }
コード例 #20
0
ファイル: SuiteStatement.cs プロジェクト: jcteague/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            if (_statements.Length == 0) {
                return AstGenerator.EmptyBlock;
            }

            MSAst.Expression[] stmts = ag.Transform(_statements);
            if (stmts.Length == 0) {
                return AstUtils.Empty();
            }

            foreach (MSAst.Expression stmt in stmts) {
                if (stmt == null) {
                    // error was encountered and added to sync, 
                    // don't return any of the block
                    return null;
                }
            }
            return AstUtils.Void(Ast.Block(new ReadOnlyCollection<MSAst.Expression>(stmts)));
        }
コード例 #21
0
ファイル: TryStatement.cs プロジェクト: octavioh/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            // allocated all variables here so they won't be shared w/ other 
            // locals allocated during the body or except blocks.
            MSAst.ParameterExpression noNestedException = null;
            if (_finally != null) {
                noNestedException = ag.GetTemporary("$noException", typeof(bool));
            }

            MSAst.ParameterExpression lineUpdated = null;
            MSAst.ParameterExpression runElse = null;

            if (_else != null || (_handlers != null && _handlers.Length > 0)) {
                lineUpdated = ag.GetTemporary("$lineUpdated", typeof(bool));
                if (_else != null) {
                    runElse = ag.GetTemporary("run_else", typeof(bool));
                }
            }

            // don't allocate locals below here...
            MSAst.Expression body = ag.Transform(_body);
            MSAst.Expression @else = ag.Transform(_else);

            if (body == null) {
                return null;
            }

            MSAst.ParameterExpression exception;
            MSAst.Expression @catch = TransformHandlers(ag, out exception);
            MSAst.Expression result;

            // We have else clause, must generate guard around it
            if (@else != null) {
                Debug.Assert(@catch != null);

                //  run_else = true;
                //  try {
                //      try_body
                //  } catch ( ... ) {
                //      run_else = false;
                //      catch_body
                //  }
                //  if (run_else) {
                //      else_body
                //  }
                result =
                    Ast.Block(
                        Ast.Assign(runElse, Ast.Constant(true)),
                        // save existing line updated, we could choose to do this only for nested exception handlers.
                        ag.PushLineUpdated(false, lineUpdated),
                        AstUtils.Try(
                            ag.AddDebugInfo(Ast.Empty(), new SourceSpan(Span.Start, _header)),
                            body
                        ).Catch(exception,
                            Ast.Assign(runElse, Ast.Constant(false)),
                            @catch,
                            // restore existing line updated after exception handler completes
                            ag.PopLineUpdated(lineUpdated),
                            Ast.Default(body.Type)
                        ),
                        AstUtils.IfThen(runElse,
                            @else
                        ),
                        Ast.Empty()
                    );

            } else if (@catch != null) {        // no "else" clause
                //  try {
                //      <try body>
                //  } catch (Exception e) {
                //      ... catch handling ...
                //  }
                //
                result = AstUtils.Try(
                        ag.AddDebugInfo(Ast.Empty(), new SourceSpan(Span.Start, _header)),
                        // save existing line updated
                        ag.PushLineUpdated(false, lineUpdated),
                        body
                    ).Catch(exception,
                        @catch,
                        // restore existing line updated after exception handler completes
                        ag.PopLineUpdated(lineUpdated),
                        Ast.Default(body.Type)
                    );
            } else {
                result = body;
            }

            try {
                return AddFinally(ag, result, noNestedException);
            } finally {
                // free all locals here after the children nodes have been generated
                if (lineUpdated != null) {
                    ag.FreeTemp(lineUpdated);
                }
                if (runElse != null) {
                    ag.FreeTemp(@runElse);
                }
            }
        }
コード例 #22
0
ファイル: MemberExpression.cs プロジェクト: techarch/ironruby
 internal override MSAst.Expression TransformDelete(AstGenerator ag) {
     return ag.Delete(
         typeof(void),
         _name,
         ag.Transform(_target)
     );
 }
コード例 #23
0
ファイル: MemberExpression.cs プロジェクト: octavioh/ironruby
 internal override MSAst.Expression TransformDelete(AstGenerator ag) {
     return Binders.Delete(
         ag.BinderState,
         typeof(object),
         SymbolTable.IdToString(_name),
         ag.Transform(_target)
     );
 }
コード例 #24
0
ファイル: TryStatement.cs プロジェクト: octavioh/ironruby
        /// <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()
            );
        }
コード例 #25
0
ファイル: TryStatement.cs プロジェクト: octavioh/ironruby
        private MSAst.Expression AddFinally(AstGenerator/*!*/ ag, MSAst.Expression/*!*/ body, MSAst.ParameterExpression noNestedException) {
            if (_finally != null) {
                Debug.Assert(noNestedException != null);

                MSAst.ParameterExpression nestedFrames = ag.GetTemporary("$nestedFrames", typeof(List<DynamicStackFrame>));

                bool inFinally = ag.InFinally;
                ag.InFinally = true;
                MSAst.Expression @finally = ag.Transform(_finally);
                ag.InFinally = inFinally;
                if (@finally == null) {
                    // error reported during compilation
                    return null;
                }

                if (ag.TrackLines) {
                    // lots is going on here.  We need to consider:
                    //      1. Exceptions propagating out of try/except/finally.  Here we need to save the line #
                    //          from the exception block and not save the # from the finally block later.
                    //      2. Exceptions propagating out of the finally block.  Here we need to report the line number
                    //          from the finally block and leave the existing stack traces cleared.
                    //      3. Returning from the try block: Here we need to run the finally block and not update the
                    //          line numbers.
                    body = AstUtils.Try(// we use a filter to know when we have an exception and when control leaves normally (via
                        // either a return or the body completing successfully).
                        AstUtils.Try(
                            ag.AddDebugInfo(Ast.Empty(), new SourceSpan(Span.Start, _header)),
                            Ast.Assign(noNestedException, Ast.Constant(true)),
                            body
                        ).Filter(
                            typeof(Exception),
                        // condition is never true, just note the exception and let it propagate
                            Ast.Equal(
                                Ast.Assign(noNestedException, Ast.Constant(false)),
                                Ast.Constant(true)
                            ),
                            Ast.Default(body.Type)
                        )
                    ).Finally(
                        // if we had an exception save the line # that was last executing during the try
                        AstUtils.If(
                            Ast.Not(noNestedException),
                            ag.GetLineNumberUpdateExpression(false)
                        ),

                        // clear the frames incase thae finally throws, and allow line number
                        // updates to proceed
                        ag.UpdateLineUpdated(false),
                        Ast.Assign(
                            nestedFrames,
                            Ast.Call(AstGenerator.GetHelperMethod("GetAndClearDynamicStackFrames"))
                        ),

                        // run the finally code
                        @finally,

                        // if the finally exits normally restore any previous exception info
                        Ast.Call(
                            AstGenerator.GetHelperMethod("SetDynamicStackFrames"),
                            nestedFrames
                        ),
                        ag.UpdateLineUpdated(true)
                    );

                    ag.FreeTemp(nestedFrames);
                    ag.FreeTemp(noNestedException);
                } else {
                    body = AstUtils.Try(body).Finally(
                            Ast.Assign(
                                nestedFrames,
                                Ast.Call(AstGenerator.GetHelperMethod("GetAndClearDynamicStackFrames"))
                            ),

                            // run the finally code
                            @finally,

                            // if the finally exits normally restore any previous exception info
                            Ast.Call(
                                AstGenerator.GetHelperMethod("SetDynamicStackFrames"),
                                nestedFrames
                            )
                        );
                }
            }
            return body;
        }
コード例 #26
0
        private void TransformBody(AstGenerator ag, List<MSAst.Expression> statements) {
            SuiteStatement suite = _body as SuiteStatement;

            // Special case suite statement to avoid unnecessary allocation of extra node.
            if (suite != null) {
                foreach (Statement one in suite.Statements) {
                    MSAst.Expression transforned = ag.Transform(one);
                    if (transforned != null) {
                        statements.Add(transforned);
                    }
                }
            } else {
                MSAst.Expression transformed = ag.Transform(_body);
                if (transformed != null) {
                    statements.Add(transformed);
                }
            }
        }
コード例 #27
0
ファイル: ClassDefinition.cs プロジェクト: jxnmaomao/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            string className = _name;
            AstGenerator classGen = new AstGenerator(ag, className, false, "class " + className);
            classGen.Parameter(_parentContextParam);
            // we always need to create a nested context for class defs
            classGen.CreateNestedContext();

            List<MSAst.Expression> init = new List<MSAst.Expression>();
            
            classGen.AddHiddenVariable(ArrayGlobalAllocator._globalContext);
            init.Add(Ast.Assign(ArrayGlobalAllocator._globalContext, Ast.Call(typeof(PythonOps).GetMethod("GetGlobalContext"), _parentContextParam)));
            init.AddRange(classGen.Globals.PrepareScope(classGen));

            CreateVariables(classGen, _parentContextParam, init, true, false);

            List<MSAst.Expression> statements = new List<MSAst.Expression>();
            // Create the body
            MSAst.Expression bodyStmt = classGen.Transform(_body);
            
            // __module__ = __name__
            MSAst.Expression modStmt = GlobalAllocator.Assign(
                classGen.Globals.GetVariable(classGen, _modVariable), 
                classGen.Globals.GetVariable(classGen, _modNameVariable));

            string doc = classGen.GetDocumentation(_body);
            if (doc != null) {
                statements.Add(
                    GlobalAllocator.Assign(
                        classGen.Globals.GetVariable(classGen, _docVariable),
                        AstUtils.Constant(doc)
                    )
                );
            }

            FunctionCode funcCodeObj = new FunctionCode(
                ag.PyContext,
                null,
                null,
                Name,
                ag.GetDocumentation(_body),
                ArrayUtils.EmptyStrings,
                FunctionAttributes.None,
                Span,
                ag.Context.SourceUnit.Path,
                ag.EmitDebugSymbols,
                ag.ShouldInterpret,
                FreeVariables,
                GlobalVariables,
                CellVariables,
                AppendVariables(new List<string>()),
                Variables == null ? 0 : Variables.Count,
                classGen.LoopLocationsNoCreate,
                classGen.HandlerLocationsNoCreate
            );
            MSAst.Expression funcCode = classGen.Globals.GetConstant(funcCodeObj);
            classGen.FuncCodeExpr = funcCode;

            if (_body.CanThrow && ag.PyContext.PythonOptions.Frames) {
                bodyStmt = AstGenerator.AddFrame(classGen.LocalContext, funcCode, bodyStmt);
                classGen.AddHiddenVariable(AstGenerator._functionStack);
            }

            bodyStmt = classGen.WrapScopeStatements(
                Ast.Block(
                    statements.Count == 0 ?
                        AstGenerator.EmptyBlock :
                        Ast.Block(new ReadOnlyCollection<MSAst.Expression>(statements)),
                    modStmt,
                    bodyStmt,
                    classGen.LocalContext    // return value
                )
            );

            var lambda = Ast.Lambda<Func<CodeContext, CodeContext>>(
                classGen.MakeBody(_parentContextParam, init.ToArray(), bodyStmt),
                classGen.Name + "$" + _classId++,
                classGen.Parameters
            );
            
            funcCodeObj.Code = lambda;

            MSAst.Expression classDef = Ast.Call(
                AstGenerator.GetHelperMethod("MakeClass"),
                ag.EmitDebugSymbols ? 
                    (MSAst.Expression)lambda : 
                    Ast.Convert(funcCode, typeof(object)),
                ag.LocalContext,
                AstUtils.Constant(_name),
                Ast.NewArrayInit(
                    typeof(object),
                    ag.TransformAndConvert(_bases, typeof(object))
                ),
                AstUtils.Constant(FindSelfNames())
            );

            classDef = ag.AddDecorators(classDef, _decorators);

            return ag.AddDebugInfoAndVoid(GlobalAllocator.Assign(ag.Globals.GetVariable(ag, _variable), classDef), new SourceSpan(Start, Header));
        }
コード例 #28
0
ファイル: PythonAst.cs プロジェクト: jcteague/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            List<MSAst.Expression> block = new List<MSAst.Expression>();
            // Create the variables
            CreateVariables(ag, null, block, false, false);

            MSAst.Expression bodyStmt = ag.Transform(_body);

            string doc = ag.GetDocumentation(_body);

            if (_isModule) {
                block.Add(ag.Globals.Assign(
                    ag.Globals.GetVariable(ag, _docVariable),
                    Ast.Constant(doc)
                ));
            }
            if (bodyStmt != null) {
                block.Add(bodyStmt); //  bodyStmt could be null if we have an error - e.g. a top level break
            }
            block.Add(AstUtils.Empty());

            return Ast.Block(block);
        }
コード例 #29
0
ファイル: ClassDefinition.cs プロジェクト: tnachen/ironruby
        internal override MSAst.Expression Transform(AstGenerator ag) {
            string className = SymbolTable.IdToString(_name);
            AstGenerator builder = new AstGenerator(ag, className, false, "class " + className);

            // we always need to create a nested context for class defs
            builder.CreateNestedContext();

            List<MSAst.Expression> init = new List<MSAst.Expression>();
            CreateVariables(builder, init);

            // Create the body
            MSAst.Expression bodyStmt = builder.Transform(_body);
            MSAst.Expression modStmt = ag.Globals.Assign(ag.Globals.GetVariable(_modVariable), ag.Globals.GetVariable(_modNameVariable));

            string doc = ag.GetDocumentation(_body);
            if (doc != null) {
                init.Add(
                    ag.Globals.Assign(
                        ag.Globals.GetVariable(_docVariable),
                        AstUtils.Constant(doc)
                    )
                );
            }

            bodyStmt = builder.WrapScopeStatements(
                Ast.Block(
                    init.Count == 0 ?
                        AstGenerator.EmptyBlock :
                        Ast.Block(new ReadOnlyCollection<MSAst.Expression>(init)),
                    modStmt,
                    bodyStmt,
                    builder.LocalContext    // return value
                )
            );

            MSAst.LambdaExpression lambda = Ast.Lambda(
                typeof(Func<CodeContext>),
                builder.MakeBody(bodyStmt, true, false),
                builder.Name + "$" + _classId++,
                builder.Parameters
            );

            MSAst.Expression classDef = Ast.Call(
                AstGenerator.GetHelperMethod("MakeClass"),
                lambda,
                ag.LocalContext,
                AstUtils.Constant(SymbolTable.IdToString(_name)),
                Ast.NewArrayInit(
                    typeof(object),
                    ag.TransformAndConvert(_bases, typeof(object))
                ),
                AstUtils.Constant(FindSelfNames())
            );

            classDef = ag.AddDecorators(classDef, _decorators);

            return ag.AddDebugInfo(ag.Globals.Assign(ag.Globals.GetVariable(_variable), classDef), new SourceSpan(Start, Header));
        }
コード例 #30
0
ファイル: ForStatement.cs プロジェクト: joshholmes/ironruby
        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()
            );
        }