예제 #1
0
        internal virtual void FinishBind(PythonNameBinder binder) {
            List<ClosureInfo> closureVariables = null;

            if (FreeVariables != null && FreeVariables.Count > 0) {
                LocalParentTuple = Ast.Parameter(Parent.GetClosureTupleType(), "$tuple");

                foreach (var variable in _freeVars) {
                    var parentClosure = Parent._closureVariables;
                    Debug.Assert(parentClosure != null);

                    for (int i = 0; i < parentClosure.Length; i++) {
                        if (parentClosure[i].Variable == variable) {
                            _variableMapping[variable] = new ClosureExpression(variable, Ast.Property(LocalParentTuple, String.Format("Item{0:D3}", i)), null);
                            break;
                        }
                    }
                    Debug.Assert(_variableMapping.ContainsKey(variable));

                    if (closureVariables == null) {
                        closureVariables = new List<ClosureInfo>();
                    }
                    closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition)));
                }
            }

            if (Variables != null) {
                foreach (PythonVariable variable in Variables.Values) {
                    if (!HasClosureVariable(closureVariables, variable) &&
                        !variable.IsGlobal && (variable.AccessedInNestedScope || ExposesLocalVariable(variable))) {
                        if (closureVariables == null) {
                            closureVariables = new List<ClosureInfo>();
                        }
                        closureVariables.Add(new ClosureInfo(variable, true));
                    }

                    if (variable.Kind == VariableKind.Local) {
                        Debug.Assert(variable.Scope == this);

                        if (variable.AccessedInNestedScope || ExposesLocalVariable(variable)) {
                            _variableMapping[variable] = new ClosureExpression(variable, Ast.Parameter(typeof(ClosureCell), variable.Name), null);
                        } else {
                            _variableMapping[variable] = Ast.Parameter(typeof(object), variable.Name);
                        }
                    }
                }
            }

            if (closureVariables != null) {
                _closureVariables = closureVariables.ToArray();
            }

            // no longer needed
            _references = null;
        }
예제 #2
0
        internal void CreateVariables(ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals, List <MSAst.Expression> init)
        {
            if (Variables != null)
            {
                foreach (PythonVariable variable in Variables.Values)
                {
                    if (variable.Kind != VariableKind.Global)
                    {
                        ClosureExpression closure = GetVariableExpression(variable) as ClosureExpression;
                        if (closure != null)
                        {
                            init.Add(closure.Create());
                            locals.Add((MSAst.ParameterExpression)closure.ClosureCell);
                        }
                        else if (variable.Kind == VariableKind.Local)
                        {
                            locals.Add((MSAst.ParameterExpression)GetVariableExpression(variable));
                            if (variable.ReadBeforeInitialized)
                            {
                                init.Add(
                                    AssignValue(
                                        GetVariableExpression(variable),
                                        MSAst.Expression.Field(null, typeof(Uninitialized).GetField(nameof(Uninitialized.Instance)))
                                        )
                                    );
                            }
                        }
                    }
                }
            }

            if (IsClosure)
            {
                Type tupleType = Parent.GetClosureTupleType();
                Debug.Assert(tupleType != null);

                init.Add(
                    MSAst.Expression.Assign(
                        LocalParentTuple,
                        MSAst.Expression.Convert(
                            GetParentClosureTuple(),
                            tupleType
                            )
                        )
                    );

                locals.Add(LocalParentTuple);
            }
        }
