← Dolaima← Docs indexCOBOL原文中文

COBOL

Both source layouts are accepted (classic fixed format and free format, detected automatically). The execution model is COBOL's paragraphs and fall-through: the main flow CALLs 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

Examples

FileWhat it shows
demo/fizzbuzz.cobFizzBuzz (PERFORM VARYING plus COMPUTE remainders plus IF)
demo/hello.cobThe smallest program in fixed format
demo/report.cobA small report (PIC X(n) space padding plus numeric layout plus accumulation)

Pitfalls we hit on real devices


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 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


Version: v1.0 | Date: 2026-10-13 | Revised by: Shenzhen Tanso Intelligent Technology Co., Ltd.

Specification standard

FieldValue
Target standardCOBOL-85 subset
Publication year1985
CompletenessSubset (not itemised)
Tests28 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 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 detected automatically and can be overridden with >>SOURCE FORMAT IS FREE|FIXED). COBOL is 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; 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:

See the sections below for details.

1. The two source layouts

COBOL sources come in two layouts. 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
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; 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 digits in columns 1–6 ⇒ still fixed.

Force it (escape hatch when auto-detection guesses wrong; the first occurrence wins):

>>SOURCE FORMAT IS FREE
>>SOURCE FORMAT IS FIXED

2. Program structure

       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

       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 numeric item is a 4-byte integer; a character item is fixed length and its initial value is padded with spaces to that length (COBOL convention). VALUE "AB" in PIC X(5) prints as AB .

4. Statements

Assignment and arithmetic
           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

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
           DISPLAY "TOTAL=" WS-N.         *> operands are printed back to back, newline at the end
           DISPLAY "X" WITH NO ADVANCING.  *> no trailing newline

DISPLAY inserts no separator between operands (that is COBOL; write the space into the literal yourself).

Conditions
           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
           EVALUATE K
               WHEN 1   DISPLAY "ONE"
               WHEN 3   DISPLAY "THREE"
               WHEN OTHER DISPLAY "OTHER"
           END-EVALUATE.
Loops and paragraph calls
           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

⚠ 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 sequentially: from the first paragraph onward, each one following the previous, unless STOP RUN / GOBACK / PERFORM moves control elsewhere.

       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 only P and returns (no fall-through past P).

String concatenation
           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)
           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. 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
           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

WhereHow
fixed format, whole line* or / in column 7
fixed format, debug lineD/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)

⚠ *> inside a string literal is text, not a comment (DISPLAY "A*>B" prints A*>B).

6. Numbers and rounding

7. Known limitations (differences from standard COBOL)

LimitationEffectCriterion
scaled decimals (V) are not scaledPIC 9(2)V99 is just an integer; COMPUTE P = 10 / 4 gives 2 (standard COBOL gives 2.50)bugs/vml_cobol_bugs/cb01
OCCURS tables unsupportedT(1) and T(2) hit the same cell (with a warning); no array semantics at allcb02
MOVE CORRESPONDING unsupportedcompile error (it does not guess)cb03
STRING … DELIMITED BY SPACE/literaleverything is treated as SIZE (whole piece)cb04
COPY is not expandedthe copybook name is recognised, but its text is not inserted—
file I/O / sorting / inspectionOPEN/READ/WRITE/CLOSE/SORT/SEARCH/INSPECT/UNSTRING report "not supported yet" at compile time—
COMP-3 packed decimalthe clause is recognised, the value is stored as a plain integer—
section-level PERFORMa SECTION header is treated as a paragraph header; PERFORM SECTION-NAME runs only its first paragraph—
ACCEPT … FROM env-nameeverything 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/:

FileShows
hello.cobsmallest fixed-format program
fizzbuzz.cobPERFORM VARYING + nested IF + remainder
report.cobfixed-length character padding + numeric layout + accumulation

Compiler README

COBOL compiler (subset)

Path: third_party/vml/VMLPrepares/CobolCompiler/ Extensions: .cob (also accepts .cbl) Language library: Lib/cobol/ (builtin.vml) Maturity: enough to write ordinary programs (full arithmetic + control flow + calls + paragraphs/PERFORM + library calls) Probe: scripts/vml-cobol-probe/run.sh — pass 28 / fail 0 / known-red 4 (measured 2026-10-13; 28 = 27 language criteria + 1 carrier criterion)


1. What this frontend accepts

FeatureStatus
Fixed format (cols 1–6 sequence area / col 7 indicator / cols 8–72 code)✅ auto-detected, see below
Free format (code from column 1)✅ auto-detected; >>SOURCE FORMAT IS FREE/FIXED overrides
Column-7 * / whole-line comment, D debug line✅
Column-7 - continuation✅ (a string literal may be split across it)
Inline comment *>✅ (*> 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, 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 period-terminated form✅
EVALUATE … WHEN … WHEN OTHER … END-EVALUATE (incl. EVALUATE TRUE)✅
PERFORM paragraph / PERFORM A THRU B✅
PERFORM para UNTIL cond (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✅
Sequential paragraph execution (fall-through) — COBOL's execution model✅
STOP RUN inside a paragraph (ends the process even when PERFORM'd)✅

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 pure function, pinned directly by the probe):

Scan every non-blank physical line; if any line has a letter in columns 1–6, it is free format; otherwise fixed format.

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

5. Build and run

The csproj is Exe during development (switch back to Library for release, see INTEGRATION.md):

# 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

FileRole
SourceFormat.csphysical line → logical line (format detection, column trimming, continuation, inline comments) — pure functions
Lexer.cstokenizer (reads a PIC picture string as one token)
Parser.cssyntax → AST (two word tables decide where a statement ends)
CodeGenerator.csAST → VML
CobolCompiler.cs / CobolPlugin.cs / Program.csthe three entry points / plugin / CLI
COBOL_LANGUAGE_SPEC.mdlanguage subset spec (what you can write, and what it means)
INTEGRATION.mdwiring checklist (which file, which line)