fortran

package module
v0.0.0-...-04860ef Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: BSD-3-Clause Imports: 19 Imported by: 0

README

go-fortran

go.dev reference Go Report Card codecov Go sourcegraph

Fortran source code parsing utilities for the Go programming language.

Transpiler

Transpiler currently working for most common modern Fortran features. Work ongoing on supporting FORTRAN77 legacy features like statement functions (inline functions) and other ambiguous and tricky to detect ambiguous statements. File manipulation WIP.

Feature set demonstration of around ~1000 lines of code shown in golden.f90 which transpiles to golden.go. Tests pass if output matches byte-to-byte running Go and Fortran programs with gfortran.

See TestTranspileGolden for example on how to transpile. WIP.

Note that not even fortls, the open source fortran language server parses some of these statements correctly and will show the transpiled Fortran file as having errors even though it compiles correctly.

Documentation

Overview

Example (ParseAndPrintAST)

Example_parseAndPrintAST demonstrates parsing a simple Fortran program and printing its Abstract Syntax Tree (AST) in a visual format.

package main

import (
	"fmt"
	"strings"

	"github.com/soypat/go-fortran"
	"github.com/soypat/go-fortran/ast"
)

func main() {
	// Sample Fortran 90 program
	src := `
PROGRAM hello
  IMPLICIT NONE
  INTEGER :: x, y
  REAL :: result

  x = 10
  y = 20
  result = x + y
  PRINT *, 'Result:', result
END PROGRAM hello
`

	// Create parser and parse the program
	var parser fortran.Parser90
	err := parser.Reset("example.f90", strings.NewReader(src))
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// Parse the first program unit
	unit := parser.ParseNextProgramUnit()
	if !unit.IsValid() {
		fmt.Println("No program unit found")
		return
	}

	// Check for parsing errors
	if len(parser.Errors()) > 0 {
		fmt.Println("Parse errors:")
		for _, e := range parser.Errors() {
			fmt.Println("  ", e)
		}
		return
	}

	// Print the AST in a visual tree format
	fmt.Println("Abstract Syntax Tree:")
	fmt.Println("=====================")
	ast.Print(unit)
	// TODO: fix this after transpiler totally finished and not expected to change.
	// OMIT Output for now:
	// Abstract Syntax Tree:
	// =====================
	// ProgramBlock {
	//   Name: "hello"
	//   Body: ast.Statement (len=7) [
	//     0: ImplicitStatement {
	//       IsNone: true
	//       Label: ""
	//       Position: Position {
	//         Start: 19
	//         End: 32
	//       }
	//     }
	//     1: TypeDeclaration {
	//       TypeSpec: "INTEGER"
	//       Entities: ast.DeclEntity (len=2) [
	//         0: DeclEntity {
	//           Name: "x"
	//           Initializer: ""
	//         }
	//         1: DeclEntity {
	//           Name: "y"
	//           Initializer: ""
	//         }
	//       ]
	//       Label: ""
	//       Position: Position {
	//         Start: 35
	//         End: 50
	//       }
	//     }
	//     2: TypeDeclaration {
	//       TypeSpec: "REAL"
	//       Entities: ast.DeclEntity (len=1) [
	//         0: DeclEntity {
	//           Name: "result"
	//           Initializer: ""
	//         }
	//       ]
	//       Label: ""
	//       Position: Position {
	//         Start: 53
	//         End: 67
	//       }
	//     }
	//     3: AssignmentStmt {
	//       Target: Identifier {
	//         Value: "x"
	//         Position: Position {
	//           Start: 71
	//           End: 72
	//         }
	//       }
	//       Value: IntegerLiteral {
	//         Value: 10
	//         Raw: "10"
	//         Position: Position {
	//           Start: 75
	//           End: 77
	//         }
	//       }
	//       Label: ""
	//       Position: Position {
	//         Start: 71
	//         End: 77
	//       }
	//     }
	//     4: AssignmentStmt {
	//       Target: Identifier {
	//         Value: "y"
	//         Position: Position {
	//           Start: 80
	//           End: 81
	//         }
	//       }
	//       Value: IntegerLiteral {
	//         Value: 20
	//         Raw: "20"
	//         Position: Position {
	//           Start: 84
	//           End: 86
	//         }
	//       }
	//       Label: ""
	//       Position: Position {
	//         Start: 80
	//         End: 86
	//       }
	//     }
	//     5: AssignmentStmt {
	//       Target: Identifier {
	//         Value: "result"
	//         Position: Position {
	//           Start: 89
	//           End: 95
	//         }
	//       }
	//       Value: BinaryExpr {
	//         Op: 91
	//         Left: Identifier {
	//           Value: "x"
	//           Position: Position {
	//             Start: 98
	//             End: 99
	//           }
	//         }
	//         Right: Identifier {
	//           Value: "y"
	//           Position: Position {
	//             Start: 102
	//             End: 103
	//           }
	//         }
	//         Position: Position {
	//           Start: 98
	//           End: 103
	//         }
	//       }
	//       Label: ""
	//       Position: Position {
	//         Start: 89
	//         End: 103
	//       }
	//     }
	//     6: PrintStmt {
	//       Format: Identifier {
	//         Value: "*"
	//         Position: Position {
	//           Start: 112
	//           End: 112
	//         }
	//       }
	//       OutputList: ast.Expression (len=2) [
	//         0: StringLiteral {
	//           Value: "Result:"
	//           Position: Position {
	//             Start: 115
	//             End: 122
	//           }
	//         }
	//         1: Identifier {
	//           Value: "result"
	//           Position: Position {
	//             Start: 126
	//             End: 132
	//           }
	//         }
	//       ]
	//       Label: ""
	//       Position: Position {
	//         Start: 106
	//         End: 132
	//       }
	//     }
	//   ]
	//   Label: ""
	//   Position: Position {
	//     Start: 3
	//     End: 133
	//   }
	// }
}
Example (ParseModule)

