internal override void Bind(PythonNameBinder binder) { base.Bind(binder); Verify(binder); if (((PythonContext)binder.Context.SourceUnit.LanguageContext).PythonOptions.FullFrames) { // force a dictionary if we have enabled full frames for sys._getframe support NeedsLocalsDictionary = true; } }
private void Verify(PythonNameBinder binder) { if (ContainsImportStar) { binder.ReportSyntaxWarning("import * only allowed at module level", this); } if (ContainsImportStar && IsClosure) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it is a nested function", Name), this); } if (ContainsImportStar && Parent is FunctionDefinition) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it is a nested function", Name), this); } if (ContainsImportStar && ContainsNestedFreeVariables) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it contains a nested function with free variables", Name), this); } if (ContainsUnqualifiedExec && ContainsNestedFreeVariables) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "unqualified exec is not allowed in function '{0}' because it contains a nested function with free variables", Name), this); } if (ContainsUnqualifiedExec && IsClosure) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "unqualified exec is not allowed in function '{0}' because it is a nested function", Name), this); } }
internal virtual void Bind(PythonNameBinder binder) { if (_references != null) { foreach (var reference in _references.Values) { reference.PythonVariable = BindReference(binder, reference); if ((reference.PythonVariable is null || reference.PythonVariable.Kind is VariableKind.Global) && TryGetNonlocalStatement(reference.Name, out NonlocalStatement node)) { binder.ReportSyntaxError($"no binding for nonlocal '{reference.Name}' found", node); } } } }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { if (TryGetVariable(reference.Name, out PythonVariable variable)) { if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } return(variable); } // then bind in our parent scope return(_comprehension.Parent.BindReference(binder, reference)); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { if (TryGetVariable(reference.Name, out PythonVariable variable)) { if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } Debug.Assert(variable.Kind != VariableKind.Nonlocal, "there should be no nonlocals in a comprehension"); return(variable); } // then bind in our parent scope return(Parent.BindReference(binder, reference)); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { PythonVariable variable; // Python semantics: The variables bound local in the class // scope are accessed by name - the dictionary behavior of classes if (TryGetVariable(reference.Name, out variable)) { // TODO: This results in doing a dictionary lookup to get/set the local, // when it should probably be an uninitialized check / global lookup for gets // and a direct set if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } else if (variable.Kind == VariableKind.Local) { return(null); } if (variable.Kind != VariableKind.Nonlocal) { return(variable); } } // Try to bind in outer scopes, if we have an unqualified exec we need to leave the // variables as free for the same reason that locals are accessed by name. bool stopAtGlobal = variable?.Kind == VariableKind.Nonlocal; for (ScopeStatement parent = Parent; parent != null && !(stopAtGlobal && parent.IsGlobal); parent = parent.Parent) { if (parent.TryBindOuter(this, reference, out variable)) { return(variable); } } return(null); }
internal override void FinishBind(PythonNameBinder binder) { _contextInfo = CompilationMode.GetContext(); // create global variables for compiler context. PythonGlobal[] globalArray = new PythonGlobal[Variables == null ? 0 : Variables.Count]; Dictionary <string, PythonGlobal> globals = new Dictionary <string, PythonGlobal>(); GlobalDictionaryStorage storage = new GlobalDictionaryStorage(globals, globalArray); var modContext = _modContext = new ModuleContext(new PythonDictionary(storage), PyContext); #if FEATURE_REFEMIT if (_mode == CompilationMode.ToDisk) { _arrayExpression = _globalArray; } else #endif { var newArray = new ConstantExpression(globalArray); newArray.Parent = this; _arrayExpression = newArray; } if (Variables != null) { int globalIndex = 0; foreach (PythonVariable variable in Variables.Values) { PythonGlobal global = new PythonGlobal(modContext.GlobalContext, variable.Name); _globalVariables[variable] = CompilationMode.GetGlobal(GetGlobalContext(), globals.Count, variable, global); globalArray[globalIndex++] = globals[variable.Name] = global; } } CompilationMode.PublishContext(modContext.GlobalContext, _contextInfo); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { // First try variables local to this scope if (TryGetVariable(reference.Name, out PythonVariable variable)) { if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } Debug.Assert(variable.Kind != VariableKind.Nonlocal, "there should be no nonlocals in a comprehension"); return(variable); } // then try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(this, reference, out variable)) { return(variable); } } return(null); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { throw new InvalidOperationException(); }
internal PythonVariable EnsureGlobalVariable(PythonNameBinder binder, SymbolId name) { PythonVariable variable; if (TryGetVariable(name, out variable)) { // use the current one if it is global only if (variable.Kind == VariableKind.Global) { return variable; } } if ((binder.Module & ModuleOptions.Optimized) == 0) { // For non-optimized modules, keep globals separate if (_globals == null) { _globals = new Dictionary<SymbolId, PythonVariable>(); } if (!_globals.TryGetValue(name, out variable)) { variable = new PythonVariable(name, typeof(object), VariableKind.Global, this); _globals[name] = variable; } } else { variable = EnsureUnboundVariable(name); } return variable; }
internal override PythonVariable BindName(PythonNameBinder binder, SymbolId name) { return EnsureVariable(name); }
internal override PythonVariable BindName(PythonNameBinder binder, SymbolId name) { PythonVariable variable; // First try variables local to this scope if (TryGetVariable(name, out variable)) { return variable; } // Try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(name, out variable)) { IsClosure = true; variable.AccessedInNestedScope = true; if (_closureVars == null) { _closureVars = new List<SymbolId>(); } if (!_closureVars.Contains(name)) { _closureVars.Add(name); } return variable; } } // Unbound variable if (HasLateBoundVariableSets) { // If the context contains unqualified exec, new locals can be introduced // We introduce the locals for every free variable to optimize the name based // lookup. EnsureHiddenVariable(name); return null; } else { // Create a global variable to bind to. return GetGlobalScope().EnsureGlobalVariable(binder, name); } }
internal override PythonVariable BindName(PythonNameBinder binder, SymbolId name) { PythonVariable variable; // Python semantics: The variables bound local in the class // scope are accessed by name - the dictionary behavior of classes if (TryGetVariable(name, out variable)) { return variable.Kind == VariableKind.Local || variable.Kind == VariableKind.GlobalLocal || variable.Kind == VariableKind.HiddenLocal ? null : variable; } // Try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(name, out variable)) { return variable; } } return null; }
internal virtual void Bind(PythonNameBinder binder) { if (_references != null) { foreach (KeyValuePair<SymbolId, PythonReference> kv in _references) { PythonVariable variable; kv.Value.PythonVariable = variable = BindName(binder, kv.Key); // Accessing outer scope variable which is being deleted? if (variable != null && variable.Deleted && (object)variable.Scope != (object)this && !variable.Scope.IsGlobal) { // report syntax error binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "can not delete variable '{0}' referenced in nested scope", SymbolTable.IdToString(kv.Key) ), this); } } } }
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; }
internal virtual void Bind(PythonNameBinder binder) { if (_references != null) { foreach (var reference in _references.Values) { PythonVariable variable; reference.PythonVariable = variable = BindReference(binder, reference); // Accessing outer scope variable which is being deleted? if (variable != null) { if (variable.Deleted && variable.Scope != this && !variable.Scope.IsGlobal) { // report syntax error binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "can not delete variable '{0}' referenced in nested scope", reference.Name ), this); } } } } }
internal abstract PythonVariable BindReference(PythonNameBinder binder, PythonReference reference);
internal override PythonVariable BindName(PythonNameBinder binder, string name) { PythonVariable variable; // First try variables local to this scope if (TryGetVariable(name, out variable)) { if (variable.Kind == VariableKind.GlobalLocal || variable.Kind == VariableKind.Global) { AddReferencedGlobal(name); } return variable; } // Try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(name, out variable)) { IsClosure = true; variable.AccessedInNestedScope = true; UpdateReferencedVariables(name, variable, parent); return variable; } } // Unbound variable if (HasLateBoundVariableSets) { // If the context contains unqualified exec, new locals can be introduced // We introduce the locals for every free variable to optimize the name based // lookup. EnsureHiddenVariable(name); return null; } else { // Create a global variable to bind to. AddReferencedGlobal(name); return GetGlobalScope().EnsureGlobalVariable(binder, name); } }
internal virtual void Bind(PythonNameBinder binder) { if (_references != null) { foreach (KeyValuePair<SymbolId, PythonReference> kv in _references) { PythonVariable variable; kv.Value.PythonVariable = variable = BindName(binder, kv.Key); // Accessing outer scope variable which is being deleted? if (variable != null) { if (variable.Deleted && (object)variable.Scope != (object)this && !variable.Scope.IsGlobal) { // report syntax error binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "can not delete variable '{0}' referenced in nested scope", SymbolTable.IdToString(kv.Key) ), this); } if (variable.Scope != this && variable.Kind != VariableKind.Global && variable.Kind != VariableKind.GlobalLocal && !variable.Scope.IsGlobal) { ScopeStatement curScope = Parent; while (curScope != variable.Scope) { if (curScope._childReferences == null) { curScope._childReferences = new Dictionary<SymbolId, PythonReference>(); } curScope._childReferences[kv.Key] = kv.Value; curScope = curScope.Parent; } } } } } }
internal abstract PythonVariable BindName(PythonNameBinder binder, SymbolId name);
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; }
internal override PythonVariable BindName(PythonNameBinder binder, string name) { return EnsureVariable(name); }
private void Verify(PythonNameBinder binder) { if (ContainsImportStar && IsClosure) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it is a nested function", Name), this); } if (ContainsImportStar && Parent is FunctionDefinition) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it is a nested function", Name), this); } if (ContainsImportStar && ContainsNestedFreeVariables) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "import * is not allowed in function '{0}' because it contains a nested function with free variables", Name), this); } if (ContainsUnqualifiedExec && ContainsNestedFreeVariables) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "unqualified exec is not allowed in function '{0}' because it contains a nested function with free variables", Name), this); } if (ContainsUnqualifiedExec && IsClosure) { binder.ReportSyntaxError( String.Format( System.Globalization.CultureInfo.InvariantCulture, "unqualified exec is not allowed in function '{0}' because it is a nested function", Name), this); } }
public DefineBinder(PythonNameBinder binder) { _binder = binder; }
internal override PythonVariable BindName(PythonNameBinder binder, string name) { PythonVariable variable; // Python semantics: The variables bound local in the class // scope are accessed by name - the dictionary behavior of classes if (TryGetVariable(name, out variable)) { return variable.Kind == VariableKind.Local || variable.Kind == VariableKind.GlobalLocal || variable.Kind == VariableKind.HiddenLocal ? null : variable; } // Try to bind in outer scopes, if we have an unqualified exec we need to leave the // variables as free for the same reason that locals are accessed by name. for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(name, out variable)) { variable.AccessedInNestedScope = true; UpdateReferencedVariables(name, variable, parent); return variable; } } return null; }
public DeleteBinder(PythonNameBinder binder) { _binder = binder; }
internal PythonVariable EnsureGlobalVariable(PythonNameBinder binder, SymbolId name) { PythonVariable variable; if (TryGetVariable(name, out variable)) { // use the current one if it is global only if (variable.Kind == VariableKind.Global) { return variable; } } return EnsureUnboundVariable(name); }
internal abstract PythonVariable BindName(PythonNameBinder binder, string name);
public ParameterBinder(PythonNameBinder binder) { _binder = binder; }
internal override PythonVariable BindName(PythonNameBinder binder, SymbolId name) { PythonVariable variable; // First try variables local to this scope if (TryGetVariable(name, out variable)) { return variable; } // Try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(name, out variable)) { IsClosure = true; variable.AccessedInNestedScope = true; return variable; } } // Unbound variable if (ContainsUnqualifiedExec || ContainsImportStar || NeedsLocalsDictionary) { // If the context contains unqualified exec, new locals can be introduced // We introduce the locals for every free variable to optimize the name based // lookup. EnsureHiddenVariable(name); return null; } else { // Create a global variable to bind to. return GetGlobalScope().EnsureGlobalVariable(binder, name); } }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { PythonVariable variable; if (TryGetVariable(reference.Name, out variable)) { if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } return variable; } // then bind in our parent scope return _comprehension.Parent.BindReference(binder, reference); }
internal override void Bind(PythonNameBinder binder) { base.Bind(binder); Verify(binder); }
/// <summary> /// Binds an AST and makes it capable of being reduced and compiled. Before calling Bind an AST cannot successfully /// be reduced. /// </summary> public void Bind() { PythonNameBinder.BindAst(this, _compilerContext); StarredExpressionChecker.Check(this, _compilerContext); }
internal static void BindAst(PythonAst ast, CompilerContext context) { Assert.NotNull(ast, context); PythonNameBinder binder = new PythonNameBinder(context); binder.Bind(ast); }
internal override void FinishBind(PythonNameBinder binder) { _contextInfo = CompilationMode.GetContext(); // create global variables for compiler context. PythonGlobal[] globalArray = new PythonGlobal[Variables == null ? 0 : Variables.Count]; Dictionary<string, PythonGlobal> globals = new Dictionary<string, PythonGlobal>(); GlobalDictionaryStorage storage = new GlobalDictionaryStorage(globals, globalArray); var modContext = _modContext = new ModuleContext(new PythonDictionary(storage), PyContext); if (_mode == CompilationMode.ToDisk) { _arrayExpression = _globalArray; } else { var newArray = new ConstantExpression(globalArray); newArray.Parent = this; _arrayExpression = newArray; } if (Variables != null) { int globalIndex = 0; foreach (PythonVariable variable in Variables.Values) { PythonGlobal global = new PythonGlobal(modContext.GlobalContext, variable.Name); _globalVariables[variable] = CompilationMode.GetGlobal(GetGlobalContext(), globals.Count, variable, global); globalArray[globalIndex++] = globals[variable.Name] = global; } } CompilationMode.PublishContext(modContext.GlobalContext, _contextInfo); }
/// <summary> /// Binds an AST and makes it capable of being reduced and compiled. Before calling Bind an AST cannot successfully /// be reduced. /// </summary> public void Bind() { PythonNameBinder.BindAst(this, _compilerContext); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { return EnsureVariable(reference.Name); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { return(EnsureVariable(reference.Name)); }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { PythonVariable variable; // First try variables local to this scope if (TryGetVariable(reference.Name, out variable)) { if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } return variable; } // Try to bind in outer scopes for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(this, reference, out variable)) { return variable; } } return null; }
internal override PythonVariable BindReference(PythonNameBinder binder, PythonReference reference) { PythonVariable variable; // Python semantics: The variables bound local in the class // scope are accessed by name - the dictionary behavior of classes if (TryGetVariable(reference.Name, out variable)) { // TODO: This results in doing a dictionary lookup to get/set the local, // when it should probably be an uninitialized check / global lookup for gets // and a direct set if (variable.Kind == VariableKind.Global) { AddReferencedGlobal(reference.Name); } else if (variable.Kind == VariableKind.Local) { return null; } return variable; } // Try to bind in outer scopes, if we have an unqualified exec we need to leave the // variables as free for the same reason that locals are accessed by name. for (ScopeStatement parent = Parent; parent != null; parent = parent.Parent) { if (parent.TryBindOuter(this, reference, out variable)) { return variable; } } return null; }
internal override void FinishBind(PythonNameBinder binder) { foreach (var param in _parameters) { _variableMapping[param.PythonVariable] = param.FinishBind(NeedsLocalsDictionary); } base.FinishBind(binder); }