Commit 9f86b4fd authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Generating pxd code, but problem with interned strings etc. (very unstable!)

parent 88aea80c
...@@ -22,6 +22,7 @@ from Scanning import PyrexScanner, FileSourceDescriptor ...@@ -22,6 +22,7 @@ from Scanning import PyrexScanner, FileSourceDescriptor
from Errors import PyrexError, CompileError, error from Errors import PyrexError, CompileError, error
from Symtab import BuiltinScope, ModuleScope from Symtab import BuiltinScope, ModuleScope
from Cython import Utils from Cython import Utils
from Cython.Utils import open_new_file, replace_suffix
module_name_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$") module_name_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$")
...@@ -32,6 +33,20 @@ def dumptree(t): ...@@ -32,6 +33,20 @@ def dumptree(t):
print t.dump() print t.dump()
return t return t
class CompilationData:
# Bundles the information that is passed from transform to transform.
# (For now, this is only)
# While Context contains every pxd ever loaded, path information etc.,
# this only contains the data related to a single compilation pass
#
# pyx ModuleNode Main code tree of this compilation.
# pxds {string : ModuleNode} Trees for the pxds used in the pyx.
# codewriter CCodeWriter Where to output final code.
# options CompilationOptions
# result CompilationResult
pass
class Context: class Context:
# This class encapsulates the context needed for compiling # This class encapsulates the context needed for compiling
# one or more Cython implementation files along with their # one or more Cython implementation files along with their
...@@ -50,6 +65,8 @@ class Context: ...@@ -50,6 +65,8 @@ class Context:
self.include_directories = include_directories self.include_directories = include_directories
self.future_directives = set() self.future_directives = set()
self.pxds = {} # full name -> node tree
standard_include_path = os.path.abspath( standard_include_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'Includes')) os.path.join(os.path.dirname(__file__), '..', 'Includes'))
self.include_directories = include_directories + [standard_include_path] self.include_directories = include_directories + [standard_include_path]
...@@ -87,9 +104,26 @@ class Context: ...@@ -87,9 +104,26 @@ class Context:
] ]
def create_pyx_pipeline(self, options, result): def create_pyx_pipeline(self, options, result):
return [create_parse(self)] + self.create_pipeline(pxd=False) + [ def generate_pyx_code(module_node):
create_generate_code(self, options, result) module_node.process_implementation(options, result)
] result.compilation_source = module_node.compilation_source
return result
def inject_pxd_code(module_node):
from Nodes import CCommentNode
from textwrap import dedent
stats = module_node.body.stats
for name, (statlistnode, scope) in self.pxds.iteritems():
#stats.append(CCommentNode('Code from cimported "%s"' % name, header=True))
stats.append(statlistnode)
return module_node
return ([
create_parse(self)
] + self.create_pipeline(pxd=False) + [
inject_pxd_code,
generate_pyx_code,
])
def create_pxd_pipeline(self, scope, module_name): def create_pxd_pipeline(self, scope, module_name):
def parse_pxd(source_desc): def parse_pxd(source_desc):
...@@ -98,7 +132,14 @@ class Context: ...@@ -98,7 +132,14 @@ class Context:
tree.scope = scope tree.scope = scope
tree.is_pxd = True tree.is_pxd = True
return tree return tree
return [parse_pxd] + self.create_pipeline(pxd=True)
from CodeGeneration import ExtractPxdCode
# The pxd pipeline ends up with a CCodeWriter containing the
# code of the pxd, as well as a pxd scope.
return [parse_pxd] + self.create_pipeline(pxd=True) + [
ExtractPxdCode(self)
]
def process_pxd(self, source_desc, scope, module_name): def process_pxd(self, source_desc, scope, module_name):
pipeline = self.create_pxd_pipeline(scope, module_name) pipeline = self.create_pxd_pipeline(scope, module_name)
...@@ -171,7 +212,8 @@ class Context: ...@@ -171,7 +212,8 @@ class Context:
if debug_find_module: if debug_find_module:
print("Context.find_module: Parsing %s" % pxd_pathname) print("Context.find_module: Parsing %s" % pxd_pathname)
source_desc = FileSourceDescriptor(pxd_pathname) source_desc = FileSourceDescriptor(pxd_pathname)
self.process_pxd(source_desc, scope, module_name) errors_occured, (pxd_codenodes, pxd_scope) = self.process_pxd(source_desc, scope, module_name)
self.pxds[module_name] = (pxd_codenodes, pxd_scope)
except CompileError: except CompileError:
pass pass
return scope return scope
...@@ -406,14 +448,6 @@ def create_parse(context): ...@@ -406,14 +448,6 @@ def create_parse(context):
return tree return tree
return parse return parse
def create_generate_code(context, options, result):
def generate_code(module_node):
scope = module_node.scope
module_node.process_implementation(options, result)
result.compilation_source = module_node.compilation_source
return result
return generate_code
def create_default_resultobj(compilation_source, options): def create_default_resultobj(compilation_source, options):
result = CompilationResult() result = CompilationResult()
result.main_source_file = compilation_source.source_desc.filename result.main_source_file = compilation_source.source_desc.filename
......
...@@ -3885,6 +3885,34 @@ class FromImportStatNode(StatNode): ...@@ -3885,6 +3885,34 @@ class FromImportStatNode(StatNode):
target.generate_assignment_code(self.item, code) target.generate_assignment_code(self.item, code)
self.module.generate_disposal_code(code) self.module.generate_disposal_code(code)
class CForeignScopeNode(StatNode):
"""
Used for wrapping FuncDefNodes from pxds so that they generate their
code in the right scope.
"""
pass
class CCommentNode(StatNode):
# not working!
def __init__(self, comment, header=False):
self.pos
assert '/' not in comment # todo: better escaping
if header:
from textwrap import dedent
comment = dedent("""
/*
* %s
*/
""") % comment
else:
comment = "/* %s */" % comment
self.comment = comment
def generate_execution_code(self, code):
code.putln(self.header)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
# #
# Runtime support code # Runtime support code
......
...@@ -217,6 +217,12 @@ class PxdPostParse(CythonTransform): ...@@ -217,6 +217,12 @@ class PxdPostParse(CythonTransform):
""" """
Basic interpretation/validity checking that should only be Basic interpretation/validity checking that should only be
done on pxd trees. done on pxd trees.
A lot of this checking currently happens in the parser; but
what is listed below happens here.
- "def" functions are let through only if they fill the
getbuffer/releasebuffer slots
""" """
ERR_FUNCDEF_NOT_ALLOWED = 'function definition not allowed here' ERR_FUNCDEF_NOT_ALLOWED = 'function definition not allowed here'
...@@ -240,7 +246,6 @@ class PxdPostParse(CythonTransform): ...@@ -240,7 +246,6 @@ class PxdPostParse(CythonTransform):
and node.name in ('__getbuffer__', '__releasebuffer__')): and node.name in ('__getbuffer__', '__releasebuffer__')):
ok = True ok = True
if not ok: if not ok:
self.context.nonfatal_error(PostParseError(node.pos, self.context.nonfatal_error(PostParseError(node.pos,
self.ERR_FUNCDEF_NOT_ALLOWED)) self.ERR_FUNCDEF_NOT_ALLOWED))
......
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