BankLang

Getting started

Clone the repository, run the browser playground, and build an example. This guide ends with generated COBOL, JCL, copybooks, and verification reports on your machine.

Requirements

Node.js 24 or later, and pnpm 11.7.0. GnuCOBOL is optional: everything except the compile and execute lanes works without it.

git clone <this repository>
cd banklang
pnpm install

Install GnuCOBOL if you want to compile and execute the generated programs:

brew install gnu-cobol        # macOS, currently 3.2.0
apt-get install gnucobol      # Debian and Ubuntu, currently 3.1.2

Check what you got. cobc --version should say 3.2. Ubuntu's package is still 3.1.2, which is missing the JSON-STATUS special register that Enterprise COBOL has and this compiler emits, so six test files fail on COBOL that is correct for the target. CI builds 3.2 from source for exactly that reason; if your distribution ships 3.1, either build 3.2 or expect those lanes to fail.


Run the playground

pnpm playground:dev

The compiler runs in your browser. There is no compile server, and editor content stays in the browser. Click a line of BankTS or COBOL to follow the source map between the two panes.


Build an example

pnpm bankc build examples/account-file-batch

That writes the following artifacts under dist/:

dist/cobol/ACCOUNTF.cbl      the program
dist/copybooks/ACCOUNTR.cpy  a copybook per record
dist/jcl/ACCOUNTF.jcl        the job that builds and runs it
dist/maps/source-map.json    every module, record, field, function, transaction
dist/audit/                  diagnostics, decimal analysis, layout report

Read dist/cobol/ACCOUNTF.cbl from the top. Its prologue describes the entry point, datasets, external calls, and return codes.

Then read dist/jcl/ACCOUNTF.jcl. It is a generated starting point that still needs the site's job-card, dataset, and procedure standards.

If you are a mainframe engineer, go to for-mainframe-engineers.md now. It reads that program with you, construct by construct, and answers most of what you are about to ask.


See a diagnostic

Open examples/account-posting/src/main.bank.ts and try each of these:

Post a debit with no matching credit.

  debit(request.debitAccount, request.amount);

bankc check reports BANK-LED-001: the transaction does not balance.

Divide without saying how to round.

  let share: MoneyBDT = request.amount / 3.00;

BANK-DEC-003. The answer depends on the rounding mode, so somebody has to say which. divide(request.amount, 3.00, "HALF_EVEN") is accepted.

Add two different currencies.

type MoneyUSD = currency<"USD", 18, 2>;

BANK-DEC-005. There is no conversion operator, because a rate is a number somebody has to supply and a compiler that invented one would be inventing an exchange rate.

Write a transaction with an audit event but no idempotency key.

BANK-TXN-001. Retries need a caller-supplied key so the operation can be identified and deduplicated by the surrounding system.

pnpm bankc explain BANK-LED-001 prints the catalogue entry for any of them, and diagnostics.md is the whole list.


Run the checks

pnpm typecheck          # TypeScript
pnpm test               # everything, including programs that are executed
pnpm test:gnucobol      # every example, compiled under an IBM-shaped dialect
pnpm lint:conformance   # every artifact, against the target's rules
pnpm lint:zos           # every artifact, against what z/OS will do with it

pnpm test:gnucobol compiles each runnable example twice: once under tools/banklang-ibm.conf, which is shaped to Enterprise COBOL 6.4, and once under GnuCOBOL's default dialect. Differences are reported because a permissive local dialect can accept a name or phrase the target does not.

pnpm lint:conformance reads emitted artifacts, fixtures, and evidence bundles as text and checks target rules such as 30-character words, column 72, ARITH(COMPAT)'s eighteen digits, dataset qualifiers at eight, and the Enterprise COBOL vocabulary used by the project.

pnpm lint:zos checks behaviors that can be identified from generated text but are not covered by syntax or formatting checks. The findings are documented in target-conformance.md.


Start a project

pnpm bankc init my-service
pnpm bankc check my-service

bankc init produces a starter project. banklang.json beside src/ holds the settings; see toolchain.md.


Bring your own records

If you have a copybook:

pnpm bankc copybook import path/to/ACCTMAST.cpy

It prints a BankTS record. Before printing anything it emits that record back to a copybook and compares the two field by field: same names, same order, same offsets, same lengths, same pictures. If they differ, nothing is written and the reason is named: a field read at the wrong length moves every field after it.

If you have a DCLGEN member:

pnpm bankc dclgen import path/to/ACCOUNT.cpy

Same idea, and it gets nullability from the catalogue: a column with no NOT NULL becomes nullable<T>, which makes the compiler require a presence check before the program reads it.


Where to go next

You are Read
A mainframe engineer for-mainframe-engineers.md
Reviewing the generated code generated-code-standards.md
Asking what it is checked against target-conformance.md, verification.md
Asking where the money could be wrong numeric-model.md
Asking what happens on a bad night error-handling.md
Asking about the job jcl-model.md
Asking about PII security-and-data.md
Asking why not something else comparison.md
Learning the language language-reference.md
Asking what it does not do divergences.md

Read this page as Markdown on GitHub →