Enterprise COBOL · z/Architecture
A COBOL compiler that targets Enterprise COBOL byte for byte.
WORKING-STORAGE stays in EBCDIC, packed and zoned decimal behave as PACK, ZAP, AP and DP treat them, COMP-1 and COMP-2 are hexadecimal floating point, and ARITH, TRUNC, NUMPROC and CODEPAGE are honoured as IBM’s compiler honours them. ironwork for COBOL is written in Rust.
git clone https://github.com/Portll/ironwork && cd ironwork && cargo run -p ironwork -- run program.cbl
- Crate dependencies
- 0
- Unsafe code
- Forbidden
- Licence
- AGPL-3.0-or-later
01 CUST-REC.
05 CUST-ID PIC 9(5) VALUE 123.
05 CUST-NAME PIC X(5) VALUE 'ACME'.
05 BALANCE PIC S9(5)V99 COMP-3 VALUE -123.45.
05 TXN-COUNT PIC S9(4) BINARY VALUE 2345.
CUST-REC16 bytesCODEPAGE(1140)
Printed by ironwork from its own storage, a byte at a time through FUNCTION ORD. Zone F sits over each digit of CUST-ID, X'40' pads the name, BALANCE packs seven digits and ends in sign nibble D, and TXN-COUNT is the halfword X'0929'.
Status
Machine model, then compiler
One model of the machine and IBM’s compiler decides every result the interpreter gives, and code generation is built on the same model.
Implemented: a model of what the machine and IBM’s compiler do with the bytes, and an oracle that writes the programs to score that model against the real compiler. In progress: a front end and interpreter that run COBOL on EBCDIC storage through that model.
IBM-equivalent machineimplemented
Decimal and floating-point results come from a model of the instructions z/Architecture runs.
- 21 single-byte EBCDIC code pages.
PACK,UNPK,ZAP,AP,SP,MP,DP,CP,SRP,CVB,CVD,TP.- Hexadecimal floating point, short, long and extended, with the guard digit, truncation and exponent exceptions.
IBM-equivalent compilerimplemented
Options change results as they change them under IBM’s compiler.
- The option vector.
- Binary stores under each
TRUNC. NUMPROCsign handling.ARITHintermediate precision and float conversions.
Conformance testsimplemented
The model can be scored against IBM’s compiler, and the machine against Hercules.
COBOL programs pin their options on a CBL card, DISPLAY each case’s storage in hex, and are scored against the model’s predictions. About two thousand instruction cases run under Hercules, a second reading of the machine.
Limit: no IBM goldens are held yet, so the predictions are not yet scored against IBM’s compiler.
Front end and interpreterin progress
COBOL programs run today, on storage laid out as IBM lays it out.
- Fixed-format source, COPY with REPLACING, the lexer and the parser.
- Storage laid out byte for byte from USAGE, PICTURE, REDEFINES and OCCURS.
- An interpreter that runs batch programs, EXEC SQL against PostgreSQL or a recording, and a CICS task on a 3270 terminal.
Code generationin progress
A program becomes a reproducible load module that static and dynamic CALL load, or runs in a VM.
Each program is lowered to the LIR: storage places resolved, arithmetic planned to IBM’s precision, basic blocks with explicit PERFORM exits, and typed service calls. Every result is decided by the same machine and compiler models, and differential testing holds it to the interpreter byte for byte.
ironwork compile writes a program as a load module, ironwork dump prints one and ironwork run x.iwm runs one on the VM. ironwork run --vm and ironwork cics --vm run a lowered program there, its files, SORT, Report Writer, EXEC SQL and EXEC CICS included, and write the evidence journal and coverage report the interpreter writes.
Limit: the VM stops a run at FUNCTION UUID4, at FUNCTION RANDOM in a subscript and at a few forms the LIR does not carry yet, and the interpreter stays the default.
Runtimein progress
Programs that run on it are not covered by the AGPL.
The library a compiled program calls: storage access, MOVE, comparison, editing and arithmetic stores; abends; files, SORT, CICS commands, BMS and the 3270 terminal, SQL, and Language Environment services. Each is decided once, for every executor, beside the models it is checked against.
The interpreter runs through rt for storage, the statements, files, CICS, SQL, Language Environment, object-oriented COBOL, SORT and Report Writer, and the VM makes the same calls.
Features
What runs today
Each feature below has a section of its own on the Features page, with a run you can reproduce.
Compiler options
A program computes what it computes under IBM’s options.
ARITH, TRUNC, NUMPROC, CODEPAGE, SSRANGE, ZONEDATA, NSYMBOL, VSAMOPENFS and the other options that change results are honoured as IBM’s compiler honours them, from IBM’s table of 85, and so are the checking options NUMCHECK, ZONECHECK, PARMCHECK and INITCHECK.
Abends
Bad data stops the run where z/OS would stop it.
S0C7, S0C4, S806 and user completion codes end the run with exit status 240.
Batch COBOL
Batch programs run today, and a construct outside the subset is refused or stops the run.
The subset covers source with COPY, data laid out byte for byte, files and VSAM, subprograms, Language Environment services and object-oriented COBOL.
SORT and MERGE
Sorted output comes out in the order DFSORT gives.
Zoned and packed keys compare as DFSORT compares them, and FASTSRT is honoured.
Report Writer
Report Writer programs run without IBM’s precompiler.
A report prints as the precompiler’s output would print it, with ASA control characters.
EXEC SQL
Programs with embedded SQL run without Db2.
They run against PostgreSQL, or from a recording of a run with no database, dynamic SQL included.
CICS and BMS
A CICS transaction runs without a CICS region.
Its maps come from BMS source and show on a 3270 terminal, scripted or served over TN3270.
Conformance tests
Every prediction can be scored against IBM’s compiler, and the machine model’s against Hercules.
302 assumptions are recorded, each naming what settles it.
Code pages
Data keeps its mainframe bytes.
Storage stays in EBCDIC, in any of 21 single-byte code pages, with DBCS data under the eleven mixed CCSIDs, and is converted only at I/O.
Run
Build and run
Nothing to vet beyond the workspace: it builds with Cargo and has no dependencies outside it.
Release 0.7.0 is on crates.io, PyPI and npm, as cargo install ironwork, pip install ironwork and npm install -g @portll/ironwork, with builds for Linux, macOS and Windows; each release is on Releases. CBL and PROCESS cards in the source set the options.
Limit: what the Roadmap marks on main needs a build from the repository.
git clone https://github.com/Portll/ironwork && cd ironwork && cargo run -p ironwork -- run program.cbl
| Command or flag | What it does |
|---|---|
run <program.cbl> | Compiles and runs. check compiles only |
cics <program.cbl> | Run as the first program of a CICS task, with run’s flags and those under CICS |
assumptions [--c-series] | Lists the register of assumptions, one per line. --c-series numbers every entry in one C series, with its own id beside it |
-I <copylib> | Where COPY members are found, after the program’s own directory |
-L <proglib> | Where CALL finds a program by name, after the programs in the same source and the program’s directory. A dynamic CALL can name only such a member, never a path |
--dd NAME=path[:text] | The file a DD names. ASSIGN names a DD, and a program reaches only the files its DDs are given, here or by DD_NAME in the environment, as JCL gives them on z/OS. ACCEPT reads DD SYSIN, or standard input without one. An indexed or relative file’s DD holds its records in key order, as an IDCAMS REPRO unload of the cluster does. :text reads UTF-8 lines through the code page, for fixtures written by hand, and shows a print file’s control characters as line spacing |
--clock <time> | Fixes the time ACCEPT FROM DATE and TIME, FUNCTION CURRENT-DATE and the Language Environment time services report, otherwise the system clock in UTC |
-silent | Stops the checked-mode reports, of TRUNC(OPT) stores and of SORTs whose outcome FASTSRT changes, without changing what is stored |
-strict-sort-keys | Reads each SORT or MERGE key as the program would, so a zoned or packed key that is not a valid number abends S0C7 |
-warnings-block | Refuses to run a program if its compile gave warnings, as NOCOMPILE(W) would; the return code stays 4. A CBL or PROCESS card’s COMPILE or NOCOMPILE wins over it |
-debug | Sets the Language Environment runtime option DEBUG, so a program compiled WITH DEBUGGING MODE runs its USE FOR DEBUGGING procedures; NODEBUG, IBM’s default, keeps them from running |
--dialect ibm|gnucobol | Whose result to give where ironwork knowingly differs from GnuCOBOL: ibm, the default, or gnucobol, which gives cobc’s results for a migration |
--compliance strict|extended | strict, the default, refuses what Enterprise COBOL refuses. extended reads Micro Focus and GnuCOBOL extensions, among them free-form source, level-78 and CONSTANT entries, <>, ASSIGN to a data item and a numeric function as a MOVE’s sender, each with a warning naming it |
--sql-db postgres://… | Runs EXEC SQL against PostgreSQL. A normal end commits and an abend rolls back |
--sql-record <path> | With --sql-db, writes each call and its answer to the file, for --sql-replay |
--sql-replay <path> | Answers EXEC SQL from a recording instead of a database. --sql-replay-mode keyed matches calls by statement and inputs rather than by order |
Licence
Programs you compile, check or run with ironwork are not covered by the AGPL.
AGPL-3.0-or-later with a runtime exception. PolyForm Internal Use is available for a fee, and a negotiated licence for other uses (LICENSING.md).
Limit: contributions need the CLA.
Tests
The emulators are tested for panics, and the interpreter is held to the model’s bytes.
cargo testruns the instruction and HFP emulators against random operands to check that none panics.- The interpreter must reproduce every predicted byte for the four oracle programs.
- The front end is fuzzed by mutating real programs on every test run, and by a coverage-guided cargo-fuzz target.
Beside cobolwork
What ironwork learns about IBM’s semantics reaches cobolwork as analysis rules.
cobolwork analyses COBOL estates for security and never links ironwork; the two share only data: IBM’s tables and fixtures, listed on the home page under Shared data.
The figures on these pages
Each output can be reproduced.
Every run shown is ironwork 0.7.0. The programs, the BMS map, the terminal script and the SQL recording are kept with this site.