REXX for VAX OpenVMS 7.3
My VAXstations now have REXX: Regina 3.3, the free implementation of IBM’s
Restructured Extended Executor, as a kit for OpenVMS VAX 7.3, with the DCL
lexical functions built in as REXX functions, DCL commands as ADDRESS
environments, and DCL symbols and logical names reachable with VALUE(). The
kit is a BACKUP saveset with a DCL installer and a DCL uninstaller; it needs
nothing on the target but the tools every VMS has.
Claude Code assisted, which is to say, did much of the hard work. (This seems to be my tagline these days.)
One correction first, because I made the mistake myself: my notes said Regina
was “available” in the Digiater freeware collection with a REGINA command. It
is not. The only copies on my media are two source tarballs on DECUS tapes
(a 1994 original VMS port and Regina 3.3 from 2004), and the 3.3 sources did not
compile on VMS: two of the files begin with a block of instructions to the
programmer that is not even a comment.
Downloads, with SHA-256 sums in SHA256SUMS.TXT:
- REXX_VAX_20261012B.BCK (5.0 MB): the kit to install.
- REXX_INSTALL.COM and REXX_UNINSTALL.COM.
- README.TXT, which says everything below about installing in more detail, and SHA256SUMS.TXT.
- The licence and the offer of the source (below): COPYING_LIB.TXT and SOURCES.TXT.
- Source kit (2.2 MB): the complete corresponding source (the original Regina 3.3 archive, the same tree with my changes applied, every change as a diff) with the build and kit procedures, the host tools, and the recipe to recreate the kit from scratch.
- Examples and tests: the programs below, their expected output, and the oracle test.
- The file list of the saveset: REXX_VAX_20261012B_LIST.LIS.
Licence
Regina is free software under the GNU Library General Public License,
version 2 (or any later version). The kit therefore does what that
licence asks: every original file keeps its header and its copyright
notice, every file I changed carries a dated “MODIFIED 12-OCT-2026” notice
and SOURCES.TXT lists each change. The
saveset itself carries the complete source of everything linked into
REXX.EXE and the procedure to rebuild it, and so does the source kit
above. The complete source, with the
changes and the build procedures
as well, are in the download. Nothing restricts
running Regina or using it for your scripts. The installer, uninstaller,
setup procedure and examples are mine; the three host tools are in the
public domain.
What REXX is
REXX was designed by Mike Cowlishaw at IBM in the late 1970s as a scripting
language for people, not for compilers: no declarations, every value a string,
arithmetic in decimal with as many digits as you ask for, and PARSE to pull
strings apart by template. It was the command language of VM/CMS, then of OS/2
and the Amiga (ARexx), and became an ANSI standard in 1996. Regina, by Anders
Christensen of Norway and later Mark Hessling and Florian Grosse-Coosmann, is the
portable free one; there was a VMS port of its early versions in 1994, which I did not use.
This is what a REXX program looks like (the picture at the top):
/* HERO.REX -- Regina REXX on a VAX: DCL lexical functions built in */
parse version name .
say name 'on' strip(F$GETSYI('HW_NAME')) 'under OpenVMS',
strip(F$GETSYI('VERSION'))
disk = 'SYS$SYSDEVICE'
say 'system disk' F$GETDVI(disk, 'VOLNAM'),
'has' F$GETDVI(disk, 'MAXBLOCK') 'blocks'
numeric digits 40
say '2**128 =' 2**128
address system 'DIRECTORY/NOHEADING/NOTRAILING *.REX' with output stem f.
say f.0 'REXX programs in' F$DIRECTORY()
say 'REXX asks DCL:' F$MESSAGE(98962)
$ REXX HERO
REXX-Regina_3.3 on VAXserver 3900 Series under OpenVMS V7.3
system disk V96SYS has 8388608 blocks
2**128 = 340282366920938463463374607431768211456
14 REXX programs in [SYSLIB.REXX.EXAMPLES]
REXX asks DCL: %RMS-E-FNF, file not found
(The “VAXserver 3900 Series” and the volume name V96SYS are what my simulator
reports: it runs a clone of my VAXstation 4000/96’s system disk.)
What was built
Regina 3.3 builds natively on the VAX with Compaq C V6.4: 43 modules, a 69-second batch job on the simulator, an 883-block image; no MACRO, MMS, MMK, lex or yacc. The work was in the VMS-specific files, which had never really worked with this compiler:
- The lexical functions:
F$GETJPI,F$GETDVI,F$GETSYI,F$TRNLNM,F$FILE_ATTRIBUTES,F$SEARCH,F$PARSE,F$CVTIME,F$FAOand about 25 more, as REXX functions of the same names. About a dozen of them had bugs – found by running every one next to the real DCL lexical function and comparing 128 results (below). Two more were added,F$EDITandF$DEVICE. - Commands:
ADDRESS SYSTEM 'any DCL command'runs it in a subprocess;WITH OUTPUT STEM d./FIFO/INPUT STEMcapture and feed it. The original code used Unixforkand pipes, which do not exist here: commands now go through temporary files andLIB$SPAWN. - Symbols and logical names:
VALUE('NAME',,'SYMBOL'),'GLOBAL','LOGICAL'. A symbol set from REXX is still there when the script ends. - Exit status:
EXIT 0is$STATUS1;EXIT nis an error status with the message display suppressed, soIF .NOT. $STATUSandON ERRORwork and DCL prints nothing.
Issues
WRITE SYS$OUTPUTin a subprocess fails with%DCL-W-UNDFILif the parent has a user-modeSYS$OUTPUTlogical name (whatDEFINE/USER SYS$OUTPUT filemakes): the child inherits it and it hides the output stream DCL opened for it. The fix is to take the definition away while the child runs.- An image can only make logical names in user mode: what a script defines with
VALUE(...,'LOGICAL')is gone when it ends, as withDEFINE/USER. 'b='bin REXX is a binary-string literal ('...'B): the interpreter says “Invalid hexadecimal or binary string”. Put a blank after the quote.- A DCL command line given to
LIB$SPAWNdoes no apostrophe substitution.
Installing
You need OpenVMS VAX 7.3, SYSTEM (or SYSPRV), and about 21,000 free
blocks on the system disk while installing. No compiler.
Put the saveset and the two
.COMfiles into one directory on the VAX. Transfer modes matter: the.BCKin binary, the.COMfiles in ASCII.A binary transfer loses the saveset’s record attributes; the installer puts them back itself:
$ SET FILE/ATTRIBUTE=(RFM:FIX,LRL:32256,MRS:32256,RAT:NONE) - REXX_VAX_20261012B.BCKAs
SYSTEM:$ @REXX_INSTALL(about 9 to 10 seconds on the simulator and 33 seconds on the VAXstation 4000/96 (first kit), for 268 files, most of them the sources.)
Each user, at the prompt or in
LOGIN.COM:$ @SYS$COMMON:[SYSLIB.REXX]REXX_SETUP $ REXX QUEENS ! found in the examples directory, type left out $ REXX MYSCRIPT.REX "some arguments"
@REXX_UNINSTALL CHECK says what an uninstall would remove, and
@REXX_UNINSTALL does it: only files the manifest lists and that are
still as installed.
Examples (all with expected output and a test)
RUN_TESTS.COM runs 11 programs and three more checks, and compares each with an
expected output made by an independent Python implementation (or by DCL
itself):
| Program | What it shows |
|---|---|
QUEENS | recursion with a procedure and stems: 2, 10, 4, 40, 92 solutions for N = 4..8 |
PRIMES | a sieve; exact 40! and 2**200, fib(200), square root and e to 30 digits |
WORDFREQ | PARSE, TRANSLATE, stems as tables |
ROMAN | Roman numerals both ways |
DATES | DATE('B') and week days against Python’s datetime |
DIRTABLE | F$SEARCH, F$PARSE, F$FILE_ATTRIBUTES; blocks checked against DIRECTORY/SIZE |
LOGLIST | a search-list logical name walked with F$TRNLNM |
SYMBOLS | local and global symbols and a logical name, set from REXX and read by DCL |
CAPTURE | command output into a stem and onto the stack, a command fed from a stem, a failing command’s condition value |
DCLCALL | REXX running a command procedure and using its status; and DCL running REXX and decoding $STATUS |
SYSREPORT | a system and process report compared with the same report in DCL |
and RUN_ORACLE.COM, the comparison of every F$ function with DCL (128 lines).
Results
Measured on a simulated MicroVAX 3900 (SIMH, OpenVMS VAX 7.3), except where the real machine is named:
- Build, link included: 69.7 s for 43 modules; the whole recipe, from the original sources to a tested kit and its lifecycle test, 2 min 21 s in one batch job. Simulated-VAX times say little about a real VAX; they are ratios.
- The DCL comparison: 128 of 128
tag=valuelines of the REXX functions equal DCL’s, as an ordinary user with the installed kit. - The examples: 14 of 14 as a fresh unprivileged user with the installed kit, about 10 s.
- The kit: 5,031,936 bytes (9,828 blocks); 268 files once installed (8,491 blocks, most of them the sources).
- The lifecycle test (install, refuse a second install, uninstall
CHECK, uninstall that keeps a changed file and a user file,REPLACE, reinstall): 21 of 21 checks. - On my VAXstation 4000/96, the first kit (the same
REXX.EXE; its test procedures left three temporary files in the home directory, which this kit’s do not) was installed system-wide on 12-OCT-2026:RUN_TESTSpassed 14 of 14 (38 s) andRUN_ORACLE128 of 128 (3 s) as an ordinary user; the install took 33 s. The kit named here, with the corrected test procedures, was tested on the simulator only: 14 of 14, 128 of 128, lifecycle 21 of 21, and the user’s home directory unchanged (746 files before and after).
What I did not check
- Real hardware, mostly: only the VAXstation 4000/96 (above). Not the 4000/60 or any other of my VAXen.
- The SAA API and the shared library: the kit is the stand-alone interpreter only.
F$CONTEXT,F$CSID,F$ENVIRONMENT,F$NODE,F$VERIFY: not implemented.- Regina 3.9.x (the current version): not on my media, and VMS support unverified. Alpha and Itanium: nothing.
- Speed: not measured against Perl or DCL on a real VAX.
Rebuilding
REBUILD.md in the source kit has every command, in order, from the DECUS
tarball (hash given) to a tested kit with the time of each step. The VAX
has no tar, so the tree goes over as one ASCII bundle made by a small
Python 3 script and unpacked by a small C program; the rebuild is then one
batch job.
How this was done
As with Emacs, Perl and Poplog: Claude sessions with written briefs, on a VAXstation and a simulator, with the rule that nothing counts until a test shows it, and the transcripts kept. Every number above comes from one of those transcripts.
Credits: Mike Cowlishaw for REXX; Anders Christensen, Mark Hessling and Florian Grosse-Coosmann for Regina; the DECUS library, which kept the tarballs; and Claude Code (Anthropic’s Claude models) for much of the building, debugging, testing and writing.
