日本語プログラミング言語Mindの小技 「処理単語」～複数の戻り値をスタックに置ける～

# はじめに
日本語プログラミング言語Mindの小技「処理単語」について説明したいと思います。

小技というよりスタック志向言語Mindの根幹をなす事柄です。関数定義ベースのプログラミング言語ですと、複数の値を返すということは通常、引数を参照型にして呼び出し側から読み取れるようにすることが多いですが、Mindの場合はその点自由度が高いです。

# 対象読者
日本語プログラミング言語Mindのユーザー、または日本語プログラミング言語に興味のある方

# この小技に関連するMind言語マニュアル

この小技に関連するMind言語仕様の記述はMind8プログラミングマニュアルに記載があります。
２ プログラム表記の基本
└処理単語

>　プログラムを自動車に例えれば、単語は自動車の部品に相当する。最初にボルトやナットのようなものを組み合わせて小さな部品を作り、それをさらに組み合わせて大きな部品を作る...というように組み合わせるのが普通である。Mindのプログラムもこれとまったく同じである。
　単語の定義は次のような記述による。
 >
>　　[１]
・・・・・とは　　　　　　　←注：「とは」は「は」でもよい
　　　　・・・・・・・・・・・・・・・・・
　　　　・・・・・・・・・・・・・・・・・
　　　　・・・・・・・・・・・・・・・・・である。
　　　　　　　　　　　　[２]
>
> 上記のように非常に簡単なものである。この例では[１]の「......とは」の末尾でいったん改行しており、また、[２]のブロックを字下げ（少し右寄せ）しているが、見易くするためにこうしただけで、強制されるものではない（ただ、慣習としてこの形式で書くことが多い）。
　[１]は新しく定義する単語名を記述する。どのような名称を付けてもよいが、すでに定義されている名前や、文字列定数や数値定数となるようなものは命名できない。送り仮名の「とは」あるいは「は」は必須である。
　[２]はこの単語の定義内容となるものである。定義の最後は必ず「。」で終わる必要がある。上図では「。」のところを、「である。」としているが、それらしくするための飾りであり、意味はない。気分としてはこのようなものであると理解されたい。
　アセンブラやC言語などの経験者は、短い単語や略号を命名しがちであるが、Mindでは逆に長くてもいいから、その動作を理解しやすい単語を命名するのがよいこととされる。
 ～略～



本機能（本記事）は、下記のバージョンに対応しています。Mindの根幹なのでMind８のLinux版も対応していますが、本記事では特に検証を行っておりませんという意味でチェックマークを入れておりません。

# 対応バージョン
■Mind７　■Mind８　■Mind９
■Windows版　□Linux版

# 小技の解説
Mindの「処理単語」の定義では、一般的な関数形式の定義をメインとするプログラミング言語とは違って、明示的な引数や戻り値の定義は基本的にはなく、「処理単語」の実行結果によって複数の変数をスタックに追加できるという意味では戻り値の数に制限がないことが特徴です。

また、関数形式ではないので、戻り値はいったんスタックに置かれますので、直接変数の代入をせず、別のスタック操作しない処理単語を挟んでから、スタック値の値を処理する処理単語を実行させることもできます。

本記事の主題ではありませんが、明示的な引数や戻り値の属性を定義してコンパイラチェックさせることも可能です。下記の記事では「関数」定義の際の属性定義に触れていますが、通常の「処理単語」定義の際の属性定義については別の記事で触れたいと考えております。

https://qiita.com/mylifewithviolin/items/86bfe9e74b10bde81088

具体的なサンプルコードを使って説明します。

# Mindプログラムソース

