Because 1959 deserves to run on the blockchain.
The world's most absurd compiler: Enterprise COBOL β Solana BPF bytecode.
It actually works. β
IDENTIFICATION DIVISION.
PROGRAM-ID. COBOLANA.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 HELLO-MSG PIC X(14) VALUE "Hello Cobolana".
PROCEDURE DIVISION.
CALL "sol_log_" USING
BY REFERENCE HELLO-MSG
BY VALUE 14.
STOP RUN.IDENTIFICATION DIVISION.
PROGRAM-ID. COUNTER.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM-COUNTER PIC 9(8) VALUE 0.
PROCEDURE DIVISION.
ADD 1 TO NUM-COUNTER.
DISPLAY NUM-COUNTER.
STOP RUN.Compiles to sBPF assembly:
# Generated by cobolana-compiler (sBPF backend)
# Variable offsets in account data:
# NUM-COUNTER: offset 0x0071, size 8
.text
.globl entrypoint
entrypoint:
# Save input parameter pointer (r1) to r6
mov64 r6, r1
# ADD 1 TO NUM-COUNTER
ldxdw r2, [r6 + 0x71]
add64 r2, 1
stxdw [r6 + 0x71], r2
lddw r0, 0
exitA complete COBOL-to-Solana compiler that:
- Takes COBOL source code from 1959
- Compiles it to Solana BPF bytecode
- Deploys it on-chain
- Executes successfully with minimal compute units
This is not a joke. This is not a wrapper. This is a real compiler using GnuCOBOL's full parser infrastructure (20,000+ line bison grammar) with a custom Solana BPF backend.
- Because we can - The ultimate test of "everything is a compiler target"
- For the memes - COBOL on blockchain is peak absurdist programming
- Historical irony - Grace Hopper's 1959 language running on 2020s distributed ledgers
- It's actually interesting - Bridging 65+ years of computer science
COBOL Source (.cob)
β
ββββββββββββββββββββββββββββββββββββββββββββ
β cobolana-cc (GnuCOBOL-based compiler) β
β - Full COBOL parser (parser.y) β
β - Custom sBPF backend (codegen.c) β
ββββββββββββββββββββββββββββββββββββββββββββ
β
sBPF Assembly (.s)
β
ββββββββββββββββββββββββββββββββββββββββββββ
β sbpf build tool β
β - Assembles to ELF object β
β - Links syscalls β
ββββββββββββββββββββββββββββββββββββββββββββ
β
Solana BPF Program (.so)
β
solana-test-validator / Mainnet
# Install Solana CLI tools
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
# Install Node.js dependencies
npm install
# Build GnuCOBOL-based compiler (one-time setup)
cd cobolana-cc
make
cd ..# Build COBOL β Solana BPF
./build.sh
# Run end-to-end tests (deploys to local validator)
npm testcobolana/
βββ src/
β βββ cobolana.cob # COBOL source code
β βββ cobolana/ # Generated sBPF assembly (build artifact)
βββ cobolana-cc/ # The compiler
β βββ codegen.c # Custom Solana BPF backend
β βββ parser.y # COBOL grammar (from GnuCOBOL)
β βββ scanner.l # COBOL lexer
β βββ ... # Full GnuCOBOL infrastructure
βββ test/
β βββ cobolana.test.ts # Jest tests (deploy & verify on-chain)
βββ build.sh # Build script
βββ README.md # You are here
Uses GnuCOBOL's industrial-strength COBOL parser:
- 20,000+ line bison grammar
- Full COBOL-85 compatibility
- Builds an AST of the program
Custom backend that walks the AST and emits sBPF assembly:
// From codegen.c - Generating a sol_log_ syscall
fprintf(out, " lddw r1, msg_%s\n", field->name); // Load string address
fprintf(out, " lddw r2, %d\n", field->size); // Load string length
fprintf(out, " call sol_log_\n"); // SyscallOutputs valid sBPF assembly:
.section .rodata
msg_HELLO_MSG:
.ascii "Hello Cobolana"
.text
.globl entrypoint
entrypoint:
lddw r1, msg_HELLO_MSG
lddw r2, 14
call sol_log_
exitUses the sbpf toolchain to:
- Assemble
.sβ.o(ELF object) - Link syscalls (sol_log_ β 0x207559bd)
- Generate final
.sobinary
Jest tests deploy to solana-test-validator and verify on-chain execution.
The compiler tracks COBOL variables and generates efficient sBPF load/store operations:
Variable Tracking (codegen.c):
struct var_info {
const char *name;
int offset; // Offset in account data
int size; // Size in bytes (8 for numerics)
int reg; // Assigned register
int dirty; // Needs writeback
};
static struct var_info variables[MAX_VARIABLES];
static int next_offset = 0x0060; // Start offset
struct var_info *var = add_variable("NUM-COUNTER", 8);
// NUM-COUNTER gets offset 0x0060, size 8Code Generation for ADD 1 TO NUM-COUNTER:
// Detect cob_add_int funcall in AST
fprintf(out, " # ADD %lld TO %s\n", val, var_name);
fprintf(out, " ldxdw r2, [r6 + 0x%x]\n", var->offset); // Load variable
fprintf(out, " add64 r2, %lld\n", val); // Add immediate
fprintf(out, " stxdw [r6 + 0x%x], r2\n", var->offset); // Store resultBinary Operations (COMPUTE RESULT = A + B):
// Detect CB_ASSIGN with CB_BINARY_OP
fprintf(out, " ldxdw r2, [r6 + 0x%x]\n", op1_var->offset);
fprintf(out, " ldxdw r3, [r6 + 0x%x]\n", op2_var->offset);
fprintf(out, " add64 r2, r3\n"); // or sub64, mul64, div64
fprintf(out, " stxdw [r6 + 0x%x], r2\n", dest_var->offset);This maps directly to sBPF's register-based architecture with minimal overhead.
- β Full COBOL parser - Not a toy, uses production compiler infrastructure
- β Arithmetic operations - ADD, SUBTRACT, MULTIPLY compile to sBPF (add64/sub64/mul64)
- β Variable tracking - Working-storage variables mapped to account data offsets
- β
Real syscalls - Calls Solana's
sol_log_to write on-chain logs - β Minimal compute - Efficient register-based operations
- β End-to-end tests - Automated deploy & verification
- β Proper toolchain - Integrates with sbpf assembler/linker
Arithmetic Operations:
ADD NUM-A TO NUM-B.
SUBTRACT NUM-A FROM NUM-B.
MULTIPLY NUM-A BY NUM-B.
COMPUTE RESULT = NUM-A + NUM-B.
COMPUTE RESULT = NUM-A * NUM-B.These compile to efficient sBPF assembly:
ldxdw r2, [r6 + 0x61] # Load NUM-A
ldxdw r3, [r6 + 0x69] # Load NUM-B
add64 r2, r3 # Add
stxdw [r6 + 0x71], r2 # Store to RESULTVariable Storage:
- Numeric variables (PIC 9) allocated in account data
- 8 bytes per variable
- Fixed offset allocation (0x0060, 0x0068, 0x0070, etc.)
- Load/store via register r6
Persistence Issue (Actively Being Fixed):
- Variables currently use simplified offset model (0x60, 0x71, etc.)
- Solana's actual account serialization format is more complex
- Counter values don't persist across multiple calls
- Root cause: Need to parse Solana's account buffer structure (headers at 0x0000-0x0060, first account data at 0x0060, second account at 0x28c0, etc.)
- See Issue #4b8a for details
Not Yet Implemented:
- β Division operations (requires decimal precision handling)
- β Branching/conditionals (IF/ELSE)
- β PERFORM loops
- β String operations beyond logging
- β DISPLAY statement (assembly generation works, syscall integration pending)
But the compiler works, arithmetic compiles correctly, and we're fixing persistence next. π
In Progress:
- β COBOL arithmetic operations (ADD, SUBTRACT, MULTIPLY)
- π§ Fix account data persistence (parsing Solana buffer format)
- π§ Integrate DISPLAY statement with sol_log_ syscall
Next Up:
- Division operations with COBOL decimal semantics
- IF/ELSE β BPF conditional jumps
- PERFORM β BPF subroutines
- Support more Solana syscalls (sol_log_64_, etc.)
- Deploy a COBOL counter to devnet (for the culture)
Future Ideas:
- Map COBOL file I/O to Solana accounts
- COBOL table operations β account arrays
- Cross-program calls via CALL statement
- Mainnet deployment (the ultimate flex)
This started as a joke: "What's the most absurd language to compile to Solana?"
COBOL won because:
- Maximum age gap - 1959 vs 2020
- Cultural contrast - Enterprise banking vs DeFi
- Technical challenge - Complex grammar, different paradigms
- Meme potential - Infinite
After 83,000+ lines of compiler code and many debugger sessions, it works.
Program log: Hello Cobolana
Chef's kiss. π¨βπ³
- GnuCOBOL - For the industrial-grade COBOL parser
- sbpf toolchain - For making sBPF assembly viable
- Solana - For being a compiler target that accepts anything
- Grace Hopper - For COBOL (sorry Grace, we did this to your baby)
MIT - Do whatever you want with this madness
PRs welcome! Especially if you want to:
- Add more syscalls
- Implement COBOL arithmetic/branching
- Write more on-chain COBOL programs
- Make the error messages less terrifying
If this made you smile, give it a β
If this made you cry, also give it a β
If you worked in COBOL in the 80s and this triggered your PTSD, definitely give it a β
Built with β€οΈ and questionable life choices.
COBOL on Solana. Because someone had to.