# COBOL

«bold»Both source layouts are accepted«/» (classic fixed format and free format, «bold»detected automatically«/»). The execution model is COBOL's paragraphs and «bold»fall-through«/»: the main flow `CALL`s each paragraph in order, and `PERFORM` is just a `CALL`.

Arithmetic, control flow, paragraphs / `PERFORM` and library calls are all there; `CALL "ui_2d_clear" USING ...` reaches the `ui_*` interfaces.

## How to run it on your phone

```
vml run examples/cobol/demo/fizzbuzz.cob
```

Compiling takes a while (one to two minutes for C, a few seconds for scripting languages).
Once the program is running, **the gamepad is at the bottom of the screen** - the D-pad
and the four action buttons are all there. Tap the back arrow in the top-right corner to
return to the Shell.

## What to know before you write

- In fixed format, mind the columns: «bold»1-6 are the sequence area, column 7 is the indicator, and only columns 8-72 are code«/»; columns 73-80 are «bold»discarded«/»
- The two layouts are «bold»detected automatically«/» (the rule is whether columns 1-6 contain a letter); to force one, write `>>SOURCE FORMAT IS FREE` (or `FIXED`) in the file
- Comments: inline `*>` («bold»not inside quotes«/»); a whole-line comment in fixed format goes in «bold»column 7«/» (`*` or `/`)
- «bold»A full stop `.` ends a sentence«/» - COBOL does not let you leave it out
- Call the UI with `CALL "ui_2d_clear" USING ...` (arguments pushed in reverse)

## Examples

| File | What it shows |
|---|---|
| `demo/fizzbuzz.cob` | FizzBuzz (`PERFORM VARYING` plus `COMPUTE` remainders plus `IF`) |
| `demo/hello.cob` | The smallest program in **fixed format** |
| `demo/report.cob` | A small report (`PIC X(n)` space padding plus numeric layout plus accumulation) |

## Pitfalls we hit on real devices

- ⚠ «bold»The `V` scaling decimal point is not converted«/» (`PIC 9(2)V99`): `V` is only recorded and this subset's arithmetic is «bold»integer«/» arithmetic, so `COMPUTE P = 10 / 4` gives `2` where standard COBOL gives `2.50`.
- ⚠ «bold»An `OCCURS` table has no array semantics«/»: `T(1)` and `T(2)` are «bold»the same cell«/» (there is a warning, but the result is still wrong).
- `MOVE CORRESPONDING` is a «bold»compile-time error«/»; `COPY` recognises the library name but does «bold»not«/» expand it.
- `STRING ... DELIMITED BY SPACE/literal` is always treated as `SIZE` (the whole field).
- «bold»File I/O and sorting / inspection are not done«/»: `OPEN`/`READ`/`WRITE`/`CLOSE`/`SORT`/`SEARCH`/`INSPECT`/`UNSTRING` all report «bold»"not supported yet" at compile time«/» (never silently).
- `COMP-3` packed decimal is recognised as a clause but «bold»stored as a plain integer«/».
- A `SECTION` header is treated as a paragraph header, so `PERFORM section-name` runs only the «bold»first«/» paragraph in it; in `ACCEPT ... FROM env-name` everything after `FROM` is «bold»ignored«/» (it always reads standard input).
- `/` is «bold»integer division«/» (`7 / 3` is `2`); a decimal in a literal is «bold»truncated«/» with a warning.

---

The rest of this page is taken straight from the VML source (`third_party/vml/VMLPrepares/CobolCompiler/`):
the `README` covers what this front end supports and how to compile it, and the
language reference covers the syntax itself. When upstream changes, regenerating
this page brings it up to date.

## Language reference

### COBOL subset — language spec

> Written for «bold»people writing programs«/»: what this frontend accepts, what those forms mean,
> and where it differs from standard COBOL.
> Implementation notes live in `README.md`; wiring lives in `INTEGRATION.md`.

Version: v1 (2026-10-13) · extensions `.cob` (also `.cbl`) · probe `scripts/vml-cobol-probe/run.sh`

