0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【Whitespace】空白文字だけで「大石泉すき」を出力する

はじめに

Whitespaceという言語を使って「I love Izumi(大石泉すき)」を出力しました。
この言語ではASCII文字しか扱えないため、英語での出力になります。

ちなみに大石泉とはゲーム「アイドルマスターシンデレラガールズ」に登場するプログラミングが趣味のアイドルです。

Whitespaceについて

Whitespaceとは、「スペース」「タブ」「改行」の3つの空白文字のみを使って記述を行うプログラミング言語です。
「スタック操作」「ヒープ操作」「演算」「入出力」「フロー制御」の5つの命令をこなすことができます。
IMPで上記の命令を指定し、続けてコマンドを記述することでプログラムを動かしていきます。

詳しくは下記をご参照ください。
今回の記事を書くにあたり、参考にさせていただきました。

コード

それでは実際にコードをみてみましょう。
実際に動作を確認したい場合はリンクから飛んでください。
https://ideone.com/Cw7y3f

izumi.ws





























何も見えませんね。空白文字なので当然ですが・・・

スペースをS、タブをT、改行をLに置き換えて表示してみましょう。
また、今回は分かりやすいように一命令一行の形式にした上で、処理内容ごとにブロック分けしました。
実際にはLの位置で改行が入ります。

izumi.ws
SSSL //スタックに0をPUSH(ループ終了フラグ)

SSSTTSTSSTL //i(105)をPUSH
SSSTTSTTSTL //m(109)をPUSH
SSSTTTSTSTL //u(117)をPUSH
SSSTTTTSTSL //z(122)をPUSH
SSSTSSTSSTL //I(73)をPUSH
SSSTSSSSSL //半角スペースをPUSH
SSSTTSSTSTL //e(101)をPUSH
SSSTTTSTTSL //v(118)をPUSH
SSSTTSTTTTL //o(111)をPUSH
SSSTTSTTSSL //l(108)をPUSH
SSSTSSSSSL //半角スペースをPUSH
SSSTSSTSSTL //I(73)をPUSH

LSSSL //ラベル0を設定(ループ始点)
SLS //スタックの一番上の値を複製
LTSTL //スタックから取り出し、値が0ならラベル1へジャンプ
TLSS //スタックから値を取り出し、値とASCIIコードに対応する文字を出力
LSLS //ラベル0へ戻る(ループ終点)

LSSTL //ラベル1を設定

SLL //スタックの一番上を削除

LLL //プログラムを終了

出力する文字をスタックに積み込んでいきます。この時、積み込む順番と出力される順番は逆になります。
その後、ループ処理を使って一つずつ出力していきます。

出力開始地点にラベル0を設定し、出力が終わるたびに、このラベルに戻ることでループを再現しています。
スタックから取り出した値が0の場合、ラベル1へジャンプしてループから抜けます。
一番最初に、スタックに0を積んでいるのはこの処理を実行させるためです。

個別解説

今回使用した処理について、個別に解説していきます。
ここで紹介するのは一部であり、これらの他にもコマンドは数多く存在します。

スタック操作

IMP コマンド 引数 内容
S S (引数) L 数値 スタックの一番上に値を積む
S L S なし スタック一番上にある値を複製
S L L なし スタック一番上にある値を削除

数値の表現ルール
1文字目が符号、2文字目以降は2進数(S=0、T=1)で数値を表記し、最後に終わりを示すLを記述します。
ラベルの設定時など符号を記述しない場合もありますが、SとTを使った2進数表記はどの命令でも共通です。

符号(S=正,T=負)
S T T S T S S T L
+ 1 1 0 1 0 0 1
S S S L //スタックに0をPUSH(ループ終了フラグ)
S S STTSTSST L //i(105)をPUSH
S LS //スタックの一番上の値を複製
S LL //スタックの一番上を削除

0を積む場合は、符号まで指定して数値は記述しないようです。
数値を0で埋めたらエラーになりました。このあたりの仕様はよく分かりません。

フロー制御

IMP コマンド 引数 内容
L S S (引数) L ラベル 現在の位置にラベルを設定。ラベルは2進数で記述。
L S L ラベル 指定したラベルにジャンプ。
L T S ラベル スタックから値を取り出し、その値が0であれば指定したラベルへジャンプ。
L L L なし プログラムをその場で終了。
L SS S L //ラベル0を設定(ループ始点)
L SS T L //ラベル1を設定
L SL S //ラベル0へ戻る(ループ終点)
L TS T L //スタックから取り出し、値が0ならラベル1へジャンプ
L LL //プログラムを終了

入出力

IMP コマンド 引数 内容
T L S S なし スタックから値を取り出し、値とASCIIコードに対応する文字を出力
TL SS //スタックから値を取り出し、値とASCIIコードに対応する文字を出力

取り出した値が「73」であれば「I」のようにASCIIコードに変換して出力します。
コード表はこちらを参照してください。

終わりに

空白文字のインパクトが強いものの、構文自体は単純で理解がしやすい言語でした。
Whitespace 超入門を始めとして、丁寧な解説サイトがたくさんありますので、興味のある方はチャレンジしてみてください。

次回はPietに挑戦してみようと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?