internal override void FinishBind(TotemNameBinder binder)
        {
            if (_freeVars != null && _freeVars.Count > 0)
            {
                ReadOnlyCollectionBuilder<TotemVariable> closureVariables = new ReadOnlyCollectionBuilder<TotemVariable>();
                _closureType = MutableTuple.MakeTupleType(_freeVars.Select(v => typeof(ClosureCell)).ToArray());
                _localClosureTuple = Expression.Parameter(_closureType, "$closure");
                for (var i = 0; i < _freeVars.Count; i++)
                {
                    var variable = _freeVars[i];
                    _variableMapping[variable] = new ClosureExpression(variable, Expression.Property(_localClosureTuple, String.Format("Item{0:D3}", i)), null);
                    closureVariables.Add(variable);
                }
                _closureVariables = closureVariables.ToReadOnlyCollection();
            }

            if (_scopeVars != null)
                foreach (var local in _scopeVars)
                {
                    if (local.Kind == VariableKind.Parameter) // handled in subclass
                        continue;

                    // scope variables, defined in this scope
                    Debug.Assert(local.Kind == VariableKind.Local);
                    Debug.Assert(local.Scope == this);

                    if (local.AccessedInNestedScope)
                    {
                        // Closure variable
                        _variableMapping[local] = new ClosureExpression(local, Expression.Parameter(typeof(ClosureCell), local.Name), null);
                    }
                    else
                    {
                        // Not used in nested function-scopes
                        _variableMapping[local] = Expression.Parameter(typeof(object), local.Name);
                    }
                }
        }
Exemple #2
0
        internal virtual void FinishBind(TotemNameBinder binder)
        {
            if (_freeVars != null)
                foreach (var variable in _freeVars)
                {
                    // Free variables, defined in outer scopes.
                    // Note that this scope is only a lexical scope (like a loop
                    // or BlockStatement), thus we don't need to query a local
                    // closure-tuple, we simply ask the parent scope for the
                    // binding.
                    _variableMapping[variable] = Parent._variableMapping[variable];
                }

            if (_scopeVars != null)
                foreach (var local in _scopeVars)
                {
                    // scope variables, defined in this scope
                    Debug.Assert(local.Kind == VariableKind.Local);
                    Debug.Assert(local.Scope == this);

                    if (local.AccessedInNestedScope)
                    {
                        // Closure variable
                        _variableMapping[local] = new ClosureExpression(local, Expression.Parameter(typeof(ClosureCell), local.Name), null);
                    }
                    else
                    {
                        // Not used in nested function-scopes
                        _variableMapping[local] = Expression.Parameter(typeof(object), local.Name);
                    }
                }
        }
Exemple #3
0
        internal virtual void FinishBind(TotemNameBinder 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, true));
                }
            }

            if (Variables != null)
            {
                foreach (TotemVariable 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();
            }
        }