Show Namespace.cs syntax highlighted
/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for IronPython. A copy of the license can be found in the License.html file
* at the root of this distribution. If you can not locate the Shared Source License
* for IronPython, please send an email to ironpy@microsoft.com.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for IronPython.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using IronPython.Runtime;
namespace IronPython.Compiler.Generation {
// Namespaces can be nested to get lexical scoping. Python looks up name as follows.
//
// Assignments to a name :
// For assignments, the name is assumed to be a local unless explicitly declared as global using
// the "global var" statement.
// GetSlotForSet() is the API which implements this.
//
// References to a name
// For names referenced in an expression or statement, Python uses the LEGB lookup rule, where the
// order of lookup is:
// 1. Locals of the function
// 2. Enclosing local function scopes for nested functions and lambdas
// 3. Globals declared by the module
// 4. Built-in module which is always available
// GetOrMakeSlotForGet() is the API which implements this
//
// Note that for module-level code, globals and locals are the same.
class Namespace {
private Dictionary<SymbolId, Slot> slots = new Dictionary<SymbolId, Slot>();
private SlotFactory locals;
private GlobalNamespace globals;
// temporary slots
private List<Slot> temps = new List<Slot>();
public Namespace(SlotFactory factory) {
this.locals = factory;
}
internal GlobalNamespace Globals {
get {
Debug.Assert(globals != null, "No globals");
return globals;
}
set { globals = value; }
}
public Slot this[SymbolId name] {
get {
Debug.Assert(slots.ContainsKey(name), "undefined slot: " + name.GetString());
return slots[name];
}
set {
Debug.Assert(!slots.ContainsKey(name), "slot override: " + name.GetString());
slots[name] = value;
}
}
public Dictionary<SymbolId, Slot> Slots {
get {
return slots;
}
}
internal Slot CreateGlobalSlot(SymbolId name) {
Slot slot = Globals.GetOrMakeSlot(name);
slots[name] = slot;
return slot;
}
internal Slot EnsureLocalSlot(SymbolId name) {
Slot slot;
if (!slots.TryGetValue(name, out slot)) {
slot = locals.MakeSlot(name);
slots[name] = slot;
}
return slot;
}
public void AddTempSlot(Slot slot) {
temps.Add(slot);
}
public void SetSlot(SymbolId name, Slot slot) {
slots[name] = slot;
}
private int tempCounter = 0;
public Slot GetTempSlot(string prefix, Type type) {
if (locals != null) {
return locals.MakeSlot(SymbolTable.StringToId(prefix + "$" + tempCounter++), type);
} else {
Debug.Assert(tempCounter < temps.Count);
return new CastSlot(temps[tempCounter++], type);
}
}
}
}
See more files for this project here