---

> «bold»Version«/»: v1.0 | «bold»Date«/»: 2026-10-13 | «bold»Revised by«/»: Shenzhen Tanso Intelligent Technology Co., Ltd.

#### Specification standard

| Field | Value |
|:-----|:----|
| «bold»Target standard«/» | COBOL-85 subset |
| «bold»Publication year«/» | 1985 |
| «bold»Completeness«/» | Subset (not itemised) |
| «bold»Tests«/» | 28 passing / 0 failing / 4 known-red |

#### Keywords

`ACCEPT` `ADD` `ADVANCING` `AFTER` `ALL` `ALTER` `AND` `ANY` `ASCENDING` `AT`
`BEFORE` `BINARY` `BLANK` `BY` `CALL` `CLOSE` `COMMUNICATION` `COMP` `COMP-1`
`COMP-2` `COMP-3` `COMP-4` `COMPUTE` `CONTENT` `CONTINUE` `CORR` `CORRESPONDING`
`DATA` `DELETE` `DELIMITED` `DESCENDING` `DISPLAY` `DIVIDE` `DIVISION` `ELSE`
`END` `END-ACCEPT` `END-ADD` `END-CALL` `END-COMPUTE` `END-DISPLAY` `END-DIVIDE`
`END-EVALUATE` `END-IF` `END-MULTIPLY` `END-PERFORM` `END-STRING` `END-SUBTRACT`
`ENTER` `ENVIRONMENT` `EQUAL` `ERROR` `EVALUATE` `EXIT` `EXTERNAL` `FILE`
`FILLER` `FROM` `GIVING` `GLOBAL` `GO` `GOBACK` `GREATER` `HIGH-VALUE`
`HIGH-VALUES` `IDENTIFICATION` `IF` `INITIAL` `INITIALIZE` `INSPECT` `INTO`
`INVALID` `IS` `JUSTIFIED` `KEY` `LESS` `LINKAGE` `LOCAL-STORAGE` `LOW-VALUE`
`LOW-VALUES` `MERGE` `MOVE` `MULTIPLY` `NEXT` `NO` `NOT` `NULL` `NULLS` `OCCURS`
`OF` `ON` `OPEN` `OR` `OTHER` `PACKED-DECIMAL` `PERFORM` `PIC` `PICTURE`
`PROCEDURE` `PROGRAM` `PROGRAM-ID` `QUOTE` `QUOTES` `READ` `REDEFINES`
`REFERENCE` `RELEASE` `REMAINDER` `REPORT` `RETURN` `RETURNING` `REWRITE`
`ROUNDED` `RUN` `SCREEN` `SEARCH` `SECTION` `SENTENCE` `SET` `SIGN` `SIZE`
`SORT` `SPACE` `SPACES` `START` `STOP` `STRING` `SUBTRACT` `TEST` `THAN` `THEN`
`THROUGH` `THRU` `TIMES` `TO` `TRUE` `UNSTRING` `UNTIL` `UPON` `USAGE` `USING`
`VALUE` `VALUES` `VARYING` `WHEN` `WITH` `WORKING-STORAGE` `WRITE` `ZERO`
`ZEROES` `ZEROS`

#### Overview
A subset of COBOL-85 is supported, compiled to VML assembly. The source first goes through `CobolSourceFormat`, which folds «bold»physical lines into logical lines«/» (fixed format: columns 1–6 sequence area, column 7 indicator, A and B areas, columns 73–80 discarded per the standard, `-` for continuation; plus free format — the two are «bold»detected automatically«/» and can be overridden with `>>SOURCE FORMAT IS FREE|FIXED`). COBOL is «bold»not tokenised by punctuation«/» (`MOVE 1 TO X ADD 1 TO Y.` is a single sentence), so the parser locates statement boundaries by asking whether the next word is a verb or clause word; «bold»unimplemented verbs report loudly«/» rather than being skipped silently. All numbers are 32-bit integers, and libraries are pulled in by the `.linked` entries in `Lib/cobol/builtin.vml`.

