Commit d2f592da authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

merge

parents 7498f3c2 06a30603
...@@ -42,14 +42,17 @@ class FunctionState(object): ...@@ -42,14 +42,17 @@ class FunctionState(object):
self.temps_used_type = {} # name -> type self.temps_used_type = {} # name -> type
self.temp_counter = 0 self.temp_counter = 0
def new_label(self): def new_label(self, name=None):
n = self.label_counter n = self.label_counter
self.label_counter = n + 1 self.label_counter = n + 1
return "%s%d" % (Naming.label_prefix, n) label = "%s%d" % (Naming.label_prefix, n)
if name is not None:
label += '_' + name
return label
def new_error_label(self): def new_error_label(self):
old_err_lbl = self.error_label old_err_lbl = self.error_label
self.error_label = self.new_label() self.error_label = self.new_label('error')
return old_err_lbl return old_err_lbl
def get_loop_labels(self): def get_loop_labels(self):
...@@ -477,7 +480,7 @@ class CCodeWriter(object): ...@@ -477,7 +480,7 @@ class CCodeWriter(object):
return_from_error_cleanup_label = funccontext_property("return_from_error_cleanup_label") return_from_error_cleanup_label = funccontext_property("return_from_error_cleanup_label")
# Functions delegated to function scope # Functions delegated to function scope
def new_label(self): return self.funcstate.new_label() def new_label(self, name=None): return self.funcstate.new_label(name)
def new_error_label(self): return self.funcstate.new_error_label() def new_error_label(self): return self.funcstate.new_error_label()
def get_loop_labels(self): return self.funcstate.get_loop_labels() def get_loop_labels(self): return self.funcstate.get_loop_labels()
def set_loop_labels(self, labels): return self.funcstate.set_loop_labels(labels) def set_loop_labels(self, labels): return self.funcstate.set_loop_labels(labels)
......
...@@ -350,10 +350,9 @@ class CNameDeclaratorNode(CDeclaratorNode): ...@@ -350,10 +350,9 @@ class CNameDeclaratorNode(CDeclaratorNode):
def analyse(self, base_type, env, nonempty = 0): def analyse(self, base_type, env, nonempty = 0):
if nonempty and self.name == '': if nonempty and self.name == '':
raise RuntimeError
# May have mistaken the name for the type. # May have mistaken the name for the type.
if base_type.is_ptr or base_type.is_array or base_type.is_buffer: if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
error(self.pos, "Missing argument name.") error(self.pos, "Missing argument name")
elif base_type.is_void: elif base_type.is_void:
error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.") 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) self.name = base_type.declaration_code("", for_display=1, pyrex=1)
...@@ -415,9 +414,11 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -415,9 +414,11 @@ class CFuncDeclaratorNode(CDeclaratorNode):
optional_arg_count = 0 optional_arg_count = 0
def analyse(self, return_type, env, nonempty = 0): def analyse(self, return_type, env, nonempty = 0):
if nonempty:
nonempty -= 1
func_type_args = [] func_type_args = []
for arg_node in self.args: for arg_node in self.args:
name_declarator, type = arg_node.analyse(env) name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
name = name_declarator.name name = name_declarator.name
if name_declarator.cname: if name_declarator.cname:
error(self.pos, error(self.pos,
...@@ -1044,7 +1045,8 @@ class CFuncDefNode(FuncDefNode): ...@@ -1044,7 +1045,8 @@ class CFuncDefNode(FuncDefNode):
def analyse_declarations(self, env): def analyse_declarations(self, env):
base_type = self.base_type.analyse(env) base_type = self.base_type.analyse(env)
name_declarator, type = self.declarator.analyse(base_type, env, self.body is not None) # The 2 here is because we need both function and argument names.
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
if not type.is_cfunction: if not type.is_cfunction:
error(self.pos, error(self.pos,
"Suite attached to non-function declaration") "Suite attached to non-function declaration")
......
...@@ -1623,15 +1623,19 @@ def p_c_simple_base_type(s, self_flag, nonempty): ...@@ -1623,15 +1623,19 @@ def p_c_simple_base_type(s, self_flag, nonempty):
# Treat trailing [] on type as buffer access # Treat trailing [] on type as buffer access
if not is_basic and s.sy == '[': if s.sy == '[':
return p_buffer_access(s, type_node) return p_buffer_access(s, type_node)
else: else:
return type_node return type_node
def p_buffer_access(s, type_node): def p_buffer_access(s, base_type_node):
# s.sy == '[' # s.sy == '['
pos = s.position() pos = s.position()
s.next() 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 = ( positional_args, keyword_args = (
p_positional_and_keyword_args(s, (']',), (0,), ('dtype',)) p_positional_and_keyword_args(s, (']',), (0,), ('dtype',))
) )
...@@ -1646,7 +1650,7 @@ def p_buffer_access(s, type_node): ...@@ -1646,7 +1650,7 @@ def p_buffer_access(s, type_node):
result = Nodes.CBufferAccessTypeNode(pos, result = Nodes.CBufferAccessTypeNode(pos,
positional_args = positional_args, positional_args = positional_args,
keyword_args = keyword_dict, keyword_args = keyword_dict,
base_type_node = type_node) base_type_node = base_type_node)
return result return result
...@@ -2124,9 +2128,13 @@ def p_decorators(s): ...@@ -2124,9 +2128,13 @@ def p_decorators(s):
while s.sy == 'DECORATOR': while s.sy == 'DECORATOR':
pos = s.position() pos = s.position()
s.next() s.next()
decorator = ExprNodes.NameNode( decstring = p_dotted_name(s, as_allowed=0)[2]
pos, name = Utils.EncodedString( names = decstring.split('.')
p_dotted_name(s, as_allowed=0)[2] )) decorator = ExprNodes.NameNode(pos, name=Utils.EncodedString(names[0]))
for name in names[1:]:
decorator = ExprNodes.AttributeNode(pos,
attribute=Utils.EncodedString(name),
obj=decorator)
if s.sy == '(': if s.sy == '(':
decorator = p_call(s, decorator) decorator = p_call(s, decorator)
decorators.append(Nodes.DecoratorNode(pos, decorator=decorator)) decorators.append(Nodes.DecoratorNode(pos, decorator=decorator))
......
...@@ -58,6 +58,7 @@ class TestBufferOptions(CythonTest): ...@@ -58,6 +58,7 @@ class TestBufferOptions(CythonTest):
self.assert_(self.expect_error) self.assert_(self.expect_error)
def parse_opts(self, opts, expect_error=False): def parse_opts(self, opts, expect_error=False):
assert opts != ""
s = u"def f():\n cdef object[%s] x" % opts s = u"def f():\n cdef object[%s] x" % opts
self.expect_error = expect_error self.expect_error = expect_error
root = self.fragment(s, pipeline=[NormalizeTree(self), PostParse(self)]).root root = self.fragment(s, pipeline=[NormalizeTree(self), PostParse(self)]).root
...@@ -89,9 +90,6 @@ class TestBufferOptions(CythonTest): ...@@ -89,9 +90,6 @@ class TestBufferOptions(CythonTest):
self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1) self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
self.assertEqual(3, buf.ndim) self.assertEqual(3, buf.ndim)
def test_dtype(self):
self.non_parse(ERR_BUF_MISSING % 'dtype', u"")
def test_ndim(self): def test_ndim(self):
self.parse_opts(u"int, 2") self.parse_opts(u"int, 2")
self.non_parse(ERR_BUF_INT % 'ndim', u"int, 'a'") self.non_parse(ERR_BUF_INT % 'ndim', u"int, 'a'")
......
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[])
_ERRORS = u"""
4:4 Expected a newline after decorator
"""
class A:
pass
@A().a
def f():
pass
...@@ -13,6 +13,10 @@ __doc__ = u""" ...@@ -13,6 +13,10 @@ __doc__ = u"""
6 6
>>> h.HERE >>> h.HERE
1 1
>>> i(4)
3
>>> i.HERE
1
""" """
class wrap: class wrap:
...@@ -47,3 +51,13 @@ def g(a,b): ...@@ -47,3 +51,13 @@ def g(a,b):
@decorate2(1,2) @decorate2(1,2)
def h(a,b): def h(a,b):
return a+b+3 return a+b+3
class A:
def decorate(self, func):
return decorate(func)
a = A()
@a.decorate
def i(x):
return x - 1
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