Example_parseModule demonstrates parsing a Fortran module with specification statements and contained procedures.

package main

import (
	"fmt"
	"strings"

	"github.com/soypat/go-fortran"
	"github.com/soypat/go-fortran/ast"
	"github.com/soypat/go-fortran/token"
)

func main() {
	src := `
MODULE math_utils
  IMPLICIT NONE
  PRIVATE
  PUBLIC :: add, multiply

  INTEGER, PARAMETER :: VERSION = 1

  CONTAINS

  FUNCTION add(a, b) RESULT(sum)
    INTEGER, INTENT(IN) :: a, b
    INTEGER :: sum
    sum = a + b
  END FUNCTION add

  FUNCTION multiply(a, b)
    INTEGER :: a, b, multiply
    multiply = a * b
  END FUNCTION multiply

END MODULE math_utils
`

	var parser fortran.Parser90
	err := parser.Reset("math_utils.f90", strings.NewReader(src))
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	unit := parser.ParseNextProgramUnit()
	if !unit.IsValid() {
		fmt.Println("No program unit found")
		return
	}

	if len(parser.Errors()) > 0 {
		fmt.Println("Parse errors:")
		for _, e := range parser.Errors() {
			fmt.Println("  ", e)
		}
		return
	}

	// Print just the module structure (not the full AST)
	if unit.Token == token.MODULE {
		mod := unit
		fmt.Printf("Module: %s\n", mod.Name)
		fmt.Printf("  Specification statements: %d\n", len(mod.Body))
		fmt.Printf("  Contained procedures: %d\n", len(mod.Contains))

		fmt.Println("\nSpecification statements:")
		for i, stmt := range mod.Body {
			switch s := stmt.(type) {
			case *ast.ImplicitStatement:
				if s.IsNone {
					fmt.Printf("  %d: IMPLICIT NONE\n", i)
				}
			case *ast.TypeDeclaration:
				fmt.Printf("  %d: %s declaration with %d entities\n", i, s.Type.Token.String(), len(s.Entities))
			default:
				fmt.Printf("  %d: %T\n", i, stmt)
			}
		}

		fmt.Println("\nContained procedures:")
		for i, proc := range mod.Contains {
			fmt.Printf("  %d: %s %s\n", i, proc.Token.String(), proc.Name)
		}
	}

	// omit Output:
	// Module: math_utils
	//   Specification statements: 2
	//   Contained procedures: 2
	//
	// Specification statements:
	//   0: IMPLICIT NONE
	//   1: INTEGER declaration with 1 entities
	//
	// Contained procedures:
	//   0: FUNCTION add
	//   1: FUNCTION multiply
}
Example (ParseSubroutine)

