# loki.backend.fgen module

fgen(ir, depth=0, conservative=False, linewidth=132)

  Generate standardized Fortran code from one or many IR objects/trees.

class FortranCodegen(depth=0, indent=' ', linewidth=90, conservative=True)

  Bases: `Stringifier`

  Tree visitor to generate standardized Fortran code from IR.

  apply_label(line, label)

    Apply a label to the given (formatted) line by replacing indentation with the label.

    Parameters:

      - line (str) – the formatted line.

      - label (str or NoneType) – the label to apply.

    Returns:

      the line with the label applied if given, else the original line.

    Return type:

      str

  visit(o, *args, **kwargs)

    Overwrite standard visit routine to inject original source in conservative mode.

  visit_Sourcefile(o, **kwargs)
    Format as

      …modules… …subroutines…

  visit_Module(o, **kwargs)
    Format as
      MODULE <name>

        …spec…

      CONTAINS

        …routines…

      END MODULE

  visit_Subroutine(o, **kwargs)
    Format as
      <ftype> [<prefix>] <name> ([<args>]) [RESULT(<name>)] [BIND(c, name=<name>)]

        …docstring… …spec… …body…

      [CONTAINS]

        […member…]

      END <ftype> <name>

  visit_Node(o, **kwargs)
    Format non-supported nodes as

      ! <repr(Node)>

  visit_tuple(o, **kwargs)

    Recurse for each item in the tuple and return as separate lines. Insert labels if existing.

  visit_list(o, **kwargs)

    Recurse for each item in the tuple and return as separate lines. Insert labels if existing.

  visit_str(o, **kwargs)
  visit_Intrinsic(o, **kwargs)

    Format intrinsic nodes.

  visit_RawSource(o, **kwargs)

    Format raw source nodes.

  visit_Comment(o, **kwargs)

    Format comments.

  visit_Pragma(o, **kwargs)

    Format pragmas.

  visit_CommentBlock(o, **kwargs)

    Format comment blocks.

  visit_PreprocessorDirective(o, **kwargs)

    Format preprocessor directives.

  visit_VariableDeclaration(o, **kwargs)
    Format declaration as

      [<type>] [, DIMENSION(…)] :: var [= initial] [, var [= initial] ] …

  visit_ProcedureDeclaration(o, **kwargs)
    Format procedure declaration as

      [PROCEDURE[(<interface>)]] [, POINTER] [, INTENT(…)] [, …] :: var [=> initial] [, var [=> initial] ] …

    or

      [MODULE] PROCEDURE [, …] :: var [, …]

    or

      GENERIC [, PUBLIC|PRIVATE] :: var => bind_name [, bind_name [, …]]

    or

      FINAL :: var [, var [, …]]

  visit_DataDeclaration(o, **kwargs)
    Format as

      DATA <var> / <values> /

  visit_StatementFunction(o, **kwargs)
    Format as

      <variable>(<arguments>) = <rhs>

  visit_Import(o, **kwargs)
    Format imports according to their type as

      #include “…”

    or

      include “…”

    or

      USE [, <nature> ::] <module> [, ONLY: <symbols>]

    or

      USE [, <nature> ::] <module> [, <rename-list>]

    or

      IMPORT <symbols>

  visit_Interface(o, **kwargs)
    Format interface node as
      INTERFACE [<spec>]

        …body…

      END INTERFACE

  visit_Loop(o, **kwargs)
    Format loop with explicit range as
      [name:] DO [label] <var>=<loop range>

        …body…

      END DO [name]

  visit_WhileLoop(o, **kwargs)
    Format loop as
      [name:] DO [label] [WHILE (<condition>)]

        …body…

      END DO [name]

  visit_Conditional(o, **kwargs)
    Format conditional as

      IF (<condition>) <single-statement body>

    or
      [name:] IF (<condition>) THEN

        …body…

      [ELSE IF (<condition>) THEN [name]]

        […body…]

      [ELSE [name]]

        […body…]

      END IF [name]

  visit_MultiConditional(o, **kwargs)
    Format as

      [name:] SELECT CASE (<expr>) CASE (<value>) [name]

      > …body…

      [CASE (<value>) [name]]

        […body…]

      [CASE DEFAULT [name]]

        […body…]

      END SELECT [name]

  visit_Assignment(o, **kwargs)
    Format statement as

      <lhs> = <rhs>

    or

      <pointer> => <rhs>

  visit_MaskedStatement(o, **kwargs)
    Format masked assignment as
      WHERE (<condition>)

        …body…

      [ELSEWHERE (<condition>)]

        []…body…]

      [ELSEWHERE]

        […body…]

      END WHERE

    or

      WHERE (<condition>) <body>

  visit_Forall(o, **kwargs)
    Format FORALL element in one of two manners:

      1. Single-line FORALL statement (inlined):

      > FORALL (<variable> = <bound>[, <variable> = <bound>] … [, <mask>]) assign-stmt

      2. Multi-line FORALL construct:

      > [name:] FORALL (<variable> = <bound>[, <variable> = <bound>] … [, <mask>])

      >   …body…

      > END FORALL [name]

    Variable bounds with an optional mask condition constitute the “triplets” - specification list.

  visit_Section(o, **kwargs)

    Format the section’s body.

  visit_Associate(o, **kwargs)
    Format scope as
      ASSOCIATE (<associates>)

        …body…

      END ASSOCIATE

  visit_CallStatement(o, **kwargs)
    Format call statement as

      CALL <name>(<args>)

  visit_Allocation(o, **kwargs)
    Format allocation statement as

      ALLOCATE(<variables> [, SOURCE=<source>])

  visit_Deallocation(o, **kwargs)
    Format de-allocation statement as

      DEALLOCATE(<variables>)

  visit_Nullify(o, **kwargs)
    Format pointer nullification as

      NULLIFY(<variables>)

  visit_SymbolAttributes(o, **kwargs)
    Format declaration attributes as

      <typename>[(<spec>)] [, <attributes>]

  visit_TypeDef(o, **kwargs)
    Format type definition as
      TYPE [, BIND(c) ::] <name>

        …declarations…

      END TYPE <name>

  visit_BasicType(o, **kwargs)
  visit_DerivedType(o, **kwargs)
  visit_ProcedureType(o, **kwargs)
  visit_Enumeration(o, **kwargs)
    Format enum as
      ENUM, BIND(C)

        ENUMERATOR :: name [= value] …

      END ENUM