#### Supported language features

The features this frontend accepts are organised by the sections below; each one states what is accepted and what it means:

- «bold»The two source layouts«/»: fixed (sequence area / column-7 indicator / A and B areas / columns 73–80 discarded / continuation) and free; the detection rule is falsifiable, and `>>SOURCE FORMAT IS …` overrides it — §1
- «bold»Program structure«/»: the `IDENTIFICATION` / `ENVIRONMENT` / `DATA` / `PROCEDURE` divisions, `SECTION`s and paragraphs (including fall-through), `PROGRAM-ID` — §2
- «bold»Data items and PIC«/»: level numbers, `PIC` / `PICTURE`, `USAGE`, `REDEFINES`, `OCCURS`, `VALUE`, `FILLER` — §3
- «bold»Statements«/»: assignment and arithmetic (`MOVE` / `COMPUTE` / `ADD` / `SUBTRACT` / `MULTIPLY` / `DIVIDE`), output (`DISPLAY`), conditionals and branching (`IF`, `EVALUATE`), loops and paragraph calls (`PERFORM`), string building (`STRING`), library calls (`CALL`), input (`ACCEPT`), termination (`STOP RUN` / `GOBACK` / `EXIT` / `CONTINUE`) — §4
- «bold»Comments«/»: fixed format column 7 `*` / `/` / `D`; inline `*>` in both formats (not inside quotes) — §5
- «bold»Numbers and rounding«/»: 32-bit integers, `/` is integer division, `**` is exponentiation — §6
- «bold»Known limits«/»: no scaling for the `V` decimal point, `OCCURS` has no array semantics, `COPY` is not expanded, file I/O / sorting / inspection not done — §7

See the sections below for details.

#### 1. The two source layouts

COBOL sources come in two layouts. «bold»This frontend detects them automatically and accepts both.«/»

##### Fixed format (classic)

```
column 123456|7|8...........11|12.....................72|73..80
meaning seq  |ind|  area A    |        area B            |dropped
```

