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         # P3K = build_parser ('3.0') Incoming !
  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         # Parse
 107         modname = 'mod_%s'%funame
 108         b = parser.parse_source ( source, 'single', CythonAstBuilder(parser))
 109         ast = b.rule_stack[-1]
 110 
 111         # Analyse to generate a Scope
 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         #Generate C Module
 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         # Validate
 128         self.validateCCode ( result.c_file)
 129 
 130         # Compile
 131         new_parser_test = self.compileModuleAndImport ( result.c_file)
 132 
 133         # Test
 134         try:
 135             self.assertEquals (getattr(new_parser_test,funame)(*args), None)
 136         except Exception, tg:
 137             self.fail(tg)

enhancements/Ast/CythonVisitorTest (last edited 2009-03-01 01:02:24 by localhost)