```mind:words.src
スタックから値を受け取らずスタックに値を返さない処理単語とは　（・　→　・）
    「スタックから値を受け取らずスタックに値を返さない処理単語です。」を　一行表示すること。

スタックから１つ値を受け取りスタックに値を返さない処理単語とは　（変数　→　・）
    「スタックから１つ値を受け取りスタックに値を返さない処理単語です。」を　一行表示し、
    ※スタックトップから受け取った値に　
    ２を　加えて　数値表示し　（数値表示で使ったのでスタックには残らない）　改行すること。

スタックから２つ値を受け取りスタックに値を返さない処理単語とは　（変数、変数　→　・）
    「スタックから２つ値を受け取りスタックに値を返さない処理単語です。」を　一行表示し、
    ※スタックトップから受け取った値に　
    ３を　加えて　数値表示し　（数値表示で使ったのでスタックには残らない）　改行し　
    ※次のスタックから受け取った値に　
    ４を　加えて　数値表示し　（数値表示で使ったのでスタックには残らない）　改行すること。

スタックから１つ値を受け取りスタックに１つ値を返す処理単語とは　（変数　→　変数）
    「スタックから１つ値を受け取りスタックに１つ値を返す処理単語です。」を　一行表示し、
    ※スタックトップから受け取った値に
    ５を　加えること　（結果をスタックに残す）。　

スタックから２つ値を受け取りスタックに１つ値を返す処理単語とは　（変数、変数　→　変数）
    「スタックから２つ値を受け取りスタックに１つ値を返す処理単語です」を　一行表示し、
    ※スタックトップから受け取った値に
    ６を　加えて　数値表示し　（数値表示で使ったのでスタックには残らない）　改行し　
    ※次のスタックから受け取った値に
    ７を　加えること　（結果をスタックに残す）。

スタックから１つ値を受け取りスタックに２つ値を返す処理単語とは　（変数　→　変数、変数）
    「スタックから１つ値を受け取りスタックに２つ値を返す処理単語です。」を　一行表示し、
    ※スタックトップから受け取った値に
    ８を　加え　（結果をスタックに残す）
    ９を　返すこと　（「返す」は無処理単語で「９を」を記述した時点で９をスタックに残す）。

スタックから２つ値を受け取りスタックに２つ値を返す処理単語とは　（変数、変数　→　変数、変数）
            一時置きは　変数
    「スタックから２つ値を受け取りスタックに２つ値を返す処理単語です。」を　一行表示し、
    ※スタックトップから受け取った値を
    一時置きに　入れ　（スタック先頭の値を一時置きしておく）
    ※次のスタックから受け取った値に
    １０を　加え　（結果をスタックに残す）
    一時置きに　１１を　加えること　（結果をスタックに残す。こちらがスタックトップとなる）。

スタックから２つ値を受け取りスタックに４つ値を返す処理単語とは　（変数、変数　→　変数、変数、変数、変数）
            一時置きは　変数
    「スタックから２つ値を受け取りスタックに４つ値を返す処理単語です。」を　一行表示し、
    ※スタックトップから受け取った値を
    一時置きに　入れ　（スタック先頭の値を一時置きしておく）
    ※次のスタックから受け取った値に
    １２を　加え　（結果をスタックに残す）
    一時置きに　１３を　加え　（結果をスタックに残す）
    一時置きに　１４を　加え　（結果をスタックに残す）
    一時置きに　１５を　加えること　（結果をスタックに残す。こちらがスタックトップとなる）。


メインとは　（・　→　・）
    スタックから値を受け取らずスタックに値を返さない処理単語をやって、
    １で　スタックから１つ値を受け取りスタックに値を返さない処理単語をやって、
    ２と　
    ３で　スタックから２つ値を受け取りスタックに値を返さない処理単語をやって、
    ４で　スタックから１つ値を受け取りスタックに１つ値を返す処理単語をやってから、数値表示し　改行し、
    ５と　
    ６で　スタックから２つ値を受け取りスタックに１つ値を返す処理単語をやってから、数値表示し　改行し、
    ７で　スタックから１つ値を受け取りスタックに２つ値を返す処理単語をやってから、
                                                            数値表示し　改行し、数値表示し　改行し、
    ８と
    ９で　スタックから２つ値を受け取りスタックに２つ値を返す処理単語をやってから、
                                                            数値表示し　改行し、数値表示し　改行し、
    １０と
    １１で　スタックから２つ値を受け取りスタックに４つ値を返す処理単語をやってから、
                        数値表示し　改行し、数値表示し　改行し、数値表示し　改行し、数値表示し　改行すること。
```

「スタックから値を受け取らずスタックに値を返さない処理単語」の定義部の「　（・　→　・）」はMindのコメント機能で、スタックからなにも受け取らず、スタックになにも返さないことを注釈しています。