예제 #3
0
        private static void CompileAssignment(LightCompiler compiler, MSAst.Expression variable, Action <LightCompiler> compileValue)
        {
            var instructions = compiler.Instructions;

            ClosureExpression closure = variable as ClosureExpression;

            if (closure != null)
            {
                compiler.Compile(closure.ClosureCell);
            }
            LookupGlobalVariable lookup = variable as LookupGlobalVariable;

            if (lookup != null)
            {
                compiler.Compile(lookup.CodeContext);
                instructions.EmitLoad(lookup.Name);
            }

            compileValue(compiler);

            if (closure != null)
            {
                instructions.EmitStoreField(ClosureExpression._cellField);
                return;
            }
            if (lookup != null)
            {
                var setter = typeof(PythonOps).GetMethod(lookup.IsLocal ? nameof(PythonOps.SetLocal) : nameof(PythonOps.SetGlobal));
                instructions.Emit(CallInstruction.Create(setter));
                return;
            }

            MSAst.ParameterExpression functionValueParam = variable as MSAst.ParameterExpression;
            if (functionValueParam != null)
            {
                instructions.EmitStoreLocal(compiler.Locals.GetLocalIndex(functionValueParam));
                return;
            }

            var globalVar = variable as PythonGlobalVariableExpression;

            if (globalVar != null)
            {
                instructions.Emit(new PythonSetGlobalInstruction(globalVar.Global));
                instructions.EmitPop();
                return;
            }
            Debug.Assert(false, "Unsupported variable type for light compiling function");
        }
예제 #4
0
        internal ClosureExpression/*!*/ LiftedParameter(PythonVariable variable, string name) {
            ParameterExpression result = Ast.Variable(typeof(object), name);
            _params.Add(result);

            ClosureExpression closureVar = new ClosureExpression(variable, HiddenVariable(typeof(ClosureCell), name), result);
            EnsureLiftedVars();

            _liftedVars.Add(new DefinitionClosureInfo(closureVar, true));
            return closureVar;
        }
예제 #5
0
        internal ClosureExpression/*!*/ LiftedVariable(PythonVariable/*!*/ variable, string/*!*/ name, bool accessInNestedScope) {
            ParameterExpression result = HiddenVariable(typeof(ClosureCell), name);

            ClosureExpression closureVar = new ClosureExpression(variable, result, null);
            EnsureLiftedVars();
            _liftedVars.Add(new DefinitionClosureInfo(closureVar, true));
            return closureVar;
        }
예제 #6
0
        internal virtual void FinishBind(PythonNameBinder binder) {
            List<ClosureInfo> closureVariables = null;
            
            if (FreeVariables != null && FreeVariables.Count > 0) {
                _localParentTuple = Ast.Parameter(Parent.GetClosureTupleType(), "$tuple");

                foreach (var variable in _freeVars) {
                    var parentClosure = Parent._closureVariables;                    
                    Debug.Assert(parentClosure != null);
                    
                    for (int i = 0; i < parentClosure.Length; i++) {
                        if (parentClosure[i].Variable == variable) {
                            _variableMapping[variable] = new ClosureExpression(variable, Ast.Property(_localParentTuple, String.Format("Item{0:D3}", i)), null);
                            break;
                        }
                    }
                    Debug.Assert(_variableMapping.ContainsKey(variable));
                    
                    if (closureVariables == null) {
                        closureVariables = new List<ClosureInfo>();
                    }
                    closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition)));
                }
            }

            if (Variables != null) {
                foreach (PythonVariable variable in Variables.Values) {
                    if (!HasClosureVariable(closureVariables, variable) &&
                        !variable.IsGlobal && (variable.AccessedInNestedScope || ExposesLocalVariable(variable))) {
                        if (closureVariables == null) {
                            closureVariables = new List<ClosureInfo>();
                        }
                        closureVariables.Add(new ClosureInfo(variable, true));
                    }

                    if (variable.Kind == VariableKind.Local) {
                        Debug.Assert(variable.Scope == this);

                        if (variable.AccessedInNestedScope || ExposesLocalVariable(variable)) {
                            _variableMapping[variable] = new ClosureExpression(variable, Ast.Parameter(typeof(ClosureCell), variable.Name), null);
                        } else {
                            _variableMapping[variable] = Ast.Parameter(typeof(object), variable.Name);
                        }
                    }
                }
            }

            if (closureVariables != null) {
                _closureVariables = closureVariables.ToArray();
            }

            // no longer needed
            _references = null;
        }