AWS Lambda Custom Runtimes で Visual じゃない BASIC を動かした #reinvent

世の中 BASIC といえば既に Visual なイメージがありますが、40〜50代のエンジニアとしたらやっぱりこっちだと思うのです。F だったり N88 だったり X だったり MSX だったりファミリーだったりするタイプの BASIC の系譜、Vintage BASIC を動かします。
2018.12.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

※こちらは、 AWS Lambda Custom Runtimes芸人 Advent Calendar 2018 の 13 日目の記事になります

はじめに

COBOL が動作することで一世を風靡した AWS Lambda Custom Runtimes ですが、ここではその COBOL や Fortran と並んで老舗の言語として名高い BASIC 言語を取り上げてみました。VB.NET はこちらでやられているので、昔ながらの趣のある Vintage BASIC を使います。

RUN

こんな BASIC プログラムを用意して実行させてみました。検算できるように簡単に、 1 〜 10,000 までの整数の合計を出力するプログラムです。

sample.bas

5 REM BASIC SAMPLE
10 S=0
20 FOR I=1 TO 10000
30 S=S+I
40 NEXT I
50 PRINT S

ちゃんと動いてますね!

解説

AWS Lambda 側は今回、難しいことは何もやっていません。Vintage BASIC インタプリタのバイナリとサンプルの BASIC プログラムを、Custom Runtimes 定番の bootstrapfunction.sh といっしょに ZIP で固めてアップロードしただけになります。

$ curl -LO http://www.vintage-basic.net/downloads/vintage-basic-1.0.3-linux-x86_64.tar.gz
$ tar xvzpf vintage-basic-1.0.3-linux-x86_64.tar.gz
$ cp -piv vintage-basic-1.0.3-linux-x86_64/bin/vintbas .
$ chmod +x bootstrap vintbas
$ zip lambda-custom-runtime-basic.zip bootstrap function.sh vintbas sample.bas

Vintage BASIC はインタプリタが ELF バイナリひとつで、最初から static link された状態で公開されていたので助かりました。

$ file vintbas
vintbas: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), 
statically linked, 
for GNU/Linux 2.6.32, BuildID[sha1]=8ecf85d2f83714d411b587ccb691e97ce4dc51be, 
stripped

bootstrap はほぼチュートリアルのまま、コメントの削除と curl-sS オプションを付けたくらいしか変えていません。

bootstrap

#!/bin/sh
set -euo pipefail
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
while true; do
  HEADERS="$(mktemp)"
  EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
  REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)

  RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")

  curl -sS -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done

function.sh は Vintage BASIC インタプリタの起動しかしていません。BASIC プログラムのファイル名は、ハードコードするのもあれだったので環境変数 File で渡すようにしました。入力データは完全に捨てていますが、動的に BASIC プログラムを書き換えるくらいしか渡す方法がなかったのでこうなりました。

function.sh

function handler () {
  $LAMBDA_TASK_ROOT/vintbas $LAMBDA_TASK_ROOT/$File
}

まとめ

のりと勢いで「 BASIC 動かそう!」と思ったのですが、正直 Lambda で動かせる実装を探すのが一番大変でした。ほんとうにただ動かしただけで、もうちょっと何か出来ればよかったのですが、何かの参考になれば幸いです。

ちなみに今回、個人的に一番驚いたのは、vim が BASIC プログラム( .bas )をシンタックスハイライトしてくれた ことでした。

参考