それぞれの処理単語定義部の
「（変数　→　・）」は
スタックから変数１つを受け取り、スタックに何も返さない
「（変数　→　変数）」は
スタックから変数１つを受け取り、スタックに変数１つを返す
「（変数、変数　→　変数）」は
スタックから変数２つを受け取り、スタックに変数１つを返す
「（変数、変数　→　変数、変数）」は
スタックから変数２つを受け取り、スタックに変数２つを返すという意味です。

これはあくまでコメントですので、定数が必ず置かれている想定であれば、「（値　→　・）」という表記も可ですし、変数や値の意味を表記しても可です。

「スタックから２つ値を受け取りスタックに２つ値を返す処理単語」の例では、最初にスタックトップの変数または定数（以下、変数と表記）を「一時置き」変数に代入してから、次のスタックの変数に加算処理を行っていますが、このあたりの書き味は要件によって変えることが可能です。

まず、スタックトップの変数を加算してから、「一時置き」変数に代入して、次のスタックの変数に加算してから、「一時置き」変数を「返す」ようにすれば、スタックに置かれた変数の上下関係が逆転します。

「返す」はMindの無処理単語で、変数名または定数を記述した時点で値がスタックに置かれますので、これは言葉の自然らしさを補助しています。

# コンパイル結果
ではコンパイルしてみます。下位ライブラリはfileを指定します。

## Mind９
下図はMind９βです。
```cmd:
C:\developments\vscode\mind9>mind words file   

日本語プログラミング言語 Ｍｉｎｄ Version 8.11 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. C:\mind9-beta\mind9-beta\bin\mindex.exe --> words.exe
```
## Mind8
```cmd:
C:\developments\vscode\mind9>mind words file

日本語プログラミング言語 Ｍｉｎｄ Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> words.exe
```
## Mind7
```cmd:
C:\developments\vscode\mind9>mind words file
日本語プログラミング言語 Ｍｉｎｄ 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
```
# 実行結果
つづいて実行してみます。Mind９βの結果です。記述は割愛していますがMind7/8も同じです。

```cmd:
C:\developments\vscode\mind9>words
スタックから値を受け取らずスタックに値を返さない処理単語です。
スタックから１つ値を受け取りスタックに値を返さない処理単語です。
3
スタックから２つ値を受け取りスタックに値を返さない処理単語です。
6
6
スタックから１つ値を受け取りスタックに１つ値を返す処理単語です。
9
スタックから２つ値を受け取りスタックに１つ値を返す処理単語です
12
12
スタックから１つ値を受け取りスタックに２つ値を返す処理単語です。
9
15
スタックから２つ値を受け取りスタックに２つ値を返す処理単語です。
20
18
スタックから２つ値を受け取りスタックに４つ値を返す処理単語です。
26
25
24
22

C:\developments\vscode\mind9>
```

# 参考情報
「処理単語」はMindの基本的な言語構成要素であるため、多数の記事がQiita上に存在しています。みんなで探してみましょう。

# おわりに
いかがでしたでしょうか？なにかの参考になれば幸いです。2025年は日本語プログラミング言語Mind生誕４０周年です。

## 本記事シリーズのご紹介
本記事シリーズ「日本語プログラミング言語Mindの小技」は「日本語プログラミング言語Mind生誕４０周年プロジェクト」の一環です。

興味を持たれた方は[日本語プログラミング言語Mind公式サイト](https://www.scripts-lab.co.jp/mind8download/download.html)にアクセスすると、Mindコンパイラをダウンロードできますよ。

[Mindプログラミングマニュアル（基本文法）](https://www.scripts-lab.co.jp/mind/ver8/doc/index.html)ページから気になるお題の構文を選んで、この記事のようにサンプル実装実行してQiitaにアウトプットしてみましょう！

筆者はMind7/8/9βで検証しておりますが、もちろんMind8だけでもじゅうぶんです。またお題が既存記事とかぶるのはまったく問題ありません。同じお題でみなさまの多様斬新なサンプルをお待ちしております:grinning:

面白い！、楽しい、カンタン、難しいのも書ける！みんなでやってみよう:relaxed: