Commit d928e45f authored by Danilo Freitas's avatar Danilo Freitas

Templates

parent 86f49e42
...@@ -721,6 +721,9 @@ class CSimpleBaseTypeNode(CBaseTypeNode): ...@@ -721,6 +721,9 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
else: else:
type = py_object_type type = py_object_type
self.arg_name = self.name self.arg_name = self.name
elif self.templates:
if not self.name in self.templates:
error(self.pos, "'%s' is not a type identifier" % self.name)
else: else:
error(self.pos, "'%s' is not a type identifier" % self.name) error(self.pos, "'%s' is not a type identifier" % self.name)
if self.complex: if self.complex:
...@@ -913,6 +916,7 @@ class CppClassNode(CStructOrUnionDefNode): ...@@ -913,6 +916,7 @@ class CppClassNode(CStructOrUnionDefNode):
# attributes [CVarDefNode] or None # attributes [CVarDefNode] or None
# entry Entry # entry Entry
# base_classes [string] # base_classes [string]
# templates [string] or None
def analyse_declarations(self, env): def analyse_declarations(self, env):
scope = None scope = None
......
...@@ -32,6 +32,7 @@ class Ctx(object): ...@@ -32,6 +32,7 @@ class Ctx(object):
overridable = 0 overridable = 0
nogil = 0 nogil = 0
namespace = None namespace = None
templates = None
def __init__(self, **kwds): def __init__(self, **kwds):
self.__dict__.update(kwds) self.__dict__.update(kwds)
...@@ -1379,6 +1380,29 @@ def p_with_statement(s): ...@@ -1379,6 +1380,29 @@ def p_with_statement(s):
s.next() s.next()
body = p_suite(s) body = p_suite(s)
return Nodes.GILStatNode(pos, state = state, body = body) return Nodes.GILStatNode(pos, state = state, body = body)
elif s.systring == 'template':
templates = []
s.next()
s.expect('[')
#s.next()
templates.append(s.systring)
s.next()
while s.systring == ',':
s.next()
templates.append(s.systring)
s.next()
s.expect(']')
if s.sy == ':':
s.next()
s.expect_newline("Syntax error in template function declaration")
s.expect_indent()
body_ctx = Ctx()
body_ctx.templates = templates
func_or_var = p_c_func_or_var_declaration(s, pos, body_ctx)
s.expect_dedent()
return func_or_var
else:
error(pos, "Syntax error in template function declaration")
else: else:
manager = p_expr(s) manager = p_expr(s)
target = None target = None
...@@ -1669,13 +1693,13 @@ def p_positional_and_keyword_args(s, end_sy_set, type_positions=(), type_keyword ...@@ -1669,13 +1693,13 @@ def p_positional_and_keyword_args(s, end_sy_set, type_positions=(), type_keyword
s.next() s.next()
return positional_args, keyword_args return positional_args, keyword_args
def p_c_base_type(s, self_flag = 0, nonempty = 0): def p_c_base_type(s, self_flag = 0, nonempty = 0, templates = None):
# If self_flag is true, this is the base type for the # If self_flag is true, this is the base type for the
# self argument of a C method of an extension type. # self argument of a C method of an extension type.
if s.sy == '(': if s.sy == '(':
return p_c_complex_base_type(s) return p_c_complex_base_type(s)
else: else:
return p_c_simple_base_type(s, self_flag, nonempty = nonempty) return p_c_simple_base_type(s, self_flag, nonempty = nonempty, templates = templates)
def p_calling_convention(s): def p_calling_convention(s):
if s.sy == 'IDENT' and s.systring in calling_convention_words: if s.sy == 'IDENT' and s.systring in calling_convention_words:
...@@ -1697,7 +1721,7 @@ def p_c_complex_base_type(s): ...@@ -1697,7 +1721,7 @@ def p_c_complex_base_type(s):
return Nodes.CComplexBaseTypeNode(pos, return Nodes.CComplexBaseTypeNode(pos,
base_type = base_type, declarator = declarator) base_type = base_type, declarator = declarator)
def p_c_simple_base_type(s, self_flag, nonempty): def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
#print "p_c_simple_base_type: self_flag =", self_flag, nonempty #print "p_c_simple_base_type: self_flag =", self_flag, nonempty
is_basic = 0 is_basic = 0
signed = 1 signed = 1
...@@ -1753,7 +1777,7 @@ def p_c_simple_base_type(s, self_flag, nonempty): ...@@ -1753,7 +1777,7 @@ def p_c_simple_base_type(s, self_flag, nonempty):
name = name, module_path = module_path, name = name, module_path = module_path,
is_basic_c_type = is_basic, signed = signed, is_basic_c_type = is_basic, signed = signed,
complex = complex, longness = longness, complex = complex, longness = longness,
is_self_arg = self_flag) is_self_arg = self_flag, templates = templates)
# Treat trailing [] on type as buffer access if it appears in a context # Treat trailing [] on type as buffer access if it appears in a context
...@@ -2253,12 +2277,12 @@ def p_c_modifiers(s): ...@@ -2253,12 +2277,12 @@ def p_c_modifiers(s):
def p_c_func_or_var_declaration(s, pos, ctx): def p_c_func_or_var_declaration(s, pos, ctx):
cmethod_flag = ctx.level in ('c_class', 'c_class_pxd') cmethod_flag = ctx.level in ('c_class', 'c_class_pxd')
modifiers = p_c_modifiers(s) modifiers = p_c_modifiers(s)
base_type = p_c_base_type(s, nonempty = 1) base_type = p_c_base_type(s, nonempty = 1, templates = ctx.templates)
declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag,
assignable = 1, nonempty = 1) assignable = 1, nonempty = 1)
declarator.overridable = ctx.overridable declarator.overridable = ctx.overridable
if s.sy == ':': if s.sy == ':':
if ctx.level not in ('module', 'c_class', 'module_pxd', 'c_class_pxd'): if ctx.level not in ('module', 'c_class', 'module_pxd', 'c_class_pxd') and not ctx.templates:
s.error("C function definition not allowed here") s.error("C function definition not allowed here")
doc, suite = p_suite(s, Ctx(level = 'function'), with_doc = 1) doc, suite = p_suite(s, Ctx(level = 'function'), with_doc = 1)
result = Nodes.CFuncDefNode(pos, result = Nodes.CFuncDefNode(pos,
...@@ -2559,6 +2583,17 @@ def p_cpp_class_definition(s, pos, ctx): ...@@ -2559,6 +2583,17 @@ def p_cpp_class_definition(s, pos, ctx):
cname = ctx.namespace + "::" + class_name cname = ctx.namespace + "::" + class_name
if s.sy == '.': if s.sy == '.':
error(pos, "Qualified class name not allowed C++ class") error(pos, "Qualified class name not allowed C++ class")
templates = None
if s.sy == '[':
s.next()
templates = []
templates.append(s.systring)
s.next()
while s.sy == ',':
s.next()
templates.append(s.systring)
s.next()
s.expect(']')
base_classes = [] base_classes = []
objstruct_name = None objstruct_name = None
typeobj_name = None typeobj_name = None
...@@ -2585,6 +2620,7 @@ def p_cpp_class_definition(s, pos, ctx): ...@@ -2585,6 +2620,7 @@ def p_cpp_class_definition(s, pos, ctx):
s.expect_indent() s.expect_indent()
attributes = [] attributes = []
body_ctx = Ctx() body_ctx = Ctx()
body_ctx.templates = templates
while s.sy != 'DEDENT': while s.sy != 'DEDENT':
if s.sy != 'pass': if s.sy != 'pass':
attributes.append( attributes.append(
...@@ -2601,7 +2637,8 @@ def p_cpp_class_definition(s, pos, ctx): ...@@ -2601,7 +2637,8 @@ def p_cpp_class_definition(s, pos, ctx):
base_classes = base_classes, base_classes = base_classes,
visibility = ctx.visibility, visibility = ctx.visibility,
in_pxd = ctx.level == 'module_pxd', in_pxd = ctx.level == 'module_pxd',
attributes = attributes) attributes = attributes,
templates = templates)
......
cdef extern from "<vector>" namespace std:
cdef cppclass vector[TYPE]:
#constructors
__init__()
__init__(vector&)
__init__(int)
__init__(int, TYPE&)
__init__(iterator, iterator)
#operators
TYPE& __getitem__(int)
TYPE& __setitem__(int, TYPE&)
vector __new__(vector&)
bool __eq__(vector&, vector&)
bool __ne__(vector&, vector&)
bool __lt__(vector&, vector&)
bool __gt__(vector&, vector&)
bool __le__(vector&, vector&)
bool __ge__(vector&, vector&)
#others
void assign(int, TYPE)
#void assign(iterator, iterator)
TYPE& at(int)
TYPE& back()
iterator begin()
int capacity()
void clear()
bool empty()
iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
TYPE& front()
iterator insert(iterator, TYPE&)
void insert(iterator, int, TYPE&)
void insert(iterator, iterator)
int max_size()
void pop_back()
void push_back(TYPE&)
iterator rbegin()
iterator rend()
void reserve(int)
void resize(int)
void resize(int, TYPE&) #void resize(size_type num, const TYPE& = TYPE())
int size()
void swap(container&)
cdef extern from "<deque>" namespace std:
cdef cppclass deque[TYPE]:
#constructors
__init__()
__init__(deque&)
__init__(int)
__init__(int, TYPE&)
__init__(iterator, iterator)
#operators
TYPE& operator[]( size_type index );
const TYPE& operator[]( size_type index ) const;
deque __new__(deque&);
bool __eq__(deque&, deque&);
bool __ne__(deque&, deque&);
bool __lt__(deque&, deque&);
bool __gt__(deque&, deque&);
bool __le__(deque&, deque&);
bool __ge__(deque&, deque&);
#others
void assign(int, TYPE&)
void assign(iterator, iterator)
TYPE& at(int)
TYPE& back()
iterator begin()
void clear()
bool empty()
iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
TYPE& front()
iterator insert(iterator, TYPE&)
void insert(iterator, int, TYPE&)
void insert(iterator, iterator, iterator)
int max_size()
void pop_back()
void pop_front()
void push_back(TYPE&)
void push_front(TYPE&)
iterator rbegin()
iterator rend()
void resize(int)
void resize(int, TYPE&)
int size()
void swap(container&)
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