def __init__(self, parent, datatype="", entity_decls=None, intent="", pointer=False, attrspec=None): if entity_decls is None: raise RuntimeError( "Cannot create a declaration of a derived-type variable " "without specifying the name(s) of the variable(s)") # make a copy of entity_decls as we may modify it local_entity_decls = entity_decls[:] if attrspec is None: attrspec = [] my_attrspec = [spec for spec in attrspec] if intent != "": my_attrspec.append("intent({0})".format(intent)) if pointer is not False: my_attrspec.append("pointer") self._names = local_entity_decls reader = FortranStringReader("type(vanillatype) :: vanilla") reader.set_mode(True, False) # free form, strict myline = reader.next() from fparser.typedecl_statements import Type self._typedecl = Type(parent.root, myline) self._typedecl.selector = ('', datatype) self._typedecl.attrspec = my_attrspec self._typedecl.entity_decls = local_entity_decls BaseGen.__init__(self, parent, self._typedecl)
def add(self, content, position=None, bubble_up=False): if position is None: position = ["auto"] if position[0] == "auto" and bubble_up: # There's currently no case where a bubbled-up statement # will live within a do loop so bubble it up again. self.parent.add(content, bubble_up=True) return if position[0] == "auto" or position[0] == "append": if position[0] == "auto" and bubble_up_type(content): # use and declaration statements cannot appear in a do loop # so pass on to parent self.parent.add(content, bubble_up=True) return else: # append at the end of the loop. This is not a simple # append as the last element in the loop is the "end # do" so we insert at the penultimate location BaseGen.add(self, content, position=["insert", len(self.root.content) - 1]) else: BaseGen.add(self, content, position=position)
def __init__(self, parent, language, position, directive_type, content): self._supported_languages = ["omp"] self._language = language self._directive_type = directive_type reader = FortranStringReader("! content\n") reader.set_mode(True, True) # free form, strict subline = reader.next() if language == "omp": my_comment = OMPDirective(parent.root, subline, position, directive_type) my_comment.content = "$omp" if position == "end": my_comment.content += " end" my_comment.content += " " + directive_type if content != "": my_comment.content += " " + content else: raise RuntimeError( "Error, unsupported directive language. Expecting one of " "{0} but found '{1}'".format(str(self._supported_languages), language)) BaseGen.__init__(self, parent, my_comment)
def __init__(self, parent, content): reader = FortranStringReader("! content\n") reader.set_mode(True, True) # free form, strict subline = reader.next() my_comment = Comment(parent.root, subline) my_comment.content = content BaseGen.__init__(self, parent, my_comment)
def __init__(self, parent, clause): reader = FortranStringReader("if (dummy) then\nend if") reader.set_mode(True, True) # free form, strict ifthenline = reader.next() endifline = reader.next() from fparser.block_statements import IfThen, EndIfThen my_if = IfThen(parent.root, ifthenline) my_if.expr = clause my_endif = EndIfThen(my_if, endifline) my_if.content.append(my_endif) BaseGen.__init__(self, parent, my_if)
def __init__(self, parent, variable_name, start, end, step=None): reader = FortranStringReader("do i=1,n\nend do") reader.set_mode(True, True) # free form, strict doline = reader.next() enddoline = reader.next() from fparser.block_statements import Do, EndDo dogen = Do(parent.root, doline) dogen.loopcontrol = variable_name + "=" + start + "," + end if step is not None: dogen.loopcontrol = dogen.loopcontrol + "," + step enddo = EndDo(dogen, enddoline) dogen.content.append(enddo) BaseGen.__init__(self, parent, dogen)
def __init__(self, parent, name="", args=None): reader = FortranStringReader("call vanilla(vanilla_arg)") reader.set_mode(True, True) # free form, strict myline = reader.next() from fparser.block_statements import Call self._call = Call(parent.root, myline) self._call.designator = name if args is None: args = [] self._call.items = args BaseGen.__init__(self, parent, self._call)
def __init__(self, parent, content): from fparser.statements import Deallocate reader = FortranStringReader("deallocate(dummy)") reader.set_mode(True, False) # free form, strict myline = reader.next() self._decl = Deallocate(parent.root, myline) if isinstance(content, str): self._decl.items = [content] elif isinstance(content, list): self._decl.items = content else: raise RuntimeError( "DeallocateGen expected the content argument to be a str" " or a list, but found {0}".format(type(content))) BaseGen.__init__(self, parent, self._decl)
def __init__(self, parent, name="", only=False, funcnames=None): reader = FortranStringReader("use kern,only : func1_kern=>func1") reader.set_mode(True, True) # free form, strict myline = reader.next() root = parent.root from fparser.block_statements import Use use = Use(root, myline) use.name = name use.isonly = only if funcnames is None: funcnames = [] use.isonly = False local_funcnames = funcnames[:] use.items = local_funcnames BaseGen.__init__(self, parent, use)
def __init__(self, parent): if not isinstance(parent, ModuleGen) and not isinstance( parent, SubroutineGen): raise Exception( "The parent of ImplicitNoneGen must be a module or a " "subroutine, but found {0}".format(type(parent))) reader = FortranStringReader("IMPLICIT NONE\n") reader.set_mode(True, True) # free form, strict subline = reader.next() from fparser.typedecl_statements import Implicit my_imp_none = Implicit(parent.root, subline) BaseGen.__init__(self, parent, my_imp_none)
def __init__(self, parent, lhs="", rhs="", pointer=False): if pointer: reader = FortranStringReader("lhs=>rhs") else: reader = FortranStringReader("lhs=rhs") reader.set_mode(True, True) # free form, strict myline = reader.next() if pointer: from fparser.statements import PointerAssignment self._assign = PointerAssignment(parent.root, myline) else: from fparser.statements import Assignment self._assign = Assignment(parent.root, myline) self._assign.expr = rhs self._assign.variable = lhs BaseGen.__init__(self, parent, self._assign)
def __init__(self, parent, datatype="", entity_decls=None, intent="", pointer=False, kind="", dimension="", allocatable=False): if entity_decls is None: raise RuntimeError( "Cannot create a variable declaration without specifying the " "name(s) of the variable(s)") if datatype.lower() == "integer": from fparser.typedecl_statements import Integer reader = FortranStringReader("integer :: vanilla") reader.set_mode(True, False) # free form, strict myline = reader.next() self._decl = Integer(parent.root, myline) elif datatype.lower() == "real": from fparser.typedecl_statements import Real reader = FortranStringReader("real :: vanilla") reader.set_mode(True, False) # free form, strict myline = reader.next() self._decl = Real(parent.root, myline) else: raise RuntimeError( "f2pygen:DeclGen:init: Only integer and real are currently" " supported and you specified '{0}'".format(datatype)) # make a copy of entity_decls as we may modify it local_entity_decls = entity_decls[:] self._decl.entity_decls = local_entity_decls my_attrspec = [] if intent != "": my_attrspec.append("intent({0})".format(intent)) if pointer is not False: my_attrspec.append("pointer") if allocatable is not False: my_attrspec.append("allocatable") self._decl.attrspec = my_attrspec if dimension != "": my_attrspec.append("dimension({0})".format(dimension)) if kind is not "": self._decl.selector = ('', kind) BaseGen.__init__(self, parent, self._decl)
def add(self, content, position=None): if position is None: position = ["auto"] if position[0] == "auto" or position[0] == "append": if position[0] == "auto" and bubble_up_type(content): # use and declaration statements cannot appear in an if # block so pass on (bubble-up) to parent self.parent.add(content, bubble_up=True) else: # append at the end of the loop. This is not a simple # append as the last element in the if is the "end if" # so we insert at the penultimate location BaseGen.add(self, content, position=["insert", len(self.root.content) - 1]) else: BaseGen.add(self, content, position=position)
def __init__(self, parent, expr="UNSET", typeselect=False): ''' construct a ... ''' from fparser.block_statements import EndSelect self._typeselect = typeselect reader = FortranStringReader( "SELECT CASE (x)\nCASE (1)\nCASE DEFAULT\nEND SELECT") reader.set_mode(True, True) # free form, strict select_line = reader.next() self._case_line = reader.next() self._case_default_line = reader.next() end_select_line = reader.next() if self._typeselect: select = TypeSelect(parent.root, select_line) else: select = Select(parent.root, select_line) endselect = EndSelect(select, end_select_line) select.expr = expr select.content.append(endselect) BaseGen.__init__(self, parent, select)
def 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)''' # By default the position is 'auto'. We set it up this way for # safety because in python, default arguments are instantiated # as objects at the time of definition. If this object is # subsequently modified then the value of the default argument # is modified for subsequent calls of this routine. if position is None: position = ["auto"] # For an object to be added to another we require that they # share a common ancestor. This means that the added object must # have the current object or one of its ancestors as an ancestor. # Loop over the ancestors of this object (starting with itself) self_ancestor = self.root while self_ancestor: # Loop over the ancestors of the object being added obj_parent = content.root.parent while (obj_parent != self_ancestor and getattr(obj_parent, 'parent', None)): obj_parent = obj_parent.parent if obj_parent == self_ancestor: break # Object being added is not an ancestor of the current # self_ancestor so move one level back up the tree and # try again if getattr(self_ancestor, 'parent', None): self_ancestor = self_ancestor.parent else: break if obj_parent != self_ancestor: raise RuntimeError( "Cannot add '{0}' to '{1}' because it is not a descendant " "of it or of any of its ancestors.".format( str(content), str(self))) if bubble_up: # If content has been passed on (is being bubbled up) then change # its parent to be this object content.root.parent = self.root import fparser if position[0] != "auto": # position[0] is not 'auto' so the baseclass can deal with it BaseGen.add(self, content, position) else: # position[0] == "auto" so insert in a context sensitive way if isinstance(content, DeclGen) or \ isinstance(content, TypeDeclGen): if isinstance(content, DeclGen): # have I already been declared? for child in self._children: if isinstance(child, DeclGen): # is this declaration the same type as me? if child.root.name == content.root.name: # we are modifying the list so we need # to iterate over a copy for var_name in content.root.entity_decls[:]: for child_name in child.root.entity_decls: if var_name.lower() == \ child_name.lower(): content.root.entity_decls.\ remove(var_name) if not content.root.entity_decls: # return as all variables in # this declaration already # exist return if isinstance(content, TypeDeclGen): # have I already been declared? for child in self._children: if isinstance(child, TypeDeclGen): # is this declaration the same type as me? if child.root.selector[1] == \ content.root.selector[1]: # we are modifying the list so we need # to iterate over a copy for var_name in content.root.entity_decls[:]: for child_name in child.root.entity_decls: if var_name.lower() == \ child_name.lower(): content.root.entity_decls.\ remove(var_name) if not content.root.entity_decls: # return as all variables in # this declaration already # exist return index = 0 # skip over any use statements index = self._skip_use_and_comments(index) # skip over implicit none if it exists index = self._skip_imp_none_and_comments(index) # skip over any declarations which have an intent try: intent = True while intent: intent = False for attr in self.root.content[index].attrspec: if attr.find("intent") == 0: intent = True index += 1 break except AttributeError: pass elif isinstance(content.root, fparser.statements.Use): # have I already been declared? for child in self._children: if isinstance(child, UseGen): if child.root.name == content.root.name: # found an existing use with the same name if not child.root.isonly and not \ content.root.isonly: # both are generic use statements so # skip this declaration return if child.root.isonly and not content.root.isonly: # new use is generic and existing use # is specific so we can safely add pass if not child.root.isonly and content.root.isonly: # existing use is generic and new use # is specific so we can skip this # declaration return if child.root.isonly and content.root.isonly: # we are modifying the list so we need # to iterate over a copy for new_name in content.root.items[:]: for existing_name in child.root.items: if existing_name.lower() == \ new_name.lower(): content.root.items.remove(new_name) if not content.root.items: return index = 0 elif isinstance(content, ImplicitNoneGen): # does implicit none already exist? for child in self._children: if isinstance(child, ImplicitNoneGen): return # skip over any use statements index = 0 index = self._skip_use_and_comments(index) else: index = len(self.root.content) - 1 self.root.content.insert(index, content.root) self._children.append(content)
def __init__(self, parent, sub): BaseGen.__init__(self, parent, sub)