Example_parseSubroutine demonstrates parsing a subroutine with parameters and specification statements.

package main

import (
	"fmt"
	"strings"

	"github.com/soypat/go-fortran"
)

func main() {
	src := `
SUBROUTINE swap(a, b)
  IMPLICIT NONE
  REAL, INTENT(INOUT) :: a, b
  REAL :: temp

  temp = a
  a = b
  b = temp
END SUBROUTINE swap
`

	var parser fortran.Parser90
	parser.Reset("swap.f90", strings.NewReader(src))

	sub := parser.ParseNextProgramUnit()
	if !sub.IsValid() {
		panic("no program unit")
	}
	fmt.Printf("Subroutine: %s\n", sub.Name)

	// Extract parameter names
	var paramNames []string
	for _, p := range sub.Parameters {
		paramNames = append(paramNames, p.Name)
	}
	fmt.Printf("Parameters: %v\n", paramNames)
	fmt.Printf("Specification statements: %d\n", len(sub.Body))

}
Output:
Subroutine: swap
Parameters: [a b]
Specification statements: 6

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Lexer90

type Lexer90 struct {
	// contains filtered or unexported fields
}

Lexer90 is a lexer for the Fortran 90 programming language.

func (*Lexer90) AppendPositionString

func (l *Lexer90) AppendPositionString(b []byte) []byte

AppendPositionString appends Lexer90.PositionString to the buffer and returns the result.

func (*Lexer90) Err

func (l *Lexer90) Err() error

Err returns the lexer error, or nil if the error is EOF.

func (*Lexer90) IsDone

func (l *Lexer90) IsDone() bool

func (*Lexer90) LineCol

func (l *Lexer90) LineCol() (line, col int)

LineCol returns the current line number and column number (utf8 relative).

func (*Lexer90) NextToken

func (l *Lexer90) NextToken() (tok token.Token, startPos int, literal []byte)

Next token parses the upcoming token and returns the literal representation of the token for identifiers, strings and numbers. The returned byte slice is reused between calls to NextToken.

func (*Lexer90) Parens

func (l *Lexer90) Parens() int

Parens returns the parentheses/braces depth at the current position.

func (*Lexer90) Pos

func (l *Lexer90) Pos() int

Pos returns the absolute position of the lexer in bytes from the start of the file.

func (*Lexer90) PositionString

func (l *Lexer90) PositionString() string

PositionString returns the "source:line:column" representation of the lexer's current position.

func (*Lexer90) Reset

func (l *Lexer90) Reset(source string, r io.Reader) error

Reset discards all state and buffered data and begins a new lexing procedure on the input r. It performs a single utf8 read to initialize.

func (*Lexer90) SkipLines

func (l *Lexer90) SkipLines(n int) error

SkipLines skips next n lines of the input.

func (*Lexer90) Source

func (l *Lexer90) Source() string

Source returns the name the lexer was reset/initialized with. Usually a filename.

func (*Lexer90) TokenLineCol

func (l *Lexer90) TokenLineCol() (line, col int)

TokenLineCol returns the line/col where the last returned token started.

type Parser90

type Parser90 struct {
	// contains filtered or unexported fields
}

func (*Parser90) Errors

func (p *Parser90) Errors() []ParserError

func (*Parser90) IsDone

func (p *Parser90) IsDone() bool

IsDone returns true if the parser is done parsing, whether it be by EOF or error(s) encountered.

func (*Parser90) ParseNextProgramUnit

func (p *Parser90) ParseNextProgramUnit() (unit ast.Unit)

ParseNextProgramUnit parses and returns the next program unit from the input. Returns nil when EOF is reached or no more units are available. This method can be called repeatedly to incrementally parse a Fortran file. Phase 1: Parses only top-level program units (PROGRAM, SUBROUTINE, FUNCTION, MODULE)

func (*Parser90) Reset

func (p *Parser90) Reset(source string, r io.Reader) error

type ParserError

type ParserError struct {
	// contains filtered or unexported fields
}

func (*ParserError) Error

func (pe *ParserError) Error() string

func (ParserError) String

func (pe ParserError) String() string

type ParserUnitData

type ParserUnitData struct {
	// contains filtered or unexported fields
}

