BESM-6 was a Soviet mainframe computer produced from the late 1960s through the 1980s. It was one of the most powerful computers of its era in the Eastern Bloc, and it supported a rich set of programming languages: Algol, Fortran, Pascal, and several assemblers. Modern ports of the B language (the predecessor of C) and of C itself are also supported.
besmc is a command-line tool that lets you write programs in those same languages on
a modern computer and compile them into BESM-6 executables. Under the hood it uses the
dubna simulator, which runs the original BESM-6 compilers
exactly as they ran on the real hardware.
In short: you write a program in one of the old BESM-6 languages, run besmc yourprogram.pascal,
and get a runnable yourprogram.exe — no real BESM-6 mainframe required.
- Prerequisites
- Build and Install
- Quick Start
- Supported Languages
- Compiling to an Object File
- Mixed-Language Programs
- Command-Line Options
- Troubleshooting
- Running the Tests
Before you can use besmc you need these installed:
-
The dubna simulator — download and install it from github.com/besm6/dubna. The
dubnacommand must be on your$PATH. This is the engine that actually runs the BESM-6 compilers and your compiled programs, so it is required at all times. -
The Rust compiler — needed only to build
besmcitself. Install it from rust-lang.org/tools/install. -
pascompl— only needed if you compile.pas(Pascal-re) files. If you never use the.pasextension you can skip this one. It must also be on your$PATH. -
The BESM-6 C compiler — only needed if you compile
.cfiles. Build and install it from github.com/besm6/c-compiler. That provides the three BESM-6 compiler passesb6parse,b6lower, andb6codegen(which must end up on your$PATH), together with the BESM-6 C headers and thelibc.binruntime library. The headers and library are installed under one of~/.local/share/besm6/,/usr/local/share/besm6/, or/usr/share/besm6/(include/for the headers,lib/libc.binfor the library);besmcfinds them automatically. You also need a standard C preprocessorcppon your$PATH— the one shipped with your system (GCC or Clang) is fine.
Get the source, build it, and install the command:
git clone https://github.com/besm6/besmc.git
cd besmc
make
make installThe besmc binary is installed to ~/.cargo/bin/besmc.
If you later type besmc and see command not found, that directory is not on your
$PATH. Add it once:
export PATH="$HOME/.cargo/bin:$PATH"To make it permanent, add that same line to the end of your shell's startup file —
~/.bashrc for bash or ~/.zshrc for zsh — then open a new terminal.
Save this Pascal program as hello.pascal:
program main(output);
_(
writeln('Hello, Pascal!');
stop;
_).Note: This Pascal dialect uses
_(and_).as block delimiters instead of the usualbegin/end.
Compile it:
besmc hello.pascalTwo files are created:
| File | What it is |
|---|---|
hello.exe |
The executable program |
hello.lst |
The compiler listing (output from the BESM-6 compiler, useful for diagnosing errors) |
Run the program:
$ ./hello.exe
HELLO, PASCAL!What is that
.exe? Despite the name, it is not a Windows program. It is a tiny text script that begins with the line#!/usr/bin/env dubna, so running it simply hands it to thedubnasimulator. It runs on any system (Linux, macOS, …) wheredubnais installed, and you can also run it explicitly withdubna hello.exe.
besmc recognises the following file extensions:
| Extension | Language |
|---|---|
.pascal |
Pascal |
.pas |
Pascal-re (requires pascompl on your $PATH) |
.ftn |
Fortran-ГДP |
.fortran |
Fortran Dubna |
.forex |
Forex |
.algol |
Algol-ГДP |
.assem |
Assembler Madlen |
.madlen |
Assembler Madlen-3.5 |
.bemsh |
Assembler БЕМШ (source code written in Cyrillic) |
.b |
B (modern port) |
.c |
C (modern port) |
.obj |
Pre-compiled object library (for linking) |
Working "Hello, World!" examples for every language are in the examples/ directory, with detailed explanations in examples/README.md.
By default besmc produces a ready-to-run .exe. If you want to compile a source file
without linking it (for example, to combine it later with code written in another language),
use the -c flag:
besmc -c hello.pascalThis produces hello.obj instead of hello.exe. Object files can be passed to a later
besmc invocation for linking.
One of BESM-6's strengths was that programs could freely mix languages — a Pascal main
program could call a Fortran subroutine, for instance. Here is how to do that with besmc.
Step 1 — Write the Pascal main program (caller.pascal):
program main (output);
procedure hello; fortran;
_(
hello;
stop;
_).The procedure hello; fortran; declaration tells the Pascal compiler that hello is
implemented in Fortran.
Step 2 — Write the Fortran subroutine (callee.ftn):
subroutine hello
print 1000
1000 format('Hello Fortran from Pascal!')
endStep 3 — Compile each file separately, then link them together:
besmc -c caller.pascal # produces caller.obj
besmc -c callee.ftn # produces callee.obj
besmc caller.obj callee.obj # links both into caller.exeRun the result:
$ ./caller.exe
HELLO FORTRAN FROM PASCAL!Note: You can list up to 16 object files in a single linking command.
| Option | Description |
|---|---|
-c / --compile |
Compile to an object file (.obj); do not link |
-o FILE / --output FILE |
Set the output file name (default: derived from the first input file) |
-t / --save-temps |
Keep intermediate files (.dub script, output.bin, persNN.bin) |
-h / --help |
Print help |
| Message you see | What it means and how to fix it |
|---|---|
dubna: command not found |
The dubna simulator is not installed or not on your $PATH. Install it from github.com/besm6/dubna and make sure the dubna command works in your terminal. |
besmc: command not found |
The besmc binary is not on your $PATH. Add ~/.cargo/bin to it — see Build and Install. |
Failed to execute pascompl |
You are compiling a .pas file but pascompl is not installed. Install it and put it on your $PATH, or use the .pascal extension instead, which does not need it. |
Failed to execute cpp / b6parse / b6lower / b6codegen |
You are compiling a .c file but part of the C toolchain is missing. Install the BESM-6 C compiler passes and make sure cpp, b6parse, b6lower, and b6codegen are all on your $PATH. |
BESM-6 C headers not found / BESM-6 libc.bin not found |
The BESM-6 C support files are not installed. Put the headers in <prefix>/share/besm6/include/ and the library in <prefix>/share/besm6/lib/libc.bin, where <prefix> is ~/.local, /usr/local, or /usr. |
Compilation failed! See details in <name>.lst |
Your source code has an error. Open the <name>.lst listing file to find it. The BESM-6 compilers report errors in Russian (for example, lines containing OШИБ mean "errors"); the annotated listings in examples/README.md show what a clean listing looks like for each language. |
Tip: When something goes wrong and you want to look under the hood, add -t
(--save-temps). besmc will then keep the intermediate files — including the generated
*.dub script that it feeds to dubna — instead of deleting them.
To verify that everything is working:
make testYou should see all tests pass:
running 52 tests
test test::test_exe::test_pascal_exe ... ok
test test::test_exe::test_fortran_exe ... ok
...
test result: ok. 51 passed; 0 failed; 0 ignored