VX/FORTRAN - OpenVMS FORTRAN to ANSI FORTRAN
Overview
VX/FORTRAN is a source-to-source migration tool that rewrites OpenVMS and VAX FORTRAN into ANSI-compliant FORTRAN (Intel FORTRAN), so existing applications compile and run on x86 Linux and Windows with no manual code changes. It is built on the Fortran Partner (fpt) transpiler and adds the VMS-specific handling, standards adherence, and performance optimizations a real OpenVMS estate depends on, so decades of scientific and engineering FORTRAN move forward intact.
The migration is fully automated. VMS language extensions are rewritten to standard FORTRAN, semantic differences are re-programmed so behaviour is preserved, and file and record access is carried by the VX/RMS runtime, so RMS and ISAM I/O, VMS system services, and embedded Pro*FORTRAN SQL keep working on the target platform. Teams keep developing on OpenVMS while each release is migrated to Linux and Windows, so there is no code freeze during a long project.
<!-- Webflow embed (min). Source: fortran-page-technical/fortran-tech-body-embed-dark.html → python3 website/embeds/minify_webflow_embed.py … -->
<div class="s7-tech-embed" data-vxfortrand-body-embed="1" data-technical-mega-embed="1" lang="en"><h2 id="architecture">Translation model and pipeline</h2><p>
VX/FORTRAN is a compile-time source-to-source translator, not a runtime emulator. It reads
OpenVMS and VAX FORTRAN and writes ANSI-standard FORTRAN, which the Intel FORTRAN compiler
(ifort or ifx) then builds into a native Linux or Windows executable. The rewriting is done
by the Fortran Partner (fpt) transpiler, which works on a typed model of the whole program
rather than doing text substitution, so it can distinguish a VMS extension from a semantic
difference and apply the correct change to each.
</p><p>
Two things ship together: the fpt transpiler that rewrites the source, and the VX/RMS
runtime library the rewritten program links against for VMS file, record, and system
behaviour. Source that used VMS filespecs, ISAM files, or VMS system services keeps working
because those constructs are routed to the runtime rather than being left to the target
compiler.
</p><div class="callout"><strong>Compile-time, not runtime.</strong> VX/FORTRAN emits ordinary ANSI FORTRAN, so the
output is standard source the Intel toolchain builds, debugs, and profiles. The VX/RMS
runtime supplies the file and record access and the OpenVMS system-service behaviour the
emitted code depends on.
</div><h6>Pipeline</h6><style>.s7-tech-embed .process-flow {margin: 1.5rem 0;padding: 16px;border: 1px solid var(--s7t-border);border-radius: 10px;background: rgba(255, 255, 255, 0.01);}.s7-tech-embed .process-endpoint {display: grid;grid-template-columns: 72px minmax(0, 1fr);gap: 14px;align-items: center;padding: 14px 16px;border-radius: 8px;background: var(--s7t-surface);color: var(--s7t-text);}.s7-tech-embed .process-output {border: 1px solid var(--s7t-note-bd);background: var(--s7t-note-bg);}.s7-tech-embed .process-label,.s7-tech-embed .process-number {font-family: var(--s7t-mono);color: var(--s7t-accent);font-size: 0.76em;font-weight: 700;letter-spacing: 0.08em;text-transform: uppercase;}.s7-tech-embed .process-endpoint div,.s7-tech-embed .process-stage {min-width: 0;}.s7-tech-embed .process-endpoint strong,.s7-tech-embed .process-endpoint span:last-child,.s7-tech-embed .process-stage strong,.s7-tech-embed .process-stage span:last-child {display: block;}.s7-tech-embed .process-endpoint strong,.s7-tech-embed .process-stage strong {margin-bottom: 4px;color: var(--s7t-text);}.s7-tech-embed .process-endpoint span:last-child,.s7-tech-embed .process-stage span:last-child {color: var(--s7t-muted);font-size: 0.9em;line-height: 1.45;}.s7-tech-embed .process-stages {display: grid;grid-template-columns: repeat(3, minmax(0, 1fr));gap: 10px;margin: 10px 0;}.s7-tech-embed .process-stage {padding: 15px;border-top: 3px solid var(--s7t-accent);border-radius: 6px;background: var(--s7t-surface2);color: var(--s7t-text);}.s7-tech-embed .process-stage .process-number {margin-bottom: 10px;}@media (max-width: 800px) {.s7-tech-embed .process-stages {grid-template-columns: 1fr;}.s7-tech-embed .process-endpoint {grid-template-columns: 1fr;gap: 5px;}}</style><div class="process-flow" aria-label="VX/FORTRAN translation pipeline"><div class="process-endpoint"><span class="process-label">Input</span><div><strong>OpenVMS or VAX FORTRAN</strong><span><code>.for</code> or <code>.f</code> source</span></div></div><div class="process-stages" role="list" aria-label="Translation stages"><div class="process-stage" role="listitem"><span class="process-number">01</span><strong>Static analysis</strong><span>Analyses the complete program and identifies VMS-specific dependencies.</span></div><div class="process-stage" role="listitem"><span class="process-number">02</span><strong>Transpile</strong><span>Rewrites VMS extensions and semantic differences into standard FORTRAN.</span></div><div class="process-stage" role="listitem"><span class="process-number">03</span><strong>Optimise</strong><span>Applies source-level optimisations to the translated program.</span></div><div class="process-stage" role="listitem"><span class="process-number">04</span><strong>Emit</strong><span>Writes ANSI or Intel FORTRAN source as <code>.f90</code>.</span></div><div class="process-stage" role="listitem"><span class="process-number">05</span><strong>Intel compiler</strong><span><code>ifort</code> or <code>ifx</code> compiles and links the source against the VX/RMS runtime.</span></div></div><div class="process-endpoint process-output"><span class="process-label">Output</span><div><strong>x86 Linux or Windows binary</strong><span>Native executable linked against the VX/RMS runtime</span></div></div></div><h6>What runs the migration</h6><div class="table-wrapper"><table><thead><tr><th>Stage</th><th>Role</th></tr></thead><tbody><tr><td>Source code analysis</td><td>Identifies VMS-specific extensions, RMS file dependencies, and embedded Pro*FORTRAN SQL, and reports missing sub-programs and mismatched arguments before any rewrite.</td></tr><tr><td>Transpile</td><td>fpt rewrites VMS spelling, language extensions, and semantic differences into standard FORTRAN.</td></tr><tr><td>Optimise</td><td>Applies inline expansion, loop unrolling, and memory-access optimisations while emitting the ANSI source.</td></tr><tr><td>Compile and validate</td><td>The Intel FORTRAN compiler builds the emitted source, and automated test cases confirm identical execution behaviour.</td></tr></tbody></table></div><h2 id="dialect-coverage">Source dialect coverage</h2><p>
VX/FORTRAN parses the full OpenVMS and VAX FORTRAN surface into a typed model, so it
understands the extensions a real estate uses rather than passing them through as text.
The table groups the VMS-specific constructs it recognises and shows how each one is carried
onto the target platform: some are rewritten inline to standard FORTRAN, others are routed
to the VX/RMS runtime, and the remainder are recognised and preserved for the target
compiler.
</p><div class="table-wrapper"><table><thead><tr><th>VMS construct</th><th>How it is migrated</th></tr></thead><tbody><tr><td><code>STRUCTURE</code> / <code>RECORD</code> / <code>UNION</code> / <code>MAP</code> aggregates, <code>BYTE</code> type</td><td>Rewritten to standard derived types and equivalence layouts.</td></tr><tr><td>Argument-passing built-ins <code>%REF</code>, <code>%VAL</code>, <code>%LOC</code>, <code>%DESCR</code></td><td>Call sites rewritten to the host calling convention.</td></tr><tr><td>Hollerith literals (<code>5HHELLO</code>) in DATA and FORMAT</td><td>Rewritten to character constants.</td></tr><tr><td>Legacy BOZ literals (<code>'FF'X</code>, <code>'377'O</code>, <code>'101'B</code>)</td><td>Rewritten to standard hexadecimal, octal, and binary constants.</td></tr><tr><td>Legacy I/O statements (<code>ACCEPT</code>, <code>TYPE</code>, <code>ENCODE</code>, <code>DECODE</code>, <code>DEFINE FILE</code>)</td><td>Rewritten to standard READ, PRINT, and internal-file I/O.</td></tr><tr><td>Record I/O statements (<code>REWRITE</code>, <code>DELETE</code>, <code>UNLOCK</code>, <code>FIND</code>)</td><td>Routed to the VX/RMS runtime for keyed and relative files.</td></tr><tr><td>Specification extensions (<code>AUTOMATIC</code>, <code>STATIC</code>, <code>VIRTUAL</code>, Cray-style integer <code>POINTER</code>, <code>IMPLICIT UNDEFINED</code>)</td><td>Mapped to standard storage and pointer declarations.</td></tr><tr><td>Variable and run-time <code>FORMAT</code> expressions</td><td>Rewritten to run-time format strings.</td></tr><tr><td>DEC-style <code>INCLUDE</code> with logical names, <code>DICTIONARY 'record'</code> (CDD)</td><td>Logical names resolved; CDD records extracted and inlined as FORTRAN.</td></tr><tr><td>VAX intrinsics (<code>IARGCOUNT</code>, <code>SIZEOF</code>)</td><td>Mapped to standard intrinsics and argument-count handling.</td></tr><tr><td><code>cDEC$</code> / <code>!DEC$</code> compiler directives</td><td>Recognised and preserved, including conditional-compilation blocks.</td></tr></tbody></table></div><div class="callout"><strong>Named gaps, not silent ones.</strong> Any construct the translator cannot fully
represent is counted and named in the analysis report rather than dropped, so the migration
is auditable and nothing disappears without a trace.
</div><h6>Compiler directives</h6><p>
VMS compiler directives written as <code>cDEC$</code>, <code>*DEC$</code>, or <code>!DEC$</code>
in fixed or free form are recognised and carried through the migration, including
<code>ATTRIBUTES</code>, <code>ALIAS</code>, <code>IVDEP</code>, <code>UNROLL</code>,
<code>PSECT</code>, and the <code>!DEC$ IF</code> / <code>ELSEIF</code> / <code>ELSE</code> /
<code>ENDIF</code> conditional-compilation construct. Source form switches such as
<code>FREEFORM</code> and <code>FIXEDFORM</code> are honoured so mixed-form estates parse
correctly.
</p><h2 id="transformations">Three classes of change</h2><p>
Moving OpenVMS FORTRAN to a standard compiler is not one problem but three, and VX/FORTRAN
treats each differently. Syntactic differences are spelling changes rewritten inline;
language extensions have no standard equivalent and are routed to the runtime; semantic
differences keep the same syntax but mean something different on the host, so the construct
is re-programmed to preserve the original behaviour.
</p><div class="table-wrapper"><table><thead><tr><th>Class</th><th>What it is</th><th>How VX/FORTRAN handles it</th></tr></thead><tbody><tr><td>Syntactic differences</td><td>VMS spelling that a standard compiler rejects</td><td>Rewritten inline to the standard spelling.</td></tr><tr><td>Language extensions</td><td>VMS features with no standard equivalent (VMS filespecs, ISAM files, variable FORMAT)</td><td>Rewritten to calls into the VX/RMS emulation library.</td></tr><tr><td>Semantic differences</td><td>Same syntax, different meaning on the host compiler</td><td>The construct is re-programmed so behaviour matches OpenVMS.</td></tr></tbody></table></div><h6>Semantic differences the migration re-programs</h6><p>
These are the subtle cases where code compiles cleanly on both platforms but would behave
differently if left unchanged. VX/FORTRAN detects each one and rewrites it so the migrated
program produces the same results as the original.
</p><div class="table-wrapper"><table><thead><tr><th>VMS behaviour</th><th>Why it differs on the host</th></tr></thead><tbody><tr><td>Integer used as a LOGICAL</td><td>VMS tests the least-significant bit; other compilers may test the whole value. The compound test is re-programmed to VMS semantics.</td></tr><tr><td>Left-to-right <code>.OR.</code> / <code>.AND.</code> evaluation</td><td>The standard permits reordering, so a short-circuiting compound <code>IF</code> is re-programmed to force VMS ordering.</td></tr><tr><td><code>CALL</code> used to invoke a FUNCTION</td><td>Mismatched call and return conventions corrupt the stack on the host, so the call site is corrected.</td></tr><tr><td>Mismatched 4-byte and 8-byte REAL arguments</td><td>VAX F, D, G, and H floats share leading bits; IEEE-754 does not, so mismatched REAL arguments are corrected.</td></tr><tr><td>Real-number and FORMAT edge cases</td><td>Differences in real formatting and FORMAT interpretation are detected and corrected.</td></tr></tbody></table></div><div class="callout"><strong>Detected before it becomes a runtime bug.</strong> Static analysis flags syntax,
logical, and performance issues before migration, so the classes above are resolved at
translation time rather than surfacing as wrong results after cutover.
</div><h2 id="examples">Before and after</h2><p>
These worked examples show VX/FORTRAN rewriting real OpenVMS FORTRAN constructs into
standard FORTRAN. The identifiers use a banking demo estate; the syntax is exactly the kind
of change the migration applies.
</p><h6>Legacy I/O statements</h6><p>VMS terminal I/O statements become their standard equivalents:</p>
<pre><span class="kw">TYPE</span> 100, ACCOUNT_ID, BALANCE
<span class="kw">ACCEPT</span> 200, NEW_BALANCE</pre>
<p>becomes:</p>
<pre><span class="kw">PRINT</span> 100, ACCOUNT_ID, BALANCE
<span class="kw">READ</span> (*, 200) NEW_BALANCE</pre>
<h6>Hollerith and BOZ literals</h6>
<pre><span class="kw">WRITE</span> (6, 100) 5HDEBIT, AMOUNT
MASK = <span class="str">'FF'</span>X</pre>
<p>becomes:</p>
<pre><span class="kw">WRITE</span> (6, 100) <span class="str">'DEBIT'</span>, AMOUNT
MASK = <span class="kw">Z</span><span class="str">'FF'</span></pre>
<p>
The Hollerith count-and-string form is rewritten to a character constant, and the VMS
<code>'FF'X</code> hexadecimal literal becomes the standard <code>Z'FF'</code> form.
</p><h6>VMS file specifications</h6><p>A file opened with a VMS filespec keeps standard OPEN syntax; the runtime translates the specification at run time:</p>
<pre><span class="kw">OPEN</span> (<span class="kw">UNIT</span>=11, <span class="kw">FILE</span>=<span class="str">'DISK$DATA:[BANKING]ACCOUNTS.DAT;3'</span>,
& <span class="kw">STATUS</span>=<span class="str">'OLD'</span>)</pre>
<p>
The device, directory, and version-numbered VMS filespec is resolved to a host path by the
VX/RMS runtime when the file is opened, so the OPEN statement itself does not need editing
and logical names still resolve.
</p><h6>Keyed (ISAM) files</h6><p>Indexed and keyed files, which a standard compiler cannot open directly, are routed to the VX/RMS runtime:</p>
<pre><span class="kw">OPEN</span> (<span class="kw">UNIT</span>=12, <span class="kw">FILE</span>=<span class="str">'STATEMENTS.DAT'</span>,
& <span class="kw">ORGANIZATION</span>=<span class="str">'INDEXED'</span>, <span class="kw">ACCESS</span>=<span class="str">'KEYED'</span>,
& <span class="kw">STATUS</span>=<span class="str">'OLD'</span>)
<span class="cmt">! ... later ...</span>
<span class="kw">REWRITE</span> (<span class="kw">UNIT</span>=12) STATEMENT_REC</pre>
<p>
The keyed OPEN and the <code>REWRITE</code>, <code>DELETE</code>, and <code>UNLOCK</code>
record operations are served by the VX/RMS runtime, which replaces obsolete ISAM handling
with modern FORTRAN record I/O while preserving key structure and record locking.
</p><h2 id="runtime">Runtime, files, and system libraries</h2><p>
The emitted ANSI FORTRAN links against Sector7 runtime libraries that supply the OpenVMS
behaviour the source relied on. File and record access, VMS system services, numeric
formats, and embedded SQL all resolve against these libraries rather than being left to the
target compiler, so the migrated program behaves as it did on OpenVMS.
</p><div class="table-wrapper"><table><thead><tr><th>Area</th><th>What the runtime provides</th></tr></thead><tbody><tr><td>File and record I/O</td><td>VMS filespec translation, sequential, relative, and indexed (ISAM) files, and the OPEN, READ, WRITE, REWRITE, DELETE, and UNLOCK record operations, served by <a href="/technical/vx-rms-sys-routines-for-rms">VX/RMS</a>.</td></tr><tr><td>Numeric formats</td><td>VAX F, D, G, and H floating-point data converted to IEEE-754 so numeric results carry over unchanged.</td></tr><tr><td>FORTRAN support routines</td><td>The OpenVMS FORTRAN run-time support entry points delivered by <a href="/technical/api-for-fortran-support-routines">FOR$</a> inside <a href="/technical/vx-rt-apis">VX/RT</a>.</td></tr><tr><td>System services and libraries</td><td>OpenVMS <code>SYS$</code>, <code>LIB$</code>, and <code>SMG$</code> services provided by the <a href="/technical/api-sys-interface-routines">SYS$</a> emulation libraries in VX/RT, so system-service calls link and run without source changes.</td></tr><tr><td>Embedded SQL</td><td>Pro*FORTRAN SQL converted to external C functions on the <a href="/technical/vx-sql-fortran-with-embedded-sql-to-pro-c">VX/SQL-FORTRAN</a> path, so database access keeps working on the target platform.</td></tr></tbody></table></div><h6>File and record access</h6><p>
File operations route through <a href="/technical/vx-rms-sys-routines-for-rms">VX/RMS</a>, so
sequential, relative, and indexed files behave exactly as they did under OpenVMS RMS. VMS
file specifications are translated to host paths at run time, keyed and relative record
access is preserved, and record locking carries over, so the migrated program reads and
writes the same data files without a data conversion step.
</p><h6>System services and DCL</h6><p>
Applications that call OpenVMS system services keep working because those calls resolve
against the VX/RT emulation libraries rather than the VMS executive. Argument passing that
used <code>%VAL</code>, <code>%REF</code>, <code>%LOC</code>, or <code>%DESCR</code> is
rewritten to the host convention at translation time, and command-procedure and event-flag
behaviour is available through <a href="/technical/vx-dcl-vms-dcl">VX/DCL</a>, so no source
changes are needed to reach the services the application depends on.
</p><h2 id="compatibility">Compilers, targets, and optimisation</h2><p>
VX/FORTRAN produces ANSI-compliant FORTRAN for the Intel compiler on Linux and Windows and
preserves the OpenVMS behaviours applications depend on. The matrix summarises what is
supported, and the subsections cover the optimisation and code-quality work the migration
does along the way.
</p><div class="table-wrapper"><table><thead><tr><th>Capability</th><th>Support</th></tr></thead><tbody><tr><td>Target compiler: Intel FORTRAN (ifort / ifx)</td><td><span class="ac-live">live</span></td></tr><tr><td>Target platforms: x86 Linux and Windows</td><td><span class="ac-live">live</span></td></tr><tr><td>OpenVMS RMS and ISAM file handling through VX/RMS</td><td><span class="ac-live">live</span></td></tr><tr><td>OpenVMS system services and run-time libraries via VX/RT</td><td><span class="ac-live">live</span></td></tr><tr><td>VAX F / D / G / H floating-point to IEEE-754 conversion</td><td><span class="ac-live">live</span></td></tr><tr><td>Embedded Pro*FORTRAN SQL to external C functions</td><td><span class="ac-live">live</span></td></tr><tr><td>Source-code security and obfuscation</td><td><span class="ac-live">live</span></td></tr></tbody></table></div><h6>Code optimisation</h6><p>
While emitting the ANSI source, VX/FORTRAN applies optimisations that the original VMS build
did not: subroutines and statement functions are expanded inline to remove call overhead,
loops are unrolled, and memory-access patterns are tuned. Together these reduce function-call
and memory latency, and execution time can improve by up to 40 percent over the legacy VMS
build.
</p><h6>Code-quality analysis</h6><p>
Static analysis runs before migration and reports the systematic defects that accumulate in
long-lived FORTRAN. A representative analysis report looks like this:
</p><div class="table-wrapper"><table><thead><tr><th>Diagnostic</th><th>Count</th><th>Impact</th></tr></thead><tbody><tr><td>Missing subroutine declarations</td><td>12</td><td>Prevents compilation errors.</td></tr><tr><td>Inconsistent argument types</td><td>8</td><td>Fixes potential runtime crashes.</td></tr><tr><td>Unsafe integer-to-real conversion</td><td>15</td><td>Prevents loss of precision.</td></tr></tbody></table></div><p>
The analysis also flags keywords and intrinsics used as variable names, inconsistent name
usage, and uninitialised variables, so defects are corrected during migration rather than
carried onto the new platform.
</p><h6>Continuous migration without a code freeze</h6><p>
Because conversion is fully automated, a team keeps developing in OpenVMS FORTRAN while each
release is migrated to Linux and Windows on demand. There is no code freeze during a long
project, and functionality is preserved across the estate.
</p><h6>How this differs from an emulator or a rewrite</h6><p>
VX/FORTRAN is neither a hand rewrite nor a runtime emulator. It is a compile-time translator
that emits ANSI-compliant FORTRAN, so the result is standard source the Intel toolchain
builds and developers can read, debug, and maintain with mainstream tools. Every change is
recorded, and any construct the translator cannot represent is named rather than dropped, so
the migration is auditable rather than a black box.
</p><h2 id="quick-reference">Quick reference</h2><h6>Pipeline</h6><p><code>analyse → transpile → optimise → emit</code>, then build the emitted ANSI FORTRAN with the Intel compiler and link the VX/RMS and VX/RT runtimes.</p>
<pre><span class="cmt">1. Migrate: OpenVMS FORTRAN in, ANSI / Intel FORTRAN out (plus an analysis report)</span>
account.for -> account.f90 + account.log
<span class="cmt">2. Compile the emitted source with Intel FORTRAN</span>
ifx -O2 account.f90 -o account <span class="cmt">! links VX/RMS + VX/RT</span></pre>
<h6>Signature transforms to remember</h6><div class="table-wrapper"><table><thead><tr><th>OpenVMS FORTRAN</th><th>ANSI FORTRAN</th></tr></thead><tbody><tr><td><code>TYPE</code> / <code>ACCEPT</code></td><td><code>PRINT</code> / <code>READ</code></td></tr><tr><td><code>5HHELLO</code> (Hollerith)</td><td><code>'HELLO'</code> (character constant)</td></tr><tr><td><code>'FF'X</code> / <code>'377'O</code> / <code>'101'B</code></td><td><code>Z'FF'</code> / <code>O'377'</code> / <code>B'101'</code></td></tr><tr><td>VMS filespec in OPEN</td><td>Translated to a host path by VX/RMS</td></tr><tr><td><code>ACCESS='KEYED'</code> / ISAM files</td><td>Routed to the VX/RMS runtime</td></tr><tr><td><code>%VAL</code> / <code>%REF</code> / <code>%LOC</code> / <code>%DESCR</code></td><td>Host calling convention</td></tr><tr><td>Integer used as LOGICAL</td><td>Re-programmed to VMS LSB semantics</td></tr><tr><td>Pro*FORTRAN embedded SQL</td><td>External C functions</td></tr></tbody></table></div><h6>What migrates</h6><div class="kw-grid"><div>VMS extensions</div><div>Semantic differences</div><div>RMS / ISAM I/O</div><div>VAX float to IEEE</div><div>SYS$ / LIB$ / SMG$</div><div>Pro*FORTRAN SQL</div><div>DEC$ directives</div><div>CDD dictionary records</div></div></div>