func (*ParserUnitData) AltReturnCount

func (p *ParserUnitData) AltReturnCount() int

AltReturnCount returns the number of alternate return (*) parameters declared.

func (*ParserUnitData) AppendVarinfo

func (p *ParserUnitData) AppendVarinfo(dst []Varinfo) []Varinfo

func (*ParserUnitData) Namelist

func (p *ParserUnitData) Namelist(name string) *ast.NamelistGroup

Namelist returns the NAMELIST group with the given name, or nil if not found.

func (*ParserUnitData) ProcedureParams

func (p *ParserUnitData) ProcedureParams() []Varinfo

ProcedureParams returns the varinfos corresponding to parameters of the function, in order.

func (*ParserUnitData) Var

func (p *ParserUnitData) Var(name string) (vi *Varinfo)

func (*ParserUnitData) Varb

func (p *ParserUnitData) Varb(name []byte) (vi *Varinfo)

type REPL

type REPL struct {
	// contains filtered or unexported fields
}

func (*REPL) Contained

func (repl *REPL) Contained(name string) *ParserUnitData

func (*REPL) ContainedOrUsed

func (repl *REPL) ContainedOrUsed(name string) *ParserUnitData

func (*REPL) DefineStmtFunc

func (repl *REPL) DefineStmtFunc(name string, params []string, expr f90.Expression, decl *f90.DeclEntity)

DefineStmtFunc registers a statement function in the current scope. Statement functions are one-line inline functions like: FUNCNAME(X) = expr

func (*REPL) Eval

func (repl *REPL) Eval(dst *Varinfo, expr f90.Expression) (err error)

Eval evaluates a Fortran expression into dst. Caller provides dst to avoid allocations; dst can be reused across calls. On success dst.Value() holds the result with val.tok set to the evaluated type.

func (*REPL) GetUsed

func (repl *REPL) GetUsed(name string) *ParserUnitData

func (*REPL) InferType

func (repl *REPL) InferType(dst *Varinfo, expr f90.Expression) error

InferType infers the type of expr without evaluating it. Sets dst.val.tok to the result type.

func (*REPL) Namelist

func (repl *REPL) Namelist(name string) *ast.NamelistGroup

Namelist returns the NAMELIST group with the given name, or nil if not found.

func (*REPL) PushHostScope

func (repl *REPL) PushHostScope(vars []Varinfo) (pop func())

PushHostScope sets host-associated variables from an enclosing MODULE or PROGRAM for contained procedure transpilation. Returns pop to restore prior state. Call pop after CONTAINS processing is complete.

func (*REPL) PushVar

func (repl *REPL) PushVar(v Varinfo) (remove func())

PushLoopVar temporarily adds an implied DO loop variable to the current scope. Returns a function that removes the variable when called. Usage: defer repl.PushLoopVar(name)()

func (*REPL) RegisterUnits

func (repl *REPL) RegisterUnits(pu ...f90.Unit) error

RegisterUnits registers a set of program units to the REPL. These units are registered at a top level and are not accessed except in the case of function/subroutine lookup.

func (*REPL) RegisteredUnit

func (repl *REPL) RegisteredUnit(name string) *f90.Unit

RegisteredUnit returns a program unit that was previously registered with RegisterUnit.

func (*REPL) Reset

func (repl *REPL) Reset()

func (*REPL) ScopeParams

func (repl *REPL) ScopeParams() []Varinfo

func (*REPL) SetScope

func (repl *REPL) SetScope(pu f90.Unit) (err error)

func (*REPL) Use

func (repl *REPL) Use(name string, only ...string) (err error)

Use loads a registered unit to the REPL scope until scope is reset.

func (*REPL) Var

func (repl *REPL) Var(name string) *Varinfo

type ToGo

type ToGo struct {
	// contains filtered or unexported fields
}

func (*ToGo) AppendCommonDecls

func (tg *ToGo) AppendCommonDecls(dst []ast.Decl) []ast.Decl

AppendCommonDecls appends COMMON block declarations and fenv to dst. Generates: var fenv = fortio.NewEnvironment() Generates: var BLK = intrinsic.NewCommonBlock("BLK", totalSize) Should be called after all program units have been processed.

func (*ToGo) Contained

func (tg *ToGo) Contained(name string) *ParserUnitData