- «bold»1–6«/»: sequence area (old-style line numbers, may be blank)
- «bold»7«/»: indicator — blank = normal code; `*` or `/` = whole-line comment; `D` (or `d`) = debug line (treated as a comment); `-` = «bold»continuation«/» (this line's column 8 onward is appended to the previous line)
- «bold»8–11 (area A)«/»: paragraph names, `SECTION`, `01`/`77` data items, …
- «bold»12–72 (area B)«/»: ordinary statements
- «bold»73–80«/»: «bold»dropped«/» per the standard (this frontend does exactly that; `23-col72-limit.cob` pins it)

##### Free format

Code starts at column 1 (or a few columns of indent); tokens are separated by whitespace; comments are `*>`.

##### The detection rule (falsifiable)

> Scan every non-blank line; «bold»if any line has a letter in columns 1–6«/», it is free format; otherwise fixed format.

Because fixed-format code always starts at column 8 (columns 1–6 never hold letters), while free-format
code starts at column 1. Fixed format with sequence numbers (`000100 IDENTIFICATION …`) has «bold»digits«/» in
columns 1–6 ⇒ still fixed.

«bold»Force it«/» (escape hatch when auto-detection guesses wrong; the first occurrence wins):

```
>>SOURCE FORMAT IS FREE
>>SOURCE FORMAT IS FIXED
```

---

#### 2. Program structure

```cobol
       IDENTIFICATION DIVISION.
       PROGRAM-ID. NAME.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-N    PIC 9(3).      *> data item
       77 WS-X    PIC X(10).     *> level-77 standalone item
       PROCEDURE DIVISION.
       MAIN-PARA.                *> a paragraph is "NAME." on its own line
           MOVE 1 TO WS-N.
           STOP RUN.
```

#### 3. Data items and PIC

```cobol
       01 WS-N    PIC 9(3).            *> 3 digits
       01 WS-NAME PIC X(10).           *> 10 characters (fixed length)
       01 WS-AMT  PIC S9(5)V99.        *> signed + implied decimals (see section 7)
       01 WS-CNT  PIC 9(3) VALUE 0.    *> with an initial value
```

Supported picture symbols: `9`, `X`/`A`, `S`, `V`, `Z`/`*`, and repetition `(n)`. Other editing symbols
(`B` `/` `,` `+` `-` `$`) are recognised but do not change the length semantics.

A «bold»numeric item«/» is a 4-byte integer; a «bold»character item«/» is fixed length and its initial value is
«bold»padded with spaces«/» to that length (COBOL convention). `VALUE "AB"` in `PIC X(5)` prints as `AB   `.

#### 4. Statements

##### Assignment and arithmetic

```cobol
           MOVE 5 TO WS-N.
           MOVE "AB" TO WS-NAME.          *> short string padded to the fixed length
           MOVE WS-N TO WS-NAME.          *> numeric -> character (converted to text)
           MOVE WS-NAME TO WS-N.          *> character -> numeric (parsed back)
           COMPUTE WS-N = (A + B) * 2.    *> + - * / ** with parentheses and precedence
           ADD 5 TO WS-N.                 *> WS-N = WS-N + 5
           ADD 5 TO WS-N GIVING WS-M.     *> WS-M = WS-N + 5 (WS-N unchanged)
           SUBTRACT 3 FROM WS-N.          *> WS-N = WS-N - 3
           MULTIPLY 2 BY WS-N.            *> WS-N = WS-N * 2
           DIVIDE 2 INTO WS-N.            *> WS-N = WS-N / 2 (integer division)
           DIVIDE 7 BY 3 GIVING WS-M.     *> WS-M = 7 / 3 = 2
```

«bold»With `GIVING` the target is only written; without `GIVING` the target takes part in the operation«/» —
that is COBOL's own rule, don't mix it up.

##### Output

```cobol
           DISPLAY "TOTAL=" WS-N.         *> operands are printed back to back, newline at the end
           DISPLAY "X" WITH NO ADVANCING.  *> no trailing newline
```

`DISPLAY` inserts «bold»no separator«/» between operands (that is COBOL; write the space into the literal yourself).

##### Conditions

```cobol
           IF A > B THEN DISPLAY "BIG" ELSE DISPLAY "SMALL" END-IF.
           IF A = 1 THEN DISPLAY "ONE".        *> period-terminated (old style) works too
```
Both operator spellings are accepted: `=` `<` `>` `<=` `>=` `<>`, and `IS [NOT] EQUAL TO` /
`IS GREATER THAN` / `IS LESS THAN`. Conditions combine with `AND` / `OR` / `NOT` and parentheses.
A bare operand as a condition (`IF FLAG`) means "non-zero is true".

##### Branching

```cobol
           EVALUATE K
               WHEN 1   DISPLAY "ONE"
               WHEN 3   DISPLAY "THREE"
               WHEN OTHER DISPLAY "OTHER"
           END-EVALUATE.
```

##### Loops and paragraph calls

```cobol
           PERFORM PARA.                                   *> call once, returns at the paragraph's end
           PERFORM A THRU B.                               *> runs every paragraph from A through B
           PERFORM PARA UNTIL WS-I > 10.                    *> test before (COBOL default)
           PERFORM PARA VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10.
           PERFORM 3 TIMES … END-PERFORM.                   *> inline block, 3 times
```

⚠ «bold»The control variable ends one step past the last executed value«/» (`UNTIL WS-I > 5` running 1..5 leaves
`WS-I = 6`) — that is COBOL's definition (increment, then test), not a defect.

##### Paragraphs and fall-through

COBOL executes paragraphs «bold»sequentially«/»: from the first paragraph onward, each one following the previous,
unless `STOP RUN` / `GOBACK` / `PERFORM` moves control elsewhere.

```cobol
       P1.
           ADD 1 TO N.
       P2.
           ADD 10 TO N.          *> no PERFORM: the main flow falls through from P1 into here
           STOP RUN.
```

`PERFORM P` runs «bold»only P«/» and returns (no fall-through past P).

##### String concatenation

```cobol
           STRING "HELLO" DELIMITED BY SIZE "WORLD" DELIMITED BY SIZE INTO WS-S.
```

Whatever follows `DELIMITED BY` is currently treated as `SIZE` (the whole piece); "stop at a space"
(`BY SPACE`) is not implemented yet.

##### Library calls (`CALL`)

```cobol
           CALL "abs" USING -9 GIVING WS-R.          *> math library
           CALL "strlen" USING WS-NAME GIVING WS-R.  *> string library
           CALL "ui_2d_clear" USING WS-COLOR.        *> host drawing API
```

`CALL "name" USING a b` passes the arguments in order (VML `__stdcall` convention); the return value,
if any, lands in the `GIVING` item. «bold»This is the door from COBOL to `ui_*` / `tty_*` and every shared library.«/»
The auto-linked set is in `Lib/cobol/builtin.vml` (includes `vmlui` / `tty` / `vml3d`).

##### Input

```cobol
           ACCEPT WS-N.        *> numeric item: reads one integer
           ACCEPT WS-NAME.     *> character item: reads one line
```

##### Termination

`STOP RUN.` / `GOBACK.` / `EXIT.` / `CONTINUE.` (no-op). `STOP RUN` inside a paragraph really ends the
process — including when reached through `PERFORM`.

#### 5. Comments

| Where | How |
|---|---|
| fixed format, whole line | `*` or `/` in column 7 |
| fixed format, debug line | `D`/`d` in column 7 (treated as a comment) |
| inline (both formats) | from `*>` to end of line |
| free format, whole line | `*>` at the start (any indent) |

⚠ «bold»`*>` inside a string literal is text, not a comment«/» (`DISPLAY "A*>B"` prints `A*>B`).

#### 6. Numbers and rounding

- All numerics are «bold»32-bit integers«/»; `/` is «bold»integer division«/» (`7 / 3 = 2`)
- A literal with a fraction (`1.5`) is «bold»truncated to an integer«/» and produces a «bold»warning«/» (never silent)
- `«bold»` is exponentiation (`2 «/» 8 = 256`, via the library function `ipow`)

#### 7. Known limitations (differences from standard COBOL)

| Limitation | Effect | Criterion |
|---|---|---|
| «bold»scaled decimals (`V`) are not scaled«/» | `PIC 9(2)V99` is just an integer; `COMPUTE P = 10 / 4` gives `2` (standard COBOL gives `2.50`) | `bugs/vml_cobol_bugs/cb01` |
| «bold»`OCCURS` tables unsupported«/» | `T(1)` and `T(2)` hit the same cell («bold»with a warning«/»); no array semantics at all | `cb02` |
| «bold»`MOVE CORRESPONDING` unsupported«/» | «bold»compile error«/» (it does not guess) | `cb03` |
| «bold»`STRING … DELIMITED BY SPACE/literal`«/» | everything is treated as `SIZE` (whole piece) | `cb04` |
| «bold»`COPY` is not expanded«/» | the copybook name is recognised, but its text is not inserted | — |
| «bold»file I/O / sorting / inspection«/» | `OPEN/READ/WRITE/CLOSE/SORT/SEARCH/INSPECT/UNSTRING` report "not supported yet" at compile time | — |
| «bold»`COMP-3` packed decimal«/» | the clause is recognised, the value is stored as a plain integer | — |
| «bold»section-level PERFORM«/» | a `SECTION` header is treated as a paragraph header; `PERFORM SECTION-NAME` runs only its first paragraph | — |
| «bold»`ACCEPT … FROM env-name`«/» | everything after `FROM` is ignored (input always comes from stdin) | — |

All of these are registered one by one, with reproductions and measured numbers, in
`bugs/vml_cobol_bugs/COBOL问题清单.md`.

#### 8. Complete runnable examples

`third_party/vml/Examples/cobol/demo/`:

| File | Shows |
|---|---|
| `hello.cob` | smallest fixed-format program |
| `fizzbuzz.cob` | `PERFORM VARYING` + nested `IF` + remainder |
| `report.cob` | fixed-length character padding + numeric layout + accumulation |

## Compiler README

### COBOL compiler (subset)

«bold»Path«/»: `third_party/vml/VMLPrepares/CobolCompiler/`
«bold»Extensions«/»: `.cob` (also accepts `.cbl`)
«bold»Language library«/»: `Lib/cobol/` (`builtin.vml`)
«bold»Maturity«/»: enough to write ordinary programs (full arithmetic + control flow + calls + paragraphs/PERFORM + library calls)
«bold»Probe«/»: `scripts/vml-cobol-probe/run.sh` — «bold»pass 28 / fail 0 / known-red 4«/» (measured 2026-10-13; 28 = 27 language criteria + 1 carrier criterion)

---

#### 1. What this frontend accepts

| Feature | Status |
|---|---|
| «bold»Fixed format«/» (cols 1–6 sequence area / col 7 indicator / cols 8–72 code) | ✅ auto-detected, see below |
| «bold»Free format«/» (code from column 1) | ✅ auto-detected; `>>SOURCE FORMAT IS FREE/FIXED` overrides |
| Column-7 `*` `/` whole-line comment, `D` debug line | ✅ |
| Column-7 `-` «bold»continuation«/» | ✅ (a string literal may be split across it) |
| Inline comment `*>` | ✅ («bold»`*>` inside quotes is not a comment«/») |
| Columns 73–80 dropped per the standard | ✅ |
| `IDENTIFICATION / DATA / PROCEDURE DIVISION` | ✅ |
| `WORKING-STORAGE SECTION` / level-`77` items | ✅ |
| `PIC`: `9` `X` `A` `S` `V` `Z` `*` plus repetition `(n)` | ✅ parsed; `V` scale is recorded only (see limitations) |
| `VALUE` initial value (numeric / string / figurative constant) | ✅ |
| `MOVE` (numeric↔numeric / char→numeric / numeric→char, «bold»char fields padded with spaces«/») | ✅ |
| `COMPUTE dst = expr` (`+ - * / **`, parentheses, precedence) | ✅ |
| `ADD / SUBTRACT / MULTIPLY / DIVIDE` (with `GIVING`) | ✅ |
| `DISPLAY` (multiple operands, `WITH NO ADVANCING`, `UPON`) | ✅ |
| `IF … THEN … ELSE … END-IF` and the «bold»period-terminated«/» form | ✅ |
| `EVALUATE … WHEN … WHEN OTHER … END-EVALUATE` (incl. `EVALUATE TRUE`) | ✅ |
| `PERFORM paragraph` / `PERFORM A THRU B` | ✅ |
| `PERFORM para UNTIL cond` («bold»test before«/», COBOL default) | ✅ |
| `PERFORM para VARYING i FROM a BY b UNTIL c` (nestable) | ✅ |
| `PERFORM n TIMES … END-PERFORM` (inline block) | ✅ |
| `STRING … DELIMITED BY SIZE … INTO …` | ✅ |
| `CALL "name" USING … GIVING …` (reaches `ui_*` / `tty_*` / shared libraries) | ✅ |
| `ACCEPT` (numeric item via `input_int`, char item via `gets`) | ✅ |
| `STOP RUN` / `GOBACK` / `EXIT` / `CONTINUE` / `NEXT SENTENCE` | ✅ |
| «bold»Sequential paragraph execution (fall-through)«/» — COBOL's execution model | ✅ |
| `STOP RUN` inside a paragraph (ends the process even when PERFORM'd) | ✅ |

«bold»Not supported yet«/» (each has a criterion in `bugs/vml_cobol_bugs/`, see `COBOL问题清单.md`):
scaled decimals (`V`) in arithmetic, `OCCURS` tables, `MOVE CORRESPONDING`, `COPY` expansion,
`STRING … DELIMITED BY SPACE/literal`, file I/O (`OPEN/READ/WRITE`),
`COMP-3` packed decimal, `SORT`/`SEARCH`/`INSPECT`/`UNSTRING`, section-level `PERFORM`.

---

#### 2. How the two formats are decided

The rule lives in `SourceFormat.cs` (a «bold»pure function«/», pinned directly by the probe):

> Scan every non-blank physical line; «bold»if any line has a letter in columns 1–6«/», it is free format; otherwise fixed format.

- Fixed-format code always starts at column 8 (columns 1–7 hold sequence/indicator/blank) ⇒ never triggers
- Free-format code starts at column 1 (a few columns of indent at most) ⇒ always triggers
- Fixed format with sequence numbers (`000100 IDENTIFICATION …`) has «bold»digits«/» in columns 1–6 ⇒ still fixed

Escape hatch: `>>SOURCE FORMAT IS FREE` / `>>SOURCE FORMAT IS FIXED` (the first one wins).

#### 3. Execution model (COBOL paragraph semantics, one-to-one)

```
main:  CALL para1 ; CALL para2 ; … ; exit    ← this is COBOL's sequential / fall-through execution
paraN: prologue ; statements… ; epilogue(RET) ← every paragraph is a subroutine that returns
PERFORM P          ⇒ CALL P
PERFORM A THRU B   ⇒ CALL A ; CALL B          ← every paragraph in the range runs, none outside it
```

The mapping is exact, not approximate: in COBOL "fall-through" and "PERFORM returns" look contradictory,
and "main calls each paragraph once + each paragraph returns" expresses both at the same time
(criteria: `20-fallthrough.cob` pins fall-through, `17-perform-thru.cob` pins the THRU boundary).

#### 4. Data and calling convention

- All data items live in the «bold»data section«/» (COBOL data is static; there is no recursion):
  a numeric item is one 4-byte word, a character item is `Length+1` bytes (NUL included,
  «bold»pre-filled with spaces«/»).
- Assigning to a character item goes through `str_padend(dst, src, totalLen, space)` — that is how
  "COBOL character items are fixed length and pad with spaces" is implemented
  (`MOVE "AB" TO X(5)` then `DISPLAY` prints `AB   `).
- Cross-type `MOVE` (numeric ↔ character) uses `int_to_str` / `str_to_int`.
- `CALL "x" USING a b` is just VML `CALL` (arguments pushed in reverse, `__stdcall` convention).

#### 5. Build and run

The csproj is `Exe` during development (switch back to `Library` for release, see `INTEGRATION.md`):

```bash
# end-to-end on one case (inlines the standard library; vmlcli can then assemble+run it)
dotnet run --project third_party/vml/VMLPrepares/CobolCompiler -- prog.cob -o prog.vml

# see what the lexer actually read (handy for fixed-format column trimming / PIC pictures)
dotnet run --project third_party/vml/VMLPrepares/CobolCompiler -- --tokens prog.cob

# inline the standard library into the output (used by the dev-time probe; see run.sh)
dotnet run --project third_party/vml/VMLPrepares/CobolCompiler -- --inline prog.cob -o prog.vml

# criteria
scripts/vml-cobol-probe/run.sh
```

#### 6. Files

| File | Role |
|---|---|
| `SourceFormat.cs` | «bold»physical line → logical line«/» (format detection, column trimming, continuation, inline comments) — pure functions |
| `Lexer.cs` | tokenizer (reads a `PIC` picture string as one token) |
| `Parser.cs` | syntax → AST (two word tables decide where a statement ends) |
| `CodeGenerator.cs` | AST → VML |
| `CobolCompiler.cs` / `CobolPlugin.cs` / `Program.cs` | the three entry points / plugin / CLI |
| `COBOL_LANGUAGE_SPEC.md` | language subset spec (what you can write, and what it means) |
| `INTEGRATION.md` | «bold»wiring checklist«/» (which file, which line) |
