Commit b9d06020 authored by Stefan Behnel's avatar Stefan Behnel

greg: Tests passed

parent 2dc560a7
......@@ -365,10 +365,7 @@ class ExprNode(Node):
if debug_temp_alloc:
print self, "Allocated result", self.result_code
else:
self.result_code = self.calculate_result_code_with_env(env)
def calculate_result_code_with_env(self, env):
return self.calculate_result_code()
self.result_code = self.calculate_result_code()
def target_code(self):
# Return code fragment for use as LHS of a C assignment.
......@@ -790,6 +787,7 @@ class NameNode(AtomicExprNode):
error(self.pos, "Assignment to non-lvalue '%s'"
% self.name)
self.type = PyrexTypes.error_type
self.entry.used = 1
def analyse_rvalue_entry(self, env):
#print "NameNode.analyse_rvalue_entry:", self.name ###
......@@ -858,20 +856,19 @@ class NameNode(AtomicExprNode):
# Name nodes are never ephemeral, even if the
# result is in a temporary.
return 0
def calculate_result_code_with_env(self, env):
def allocate_temp(self, env, result = None):
AtomicExprNode.allocate_temp(self, env, result)
entry = self.entry
if entry:
entry.used = 1
if entry.utility_code:
env.use_utility_code(entry.utility_code)
return self.calculate_result_code()
def calculate_result_code(self):
entry = self.entry
if not entry:
return "<error>" # There was an error earlier
entry.used = 1
return entry.cname
def generate_result_code(self, code):
......
......@@ -57,23 +57,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
return 0
def generate_h_code(self, env, options, result):
public_types = []
public_vars = []
public_funcs = []
public_extension_types = []
for entry in env.type_entries:
if entry.visibility == 'public':
public_types.append(entry)
for entry in env.var_entries:
if entry.visibility == 'public':
public_vars.append(entry)
for entry in env.cfunc_entries:
if entry.visibility == 'public' and not entry.in_cinclude:
public_funcs.append(entry)
for entry in env.c_class_entries:
if entry.visibility == 'public':
public_extension_types.append(entry)
if public_types or public_vars or public_funcs or public_extension_types:
def h_entries(entries, pxd = 0):
return [entry for entry in entries
if entry.visibility == 'public' or pxd and entry.defined_in_pxd]
h_types = h_entries(env.type_entries)
h_vars = h_entries(env.var_entries)
h_funcs = h_entries(env.cfunc_entries)
h_extension_types = h_entries(env.c_class_entries)
if h_types or h_vars or h_funcs or h_extension_types:
result.h_file = replace_suffix(result.c_file, ".h")
h_code = Code.CCodeWriter(open_new_file(result.h_file))
if options.generate_pxi:
......@@ -84,20 +75,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
h_code.put_h_guard(guard)
self.generate_extern_c_macro_definition(h_code)
self.generate_type_header_code(public_types, h_code)
self.generate_type_header_code(h_types, h_code)
h_code.putln("")
h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
if public_vars:
if h_vars:
h_code.putln("")
for entry in public_vars:
for entry in h_vars:
self.generate_public_declaration(entry, h_code, i_code)
if public_funcs:
if h_funcs:
h_code.putln("")
for entry in public_funcs:
for entry in h_funcs:
self.generate_public_declaration(entry, h_code, i_code)
if public_extension_types:
if h_extension_types:
h_code.putln("")
for entry in public_extension_types:
for entry in h_extension_types:
self.generate_cclass_header_code(entry.type, h_code)
if i_code:
self.generate_cclass_include_code(entry.type, i_code)
......@@ -122,14 +113,17 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_api_code(self, env, result):
api_funcs = []
public_extension_types = []
has_api_extension_types = 0
for entry in env.cfunc_entries:
if entry.api:
api_funcs.append(entry)
public_extension_types = []
for entry in env.c_class_entries:
if entry.visibility == 'public':
public_extension_types.append(entry)
if api_funcs or public_extension_types:
if entry.api:
has_api_extension_types = 1
if api_funcs or has_api_extension_types:
result.api_file = replace_suffix(result.c_file, "_api.h")
h_code = Code.CCodeWriter(open_new_file(result.api_file))
name = self.api_name(env)
......@@ -156,16 +150,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code.putln("#endif")
if api_funcs:
h_code.putln("")
h_code.put_h_guard(Naming.api_func_guard + "import_function")
h_code.put(function_import_utility_code[1])
h_code.putln("")
h_code.putln("#endif")
if public_extension_types:
h_code.putln("")
h_code.put_h_guard(Naming.api_func_guard + "import_type")
h_code.put(type_import_utility_code[1])
h_code.putln("")
h_code.putln("#endif")
h_code.putln("")
h_code.putln("static int import_%s(void) {" % name)
h_code.putln("PyObject *module = 0;")
......@@ -207,10 +195,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else:
i_code.putln("pass")
i_code.dedent()
def generate_c_code(self, env, result):
# modules = []
# self.find_referenced_modules(env, modules, {})
modules = self.referenced_modules
code = Code.CCodeWriter(StringIO())
code.h = Code.CCodeWriter(StringIO())
......@@ -358,9 +344,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if definition:
type_entries = env.type_entries
else:
type_entries = [
entry for entry in env.type_entries
if entry.defined_in_pxd]
type_entries = []
for entry in env.type_entries:
if entry.defined_in_pxd:
type_entries.append(entry)
self.generate_type_header_code(type_entries, code)
for entry in env.c_class_entries:
if not entry.in_cinclude:
......@@ -1485,12 +1472,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
objstruct = type.objstruct_cname
else:
objstruct = "struct %s" % type.objstruct_cname
# code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); %s' % (
# type.typeptr_cname,
# type.module_name,
# type.name,
# objstruct,
# code.error_goto_if_null(type.typeptr_cname, pos)))
self.generate_type_import_call(type, code,
code.error_goto_if_null(type.typeptr_cname, pos))
self.use_type_import_utility_code(env)
......@@ -1600,62 +1581,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put(utility_code[1])
#------------------------------------------------------------------------------------
#type_import_utility_code = [
#"""
#static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
#""","""
#static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
# long size)
#{
# PyObject *py_module_name = 0;
# PyObject *py_class_name = 0;
# PyObject *py_name_list = 0;
# PyObject *py_module = 0;
# PyObject *result = 0;
#
# py_module_name = PyString_FromString(module_name);
# if (!py_module_name)
# goto bad;
# py_class_name = PyString_FromString(class_name);
# if (!py_class_name)
# goto bad;
# py_name_list = PyList_New(1);
# if (!py_name_list)
# goto bad;
# Py_INCREF(py_class_name);
# if (PyList_SetItem(py_name_list, 0, py_class_name) < 0)
# goto bad;
# py_module = __Pyx_Import(py_module_name, py_name_list);
# if (!py_module)
# goto bad;
# result = PyObject_GetAttr(py_module, py_class_name);
# if (!result)
# goto bad;
# if (!PyType_Check(result)) {
# PyErr_Format(PyExc_TypeError,
# "%s.%s is not a type object",
# module_name, class_name);
# goto bad;
# }
# if (((PyTypeObject *)result)->tp_basicsize != size) {
# PyErr_Format(PyExc_ValueError,
# "%s.%s does not appear to be the correct type object",
# module_name, class_name);
# goto bad;
# }
# goto done;
#bad:
# Py_XDECREF(result);
# result = 0;
#done:
# Py_XDECREF(py_module_name);
# Py_XDECREF(py_class_name);
# Py_XDECREF(py_name_list);
# return (PyTypeObject *)result;
#}
#"""]
#
# Runtime support code
#
#------------------------------------------------------------------------------------
import_module_utility_code = [
......@@ -1701,6 +1629,8 @@ type_import_utility_code = [
"""
static PyTypeObject *__Pyx_ImportType(PyObject *py_module, char *module_name, char *class_name, long size); /*proto*/
""","""
#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(PyObject *py_module, char *module_name, char *class_name, long size) {
PyObject *result = 0;
......@@ -1724,6 +1654,7 @@ bad:
Py_XDECREF(result);
return 0;
}
#endif
"""]
#------------------------------------------------------------------------------------
......@@ -1765,6 +1696,8 @@ function_import_utility_code = [
"""
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
""","""
#ifndef __PYX_HAVE_RT_ImportFunction
#define __PYX_HAVE_RT_ImportFunction
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
......@@ -1798,4 +1731,5 @@ bad:
Py_XDECREF(d);
return -1;
}
#endif
""" % dict(API = Naming.api_name)]
......@@ -449,6 +449,7 @@ class CVarDefNode(StatNode):
# base_type CBaseTypeNode
# declarators [CDeclaratorNode]
# in_pxd boolean
# api boolean
def analyse_declarations(self, env, dest_scope = None):
if not dest_scope:
......@@ -470,13 +471,8 @@ class CVarDefNode(StatNode):
return
if type.is_cfunction:
entry = dest_scope.declare_cfunction(name, type, declarator.pos,
cname = cname, visibility = self.visibility, in_pxd = self.in_pxd)
#if self.visibility <> 'extern':
# if self.in_pxd:
# entry.defined_in_pxd = 1
# else:
# error(declarator.pos,
# "Non-extern C function declared but not defined")
cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
api = self.api)
else:
if self.in_pxd and self.visibility != 'extern':
error(self.pos,
......@@ -499,6 +495,7 @@ class CStructOrUnionDefNode(StatNode):
# kind "struct" or "union"
# typedef_flag boolean
# visibility "public" or "private"
# in_pxd boolean
# attributes [CVarDefNode] or None
# entry Entry
......@@ -510,9 +507,11 @@ class CStructOrUnionDefNode(StatNode):
self.name, self.kind, scope, self.typedef_flag, self.pos,
self.cname, visibility = self.visibility)
if self.attributes is not None:
if self.in_pxd and not env.in_cinclude:
self.entry.defined_in_pxd = 1
for attr in self.attributes:
attr.analyse_declarations(env, scope)
def analyse_expressions(self, env):
pass
......@@ -525,15 +524,19 @@ class CEnumDefNode(StatNode):
# cname string or None
# items [CEnumDefItemNode]
# typedef_flag boolean
# visibility "public" or "private"
# visibility "public" or "private"
# in_pxd boolean
# entry Entry
def analyse_declarations(self, env):
self.entry = env.declare_enum(self.name, self.pos,
cname = self.cname, typedef_flag = self.typedef_flag,
visibility = self.visibility)
for item in self.items:
item.analyse_declarations(env, self.entry)
if self.items is not None:
if self.in_pxd and not env.in_cinclude:
self.entry.defined_in_pxd = 1
for item in self.items:
item.analyse_declarations(env, self.entry)
def analyse_expressions(self, env):
pass
......@@ -559,23 +562,23 @@ class CEnumDefItemNode(StatNode):
class CTypeDefNode(StatNode):
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# visibility "public" or "private"
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# visibility "public" or "private"
# in_pxd boolean
def analyse_declarations(self, env):
base = self.base_type.analyse(env)
name_declarator, type = self.declarator.analyse(base, env)
name = name_declarator.name
cname = name_declarator.cname
#if env.in_cinclude:
# type = CTypedefType(cname, type)
env.declare_typedef(name, type, self.pos,
entry = env.declare_typedef(name, type, self.pos,
cname = cname, visibility = self.visibility)
if self.in_pxd and not env.in_cinclude:
entry.defined_in_pxd = 1
def analyse_expressions(self, env):
pass
def generate_execution_code(self, code):
pass
......
......@@ -1728,9 +1728,9 @@ def p_cdef_statement(s, level, visibility = 'private', api = 0,
#if api:
# error(pos, "'api' not allowed with '%s'" % s.systring)
if s.systring == "enum":
return p_c_enum_definition(s, pos, visibility)
return p_c_enum_definition(s, pos, level, visibility)
else:
return p_c_struct_or_union_definition(s, pos, visibility)
return p_c_struct_or_union_definition(s, pos, level, visibility)
elif s.sy == 'pass':
node = p_pass_statement(s)
s.expect_newline('Expected a newline')
......@@ -1758,7 +1758,7 @@ struct_union_or_enum = (
"struct", "union", "enum"
)
def p_c_enum_definition(s, pos, visibility, typedef_flag = 0):
def p_c_enum_definition(s, pos, level, visibility, typedef_flag = 0):
# s.sy == ident 'enum'
s.next()
if s.sy == 'IDENT':
......@@ -1781,7 +1781,8 @@ def p_c_enum_definition(s, pos, visibility, typedef_flag = 0):
p_c_enum_line(s, items)
s.expect_dedent()
return Nodes.CEnumDefNode(pos, name = name, cname = cname,
items = items, typedef_flag = typedef_flag, visibility = visibility)
items = items, typedef_flag = typedef_flag, visibility = visibility,
in_pxd = level == 'module_pxd')
def p_c_enum_line(s, items):
if s.sy <> 'pass':
......@@ -1806,7 +1807,7 @@ def p_c_enum_item(s, items):
items.append(Nodes.CEnumDefItemNode(pos,
name = name, cname = cname, value = value))
def p_c_struct_or_union_definition(s, pos, visibility, typedef_flag = 0):
def p_c_struct_or_union_definition(s, pos, level, visibility, typedef_flag = 0):
# s.sy == ident 'struct' or 'union'
kind = s.systring
s.next()
......@@ -1831,7 +1832,8 @@ def p_c_struct_or_union_definition(s, pos, visibility, typedef_flag = 0):
s.expect_newline("Syntax error in struct or union definition")
return Nodes.CStructOrUnionDefNode(pos,
name = name, cname = cname, kind = kind, attributes = attributes,
typedef_flag = typedef_flag, visibility = visibility)
typedef_flag = typedef_flag, visibility = visibility,
in_pxd = level == 'module_pxd')
def p_visibility(s, prev_visibility):
pos = s.position()
......@@ -1884,7 +1886,8 @@ def p_c_func_or_var_declaration(s, level, pos, visibility = 'private', api = 0,
visibility = visibility,
base_type = base_type,
declarators = declarators,
in_pxd = level == 'module_pxd')
in_pxd = level == 'module_pxd',
api = api)
return result
def p_ctypedef_statement(s, level, visibility = 'private', api = 0):
......@@ -1897,15 +1900,17 @@ def p_ctypedef_statement(s, level, visibility = 'private', api = 0):
visibility = visibility, typedef_flag = 1, api = api)
elif s.sy == 'IDENT' and s.systring in ('struct', 'union', 'enum'):
if s.systring == 'enum':
return p_c_enum_definition(s, pos, visibility, typedef_flag = 1)
return p_c_enum_definition(s, pos, level, visibility, typedef_flag = 1)
else:
return p_c_struct_or_union_definition(s, pos, visibility, typedef_flag = 1)
return p_c_struct_or_union_definition(s, pos, level, visibility,
typedef_flag = 1)
else:
base_type = p_c_base_type(s)
declarator = p_c_declarator(s, is_type = 1, nonempty = 1)
s.expect_newline("Syntax error in ctypedef statement")
return Nodes.CTypeDefNode(pos,
base_type = base_type, declarator = declarator, visibility = visibility)
base_type = base_type, declarator = declarator, visibility = visibility,
in_pxd = level == 'module_pxd')
def p_def_statement(s):
# s.sy == 'def'
......
......@@ -267,6 +267,7 @@ class Scope:
type = PyrexTypes.CTypedefType(cname, base_type)
entry = self.declare_type(name, type, pos, cname, visibility)
type.qualified_name = entry.qualified_name
return entry
def declare_struct_or_union(self, name, kind, scope,
typedef_flag, pos, cname = None, visibility = 'private'):
......
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