def __init__(self, parent_reporter, parent_frame, parent_space, anchor, name, bases, evals, tree): from pyntch.syntax import build_stmt self.anchor = anchor self.loc = (tree._module, tree.lineno) self.space = Namespace(parent_space, name) TreeReporter.__init__(self, parent_reporter) ClassType.__init__(self, name, bases) if tree.code: self.space.register_names(tree.code) build_stmt(self, parent_frame, self.space, tree.code, evals, parent_space=parent_space) for (name,var) in self.space: # Do not consider the values of attributes inherited from the base class # if they are explicitly overriden. attr = self.ClassAttr(parent_frame, anchor, name, self) var.connect(attr.recv) self.attrs[name] = attr return
def __init__(self, parent_reporter, parent_frame, parent_space, anchor, name, argnames, defaults, variargs, kwargs, tree): TreeReporter.__init__(self, parent_reporter) def maprec(func, x): if isinstance(x, tuple): return tuple(maprec(func, y) for y in x) else: return func(x) self.name = name # prepare local variables that hold passed arguments. self.space = Namespace(parent_space, name) self.frame = ExecutionFrame(None, tree) # handle "**kwd". self.kwarg = None if kwargs: self.kwarg = argnames[-1] del argnames[-1] self.space.register_var(self.kwarg) # handle "*args". self.variarg = None if variargs: self.variarg = argnames[-1] del argnames[-1] self.space.register_var(self.variarg) # handle normal args. self.argnames = tuple(argnames) maprec(lambda argname: self.space.register_var(argname), self.argnames) # build the function body. self.space.register_names(tree.code) self.body = self.FuncBody(name) self.body.set_retval(self.build_evals(tree.code)) self.argvars = maprec(lambda argname: self.space[argname], self.argnames) # assign the default values. self.defaults = tuple(defaults) for (var1, arg1) in zip(self.argvars[-len(defaults):], self.defaults): assign_arg(parent_frame, anchor, var1, arg1) self.frames = set() BuiltinType.__init__(self) return
def __init__(self, parent_reporter, parent_frame, parent_space, anchor, name, argnames, defaults, variargs, kwargs, tree): TreeReporter.__init__(self, parent_reporter) def maprec(func, x): if isinstance(x, tuple): return tuple( maprec(func, y) for y in x ) else: return func(x) self.name = name # prepare local variables that hold passed arguments. self.space = Namespace(parent_space, name) self.frame = ExecutionFrame(None, tree) # handle "**kwd". self.kwarg = None if kwargs: self.kwarg = argnames[-1] del argnames[-1] self.space.register_var(self.kwarg) # handle "*args". self.variarg = None if variargs: self.variarg = argnames[-1] del argnames[-1] self.space.register_var(self.variarg) # handle normal args. self.argnames = tuple(argnames) maprec(lambda argname: self.space.register_var(argname), self.argnames) # build the function body. self.space.register_names(tree.code) self.body = self.FuncBody(name) self.body.set_retval(self.build_evals(tree.code)) self.argvars = maprec(lambda argname: self.space[argname], self.argnames) # assign the default values. self.defaults = tuple(defaults) for (var1,arg1) in zip(self.argvars[-len(defaults):], self.defaults): assign_arg(parent_frame, anchor, var1, arg1) self.frames = set() BuiltinType.__init__(self) return
class FuncType(BuiltinType, TreeReporter): TYPE_NAME = 'function' ## FuncBody ## class FuncBody(CompoundTypeNode): def __init__(self, name): self.name = name CompoundTypeNode.__init__(self) return def __repr__(self): return '<funcbody %s>' % self.name def set_retval(self, evals): from pyntch.aggregate_types import GeneratorType returns = [obj for (t, obj) in evals if t == 'r'] yields = [obj for (t, obj) in evals if t == 'y'] if yields: retvals = [GeneratorType.create_generator(yields)] else: retvals = returns for obj in retvals: obj.connect(self.recv) return def __init__(self, parent_reporter, parent_frame, parent_space, anchor, name, argnames, defaults, variargs, kwargs, tree): TreeReporter.__init__(self, parent_reporter) def maprec(func, x): if isinstance(x, tuple): return tuple(maprec(func, y) for y in x) else: return func(x) self.name = name # prepare local variables that hold passed arguments. self.space = Namespace(parent_space, name) self.frame = ExecutionFrame(None, tree) # handle "**kwd". self.kwarg = None if kwargs: self.kwarg = argnames[-1] del argnames[-1] self.space.register_var(self.kwarg) # handle "*args". self.variarg = None if variargs: self.variarg = argnames[-1] del argnames[-1] self.space.register_var(self.variarg) # handle normal args. self.argnames = tuple(argnames) maprec(lambda argname: self.space.register_var(argname), self.argnames) # build the function body. self.space.register_names(tree.code) self.body = self.FuncBody(name) self.body.set_retval(self.build_evals(tree.code)) self.argvars = maprec(lambda argname: self.space[argname], self.argnames) # assign the default values. self.defaults = tuple(defaults) for (var1, arg1) in zip(self.argvars[-len(defaults):], self.defaults): assign_arg(parent_frame, anchor, var1, arg1) self.frames = set() BuiltinType.__init__(self) return def build_evals(self, code): from pyntch.syntax import build_stmt evals = [] build_stmt(self, self.frame, self.space, code, evals, isfuncdef=True) return evals def __repr__(self): return ('<function %s>' % self.get_name()) def descxml(self, done): done[self] = len(done) return Element('function', name=self.get_name()) def get_name(self): return self.space.get_name() def get_type(self): return self def call(self, frame, anchor, args, kwargs): from pyntch.basic_types import StrType from pyntch.aggregate_types import DictType, TupleType from pyntch.expression import TupleUnpack, TupleSlice # Process keyword arguments first. varsleft = list(self.argvars) varikwargs = [] for (kwname, kwvalue) in kwargs.iteritems(): for var1 in varsleft: if isinstance(var1, Variable) and var1.name == kwname: var1.bind(kwvalue) # When a keyword argument is given, remove that name from the remaining arguments. varsleft.remove(var1) break else: if self.kwarg: varikwargs.append(kwvalue) else: frame.raise_expt(ErrorConfig.InvalidKeywordArgs(kwname)) # Process standard arguments. variargs = [] for arg1 in args: assert arg1 != None, args if varsleft: var1 = varsleft.pop(0) assign_arg(frame, anchor, var1, arg1) elif self.variarg: variargs.append(arg1) else: # Too many arguments. frame.raise_expt( ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) if len(self.defaults) < len(varsleft): # Too few arguments. frame.raise_expt( ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) # Handle remaining arguments: kwargs and variargs. if self.variarg and variargs: self.space[self.variarg].bind(TupleType.create_tuple(variargs)) if self.kwarg: if varikwargs: self.space[self.kwarg].bind( DictType.create_dict(key=StrType.get_object(), value=varikwargs)) else: self.space[self.kwarg].bind(DictType.create_null( frame, anchor)) # Remember where this is called from. self.frames.add(frame) # Propagate the exceptions upward. self.frame.connect(frame.recv) return self.body def showtxt(self, out): (module, lineno) = self.frame.getloc() out.write('### %s(%s)' % (module.get_name(), lineno)) for frame in self.frames: (module, lineno) = frame.getloc() out.write('# called at %s(%s)' % (module.get_name(), lineno)) names = set() def recjoin(sep, seq): for x in seq: if isinstance(x, tuple): yield '(%s)' % sep.join(recjoin(sep, x)) else: names.add(x) yield '%s=%s' % (x, self.space[x].desctxt({})) return r = list(recjoin(', ', self.argnames)) if self.variarg: r.append('*' + self.variarg) if self.kwarg: r.append('**' + self.kwarg) out.write('def %s(%s):' % (self.name, ', '.join(r))) out.indent(+1) names.update(child.name for child in self.children) for (k, v) in sorted(self.space): if k not in names: out.write_value(k, v) out.write_value('return', self.body) self.frame.showtxt(out) for child in self.children: child.showtxt(out) out.indent(-1) out.write('') return def showxml(self, out): (module, lineno) = self.frame.getloc() out.start_xmltag('function', name=self.name, loc='%s:%s' % (module.get_name(), lineno)) for frame in self.frames: (module, lineno) = frame.getloc() out.show_xmltag('caller', loc='%s:%s' % (module.get_name(), lineno)) names = set() def recjoin(seq): for x in seq: if isinstance(x, tuple): recjoin(x) else: names.add(x) out.show_xmlvalue('arg', self.space[x], name=x) return recjoin(self.argnames) if self.variarg: out.show_xmltag('vararg', name=self.variarg) if self.kwarg: out.show_xmltag('kwarg', name=self.kwarg) names.update(child.name for child in self.children) for (k, v) in sorted(self.space): if k not in names: out.show_xmlvalue('var', v, name=k) out.show_xmlvalue('return', self.body) self.frame.showxml(out) for child in self.children: child.showxml(out) out.end_xmltag('function') return
class FuncType(BuiltinType, TreeReporter): TYPE_NAME = 'function' ## FuncBody ## class FuncBody(CompoundTypeNode): def __init__(self, name): self.name = name CompoundTypeNode.__init__(self) return def __repr__(self): return '<funcbody %s>' % self.name def set_retval(self, evals): from pyntch.aggregate_types import GeneratorType returns = [ obj for (t,obj) in evals if t == 'r' ] yields = [ obj for (t,obj) in evals if t == 'y' ] if yields: retvals = [ GeneratorType.create_generator(yields) ] else: retvals = returns for obj in retvals: obj.connect(self.recv) return def __init__(self, parent_reporter, parent_frame, parent_space, anchor, name, argnames, defaults, variargs, kwargs, tree): TreeReporter.__init__(self, parent_reporter) def maprec(func, x): if isinstance(x, tuple): return tuple( maprec(func, y) for y in x ) else: return func(x) self.name = name # prepare local variables that hold passed arguments. self.space = Namespace(parent_space, name) self.frame = ExecutionFrame(None, tree) # handle "**kwd". self.kwarg = None if kwargs: self.kwarg = argnames[-1] del argnames[-1] self.space.register_var(self.kwarg) # handle "*args". self.variarg = None if variargs: self.variarg = argnames[-1] del argnames[-1] self.space.register_var(self.variarg) # handle normal args. self.argnames = tuple(argnames) maprec(lambda argname: self.space.register_var(argname), self.argnames) # build the function body. self.space.register_names(tree.code) self.body = self.FuncBody(name) self.body.set_retval(self.build_evals(tree.code)) self.argvars = maprec(lambda argname: self.space[argname], self.argnames) # assign the default values. self.defaults = tuple(defaults) for (var1,arg1) in zip(self.argvars[-len(defaults):], self.defaults): assign_arg(parent_frame, anchor, var1, arg1) self.frames = set() BuiltinType.__init__(self) return def build_evals(self, code): from pyntch.syntax import build_stmt evals = [] build_stmt(self, self.frame, self.space, code, evals, isfuncdef=True) return evals def __repr__(self): return ('<function %s>' % self.get_name()) def descxml(self, done): done[self] = len(done) return Element('function', name=self.get_name()) def get_name(self): return self.space.get_name() def get_type(self): return self def call(self, frame, anchor, args, kwargs): from pyntch.basic_types import StrType from pyntch.aggregate_types import DictType, TupleType from pyntch.expression import TupleUnpack, TupleSlice # Process keyword arguments first. varsleft = list(self.argvars) varikwargs = [] for (kwname, kwvalue) in kwargs.iteritems(): for var1 in varsleft: if isinstance(var1, Variable) and var1.name == kwname: var1.bind(kwvalue) # When a keyword argument is given, remove that name from the remaining arguments. varsleft.remove(var1) break else: if self.kwarg: varikwargs.append(kwvalue) else: frame.raise_expt(ErrorConfig.InvalidKeywordArgs(kwname)) # Process standard arguments. variargs = [] for arg1 in args: assert arg1 != None, args if varsleft: var1 = varsleft.pop(0) assign_arg(frame, anchor, var1, arg1) elif self.variarg: variargs.append(arg1) else: # Too many arguments. frame.raise_expt(ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) if len(self.defaults) < len(varsleft): # Too few arguments. frame.raise_expt(ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) # Handle remaining arguments: kwargs and variargs. if self.variarg and variargs: self.space[self.variarg].bind(TupleType.create_tuple(variargs)) if self.kwarg: if varikwargs: self.space[self.kwarg].bind(DictType.create_dict(key=StrType.get_object(), value=varikwargs)) else: self.space[self.kwarg].bind(DictType.create_null(frame, anchor)) # Remember where this is called from. self.frames.add(frame) # Propagate the exceptions upward. self.frame.connect(frame.recv) return self.body def showtxt(self, out): (module,lineno) = self.frame.getloc() out.write('### %s(%s)' % (module.get_name(), lineno)) for frame in self.frames: (module,lineno) = frame.getloc() out.write('# called at %s(%s)' % (module.get_name(), lineno)) names = set() def recjoin(sep, seq): for x in seq: if isinstance(x, tuple): yield '(%s)' % sep.join(recjoin(sep, x)) else: names.add(x) yield '%s=%s' % (x, self.space[x].desctxt({})) return r = list(recjoin(', ', self.argnames)) if self.variarg: r.append('*'+self.variarg) if self.kwarg: r.append('**'+self.kwarg) out.write('def %s(%s):' % (self.name, ', '.join(r)) ) out.indent(+1) names.update( child.name for child in self.children ) for (k,v) in sorted(self.space): if k not in names: out.write_value(k, v) out.write_value('return', self.body) self.frame.showtxt(out) for child in self.children: child.showtxt(out) out.indent(-1) out.write('') return def showxml(self, out): (module,lineno) = self.frame.getloc() out.start_xmltag('function', name=self.name, loc='%s:%s' % (module.get_name(), lineno)) for frame in self.frames: (module,lineno) = frame.getloc() out.show_xmltag('caller', loc='%s:%s' % (module.get_name(), lineno)) names = set() def recjoin(seq): for x in seq: if isinstance(x, tuple): recjoin(x) else: names.add(x) out.show_xmlvalue('arg', self.space[x], name=x) return recjoin(self.argnames) if self.variarg: out.show_xmltag('vararg', name=self.variarg) if self.kwarg: out.show_xmltag('kwarg', name=self.kwarg) names.update( child.name for child in self.children ) for (k,v) in sorted(self.space): if k not in names: out.show_xmlvalue('var', v, name=k) out.show_xmlvalue('return', self.body) self.frame.showxml(out) for child in self.children: child.showxml(out) out.end_xmltag('function') return
class PythonClassType(ClassType, TreeReporter): def __init__(self, parent_reporter, parent_frame, parent_space, anchor, name, bases, evals, tree): from pyntch.syntax import build_stmt self.anchor = anchor self.loc = (tree._module, tree.lineno) self.space = Namespace(parent_space, name) TreeReporter.__init__(self, parent_reporter) ClassType.__init__(self, name, bases) if tree.code: self.space.register_names(tree.code) build_stmt(self, parent_frame, self.space, tree.code, evals, parent_space=parent_space) for (name,var) in self.space: # Do not consider the values of attributes inherited from the base class # if they are explicitly overriden. attr = self.ClassAttr(parent_frame, anchor, name, self) var.connect(attr.recv) self.attrs[name] = attr return def get_name(self): return self.space.get_name() def showtxt(self, out): (module,lineno) = self.loc out.write('### %s(%s)' % (module.get_name(), lineno)) for frame in self.frames: (module,lineno) = frame.getloc() out.write('# instantiated at %s(%d)' % (module.get_name(), lineno)) if self.bases: out.write('class %s(%s):' % (self.name, ', '.join( base.typename() for base in self.klasses if base is not self ))) else: out.write('class %s:' % self.name) out.indent(+1) blocks = set( child.name for child in self.children ) for (name, attr) in self.attrs.iteritems(): if name in blocks or not attr.types: continue out.write_value('class.'+name, attr) for (name, attr) in self.instance.attrs.iteritems(): if name in blocks or not attr.types: continue out.write_value('instance.'+name, attr) for child in self.children: child.showtxt(out) out.indent(-1) out.write('') return def showxml(self, out): (module,lineno) = self.loc out.start_xmltag('class', name=self.name, loc='%s:%s' % (module.get_name(), lineno)) for frame in self.frames: (module,lineno) = frame.getloc() out.show_xmltag('caller', loc='%s:%s' % (module.get_name(), lineno)) for base in self.klasses: if base is self: continue out.show_xmltag('base', name=base.typename()) blocks = set( child.name for child in self.children ) for (name, attr) in self.attrs.iteritems(): if name in blocks or not attr.types: continue out.show_xmlvalue('classattr', attr, name=name) for (name, attr) in self.instance.attrs.iteritems(): if name in blocks or not attr.types: continue out.show_xmlvalue('instanceattr', attr, name=name) for child in self.children: child.showxml(out) out.end_xmltag('class') return