class FCodeMapper(*args, **kwargs)

  Bases: `LokiStringifyMapper`

  A `StringifyMapper`-derived visitor for Pymbolic expression trees that converts an expression to a string adhering to the Fortran standard.

  COMPARISON_OP_TO_FORTRAN = {'!=': '/=', '<': '<', '<=': '<=', '==': '==', '>': '>', '>=': '>='}
  map_logic_literal(expr, enclosing_prec, *args, **kwargs)
  map_float_literal(expr, enclosing_prec, *args, **kwargs)
  map_int_literal(expr, enclosing_prec, *args, **kwargs)
  map_logical_not(expr, enclosing_prec, *args, **kwargs)
  map_logical_and(expr, enclosing_prec, *args, **kwargs)
  map_logical_or(expr, enclosing_prec, *args, **kwargs)
  map_comparison(expr, enclosing_prec, *args, **kwargs)

    This translates the C-style notation for comparison operators used internally in Pymbolic to the corresponding Fortran comparison operators.

  map_literal_list(expr, enclosing_prec, *args, **kwargs)
  map_foreign(expr, *args, **kwargs)

    Mapper method dispatch for non-`pymbolic` objects.

  map_loop_range(expr, enclosing_prec, *args, **kwargs)
  multiplicative_primitives = (<class 'pymbolic.primitives.FloorDiv'>, <class 'pymbolic.primitives.Remainder'>)