Commit 88c3bd04 authored by Robert Bradshaw's avatar Robert Bradshaw

pure mode enhancements, tests

parent d19f6252
......@@ -570,7 +570,7 @@ class ExprNode(Node):
# reference, or temporary.
return self.result_in_temp()
def magic_cython_method(self):
def as_cython_attribute(self):
return None
......@@ -939,7 +939,7 @@ class NameNode(AtomicExprNode):
node.analyse_types(env, entry=entry)
return node
def magic_cython_method(self):
def as_cython_attribute(self):
return self.cython_attribute
create_analysed_rvalue = staticmethod(create_analysed_rvalue)
......@@ -979,6 +979,9 @@ class NameNode(AtomicExprNode):
return None
def analyse_as_type(self, env):
if self.cython_attribute:
type = PyrexTypes.parse_basic_type(self.cython_attribute)
else:
type = PyrexTypes.parse_basic_type(self.name)
if type:
return type
......@@ -1907,7 +1910,7 @@ class SimpleCallNode(CallNode):
self.compile_time_value_error(e)
def analyse_as_type(self, env):
attr = self.function.magic_cython_method()
attr = self.function.as_cython_attribute()
if attr == 'pointer':
if len(self.args) != 1:
error(self.args.pos, "only one type allowed.")
......@@ -2262,7 +2265,7 @@ class AttributeNode(ExprNode):
is_called = 0
needs_none_check = True
def magic_cython_method(self):
def as_cython_attribute(self):
if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
return self.attribute
......
......@@ -2552,7 +2552,7 @@ class ExprStatNode(StatNode):
def analyse_declarations(self, env):
import ExprNodes
if isinstance(self.expr, ExprNodes.GeneralCallNode):
func = self.expr.function.magic_cython_method()
func = self.expr.function.as_cython_attribute()
if func == u'declare':
args, kwds = self.expr.explicit_args_kwds()
if len(args):
......@@ -2620,7 +2620,7 @@ class SingleAssignmentNode(AssignmentNode):
# handle declarations of the form x = cython.foo()
if isinstance(self.rhs, ExprNodes.CallNode):
func_name = self.rhs.function.magic_cython_method()
func_name = self.rhs.function.as_cython_attribute()
if func_name:
args, kwds = self.rhs.explicit_args_kwds()
......@@ -2652,7 +2652,7 @@ class SingleAssignmentNode(AssignmentNode):
self.declaration_only = True
if not isinstance(lhs, ExprNodes.NameNode):
error(lhs.pos, "Invalid declaration.")
env.declare_typedef(lhs.name, type, self.pos, 'private')
env.declare_typedef(lhs.name, type, self.pos, visibility='private')
elif func_name in ['struct', 'union']:
self.declaration_only = True
......
......@@ -267,6 +267,7 @@ class InterpretCompilerDirectives(CythonTransform):
duplication of functionality has to occur: We manually track cimports
and which names the "cython" module may have been imported to.
"""
special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof', 'cast', 'address', 'pointer', 'compiled', 'NULL'])
def __init__(self, context, compilation_option_overrides):
super(InterpretCompilerDirectives, self).__init__(context)
......@@ -299,7 +300,9 @@ class InterpretCompilerDirectives(CythonTransform):
if node.module_name == u"cython":
newimp = []
for pos, name, as_name, kind in node.imported_names:
if name in Options.option_types:
if (name in Options.option_types or
name in self.special_methods or
PyrexTypes.parse_basic_type(name)):
if as_name is None:
as_name = name
self.option_names[as_name] = name
......@@ -316,11 +319,13 @@ class InterpretCompilerDirectives(CythonTransform):
def visit_FromImportStatNode(self, node):
if node.module.module_name.value == u"cython":
newimp = []
for true_name, name_node in node.items:
if true_name in Options.option_types:
self.option_names[name_node.name] = true_name
for name, name_node in node.items:
if (name in Options.option_types or
name in self.special_methods or
PyrexTypes.parse_basic_type(name)):
self.option_names[name_node.name] = name
else:
newimp.append((true_name, name_node))
newimp.append((name, name_node))
if not newimp:
return None
node.items = newimp
......@@ -355,14 +360,7 @@ class InterpretCompilerDirectives(CythonTransform):
optname = None
if isinstance(node, CallNode):
self.visit(node.function)
optname = node.function.magic_cython_method()
# if (isinstance(node.function, AttributeNode) and
# isinstance(node.function.obj, NameNode) and
# node.function.obj.name in self.cython_module_names):
# optname = node.function.attribute
# elif (isinstance(node.function, NameNode) and
# node.function.name in self.option_names):
# optname = self.option_names[node.function.name]
optname = node.function.as_cython_attribute()
if optname:
optiontype = Options.option_types.get(optname)
......@@ -714,11 +712,19 @@ class TransformBuiltinMethods(EnvTransform):
return node
def visit_AttributeNode(self, node):
attribute = node.magic_cython_method()
return self.visit_cython_attribute(node)
def visit_NameNode(self, node):
return self.visit_cython_attribute(node)
def visit_cython_attribute(self, node):
attribute = node.as_cython_attribute()
if attribute:
if attribute == u'compiled':
node = BoolNode(node.pos, value=True)
else:
elif attribute == u'NULL':
node = NullNode(node.pos)
elif not PyrexTypes.parse_basic_type(attribute):
error(node.pos, u"'%s' not a valid cython attribute or is being used incorrectly" % attribute)
return node
......@@ -735,11 +741,11 @@ class TransformBuiltinMethods(EnvTransform):
return ExprNodes.DictNode(pos, key_value_pairs=items)
# cython.foo
function = node.function.magic_cython_method()
function = node.function.as_cython_attribute()
if function:
if function == u'cast':
if len(node.args) != 2:
error(node.function.pos, u"cast takes exactly two arguments" % function)
error(node.function.pos, u"cast takes exactly two arguments")
else:
type = node.args[0].analyse_as_type(self.env_stack[-1])
if type:
......
......@@ -1251,6 +1251,7 @@ modifiers_and_name_to_type = {
(2, 0, "Py_ssize_t"): c_py_ssize_t_type,
(1, 0, "long"): c_long_type,
(1, 0, "short"): c_short_type,
(1, 0, "longlong"): c_longlong_type,
(1, 0, "bint"): c_bint_type,
}
......
import sys, os
sys.path.insert(0, "..")
import cython
def test_sizeof():
x = cython.declare(cython.bint)
print sizeof(x) == sizeof(cython.bint)
print sizeof(cython.char) <= sizeof(cython.short) <= sizeof(cython.int) <= sizeof(cython.long) <= sizeof(cython.longlong)
print sizeof(cython.uint) == sizeof(cython.int)
print sizeof(cython.p_int) == sizeof(cython.p_double)
if cython.compiled:
print sizeof(cython.char) < sizeof(cython.longlong)
else:
print sizeof(cython.char) == 1
def test_declare(n):
x = cython.declare(cython.int)
y = cython.declare(cython.int, n)
if cython.compiled:
cython.declare(xx=cython.int, yy=cython.long)
sizeof(xx)
ptr = cython.declare(cython.p_int, cython.address(y))
return y, ptr[0]
@cython.locals(x=cython.double, n=cython.int)
def test_cast(x):
n = cython.cast(cython.int, x)
return n
@cython.locals(x=cython.int, y=cython.p_int)
def test_address(x):
y = cython.address(x)
return y[0]
@cython.locals(x=cython.int, y=cython.bint)
def test_locals(x):
y = x
return y
MyUnion = cython.union(n=cython.int, x=cython.double)
MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion)
MyStruct2 = cython.typedef(MyStruct[2])
def test_struct(n, x):
a = cython.declare(MyStruct2)
a[0] = MyStruct(True, data=MyUnion(n=n))
a[1] = MyStruct(is_integral=False, data={x: x})
return a[0].data.n, a[1].data.x
import cython as cy
from cython import declare, cast, locals, address, typedef, p_void, compiled
from cython import declare as my_declare, locals as my_locals, p_void as my_void_star, typedef as my_typedef, my_compiled
@my_locals(a=cython.p_void)
def test_imports():
a = NULL
b = declare(p_void, NULL)
c = my_declare(my_void_star, NULL)
d = cy.declare(cy.p_void, NULL)
compiled and my_compiled
MyStruct3 = typedef(MyStruct[3])
MyStruct4 = my_typedef(MyStruct[4])
MyStruct5 = cy.typedef(MyStruct[5])
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