# generation (labels and temps state etc.)
# globalstate GlobalState contains state global for a C file (input file info,
# utility code, declared constants etc.)
- # emit_linenums boolean whether or not to write #line pragmas
-
+ # emit_linenums boolean whether or not to write #line pragmas
+ #
+ # pyclass_stack list used during recursive code generation to pass information
+ # about the current class one is in
+
def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None):
if buffer is None: buffer = StringIOTree()
self.buffer = buffer
self.marker = None
self.last_marker_line = 0
self.source_desc = ""
+ self.pyclass_stack = []
self.funcstate = None
self.level = 0
return iter([self.key, self.value])
-class ClassNode(ExprNode):
+class ClassNode(NewTempExprNode):
# Helper class used in the implementation of Python
# class definitions. Constructs a class object given
# a name, tuple of bases and class dictionary.
# class definitions. Constructs an unbound method
# object from a class and a function.
#
- # class_cname string C var holding the class object
# function ExprNode Function object
subexprs = ['function']
gil_message = "Constructing an unbound method"
def generate_result_code(self, code):
+ class_cname = code.pyclass_stack[-1].classobj.result()
code.putln(
"%s = PyMethod_New(%s, 0, %s); %s" % (
self.result(),
self.function.py_result(),
- self.class_cname,
+ class_cname,
code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result())
self.analyse_default_values(env)
if env.is_py_class_scope:
self.synthesize_assignment_node(env)
-
+
def synthesize_assignment_node(self, env):
import ExprNodes
self.assmt = SingleAssignmentNode(self.pos,
lhs = ExprNodes.NameNode(self.pos, name = self.name),
rhs = ExprNodes.UnboundMethodNode(self.pos,
- class_cname = env.class_obj_cname,
function = ExprNodes.PyCFunctionNode(self.pos,
pymethdef_cname = self.entry.pymethdef_cname)))
self.assmt.analyse_declarations(env)
self.classobj.analyse_expressions(env)
genv = env.global_scope()
cenv = self.scope
- cenv.class_dict_cname = self.dict.result()
- cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
+ cenv.class_dict_cname = self.dict.result() # TODO newtemps -- move to code generation
self.body.analyse_expressions(cenv)
self.target.analyse_target_expression(env, self.classobj)
self.dict.release_temp(env)
self.body.generate_function_definitions(self.scope, code)
def generate_execution_code(self, code):
+ code.pyclass_stack.append(self)
+ cenv = self.scope
self.dict.generate_evaluation_code(code)
self.classobj.generate_evaluation_code(code)
+ cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
self.body.generate_execution_code(code)
self.target.generate_assignment_code(self.classobj, code)
self.dict.generate_disposal_code(code)
self.dict.free_temps(code)
+ code.pyclass_stack.pop()
class CClassDefNode(ClassDefNode):