func (*ToGo) ContainedOrUsed

func (tg *ToGo) ContainedOrUsed(name string) *ParserUnitData

func (*ToGo) ImportDecl

func (tg *ToGo) ImportDecl() ast.Decl

func (*ToGo) Reset

func (tg *ToGo) Reset()

func (*ToGo) SetDeferredSource

func (tg *ToGo) SetDeferredSource(source string)

func (*ToGo) SetSource

func (tg *ToGo) SetSource(source string, r io.ReaderAt)

func (*ToGo) TransformUnits

func (tg *ToGo) TransformUnits(dst []ast.Decl, units ...f90.Unit) (_ []ast.Decl, err error)

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value holds a runtime Fortran value for REPL evaluation.

Two type concepts exist in varinfo:

  • val.tok (Value.Token): The evaluated result's runtime type
  • decl.Type.Token: The declared type from AST

For declared variables both match. For ephemeral results (intermediates like 2+3.0), decl comes from templates (_tgtFloat32 etc), val.tok tracks the actual evaluated type after promotion.

func (*Value) Bool

func (v *Value) Bool() bool

func (*Value) Float

func (v *Value) Float() float64

func (*Value) Floatlike

func (v *Value) Floatlike() bool

func (*Value) Int

func (v *Value) Int() int64

func (*Value) IsInt

func (v *Value) IsInt() bool

func (*Value) StringValue

func (v *Value) StringValue() string

func (*Value) Token

func (v *Value) Token() f90token.Token

type VarFlags

type VarFlags uint64

VarFlags tracks attributes and semantic properties of Fortran variables. Flags are set during parsing and used during transpilation to determine the correct Go representation and access patterns.

const (
	// VFlagImplicit: Type was inferred from IMPLICIT rules rather than explicit declaration.
	// Set when: Variable used without prior declaration, type derived from first letter.
	VFlagImplicit VarFlags = 1 << iota
	// VFlagUsed: Symbol is referenced somewhere in the code.
	// Set when: Any use of the identifier in expressions or statements.
	VFlagUsed
	// VFlagPointer: Variable has POINTER attribute or is a Cray-style pointer.
	// Set when: "INTEGER, POINTER :: x" (F90) or "POINTER (ptr, pointee)" (Cray ptr).
	// For Cray: the pointer variable (ptr) holds an address, not auto-dereferenced.
	// For F90 POINTER: typically combined with VFlagDimension for pointer arrays.
	VFlagPointer
	// VFlagTarget: Variable has TARGET attribute (can be pointed to by F90 pointers).
	// Set when: "INTEGER, TARGET :: x"
	VFlagTarget
	// VFlagParameter: Is a dummy argument (parameter) of a function/subroutine.
	// Set when: Variable appears in procedure's parameter list.
	VFlagParameter
	// VFlagAllocatable: Variable has ALLOCATABLE attribute.
	// Set when: "INTEGER, ALLOCATABLE :: arr(:)" - dynamic allocation via ALLOCATE.
	VFlagAllocatable
	// VFlagCommon: Variable is in a COMMON block (shared storage).
	// Set when: Variable appears in a COMMON statement.
	VFlagCommon
	// VFlagPointee: Cray-style pointee accessed through a pointer variable.
	// Set when: "POINTER (ptr, pointee)" - pointee is accessed via ptr.
	// Access to pointee requires dereferencing the pointer variable.
	VFlagPointee
	// VFlagDimension: Variable is an array (has DIMENSION attribute or explicit bounds).
	// Set when: "INTEGER :: arr(10)" or "INTEGER, DIMENSION(:) :: arr"
	// Go type: *intrinsic.Array[T]
	VFlagDimension
	// VFlagIntentOut: Parameter has INTENT(OUT) - callee provides value.
	VFlagIntentOut
	// VFlagIntentIn: Parameter has INTENT(IN) - caller provides value.
	VFlagIntentIn
	// VFlagArrayInit: Array has been initialized via DATA or inline initializer.
	VFlagArrayInit
	// VFlagArraySpec: ArraySpec was used in the type declaration.
	VFlagArraySpec
	// VFlagReturned: Variable is the function return value.
	VFlagReturned
	// VFlagRecursive: Function/subroutine has RECURSIVE attribute.
	VFlagRecursive
	// VFlagEquivalenced: Variable shares storage via EQUIVALENCE statement.
	// Set when: "EQUIVALENCE (a, b)" - scalars become PointerTo[T] in Go.
	VFlagEquivalenced
	// VFlagConstantParameter: Compile-time constant (PARAMETER statement or attribute).
	// Set when: "PARAMETER (PI = 3.14159)" or "REAL, PARAMETER :: PI = 3.14"
	VFlagConstantParameter
	// VFlagStmtFunc: Statement function (one-line inline function).
	// Set when: "AREA(R) = 3.14159 * R * R"
	VFlagStmtFunc
)

