Dockerとdocker-composeでFreeBASICの実行環境を作った

# 概要

昔の資料にあるBASICのプログラムを移植してみたくなり、まずはBASICの動く環境を作ってみた。

# 参考

[https://qiita.com/yam_dev/items/76743f63a2e8911f10f7](https://qiita.com/yam_dev/items/76743f63a2e8911f10f7)

# FreeBASICのダウンロード

[https://sourceforge.net/projects/fbc/files/FreeBASIC-1.10.1/Binaries-Linux/](https://sourceforge.net/projects/fbc/files/FreeBASIC-1.10.1/Binaries-Linux/)

GUIでダウンロードしたほうが良さげ

# Dockerfile

```docker
# ベースイメージとしてUbuntuを使用
FROM ubuntu:latest

# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
    tar \
    xz-utils \
    nano \
    gcc \
    libncurses5-dev \
    && rm -rf /var/lib/apt/lists/*

# FreeBASICのバイナリをコンテナにコピー
COPY FreeBASIC-1.10.1-ubuntu-22.04-x86_64.tar.xz /tmp

# FreeBASICを解凍してインストール
RUN tar -xJf /tmp/FreeBASIC-1.10.1-ubuntu-22.04-x86_64.tar.xz -C /usr/local
ENV PATH="/usr/local/FreeBASIC-1.10.1-ubuntu-22.04-x86_64/bin:${PATH}"

# ワークディレクトリの設定
WORKDIR /workspace/src

COPY system-info.bas /workspace/system-info.bas
```

ほとんど参考元と同じだが、`src` フォルダをコンテナ内と同期させて使いたいので、ワークディレクトリにしている。

# 単純なコンテナのビルドと起動

```bash
docker build -t basic-env .
docker run -it basic-env
```

`docker`コマンドを打つとき、常駐してないとdocker desktopの起動を忘れがちなので注意。

動作確認

```bash
root@9c7f1229caaf:/workspace/src# ls ..
src  system-info.bas
root@9c7f1229caaf:/workspace/src# which fbc
/usr/local/FreeBASIC-1.10.1-ubuntu-22.04-x86_64/bin/fbc
```

参考元と同じ表示
`system-info` のコンパイル等々に関しては省略

# フォルダ同期と停止後コンテナ即削除

`src` フォルダをコンテナ内外で同期させるのと、コンテナ停止したら即削除するようにする。

```powershell
PS> docker run --rm -it -v $pwd/src:/workspace/src basic-env
```

# docker-composeで書く

毎回オプションが覚えられないので、docker-composeで設定してみる。

以下のdocker-compose.ymlを作成。

```yaml
# BASIC実行用の対話型コンテナを起動
version: '3'
services:
  basic-env:
    image: basic-env
    container_name: basic-env-container
    # ./srcコンテナを同期
    volumes:
      - ./src:/workspace/src
    working_dir: /workspace/src
    stdin_open: true
    tty: true
    # 実行したいコマンドを設定
    command: /bin/bash

```

# docker-composeの起動コマンド

```bash
PS> docker-compose run --rm basic-env
```

# テストプログラム

大学時代の教科書にあった、消去法で一次連立方程式を解くプログラムを入力してみた。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601058/d91acf01-692d-7d7f-922c-a24ec510c713.png" width="200"/>

# コンパイル

```bash
root@9c7f1229caaf:/workspace/src# ls  
matrix.bas
root@9c7f1229caaf:/workspace/src# fbc matrix.bas
matrix.bas(1) error 146: Only valid in -lang deprecated or fblite or qb in '100 REM renritu 1 ji houteisiki'
matrix.bas(2) error 146: Only valid in -lang deprecated or fblite or qb in '110 DIM A(10,11), X(10)'
matrix.bas(3) error 146: Only valid in -lang deprecated or fblite or qb in '120 WIDTH 80,25'
matrix.bas(4) error 146: Only valid in -lang deprecated or fblite or qb in '130 REM yomikomi to shokisettei'
matrix.bas(5) error 146: Only valid in -lang deprecated or fblite or qb in '140 READ M,N'
matrix.bas(6) error 146: Only valid in -lang deprecated or fblite or qb in '150 LET N1=N+1'
matrix.bas(7) error 146: Only valid in -lang deprecated or fblite or qb in '155 PRINT'
matrix.bas(8) error 146: Only valid in -lang deprecated or fblite or qb in '157 LPRINT'
matrix.bas(9) error 146: Only valid in -lang deprecated or fblite or qb in '160 PRINT "renritu 1 ji houteisiki"'
matrix.bas(10) error 146: Only valid in -lang deprecated or fblite or qb in '162 LPRINT "renritu 1 ji houteisiki"'
matrix.bas(10) error 133: Too many errors, exiting
```

FreeBASICは行番号をサポートしているはずだが、エラーになる。

https://life-is-command.com/free-basic/

を参考に `-lang qb`  オプションを入れる

もう一度ビルド

```powershell
root@9c7f1229caaf:/workspace/src# fbc -lang qb matrix.bas
root@9c7f1229caaf:/workspace/src# ls
matrix  matrix.bas
root@9c7f1229caaf:/workspace/src# ll
total 76
drwxrwxrwx 1 root root  4096 Nov 24 08:57 ./
drwxr-xr-x 1 root root  4096 Nov 22 01:18 ../
-rwxr-xr-x 1 root root 68296 Nov 24 08:57 matrix*
-rwxrwxrwx 1 root root  3493 Nov 24 08:54 matrix.bas*
```

ビルドできている。

# 実行

```powershell
root@9c7f1229caaf:/workspace/src# ./matrix
```

```bash
renritu 1 ji houteisiki

nyuuryoku DATA
 1 -2  1 -1 
 2 -1  8 -5 
 1 -3  2 -3 

shoukyohou no jyoukyou ( 1 )
x( 1 )        x( 2 )        x( 3 )        
 1            -2             1            -1
 0             3             6            -3
 0            -1             1            -2

shoukyohou no jyoukyou ( 2 )
x( 1 )        x( 2 )        x( 3 )        
 1             0             5            -3
 0             1             2            -1
 0             0             3            -3

shoukyohou no jyoukyou ( 3 )
x( 1 )        x( 2 )        x( 3 )        
 1             0             0             2
 0             1             0             1
 0             0             1            -1

ichii na kai
     x( 1 )=  2
     x( 2 )=  1
     x( 3 )= -1
```

Freebasicはセミコロンでうまく整形されなかったりするが、とりあえずは動いた。