Commit d97bdff5 authored by Stefan Behnel's avatar Stefan Behnel

merge

parents 46f2563c 1d5644c7
......@@ -628,7 +628,7 @@ class BoolNode(ConstNode):
return self.value
def calculate_result_code(self):
return int(self.value)
return str(int(self.value))
class NullNode(ConstNode):
type = PyrexTypes.c_null_ptr_type
......@@ -1680,6 +1680,7 @@ class SimpleCallNode(CallNode):
# self ExprNode or None used internally
# coerced_self ExprNode or None used internally
# wrapper_call bool used internally
# has_optional_args bool used internally
subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
......@@ -1687,6 +1688,7 @@ class SimpleCallNode(CallNode):
coerced_self = None
arg_tuple = None
wrapper_call = False
has_optional_args = False
def compile_time_value(self, denv):
function = self.function.compile_time_value(denv)
......@@ -1773,6 +1775,11 @@ class SimpleCallNode(CallNode):
self.type = PyrexTypes.error_type
self.result_code = "<error>"
return
if func_type.optional_arg_count and expected_nargs != actual_nargs:
self.has_optional_args = 1
self.is_temp = 1
self.opt_arg_struct = env.allocate_temp(func_type.op_arg_struct.base_type)
env.release_temp(self.opt_arg_struct)
# Coerce arguments
for i in range(min(max_nargs, actual_nargs)):
formal_type = func_type.args[i].type
......@@ -1818,15 +1825,7 @@ class SimpleCallNode(CallNode):
if expected_nargs == actual_nargs:
optional_args = 'NULL'
else:
optional_arg_code = [str(actual_nargs - expected_nargs)]
for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
arg_code = actual_arg.result_as(formal_arg.type)
optional_arg_code.append(arg_code)
# for formal_arg in formal_args[actual_nargs:max_nargs]:
# optional_arg_code.append(formal_arg.type.cast_code('0'))
optional_arg_struct = '{%s}' % ','.join(optional_arg_code)
optional_args = PyrexTypes.c_void_ptr_type.cast_code(
'&' + func_type.op_arg_struct.base_type.cast_code(optional_arg_struct))
optional_args = "&%s" % self.opt_arg_struct
arg_list_code.append(optional_args)
for actual_arg in self.args[len(formal_args):]:
......@@ -1849,6 +1848,19 @@ class SimpleCallNode(CallNode):
arg_code,
code.error_goto_if_null(self.result_code, self.pos)))
elif func_type.is_cfunction:
if self.has_optional_args:
actual_nargs = len(self.args)
expected_nargs = len(func_type.args) - func_type.optional_arg_count
code.putln("%s.%s = %s;" % (
self.opt_arg_struct,
Naming.pyrex_prefix + "n",
len(self.args) - expected_nargs))
args = zip(func_type.args, self.args)
for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
code.putln("%s.%s = %s;" % (
self.opt_arg_struct,
formal_arg.name,
actual_arg.result_as(formal_arg.type)))
exc_checks = []
if self.type.is_pyobject:
exc_checks.append("!%s" % self.result_code)
......@@ -1883,12 +1895,12 @@ class SimpleCallNode(CallNode):
rhs,
raise_py_exception,
code.error_goto(self.pos)))
return
code.putln(
"%s%s; %s" % (
lhs,
rhs,
code.error_goto_if(" && ".join(exc_checks), self.pos)))
else:
if exc_checks:
goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
else:
goto_error = ""
code.putln("%s%s; %s" % (lhs, rhs, goto_error))
class GeneralCallNode(CallNode):
# General Python function call, including keyword,
......
......@@ -1467,7 +1467,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
entry.is_identifier
))
code.putln(
"{0, 0, 0, 0, 0}")
"{0, 0, 0, 0, 0, 0}")
code.putln(
"};")
......
......@@ -362,8 +362,13 @@ class CNameDeclaratorNode(CDeclaratorNode):
def analyse(self, base_type, env, nonempty = 0):
if nonempty and self.name == '':
# Must have mistaken the name for the type.
self.name = base_type.name
raise RuntimeError
# May have mistaken the name for the type.
if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
error(self.pos, "Missing argument name.")
elif base_type.is_void:
error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
self.name = base_type.declaration_code("", for_display=1, pyrex=1)
base_type = py_object_type
self.type = base_type
return self, base_type
......@@ -424,7 +429,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
def analyse(self, return_type, env, nonempty = 0):
func_type_args = []
for arg_node in self.args:
name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
name_declarator, type = arg_node.analyse(env)
name = name_declarator.name
if name_declarator.cname:
error(self.pos,
......
......@@ -1620,15 +1620,19 @@ def p_c_simple_base_type(s, self_flag, nonempty):
# Treat trailing [] on type as buffer access
if not is_basic and s.sy == '[':
if s.sy == '[':
return p_buffer_access(s, type_node)
else:
return type_node
def p_buffer_access(s, type_node):
def p_buffer_access(s, base_type_node):
# s.sy == '['
pos = s.position()
s.next()
if s.sy == ']':
# not buffer, could be [] on C type nameless array arguments
s.put_back('[', '[')
return base_type_node
positional_args, keyword_args = (
p_positional_and_keyword_args(s, (']',), (0,), ('dtype',))
)
......@@ -1643,7 +1647,7 @@ def p_buffer_access(s, type_node):
result = Nodes.CBufferAccessTypeNode(pos,
positional_args = positional_args,
keyword_args = keyword_dict,
base_type_node = type_node)
base_type_node = base_type_node)
return result
......
......@@ -58,6 +58,7 @@ class TestBufferOptions(CythonTest):
self.assert_(self.expect_error)
def parse_opts(self, opts, expect_error=False):
assert opts != ""
s = u"def f():\n cdef object[%s] x" % opts
self.expect_error = expect_error
root = self.fragment(s, pipeline=[NormalizeTree(self), PostParse(self)]).root
......@@ -89,9 +90,6 @@ class TestBufferOptions(CythonTest):
self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
self.assertEqual(3, buf.ndim)
def test_dtype(self):
self.non_parse(ERR_BUF_MISSING % 'dtype', u"")
def test_ndim(self):
self.parse_opts(u"int, 2")
self.non_parse(ERR_BUF_INT % 'ndim', u"int, 'a'")
......
......@@ -7,7 +7,6 @@ from Cython.Distutils import build_ext
ext_modules=[
Extension("primes", ["primes.pyx"]),
Extension("spam", ["spam.pyx"]),
# Extension("optargs", ["optargs.pyx"], language = "c++"),
]
for file in glob.glob("*.pyx"):
......
PYTHON?=python
all: local
local:
${PYTHON} setup.py build_ext --inplace
clean:
@echo Cleaning Source
@rm -fr build
@rm -f *.pyc */*.pyc */*/*.pyc
@rm -f *~ */*~ */*/*~
@rm -f core */core
@rm -f Cython/Plex/Scanners.{so,pyd}
@(cd Demos; $(MAKE) clean)
testclean:
......
cdef extern from *:
cdef void foo(int[])
ctypedef int MyInt
cdef void foo(MyInt[])
struct MyStruct:
pass
cdef void bar(MyStruct[])
ctypedef MyStruct* MyStructP
cdef void baz(MyStructP[])
def f(obj, int i, float f, char *s1, char s2[]):
pass
cdef g(obj, int i, float f, char *s1, char s2[]):
pass
cdef do_g(object (*func)(object, int, float, char*, char*)):
return func(1, 2, 3.14159, "a", "b")
do_g(&g)
__doc__ = u"""
>>> e = ExtClass()
>>> e.get()
5
"""
cdef class ExtClass:
cdef int _attribute = 2
def get(self):
return self._attribute
_attribute = 5 # FIXME: this is not currently handled!!!
_ERRORS = u"""
8:13: Cannot assign default value to cdef class attributes
"""
"""
>>> call_test()
False
True
False
True
True
True
True
"""
cdef test(bint value):
print value
def call_test():
test(False)
test(True)
test(0)
test(234)
test(-1)
x = True
test(x)
x = 3242
test(x)
__doc__ = u"""
>>> test_c(u'abc')
fileabc
typeabc
>>> print test_file_py(u'abc')
abc
>>> print range(u'abc')
rangeabc
"""
def test_file_py(file):
return file
cdef test_file_c(file):
return u'file' + file
def range(arg):
return u'range' + arg
cdef type(arg):
return u'type' + arg
def test_c(arg):
print test_file_c(arg)
print type(arg)
......@@ -2,6 +2,11 @@ __doc__ = u"""
>>> call2()
>>> call3()
>>> call4()
>>> test_foo()
2
3
7
26
"""
# the calls:
......@@ -19,3 +24,13 @@ def call4():
cdef b(a, b, c=1, d=2):
pass
cdef int foo(int a, int b=1, int c=1):
return a+b*c
def test_foo():
print foo(1)
print foo(1, 2)
print foo(1, 2, 3)
print foo(1, foo(2, 3), foo(4))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment