Reference Guide  2.5.0
psyclone.f2pygen.ProgUnitGen Class Reference
Inheritance diagram for psyclone.f2pygen.ProgUnitGen:
Collaboration diagram for psyclone.f2pygen.ProgUnitGen:

Public Member Functions

def __init__ (self, parent, sub)
 
def add (self, content, position=None, bubble_up=False)
 
- Public Member Functions inherited from psyclone.f2pygen.BaseGen
def parent (self)
 
def children (self)
 
def root (self)
 
def add (self, new_object, position=None)
 
def previous_loop (self)
 
def last_declaration (self)
 
def start_parent_loop (self, debug=False)
 

Detailed Description

 Functionality relevant to program units (currently modules,
subroutines)

Definition at line 335 of file f2pygen.py.

Member Function Documentation

◆ add()

def psyclone.f2pygen.ProgUnitGen.add (   self,
  content,
  position = None,
  bubble_up = False 
)
Specialise the add method to provide module- and subroutine-
-specific intelligent adding of use statements, implicit
none statements and declarations if the position argument
is set to auto (which is the default).

:param content: the Node (or sub-tree of Nodes) to add in to \
                the AST.
:type content: :py:class:`psyclone.f2pygen.BaseGen`
:param list position: where to insert the node. One of "append", \
                      "first", "insert", "after", "after_index", \
                      "before_index", "before" or "auto". For the \
                      *_index options, the second element of the \
                      list holds the integer index.
:param bool bubble_up: whether or not object (content) is in the \
                       process of being bubbled-up.

Definition at line 341 of file f2pygen.py.

341  def add(self, content, position=None, bubble_up=False):
342  '''
343  Specialise the add method to provide module- and subroutine-
344  -specific intelligent adding of use statements, implicit
345  none statements and declarations if the position argument
346  is set to auto (which is the default).
347 
348  :param content: the Node (or sub-tree of Nodes) to add in to \
349  the AST.
350  :type content: :py:class:`psyclone.f2pygen.BaseGen`
351  :param list position: where to insert the node. One of "append", \
352  "first", "insert", "after", "after_index", \
353  "before_index", "before" or "auto". For the \
354  *_index options, the second element of the \
355  list holds the integer index.
356  :param bool bubble_up: whether or not object (content) is in the \
357  process of being bubbled-up.
358  '''
359  # By default the position is 'auto'. We set it up this way for
360  # safety because in python, default arguments are instantiated
361  # as objects at the time of definition. If this object is
362  # subsequently modified then the value of the default argument
363  # is modified for subsequent calls of this routine.
364  if position is None:
365  position = ["auto"]
366 
367  # For an object to be added to another we require that they
368  # share a common ancestor. This means that the added object must
369  # have the current object or one of its ancestors as an ancestor.
370  # Loop over the ancestors of this object (starting with itself)
371  self_ancestor = self.root
372  while self_ancestor:
373  # Loop over the ancestors of the object being added
374  obj_parent = content.root.parent
375  while (obj_parent != self_ancestor and
376  getattr(obj_parent, 'parent', None)):
377  obj_parent = obj_parent.parent
378  if obj_parent == self_ancestor:
379  break
380  # Object being added is not an ancestor of the current
381  # self_ancestor so move one level back up the tree and
382  # try again
383  if getattr(self_ancestor, 'parent', None):
384  self_ancestor = self_ancestor.parent
385  else:
386  break
387 
388  if obj_parent != self_ancestor:
389  raise RuntimeError(
390  f"Cannot add '{content}' to '{self}' because it is not a "
391  f"descendant of it or of any of its ancestors.")
392 
393  if bubble_up:
394  # If content has been passed on (is being bubbled up) then change
395  # its parent to be this object
396  content.root.parent = self.root
397 
398  if position[0] != "auto":
399  # position[0] is not 'auto' so the baseclass can deal with it
400  BaseGen.add(self, content, position)
401  else:
402  # position[0] == "auto" so insert in a context sensitive way
403  if isinstance(content, BaseDeclGen):
404 
405  if isinstance(content, (DeclGen, CharDeclGen)):
406  # have I already been declared?
407  for child in self._children:
408  if isinstance(child, (DeclGen, CharDeclGen)):
409  # is this declaration the same type as me?
410  if child.root.name == content.root.name:
411  # we are modifying the list so we need
412  # to iterate over a copy
413  for var_name in content.root.entity_decls[:]:
414  for child_name in child.root.entity_decls:
415  if var_name.lower() == \
416  child_name.lower():
417  content.root.entity_decls.\
418  remove(var_name)
419  if not content.root.entity_decls:
420  # return as all variables in
421  # this declaration already
422  # exist
423  return
424  if isinstance(content, TypeDeclGen):
425  # have I already been declared?
426  for child in self._children:
427  if isinstance(child, TypeDeclGen):
428  # is this declaration the same type as me?
429  if child.root.selector[1] == \
430  content.root.selector[1]:
431  # we are modifying the list so we need
432  # to iterate over a copy
433  for var_name in content.root.entity_decls[:]:
434  for child_name in child.root.entity_decls:
435  if var_name.lower() == \
436  child_name.lower():
437  content.root.entity_decls.\
438  remove(var_name)
439  if not content.root.entity_decls:
440  # return as all variables in
441  # this declaration already
442  # exist
443  return
444 
445  index = 0
446  # skip over any use statements
447  index = self._skip_use_and_comments(index)
448  # skip over implicit none if it exists
449  index = self._skip_imp_none_and_comments(index)
450  # skip over any declarations which have an intent
451  try:
452  intent = True
453  while intent:
454  intent = False
455  for attr in self.root.content[index].attrspec:
456  if attr.find("intent") == 0:
457  intent = True
458  index += 1
459  break
460  except AttributeError:
461  pass
462  elif isinstance(content.root, fparser1.statements.Use):
463  # have I already been declared?
464  for child in self._children:
465  if isinstance(child, UseGen):
466  if child.root.name == content.root.name:
467  # found an existing use with the same name
468  if not child.root.isonly and not \
469  content.root.isonly:
470  # both are generic use statements so
471  # skip this declaration
472  return
473  if child.root.isonly and not content.root.isonly:
474  # new use is generic and existing use
475  # is specific so we can safely add
476  pass
477  if not child.root.isonly and content.root.isonly:
478  # existing use is generic and new use
479  # is specific so we can skip this
480  # declaration
481  return
482  if child.root.isonly and content.root.isonly:
483  # we are modifying the list so we need
484  # to iterate over a copy
485  for new_name in content.root.items[:]:
486  for existing_name in child.root.items:
487  if existing_name.lower() == \
488  new_name.lower():
489  content.root.items.remove(new_name)
490  if not content.root.items:
491  return
492  index = 0
493  elif isinstance(content, ImplicitNoneGen):
494  # does implicit none already exist?
495  for child in self._children:
496  if isinstance(child, ImplicitNoneGen):
497  return
498  # skip over any use statements
499  index = 0
500  index = self._skip_use_and_comments(index)
501  else:
502  index = len(self.root.content) - 1
503  self.root.content.insert(index, content.root)
504  self._children.append(content)
505 

References psyclone.f2pygen.BaseGen._children, psyclone.psyir.nodes.node.Node._children, psyclone.psyir.nodes.omp_directives.OMPParallelDirective._children, psyclone.f2pygen.ProgUnitGen._skip_imp_none_and_comments(), psyclone.f2pygen.ProgUnitGen._skip_use_and_comments(), psyclone.f2pygen.BaseGen.root(), psyclone.f2pygen.BaseDeclGen.root(), and psyclone.psyir.nodes.node.Node.root().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following file: