日本語プログラミング言語Mindの小技「処理単語」について説明したいと思います。
小技というよりスタック志向言語Mindの根幹をなす事柄です。関数定義ベースのプログラミング言語ですと、複数の値を返すということは通常、引数を参照型にして呼び出し側から読み取れるようにすることが多いですが、Mindの場合はその点自由度が高いです。
日本語プログラミング言語Mindのユーザー、または日本語プログラミング言語に興味のある方
この小技に関連するMind言語仕様の記述はMind8プログラミングマニュアルに記載があります。
2 プログラム表記の基本
└処理単語
プログラムを自動車に例えれば、単語は自動車の部品に相当する。最初にボルトやナットのようなものを組み合わせて小さな部品を作り、それをさらに組み合わせて大きな部品を作る…というように組み合わせるのが普通である。Mindのプログラムもこれとまったく同じである。
単語の定義は次のような記述による。[1]
・・・・・とは ←注:「とは」は「は」でもよい
・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・である。
[2]上記のように非常に簡単なものである。この例では[1]の「……とは」の末尾でいったん改行しており、また、[2]のブロックを字下げ(少し右寄せ)しているが、見易くするためにこうしただけで、強制されるものではない(ただ、慣習としてこの形式で書くことが多い)。
[1]は新しく定義する単語名を記述する。どのような名称を付けてもよいが、すでに定義されている名前や、文字列定数や数値定数となるようなものは命名できない。送り仮名の「とは」あるいは「は」は必須である。
[2]はこの単語の定義内容となるものである。定義の最後は必ず「。」で終わる必要がある。上図では「。」のところを、「である。」としているが、それらしくするための飾りであり、意味はない。気分としてはこのようなものであると理解されたい。
アセンブラやC言語などの経験者は、短い単語や略号を命名しがちであるが、Mindでは逆に長くてもいいから、その動作を理解しやすい単語を命名するのがよいこととされる。
~略~
本機能(本記事)は、下記のバージョンに対応しています。Mindの根幹なのでMind8のLinux版も対応していますが、本記事では特に検証を行っておりませんという意味でチェックマークを入れておりません。
■Mind7 ■Mind8 ■Mind9
■Windows版 □Linux版
Mindの「処理単語」の定義では、一般的な関数形式の定義をメインとするプログラミング言語とは違って、明示的な引数や戻り値の定義は基本的にはなく、「処理単語」の実行結果によって複数の変数をスタックに追加できるという意味では戻り値の数に制限がないことが特徴です。
また、関数形式ではないので、戻り値はいったんスタックに置かれますので、直接変数の代入をせず、別のスタック操作しない処理単語を挟んでから、スタック値の値を処理する処理単語を実行させることもできます。
本記事の主題ではありませんが、明示的な引数や戻り値の属性を定義してコンパイラチェックさせることも可能です。下記の記事では「関数」定義の際の属性定義に触れていますが、通常の「処理単語」定義の際の属性定義については別の記事で触れたいと考えております。
具体的なサンプルコードを使って説明します。
words.src
スタックから値を受け取らずスタックに値を返さない処理単語とは (・ → ・)
「スタックから値を受け取らずスタックに値を返さない処理単語です。」を 一行表示すること。
スタックから1つ値を受け取りスタックに値を返さない処理単語とは (変数 → ・)
「スタックから1つ値を受け取りスタックに値を返さない処理単語です。」を 一行表示し、
※スタックトップから受け取った値に
2を 加えて 数値表示し (数値表示で使ったのでスタックには残らない) 改行すること。
スタックから2つ値を受け取りスタックに値を返さない処理単語とは (変数、変数 → ・)
「スタックから2つ値を受け取りスタックに値を返さない処理単語です。」を 一行表示し、
※スタックトップから受け取った値に
3を 加えて 数値表示し (数値表示で使ったのでスタックには残らない) 改行し
※次のスタックから受け取った値に
4を 加えて 数値表示し (数値表示で使ったのでスタックには残らない) 改行すること。
スタックから1つ値を受け取りスタックに1つ値を返す処理単語とは (変数 → 変数)
「スタックから1つ値を受け取りスタックに1つ値を返す処理単語です。」を 一行表示し、
※スタックトップから受け取った値に
5を 加えること (結果をスタックに残す)。
スタックから2つ値を受け取りスタックに1つ値を返す処理単語とは (変数、変数 → 変数)
「スタックから2つ値を受け取りスタックに値を返さない処理単語です」を 一行表示し、
※スタックトップから受け取った値に
6を 加えて 数値表示し (数値表示で使ったのでスタックには残らない) 改行し
※次のスタックから受け取った値に
7を 加えること (結果をスタックに残す)。
スタックから1つ値を受け取りスタックに2つ値を返す処理単語とは (変数 → 変数、変数)
「スタックから1つ値を受け取りスタックに2つ値を返す処理単語です。」を 一行表示し、
※スタックトップから受け取った値に
8を 加え (結果をスタックに残す)
9を 返すこと (「返す」は無処理単語で「9を」を記述した時点で9をスタックに残す)。
スタックから2つ値を受け取りスタックに2つ値を返す処理単語とは (変数、変数 → 変数、変数)
一時置きは 変数
「スタックから2つ値を受け取りスタックに2つ値を返す処理単語です。」を 一行表示し、
※スタックトップから受け取った値を
一時置きに 入れ (スタック先頭の値を一時置きしておく)
※次のスタックから受け取った値に
10を 加え (結果をスタックに残す)
一時置きに 11を 加えること (結果をスタックに残す。こちらがスタックトップとなる)。
スタックから2つ値を受け取りスタックに4つ値を返す処理単語とは (変数、変数 → 変数、変数、変数、変数)
一時置きは 変数
「スタックから2つ値を受け取りスタックに4つ値を返す処理単語です。」を 一行表示し、
※スタックトップから受け取った値を
一時置きに 入れ (スタック先頭の値を一時置きしておく)
※次のスタックから受け取った値に
12を 加え (結果をスタックに残す)
一時置きに 13を 加え (結果をスタックに残す)
一時置きに 14を 加え (結果をスタックに残す)
一時置きに 15を 加えること (結果をスタックに残す。こちらがスタックトップとなる)。
メインとは (・ → ・)
スタックから値を受け取らずスタックに値を返さない処理単語をやって、
1で スタックから1つ値を受け取りスタックに値を返さない処理単語をやって、
2と
3で スタックから2つ値を受け取りスタックに値を返さない処理単語をやって、
4で スタックから1つ値を受け取りスタックに1つ値を返す処理単語をやってから、数値表示し 改行し、
5と
6で スタックから2つ値を受け取りスタックに1つ値を返す処理単語をやってから、数値表示し 改行し、
7で スタックから1つ値を受け取りスタックに2つ値を返す処理単語をやってから、
数値表示し 改行し、数値表示し 改行し、
8と
9で スタックから2つ値を受け取りスタックに2つ値を返す処理単語をやってから、
数値表示し 改行し、数値表示し 改行し、
10と
11で スタックから2つ値を受け取りスタックに4つ値を返す処理単語をやってから、
数値表示し 改行し、数値表示し 改行し、数値表示し 改行し、数値表示し 改行すること。
「スタックから値を受け取らずスタックに値を返さない処理単語」の定義部の「 (・ → ・)」はMindのコメント機能で、スタックからなにも受け取らず、スタックになにも返さないことを注釈しています。
それぞれの処理単語定義部の
「(変数 → ・)」は
スタックから変数1つを受け取り、スタックに何も返さない
「(変数 → 変数)」は
スタックから変数1つを受け取り、スタックに変数1つを返す
「(変数、変数 → 変数)」は
スタックから変数2つを受け取り、スタックに変数1つを返す
「(変数、変数 → 変数、変数)」は
スタックから変数2つを受け取り、スタックに変数2つを返すという意味です。
これはあくまでコメントですので、定数が必ず置かれている想定であれば、「(値 → ・)」という表記も可ですし、変数や値の意味を表記しても可です。
「スタックから2つ値を受け取りスタックに2つ値を返す処理単語」の例では、最初にスタックトップの変数または定数(以下、変数と表記)を「一時置き」変数に代入してから、次のスタックの変数に加算処理を行っていますが、このあたりの書き味は要件によって変えることが可能です。
まず、スタックトップの変数を加算してから、「一時置き」変数に代入して、次のスタックの変数に加算してから、「一時置き」変数を「返す」ようにすれば、スタックに置かれた変数の上下関係が逆転します。
「返す」はMindの無処理単語で、変数名または定数を記述した時点で値がスタックに置かれますので、これは言葉の自然らしさを補助しています。
ではコンパイルしてみます。下位ライブラリはfileを指定します。
Mind9
下図はMind9βです。
C:\developments\vscode\mind9>mind words file
日本語プログラミング言語 Mind Version 8.11 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. C:\mind9-beta\mind9-beta\bin\mindex.exe --> words.exe
Mind8
C:\developments\vscode\mind9>mind words file
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> words.exe
Mind7
C:\developments\vscode\mind9>mind words file
日本語プログラミング言語 Mind Version 7.5 for Windows
Copyright(C) 1985-2004 Scripts Lab. Inc.
Single user license. Serial No:*********
コンパイル中 - 終了
Coping.. C:\mind7\bin\mindexec.exe -> words.exe
つづいて実行してみます。Mind9βの結果です。記述は割愛していますがMind7/8も同じです。
C:\developments\vscode\mind9>words
スタックから値を受け取らずスタックに値を返さない処理単語です。
スタックから1つ値を受け取りスタックに値を返さない処理単語です。
3
スタックから2つ値を受け取りスタックに値を返さない処理単語です。
6
6
スタックから1つ値を受け取りスタックに1つ値を返す処理単語です。
9
スタックから2つ値を受け取りスタックに値を返さない処理単語です
12
12
スタックから1つ値を受け取りスタックに2つ値を返す処理単語です。
9
15
スタックから2つ値を受け取りスタックに2つ値を返す処理単語です。
20
18
スタックから2つ値を受け取りスタックに4つ値を返す処理単語です。
26
25
24
22
C:\developments\vscode\mind9>
「処理単語」はMindの基本的な言語構成要素であるため、多数の記事がQiita上に存在しています。みんなで探してみましょう。
いかがでしたでしょうか?なにかの参考になれば幸いです。2025年は日本語プログラミング言語Mind生誕40周年です。
本記事シリーズのご紹介
本記事シリーズ「日本語プログラミング言語Mindの小技」は「日本語プログラミング言語Mind生誕40周年プロジェクト」の一環です。
興味を持たれた方は日本語プログラミング言語Mind公式サイトにアクセスすると、Mindコンパイラをダウンロードできますよ。
Mindプログラミングマニュアル(基本文法)ページから気になるお題の構文を選んで、この記事のようにサンプル実装実行してQiitaにアウトプットしてみましょう!
筆者はMind7/8/9βで検証しておりますが、もちろんMind8だけでもじゅうぶんです。またお題が既存記事とかぶるのはまったく問題ありません。同じお題でみなさまの多様斬新なサンプルをお待ちしております
面白い!、楽しい、カンタン、難しいのも書ける!みんなでやってみよう
Views: 0