COBOLを書いてみた~UbuntuとGnuCOBOLによる環境構築からプログラムを実行する~

どうも、N高生のゆういちです。

今回は興味本位でCOBOLを書いてみました。
あまりなじみのないCOBOLを触れようと思った理由はどんな技術だろうといった理由ですね。

色々調べていくうちに分かったことがありましたので、
初心者向けに説明していきます。

# 概要
COBOLのプログラムを作るにあたって、UbuntuやGnuCOBOL(旧openCOBOL)の環境構築した後、プログラムを作ります。

自分はWindows10で、GnuCOBOLどころかUbuntuもありません。なので、一から準備していく形です。

# 前提
- Windows10を使用
- Ubuntu上で行います。
- viエディタを使用。

# 1.Windows10にUbuntu20.04 LTSを導入

WindowsでGnuCOBOLを使用するにはWSLが必要になるので、WSLとUbuntuのインストールを行います。

## 1-1.WSLを有効化する
`Windowsの機能の有効化または無効化`を検索します。
Windowsの機能画面が出たら、`Linux用 Windows サブシステム`にチェックします。
環境によって言葉が変わってるかもしれないので、上記のチェック項目がない場合は`Windows Subsystem for Linux`という項目を探して、チェックしてください。

![ac43d6e8c363541fa23b972757072e3c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/eeb7a6de-d57c-b965-08cc-943783c40c89.png)

## 1-2.Ubuntu 20.04 LTSをインストール
MicroSoft Storeより、「Ubuntu 20.04 LTS」を検索→入手→起動

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/5308c0cf-ae53-c981-a568-8c04e47cdeca.png)

インストール後、最初の起動だけユーザー名とパスワードの入力が求められます。
パスワードは確認のパスワードの入力も含まれるので、これもパスワードを入力します。

```
Enter new UNIX username: <ユーザー名>
New password: <パスワード>
```

これでセットアップはひとまず完了です。

## 【おまけ】ターミナルを新調してみた
起動したUbuntuのターミナルでもいいのですが、せっかくなのでMac感がでてるターミナルに変えてみます。

MicroSoft Storeで「Windows Terminal Preview」を検索→入手→起動。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/45d4d257-778d-eb7b-c8a6-33ff0c26db8d.png)

起動するとmacっぽいターミナルが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/6196b6c2-a75e-4ecb-097d-599ec9856bdb.png)

タイトルバーの下向きの矢印(ドロップダウンメニュー)をクリックするとメニューが表示されます。
ここにはそのPCで利用可能なターミナルが反映されていて、任意のターミナルを起動できます。(PowerShellやコマンドプロンプトなど)
あとはUbuntu 20.04を選択すれば完了です。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/5cc2b103-2ea6-d2f2-7044-417e1ccde9b7.png)

これでターミナルの新調が完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/b01b97bb-3f62-f7c2-315c-6dbeb8f2a420.png)

# 2.GnuCOBOLをインストール

ターミナル上で以下のコマンドを実行しましょう。

- Windows10の場合

WindowsでGnuCOBOLを使うにはWSLを使います。先ほどUbuntuをインストール等と準備しましたので、あとは以下のコマンドを実行します。

```
sudo apt update
sudo apt install open-cobol
```

- macOSの場合

