Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
2dc560a7
Commit
2dc560a7
authored
Oct 18, 2007
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added getattr3() builtin
parent
0f319c23
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
149 additions
and
17 deletions
+149
-17
Cython/Compiler/Builtin.py
Cython/Compiler/Builtin.py
+115
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+21
-12
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+13
-5
No files found.
Cython/Compiler/Builtin.py
0 → 100644
View file @
2dc560a7
#
# Pyrex - Builtin Definitions
#
from
Symtab
import
BuiltinScope
from
TypeSlots
import
Signature
builtin_function_table
=
[
# name, args, return, C API func, py equiv = "*"
(
'abs'
,
"O"
,
"O"
,
"PyNumber_Absolute"
),
#('chr', "", "", ""),
#('cmp', "", "", "", ""), # int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
#('compile', "", "", ""), # PyObject* Py_CompileString( char *str, char *filename, int start)
(
'delattr'
,
"OO"
,
"r"
,
"PyObject_DelAttr"
),
(
'dir'
,
"O"
,
"O"
,
"PyObject_Dir"
),
(
'divmod'
,
"OO"
,
"O"
,
"PyNumber_Divmod"
),
#('eval', "", "", ""),
#('execfile', "", "", ""),
#('filter', "", "", ""),
(
'getattr'
,
"OO"
,
"O"
,
"PyObject_GetAttr"
),
(
'getattr3'
,
"OOO"
,
"O"
,
"__Pyx_GetAttr3"
,
"getattr"
),
(
'hasattr'
,
"OO"
,
"i"
,
"PyObject_HasAttr"
),
(
'hash'
,
"O"
,
"i"
,
"PyObject_Hash"
),
#('hex', "", "", ""),
#('id', "", "", ""),
#('input', "", "", ""),
(
'intern'
,
"s"
,
"O"
,
"PyString_InternFromString"
),
(
'isinstance'
,
"OO"
,
"i"
,
"PyObject_IsInstance"
),
(
'issubclass'
,
"OO"
,
"i"
,
"PyObject_IsSubclass"
),
(
'iter'
,
"O"
,
"O"
,
"PyObject_GetIter"
),
(
'len'
,
"O"
,
"Z"
,
"PyObject_Length"
),
#('map', "", "", ""),
#('max', "", "", ""),
#('min', "", "", ""),
#('oct', "", "", ""),
# Not worth doing open, when second argument would become mandatory
#('open', "ss", "O", "PyFile_FromString"),
#('ord', "", "", ""),
(
'pow'
,
"OOO"
,
"O"
,
"PyNumber_Power"
),
#('range', "", "", ""),
#('raw_input', "", "", ""),
#('reduce', "", "", ""),
(
'reload'
,
"O"
,
"O"
,
"PyImport_ReloadModule"
),
(
'repr'
,
"O"
,
"O"
,
"PyObject_Repr"
),
#('round', "", "", ""),
(
'setattr'
,
"OOO"
,
"r"
,
"PyObject_SetAttr"
),
#('sum', "", "", ""),
#('unichr', "", "", ""),
#('unicode', "", "", ""),
#('vars', "", "", ""),
#('zip', "", "", ""),
# Can't do these easily until we have builtin type entries.
#('typecheck', "OO", "i", "PyObject_TypeCheck", False),
#('issubtype', "OO", "i", "PyType_IsSubtype", False),
]
# Builtin types
# bool
# buffer
# classmethod
# dict
# enumerate
# file
# float
# int
# list
# long
# object
# property
# slice
# staticmethod
# super
# str
# tuple
# type
# xrange
getattr3_utility_code
=
[
"""
static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
"""
,
"""
static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
PyObject *r = PyObject_GetAttr(o, n);
if (!r) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
goto bad;
PyErr_Clear();
r = d;
Py_INCREF(d);
}
return r;
bad:
return 0;
}
"""
]
builtin_utility_code
=
{
'getattr3'
:
getattr3_utility_code
,
}
builtin_scope
=
BuiltinScope
()
def
declare_builtin_func
(
name
,
args
,
ret
,
cname
,
py_equiv
=
"*"
):
sig
=
Signature
(
args
,
ret
)
type
=
sig
.
function_type
()
utility
=
builtin_utility_code
.
get
(
name
)
builtin_scope
.
declare_builtin_cfunction
(
name
,
type
,
cname
,
py_equiv
,
utility
)
def
init_builtin_funcs
():
for
desc
in
builtin_function_table
:
declare_builtin_func
(
*
desc
)
def
init_builtins
():
init_builtin_funcs
()
init_builtins
()
Cython/Compiler/ExprNodes.py
View file @
2dc560a7
...
@@ -99,9 +99,9 @@ class ExprNode(Node):
...
@@ -99,9 +99,9 @@ class ExprNode(Node):
# temps used during assignment.
# temps used during assignment.
#
#
# calculate_result_code
# calculate_result_code
# -
Return a C code fragment evaluating to
# -
Called during the Allocate Temps phase. Should return a
#
the result. This is only called when the
#
C code fragment evaluating to the result. This is only
# result is not a temporary.
#
called when the
result is not a temporary.
#
#
# target_code
# target_code
# Called by the default implementation of allocate_target_temps.
# Called by the default implementation of allocate_target_temps.
...
@@ -365,7 +365,10 @@ class ExprNode(Node):
...
@@ -365,7 +365,10 @@ class ExprNode(Node):
if
debug_temp_alloc
:
if
debug_temp_alloc
:
print
self
,
"Allocated result"
,
self
.
result_code
print
self
,
"Allocated result"
,
self
.
result_code
else
:
else
:
self
.
result_code
=
self
.
calculate_result_code
()
self
.
result_code
=
self
.
calculate_result_code_with_env
(
env
)
def
calculate_result_code_with_env
(
self
,
env
):
return
self
.
calculate_result_code
()
def
target_code
(
self
):
def
target_code
(
self
):
# Return code fragment for use as LHS of a C assignment.
# Return code fragment for use as LHS of a C assignment.
...
@@ -814,13 +817,13 @@ class NameNode(AtomicExprNode):
...
@@ -814,13 +817,13 @@ class NameNode(AtomicExprNode):
if
entry
.
is_pyglobal
or
entry
.
is_builtin
:
if
entry
.
is_pyglobal
or
entry
.
is_builtin
:
assert
type
.
is_pyobject
,
"Python global or builtin not a Python object"
assert
type
.
is_pyobject
,
"Python global or builtin not a Python object"
if
Options
.
intern_names
:
if
Options
.
intern_names
:
self
.
interned_cname
=
env
.
intern
(
self
.
name
)
self
.
interned_cname
=
env
.
intern
(
self
.
entry
.
name
)
def
check_identifier_kind
(
self
):
def
check_identifier_kind
(
self
):
#print "NameNode.check_identifier_kind:", self.entry.name ###
#print "NameNode.check_identifier_kind:", self.entry.name ###
#print self.entry.__dict__ ###
#print self.entry.__dict__ ###
entry
=
self
.
entry
entry
=
self
.
entry
entry
.
used
=
1
#
entry.used = 1
if
not
(
entry
.
is_const
or
entry
.
is_variable
if
not
(
entry
.
is_const
or
entry
.
is_variable
or
entry
.
is_builtin
or
entry
.
is_cfunction
):
or
entry
.
is_builtin
or
entry
.
is_cfunction
):
if
self
.
entry
.
as_variable
:
if
self
.
entry
.
as_variable
:
...
@@ -856,15 +859,23 @@ class NameNode(AtomicExprNode):
...
@@ -856,15 +859,23 @@ class NameNode(AtomicExprNode):
# result is in a temporary.
# result is in a temporary.
return
0
return
0
def
calculate_result_code_with_env
(
self
,
env
):
entry
=
self
.
entry
if
entry
:
entry
.
used
=
1
if
entry
.
utility_code
:
env
.
use_utility_code
(
entry
.
utility_code
)
return
self
.
calculate_result_code
()
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
if
self
.
entry
is
None
:
entry
=
self
.
entry
if
not
entry
:
return
"<error>"
# There was an error earlier
return
"<error>"
# There was an error earlier
return
self
.
entry
.
cname
entry
.
used
=
1
return
entry
.
cname
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
assert
hasattr
(
self
,
'entry'
)
assert
hasattr
(
self
,
'entry'
)
#if not hasattr(self, 'entry'):
# error(self.pos, "INTERNAL ERROR: NameNode has no entry attribute during code generation")
entry
=
self
.
entry
entry
=
self
.
entry
if
entry
is
None
:
if
entry
is
None
:
return
# There was an error earlier
return
# There was an error earlier
...
@@ -876,12 +887,10 @@ class NameNode(AtomicExprNode):
...
@@ -876,12 +887,10 @@ class NameNode(AtomicExprNode):
else
:
# entry.is_pyglobal
else
:
# entry.is_pyglobal
namespace
=
entry
.
namespace_cname
namespace
=
entry
.
namespace_cname
if
Options
.
intern_names
:
if
Options
.
intern_names
:
#assert entry.interned_cname is not None
code
.
putln
(
code
.
putln
(
'%s = __Pyx_GetName(%s, %s); %s'
%
(
'%s = __Pyx_GetName(%s, %s); %s'
%
(
self
.
result_code
,
self
.
result_code
,
namespace
,
namespace
,
#entry.interned_cname,
self
.
interned_cname
,
self
.
interned_cname
,
code
.
error_goto_if_null
(
self
.
result_code
,
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result_code
,
self
.
pos
)))
else
:
else
:
...
...
Cython/Compiler/Symtab.py
View file @
2dc560a7
...
@@ -69,6 +69,7 @@ class Entry:
...
@@ -69,6 +69,7 @@ class Entry:
# of an extension type
# of an extension type
# defined_in_pxd boolean Is defined in a .pxd file (not just declared)
# defined_in_pxd boolean Is defined in a .pxd file (not just declared)
# api boolean Generate C API for C class or function
# api boolean Generate C API for C class or function
# utility_code string Utility code needed when this entry is used
borrowed
=
0
borrowed
=
0
init
=
""
init
=
""
...
@@ -105,6 +106,7 @@ class Entry:
...
@@ -105,6 +106,7 @@ class Entry:
is_special
=
0
is_special
=
0
defined_in_pxd
=
0
defined_in_pxd
=
0
api
=
0
api
=
0
utility_code
=
None
def
__init__
(
self
,
name
,
cname
,
type
,
pos
=
None
,
init
=
None
):
def
__init__
(
self
,
name
,
cname
,
type
,
pos
=
None
,
init
=
None
):
self
.
name
=
name
self
.
name
=
name
...
@@ -574,13 +576,19 @@ class BuiltinScope(Scope):
...
@@ -574,13 +576,19 @@ class BuiltinScope(Scope):
self
.
cached_entries
.
append
(
entry
)
self
.
cached_entries
.
append
(
entry
)
self
.
undeclared_cached_entries
.
append
(
entry
)
self
.
undeclared_cached_entries
.
append
(
entry
)
else
:
else
:
entry
.
is_builtin
=
1
entry
.
is_builtin
=
1
return
entry
return
entry
def
declare_builtin_cfunction
(
self
,
name
,
type
,
cname
,
with_python_equiv
=
0
):
def
declare_builtin_cfunction
(
self
,
name
,
type
,
cname
,
python_equiv
=
None
,
utility_code
=
None
):
# If python_equiv == "*", the Python equivalent has the same name
# as the entry, otherwise it has the name specified by python_equiv.
entry
=
self
.
declare_cfunction
(
name
,
type
,
None
,
cname
)
entry
=
self
.
declare_cfunction
(
name
,
type
,
None
,
cname
)
if
with_python_equiv
:
entry
.
utility_code
=
utility_code
var_entry
=
Entry
(
name
,
name
,
py_object_type
)
if
python_equiv
:
if
python_equiv
==
"*"
:
python_equiv
=
name
var_entry
=
Entry
(
python_equiv
,
python_equiv
,
py_object_type
)
var_entry
.
is_variable
=
1
var_entry
.
is_variable
=
1
var_entry
.
is_builtin
=
1
var_entry
.
is_builtin
=
1
entry
.
as_variable
=
var_entry
entry
.
as_variable
=
var_entry
...
...
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