diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
commit | a73a964e51247ed169d322c725a3a18859f109a3 (patch) | |
tree | 3f752d117274d444bda44e85609aeac1acf313f3 /sys/lib/python/symtable.py | |
parent | e64efe273fcb921a61bf27d33b230c4e64fcd425 (diff) |
python, hg: tow outside the environment.
they've served us well, and can ride off into the sunset.
Diffstat (limited to 'sys/lib/python/symtable.py')
-rw-r--r-- | sys/lib/python/symtable.py | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/sys/lib/python/symtable.py b/sys/lib/python/symtable.py deleted file mode 100644 index 3f1332e8e..000000000 --- a/sys/lib/python/symtable.py +++ /dev/null @@ -1,252 +0,0 @@ -"""Interface to the compiler's internal symbol tables""" - -import _symtable -from _symtable import USE, DEF_GLOBAL, DEF_LOCAL, DEF_PARAM, \ - DEF_STAR, DEF_DOUBLESTAR, DEF_INTUPLE, DEF_FREE, \ - DEF_FREE_GLOBAL, DEF_FREE_CLASS, DEF_IMPORT, DEF_BOUND, \ - OPT_IMPORT_STAR, OPT_EXEC, OPT_BARE_EXEC - -import weakref - -__all__ = ["symtable", "SymbolTable", "newSymbolTable", "Class", - "Function", "Symbol"] - -def symtable(code, filename, compile_type): - raw = _symtable.symtable(code, filename, compile_type) - for top in raw.itervalues(): - if top.name == 'top': - break - return newSymbolTable(top, filename) - -class SymbolTableFactory: - def __init__(self): - self.__memo = weakref.WeakValueDictionary() - - def new(self, table, filename): - if table.type == _symtable.TYPE_FUNCTION: - return Function(table, filename) - if table.type == _symtable.TYPE_CLASS: - return Class(table, filename) - return SymbolTable(table, filename) - - def __call__(self, table, filename): - key = table, filename - obj = self.__memo.get(key, None) - if obj is None: - obj = self.__memo[key] = self.new(table, filename) - return obj - -newSymbolTable = SymbolTableFactory() - -def is_free(flags): - if (flags & (USE | DEF_FREE)) \ - and (flags & (DEF_LOCAL | DEF_PARAM | DEF_GLOBAL)): - return True - if flags & DEF_FREE_CLASS: - return True - return False - -class SymbolTable: - def __init__(self, raw_table, filename): - self._table = raw_table - self._filename = filename - self._symbols = {} - - def __repr__(self): - if self.__class__ == SymbolTable: - kind = "" - else: - kind = "%s " % self.__class__.__name__ - - if self._table.name == "global": - return "<%sSymbolTable for module %s>" % (kind, self._filename) - else: - return "<%sSymbolTable for %s in %s>" % (kind, self._table.name, - self._filename) - - def get_type(self): - if self._table.type == _symtable.TYPE_MODULE: - return "module" - if self._table.type == _symtable.TYPE_FUNCTION: - return "function" - if self._table.type == _symtable.TYPE_CLASS: - return "class" - assert self._table.type in (1, 2, 3), \ - "unexpected type: %s" % self._table.type - - def get_id(self): - return self._table.id - - def get_name(self): - return self._table.name - - def get_lineno(self): - return self._table.lineno - - def is_optimized(self): - return bool(self._table.type == _symtable.TYPE_FUNCTION - and not self._table.optimized) - - def is_nested(self): - return bool(self._table.nested) - - def has_children(self): - return bool(self._table.children) - - def has_exec(self): - """Return true if the scope uses exec""" - return bool(self._table.optimized & (OPT_EXEC | OPT_BARE_EXEC)) - - def has_import_star(self): - """Return true if the scope uses import *""" - return bool(self._table.optimized & OPT_IMPORT_STAR) - - def get_identifiers(self): - return self._table.symbols.keys() - - def lookup(self, name): - sym = self._symbols.get(name) - if sym is None: - flags = self._table.symbols[name] - namespaces = self.__check_children(name) - sym = self._symbols[name] = Symbol(name, flags, namespaces) - return sym - - def get_symbols(self): - return [self.lookup(ident) for ident in self.get_identifiers()] - - def __check_children(self, name): - return [newSymbolTable(st, self._filename) - for st in self._table.children - if st.name == name] - - def get_children(self): - return [newSymbolTable(st, self._filename) - for st in self._table.children] - -class Function(SymbolTable): - - # Default values for instance variables - __params = None - __locals = None - __frees = None - __globals = None - - def __idents_matching(self, test_func): - return tuple([ident for ident in self.get_identifiers() - if test_func(self._table.symbols[ident])]) - - def get_parameters(self): - if self.__params is None: - self.__params = self.__idents_matching(lambda x:x & DEF_PARAM) - return self.__params - - def get_locals(self): - if self.__locals is None: - self.__locals = self.__idents_matching(lambda x:x & DEF_BOUND) - return self.__locals - - def get_globals(self): - if self.__globals is None: - glob = DEF_GLOBAL | DEF_FREE_GLOBAL - self.__globals = self.__idents_matching(lambda x:x & glob) - return self.__globals - - def get_frees(self): - if self.__frees is None: - self.__frees = self.__idents_matching(is_free) - return self.__frees - -class Class(SymbolTable): - - __methods = None - - def get_methods(self): - if self.__methods is None: - d = {} - for st in self._table.children: - d[st.name] = 1 - self.__methods = tuple(d) - return self.__methods - -class Symbol: - def __init__(self, name, flags, namespaces=None): - self.__name = name - self.__flags = flags - self.__namespaces = namespaces or () - - def __repr__(self): - return "<symbol '%s'>" % self.__name - - def get_name(self): - return self.__name - - def is_referenced(self): - return bool(self.__flags & _symtable.USE) - - def is_parameter(self): - return bool(self.__flags & DEF_PARAM) - - def is_global(self): - return bool((self.__flags & DEF_GLOBAL) - or (self.__flags & DEF_FREE_GLOBAL)) - - def is_vararg(self): - return bool(self.__flags & DEF_STAR) - - def is_keywordarg(self): - return bool(self.__flags & DEF_DOUBLESTAR) - - def is_local(self): - return bool(self.__flags & DEF_BOUND) - - def is_free(self): - if (self.__flags & (USE | DEF_FREE)) \ - and (self.__flags & (DEF_LOCAL | DEF_PARAM | DEF_GLOBAL)): - return True - if self.__flags & DEF_FREE_CLASS: - return True - return False - - def is_imported(self): - return bool(self.__flags & DEF_IMPORT) - - def is_assigned(self): - return bool(self.__flags & DEF_LOCAL) - - def is_in_tuple(self): - return bool(self.__flags & DEF_INTUPLE) - - def is_namespace(self): - """Returns true if name binding introduces new namespace. - - If the name is used as the target of a function or class - statement, this will be true. - - Note that a single name can be bound to multiple objects. If - is_namespace() is true, the name may also be bound to other - objects, like an int or list, that does not introduce a new - namespace. - """ - return bool(self.__namespaces) - - def get_namespaces(self): - """Return a list of namespaces bound to this name""" - return self.__namespaces - - def get_namespace(self): - """Returns the single namespace bound to this name. - - Raises ValueError if the name is bound to multiple namespaces. - """ - if len(self.__namespaces) != 1: - raise ValueError, "name is bound to multiple namespaces" - return self.__namespaces[0] - -if __name__ == "__main__": - import os, sys - src = open(sys.argv[0]).read() - mod = symtable(src, os.path.split(sys.argv[0])[1], "exec") - for ident in mod.get_identifiers(): - info = mod.lookup(ident) - print info, info.is_local(), info.is_namespace() |