示例#1
0
        internal MSAst.Expression Transform(AstGenerator inner, bool needsWrapperMethod, bool needsLocalsDictionary, List<MSAst.Expression> init) {
            string name = SymbolTable.IdToString(Name);
            if (_variable.AccessedInNestedScope || needsLocalsDictionary) {
                ClosureExpression closureVar;
                if (needsWrapperMethod) {
                    closureVar = inner.LiftedVariable(Variable, name, _variable.AccessedInNestedScope);
                } else {
                    closureVar = inner.LiftedParameter(Variable, name);
                }
                inner.SetLocalLiftedVariable(_variable, closureVar);
                init.Add(closureVar.Create());

                return closureVar;                
            } else {
                MSAst.Expression parameter;
                if (needsWrapperMethod) {
                    parameter = inner.Variable(typeof(object), name);
                } else {
                    parameter = inner.Parameter(typeof(object), name);
                }
                inner.Globals.SetParameter(_variable, parameter);
                return parameter;
            }
        }
示例#2
0
        public MSAst.Expression/*!*/ CreateVariable(AstGenerator/*!*/ ag, PythonVariable/*!*/ variable, bool emitDictionary) {
            Assert.NotNull(ag, variable);

            Debug.Assert(variable.Kind != VariableKind.Parameter);

            string name = SymbolTable.IdToString(variable.Name);
            switch (variable.Kind) {
                case VariableKind.Global:
                case VariableKind.GlobalLocal:
                    return _variables[variable] = GetGlobal(name, ag, false);
                case VariableKind.Local:
                case VariableKind.HiddenLocal:
                    if (ag.IsGlobal) {
                        return _variables[variable] = GetGlobal(name, ag, true);
                    } else if (variable.AccessedInNestedScope || (emitDictionary && variable.Kind != VariableKind.HiddenLocal)) {
                        return ag.SetLocalLiftedVariable(variable, ag.LiftedVariable(variable, name, variable.AccessedInNestedScope));
                    } else {
                        return _variables[variable] = ag.Variable(typeof(object), name);
                    }
                default:
                    throw Assert.Unreachable;
            }
        }
示例#3
0
        /// <summary>
        /// Creates variables which are defined in a parent scope and accessed in this scope.
        /// </summary>
        private void CreateReferencedVariables(AstGenerator ag, List<MSAst.Expression> init, bool emitDictionary, bool needsLocals) {
            MSAst.Expression localTuple = null;
            foreach (KeyValuePair<SymbolId, PythonReference> kv in _references) {
                PythonVariable var = kv.Value.PythonVariable;

                if (var == null || var.Scope == this) {
                    continue;
                }

                if ((var.Kind == VariableKind.Local || var.Kind == VariableKind.Parameter) && !var.Scope.IsGlobal) {
                    // closed over local, we need to pull in the closure variable
                    Type tupleType = ag.GetParentTupleType();
                    int index = ag.TupleIndex(var);

                    localTuple = EnsureLocalTuple(ag, init, localTuple, tupleType);

                    // get the closure cell from the tuple
                    MSAst.Expression tuplePath = localTuple;
                    foreach (var v in MutableTuple.GetAccessPath(tupleType, index)) {
                        tuplePath = MSAst.Expression.Property(tuplePath, v);
                    }

                    MSAst.ParameterExpression pe = ag.HiddenVariable(typeof(ClosureCell), SymbolTable.IdToString(var.Name));
                    init.Add(MSAst.Expression.Assign(pe, tuplePath));

                    ag.SetLocalLiftedVariable(var, new ClosureExpression(var, pe, null));

                    if (emitDictionary) {
                        ag.ReferenceVariable(var, index, localTuple, needsLocals);
                    }
                }
            }
        }