func (VarFlags) HasAll

func (f VarFlags) HasAll(hasBits VarFlags) bool

func (VarFlags) HasAny

func (f VarFlags) HasAny(hasBits VarFlags) bool

func (VarFlags) With

func (f VarFlags) With(mask VarFlags, setBits bool) VarFlags

type Varinfo

type Varinfo struct {
	// contains filtered or unexported fields
}

func (*Varinfo) Charlen

func (p *Varinfo) Charlen() ast.Expression

func (*Varinfo) CommonBlock

func (p *Varinfo) CommonBlock() string

func (*Varinfo) DeclPos

func (p *Varinfo) DeclPos() (source string, line, col int)

func (*Varinfo) Dimensions

func (p *Varinfo) Dimensions() *ast.ArraySpec

func (*Varinfo) Flags

func (p *Varinfo) Flags() VarFlags

func (*Varinfo) Identifier

func (p *Varinfo) Identifier() string

func (*Varinfo) IsAllocatable

func (p *Varinfo) IsAllocatable() bool

func (*Varinfo) IsArray

func (p *Varinfo) IsArray() bool

IsArray returns true if this is an array (has DIMENSION).

func (*Varinfo) IsChar

func (p *Varinfo) IsChar() bool

IsChar returns true if this is a character type (not an array of characters).

func (*Varinfo) IsCharArray

func (p *Varinfo) IsCharArray() bool

IsCharArray returns true if this is an array of character type.

func (*Varinfo) IsParameter

func (p *Varinfo) IsParameter() bool

func (*Varinfo) IsPointer

func (p *Varinfo) IsPointer() bool

IsPointer returns true if accessing this variable requires automatic pointer dereferencing.

Fortran pointer semantics:

  • VFlagPointer (Cray pointer): In "POINTER (NPAA, AA(1))", NPAA holds an address. Accessing NPAA returns the address VALUE, not the pointed-to data. Never auto-deref.
  • VFlagPointee: AA in the above example. Accessing AA(i) implicitly dereferences NPAA to reach the data. Pointees need auto-dereferencing.
  • VFlagEquivalenced: Variables sharing storage via EQUIVALENCE. In Go, we use pointers so they share memory, and accessing them requires dereferencing.

Returns false for VFlagPointer because you want the address, not what it points to. Returns false for arrays (VFlagDimension) which have their own access patterns. Returns false for CHARACTER types which use intrinsic.CharacterArray.

Note: VFlagIntentOut is handled separately via wrapPointer() in function call transpilation.

func (*Varinfo) IsStmtFunc

func (p *Varinfo) IsStmtFunc() bool

func (*Varinfo) Kind

func (p *Varinfo) Kind() ast.Expression

func (*Varinfo) StmtFuncExpr

func (p *Varinfo) StmtFuncExpr() ast.Expression

func (*Varinfo) StmtFuncParams

func (p *Varinfo) StmtFuncParams() []string

func (*Varinfo) TypeToken

func (p *Varinfo) TypeToken() token.Token

func (*Varinfo) Value

func (p *Varinfo) Value() Value

Directories

Path Synopsis
cmd
fortran2go command
fortrangrep command
fortrangrep searches Fortran source files with comment awareness.
fortrangrep searches Fortran source files with comment awareness.
fortranpp command
fortranpp preprocesses Fortran source files by expanding INCLUDE statements.
fortranpp preprocesses Fortran source files by expanding INCLUDE statements.
fortranvar command
fortranvar prints variable information from Fortran source files.
fortranvar prints variable information from Fortran source files.
fortio
Package fortio provides Fortran I/O types and operations.
Package fortio provides Fortran I/O types and operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL