1 import unittest
2 from cython.pyparser.pythonutil import get_grammar
3 from cython.pyparser.cyparser import CythonAstBuilder, build_parser as cython_parser
4 from cython.Compiler.ast import ASTVisitor
5
6 from cython.Compiler.Nodes import StatListNode, DefNode, PassStatNode, CFuncDeclaratorNode, CNameDeclaratorNode, CFuncDefNode, CSimpleBaseTypeNode, CDeclaratorNode
7 from cython.Compiler.ModuleNode import ModuleNode
8
9 from cython.Compiler.Symtab import BuiltinScope, ModuleScope
10 from cython.Compiler.Main import Context, CompilationResult, CompilationOptions
11
12 from cython.test.tools import CythonTestCase
13
14 class TestMark:
15 pass
16 class CythonVisitor(ASTVisitor):
17
18 def visitCFunction (self, node):
19 pos = (__file__, 0, node.lineno)
20 basenode = CSimpleBaseTypeNode(pos,
21 name = 'int',
22 module_path = [],
23 is_basic_c_type = True,
24 signed = 1,
25 longness = 0,
26 is_self_arg = False)
27
28 base = CNameDeclaratorNode(pos, name = node.name, cname = node.name)
29
30 declarator = CFuncDeclaratorNode (pos,
31 base = base,
32 args = [],
33 has_varargs = False,
34 exception_value = None,
35 exception_check = 0,
36 nogil = True,
37 with_gil = False)
38
39
40
41 suite = node.code.accept(self)
42 return CFuncDefNode(pos,
43 visibility = 'private',
44 base_type = basenode,
45 declarator = declarator,
46 body = suite,
47 doc = node.doc,
48 modifiers = [],
49 api = False,
50 overridable = False)
51
52 def visitPass (self,node):
53 return PassStatNode((__file__, 0, node.lineno))
54
55 def visitStmt (self, node):
56 return StatListNode ((__file__, 0, node.lineno), stats = [n.accept(self) for n in node ] )
57
58 def visitFunction(self,node):
59 return DefNode((__file__, 0, node.lineno),
60 name = node.name,
61 args = [],
62 star_arg = [],
63 starstar_arg = [],
64 doc = node.doc,
65 body = node.code.accept(self))
66
67 def visitModule(self, node):
68 body = node.node.accept(self)
69 return ModuleNode((__file__, 0, node.lineno), doc = node.doc, body = body, full_module_name = "CythonMODHACK")
70
71 CYTHON_GRAMMAR_EXTENSION = """
72 compound_stmt: cfuncdef | if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef
73
74 cfuncdef: 'cdef' NAME parameters ':' suite
75
76 """
77 def build_parser (version):
78 grammar = get_grammar (version)
79
80 return cython_parser( CYTHON_GRAMMAR_EXTENSION + grammar )
81
82 class PyParsingTestCase (CythonTestCase):
83
84 def test_simple_python_function(self):
85 funame = 'test_simple_pass'
86 source = """
87 def %s():
88 pass
89 """
90 P23 = build_parser ('2.3')
91 P24 = build_parser ('2.4')
92 P25 = build_parser ('2.5a')
93
94 self.assertProduces(P24, source % funame, None, funame)
95
96 def test_simple_Cython_function(self):
97 funame = 'ctest_simple_pass'
98 source = """
99 cdef %s():
100 pass
101 """
102 P24 = build_parser ('2.4')
103 self.assertProduces(P24, source % funame, None, funame)
104
105 def assertProduces (self, parser, source, result, funame, *args):
106
107 modname = 'mod_%s'%funame
108 b = parser.parse_source ( source, 'single', CythonAstBuilder(parser))
109 ast = b.rule_stack[-1]
110
111
112 v = CythonVisitor()
113 tree = ast.accept (v)
114 ctx = Context([])
115 scope = ModuleScope(modname, None, context = ctx)
116 tree.analyse_declarations (scope)
117
118
119 result = CompilationResult()
120 result.c_file = modname+'.c'
121 result.h_file = modname+'.h'
122 result.i_file = ''
123
124 options = CompilationOptions()
125 tree.process_implementation(scope, options, result)
126
127
128 self.validateCCode ( result.c_file)
129
130
131 new_parser_test = self.compileModuleAndImport ( result.c_file)
132
133
134 try:
135 self.assertEquals (getattr(new_parser_test,funame)(*args), None)
136 except Exception, tg:
137 self.fail(tg)