macOSではホームブリューを使います。[こちら](https://brew.sh/index_ja)からインストールできます。

```
brew install gnu-cobol
```

完了まで10分以上かかると思いますので、その間は本を読んだりして、時間を有効的に使いましょう。

# 3.COBOLのプログラムをつくる

やっと本題です。実際にCOBOLを使ってプログラムを書いていきましょう。
手順は以下です。

## 3-1.Hello, World!を書く

1.現在のディレクトリの位置を確認。

pwdコマンドを実行。

```
$ pwd
/mnt/c/Users/user
```

2.任意のディレクトリを作成
ここでは、`dev`ディレクトリ、`hello.cbl`というソースファイルを作成します。
前提通り、viコマンドを実行してviエディタでプログラムを書いていきます。

```
$ mkdir dev
$ cd dev
$ vi hello.cbl // COBOLのソースファイルを作成
```

3.ソースコードを書く。

```vim

       IDENTIFICATION DIVISION.
       PROGRAM-ID. HELLO.
       PROCEDURE DIVISION.
       DISPLAY "Hello, World!".
       STOP RUN.
```

4.コンパイル
`-x`オプションは、実行ファイルを作成するためのオプションです。

```
$ cobc -x ./hello.cbl
```

5.実行ファイルが作成。
先ほどの`-x`オプションによって、実行ファイルとしてhelloという名前のファイルが作成されました。

```
$ ls
hello  hello.cbl
```

6.プログラムを実行。
結果が出力されたらクリアです！

```
$ ./hello
Hello, World!
```

## 3-2.1から10まで加算して表示する

```vim
       IDENTIFICATION DIVISION.
       PROGRAM-ID.loop.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 I PIC 9(2).
       01 CNT PIC 9(2).
       PROCEDURE DIVISION.
       MAIN.
        MOVE 0 TO I
        MOVE 0 TO CNT
           PERFORM UNTIL I >= 10
            ADD 1 TO I
            ADD I TO CNT
            DISPLAY "I=" I ", CNT=" CNT
           END-PERFORM.
           DISPLAY "CNT=" CNT
           STOP RUN.
           END PROGRAM loop.
```

`DATA DIVISION.`と`WORKING-STORAGE SECTION.`以下で変数を宣言。
`PERFORM`から`END-PERFORM`の範囲が繰り返し処理を行い、
`PERFORM UNTIL 条件`というように書きます。

あとは実行すると以下のようになります。

```
I=01, CNT=01
I=02, CNT=03
I=03, CNT=06
I=04, CNT=10
I=05, CNT=15
I=06, CNT=21
I=07, CNT=28
I=08, CNT=36
I=09, CNT=45
I=10, CNT=55
CNT=55
```

## 3-3.FizzBuzz問題を書いてみる

```vim

       IDENTIFICATION DIVISION.
       PROGRAM-ID. FizzBuzz.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 N PIC 9(3) VALUE 1.
       01 FIZZ PIC 9(1).
       01 BUZZ PIC 9(1).
       PROCEDURE DIVISION.
           PERFORM 100 TIMES
                   COMPUTE FIZZ = FUNCTION MOD(N 3)
                   COMPUTE BUZZ = FUNCTION MOD(N 5)
                   IF FIZZ = 0 AND BUZZ = 0 THEN
                           DISPLAY "FizzBuzz"
                   ELSE IF FIZZ = 0 THEN
                           DISPLAY "Fizz"
                   ELSE IF BUZZ = 0 THEN
                           DISPLAY "Buzz"
                   ELSE
                           DISPLAY N
                   END-IF
                   END-IF
                   END-IF
                   ADD 1 TO N
           END-PERFORM.
           STOP RUN.
```

`PERFORM 100 TIMES`で、100回繰り返しが行われます。
`COMPUTE FIZZ = FUNCTION MOD(N 3)`は、Nを3で割った余りを変数FIZZに代入。


↓実行

```
001
002
Fizz
004
Buzz
Fizz
007
008
Fizz
Buzz
011
Fizz
013
014
FizzBuzz
...
```

# 実際にやってみて
以上でCOBOLの環境構築からプログラムを書くところまで行いました。
COBOLは仕様上、構文が冗長なのが特徴的で、クセの強い言語だなぁというのが感想ですね。
FizzBuzz問題のコードはif elseの部分とかは他のプログラミング言語とさほど変わらないかな。

VScodeで書きたい人向けとして、「COBOL」という拡張機能を使えばシンタックスハイライトや入力補完が使えますので是非使ってみてください。(てかCOBOL書きたい人いるのか???)

### 参考サイト

- [COBOLがコロナで大注目?! 60年以上前の言語が最近話題](https://news.mynavi.jp/article/programinglanguageoftheworld-28/)
- [Windows 10にUbuntu 20.04 LTSをインストールする
](https://news.mynavi.jp/article/liunx_win-51/)
- [【COBOL】初めての人でも簡単に開発環境（OpenCOBOL）を構築し、Hello Worldのプログラムを作成・実行出来るようにするまで](https://qiita.com/yut-nagase/items/bd76b6424d7d0b23221f)