Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
816e149c
Kaydet (Commit)
816e149c
authored
Mar 22, 2001
tarafından
Jeremy Hylton
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
First cut at a high-level symbol table interface
üst
987f1332
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
258 additions
and
0 deletions
+258
-0
symtable.py
Lib/symtable.py
+258
-0
No files found.
Lib/symtable.py
0 → 100644
Dosyayı görüntüle @
816e149c
"""Interface to the compiler's internal symbol tables"""
from
__future__
import
nested_scopes
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
import
weakref
__all__
=
[
"symtable"
,
"SymbolTable"
,
"newSymbolTable"
]
def
symtable
(
code
,
filename
,
compile_type
):
raw
=
_symtable
.
symtable
(
code
,
filename
,
compile_type
)
return
newSymbolTable
(
raw
[
0
],
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
bool
(
x
):
"""Helper to force boolean result to 1 or 0"""
if
x
:
return
1
return
0
def
is_free
(
flags
):
if
(
flags
&
(
USE
|
DEF_FREE
))
\
and
(
flags
&
(
DEF_LOCAL
|
DEF_PARAM
|
DEF_GLOBAL
)):
return
1
if
flags
&
DEF_FREE_CLASS
:
return
1
return
0
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
bool
()
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
]
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
.
keys
())
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
.
flag
&
DEF_STAR
)
def
is_keywordarg
(
self
):
return
bool
(
self
.
__flags
&
DEF_STARSTAR
)
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
1
if
self
.
__flags
&
DEF_FREE_CLASS
:
return
1
return
0
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
__debug__
:
class
Foo
:
version
=
1
class
Foo
:
version
=
2
class
Foo
:
version
=
3
def
execfunc
(
x
):
exec
x
in
y
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
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment