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

merge

parents 7498f3c2 06a30603
......@@ -42,14 +42,17 @@ class FunctionState(object):
self.temps_used_type = {} # name -> type
self.temp_counter = 0
def new_label(self):
def new_label(self, name=None):
n = self.label_counter
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):
old_err_lbl = self.error_label
self.error_label = self.new_label()
self.error_label = self.new_label('error')
return old_err_lbl
def get_loop_labels(self):
......@@ -477,7 +480,7 @@ class CCodeWriter(object):
return_from_error_cleanup_label = funccontext_property("return_from_error_cleanup_label")
# 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 get_loop_labels(self): return self.funcstate.get_loop_labels()
def set_loop_labels(self, labels): return self.funcstate.set_loop_labels(labels)
......
......@@ -350,10 +350,9 @@ class CNameDeclaratorNode(CDeclaratorNode):
def analyse(self, base_type, env, nonempty = 0):
if nonempty and self.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.")
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)
......@@ -415,9 +414,11 @@ class CFuncDeclaratorNode(CDeclaratorNode):
optional_arg_count = 0
def analyse(self, return_type, env, nonempty = 0):
if nonempty:
nonempty -= 1
func_type_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
if name_declarator.cname:
error(self.pos,
......@@ -1044,7 +1045,8 @@ class CFuncDefNode(FuncDefNode):
def analyse_declarations(self, 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:
error(self.pos,
"Suite attached to non-function declaration")
......
......@@ -1623,15 +1623,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',))
)
......@@ -1646,7 +1650,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
......@@ -2124,9 +2128,13 @@ def p_decorators(s):
while s.sy == 'DECORATOR':
pos = s.position()
s.next()
decorator = ExprNodes.NameNode(
pos, name = Utils.EncodedString(
p_dotted_name(s, as_allowed=0)[2] ))
decstring = p_dotted_name(s, as_allowed=0)[2]
names = decstring.split('.')
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 == '(':
decorator = p_call(s, decorator)
decorators.append(Nodes.DecoratorNode(pos, decorator=decorator))
......
......@@ -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'")
......
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"""
6
>>> h.HERE
1
>>> i(4)
3
>>> i.HERE
1
"""
class wrap:
......@@ -47,3 +51,13 @@ def g(a,b):
@decorate2(1,2)
def h(a,b):
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