日本語プログラミング言語Mindの小技 「処理単語の属性指定」～スタック上の変数の数や型チェック～

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

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

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

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

>　今まで例に書いた処理単語の定義では、受け取るデータの数やその型、返すデータの型、などは明示しなかった。
　「Mindの文法検査は限りなくゆるい」のが流儀なので通常はそれで構わないのだが、本機能を使うことで明に型を指示することもできる。
 >
>構文＝
＜処理単語名＞とは　**処理単語　＜属性＞　＜属性＞　・・　＜属性＞**
　　　　・・・・・し　　　　↑太字部は途中で改行してはならない
　　　　・・・・・すること。
>
>　　　　　　　　　　─── 属性に記述できる語 ───
　　　　　　　　　　整数入力、 小数入力　|  整数出力、 小数出力
　　　　　　　　　　逆転抑制
　　　　　　　　　　  (その他細かなものについては上級編に)
>
>
> 　以下は例である。
>
>（例１）
**差を表示**とは　（数値１、数値２　→　・）
　　　　引いたものを、「差は 」を　表示してから　数値表示し　「 です。」を　一行表示すること。
（例２）
**差を表示**とは　（数値１、数値２　→　・）　処理単語　整数入力　整数入力
　　　　引いたものを、「差は 」を　表示してから　数値表示し　「 です。」を　一行表示すること。
>
>上の２つは動作としてはまったく同じだが、この処理単語を引用する際、後者は簡単なデータ型の検査が行われるようになる。
 
 ～略～



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

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

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

本記事では、明示的な引数や戻り値の属性とその数を定義してコンパイラチェックさせることも可能な点を取り扱います。

下記の記事では「関数」定義の際の属性定義に触れていますが、今回は通常の「処理単語」定義の際の属性定義について説明しています。

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

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

# Mindプログラムソース

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

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

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

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

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


メインとは　（・　→　・）
    １で　スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語をやってから、
    　　　　数値表示し　改行し、
    ２と　
    ３で　スタックから２つ整数を受け取りスタックに１つ整数を返す処理単語をやってから、
    　　　　数値表示し　改行し、
    ４と
    ５で　スタックから２つ整数を受け取りスタックに２つ整数を返す処理単語をやってから、
           数値表示し　改行し、数値表示し　改行し、
    ６と
    ７で　スタックから２つ整数を受け取りスタックに４つ整数を返す処理単語をやってから、
           数値表示し　改行し、数値表示し　改行し、数値表示し　改行し、数値表示し　改行し
    ８．０と
    ９．０で  スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語をやってから
           ０桁と　１桁で　文字列変換・小数形式し　表示し　改行し、
           ０桁と　１桁で　文字列変換・小数形式し　表示し  改行すること。
```

「スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語」の定義部の「（変数　→　変数）」ははMindのコメント機能で、スタックから変数１つを受け取り、スタックに変数１つを返すことを注釈しています。

それぞれの処理単語定義部の改行したところの
「（変数、変数　→　変数）」は
スタックから変数２つを受け取り、スタックに変数１つを返す
「（変数、変数　→　変数、変数）」は
スタックから変数２つを受け取り、スタックに変数２つを返す
「（小数変数、小数変数　→　小数変数、小数変数）」は
スタックから変数２つを受け取り、スタックに変数２つを返すという意味です。

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

そして、これらのコメントの右側の「処理単語」と空白挟んだ「整数入力　整数出力」が属性指定です。公式マニュアルに記載のあるとおり、この範囲の改行は不可で１行で書く必要があります。公式マニュアルの例では、処理単語名の「とは」から全部１行で書かれていますが、このサンプルソースのように「処理単語」の範囲が改行されていなければOKです。


それぞれのスタックコメントの右側の
「処理単語　整数入力　整数出力」は
スタックから（整数型の）変数１つを受け取り、スタックに（整数型の）変数１つを返すことをコンパイラチェックする
「処理単語　整数入力　整数入力　整数出力」は
スタックから（整数型の）変数２つを受け取り、スタックに（整数型の）変数１つを返すことをコンパイラチェックすることを意味します。

「（変数、変数　→　変数、変数）」の右側も「処理単語　整数入力　整数入力　整数出力」となっているのは
スタックから（整数型の）変数２つを受け取ることはコンパイラチェックしますが、スタックに変数２つを返すうち最初の１つが（整数型の）変数であることをチェックしますということを意味します。
ここで「処理単語　整数入力　整数入力　整数出力　整数出力」と書くことはできません。スタックへ戻す値の型チェックは１つとなりますが、１つしか戻せないということではありません。

「（小数変数、小数変数　→　小数変数、小数変数）」の右側の「処理単語　小数入力　小数入力　小数出力」は
スタックから（倍精度浮動小数点型の）変数２つを受け取ることをコンパイラチェックし、スタックに（倍精度浮動小数点型の）変数２つを返しますが、コンパイラチェックするのは最初の１つという意味です。

※戻り側の型チェックは処理単語形式の場合は作動しないようでした。作動条件がなにか必要なのかもしれませんが、本記事では戻り値側チェックの検証は対象外となります。

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

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

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

日本語プログラミング言語 Ｍｉｎｄ Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> wordswithprop.exe
```

# 実行結果
とりあえず正常な状態を実行してみます。Mind９βの結果です。記述は割愛していますがMind8も同じです。

```cmd:
C:\developments\vscode\mind9>wordswithprop
スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語です。
6
スタックから２つ整数を受け取りスタックに１つ整数を返す処理単語です
9（単語内部で出力）
9
スタックから２つ整数を受け取りスタックに２つ整数を返す処理単語です。
16
14
スタックから２つ整数を受け取りスタックに４つ整数を返す処理単語です。
22
21
20
18
スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語です。
22.0
20.0
C:\developments\vscode\mind9>
```
# 型チェックを検証
ではここからはコンパイラの型チェックを検証してみます。

整数を想定している単語に小数を与えてみます。

```mind:wordswithprop.src
メインとは　（・　→　・）
    １．０で　スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語をやってから、数値表示し　改行し、
```
## Mind8
```cmd:
c:\developments\vscode\mind9>mind wordswithprop file

日本語プログラミング言語 Ｍｉｎｄ Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
1 個のエラーが有ります。

c:\developments\vscode\mind9>
```
コンパイルエラーとなりました。エラー内容はコンパイラが出力するwordswithprop.infで確認できます。

```mind:wordswithprop.inf
wordswithprop.src 49 行目でエラー。行内容は、
    １．０で　スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語をやってから、数値表示し　改行し、
      要因１：処理単語"スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語"に与えるデータの型が誤りです。

1 個のエラーが有ります。
```

続いて、小数を想定している処理単語に整数を与えてみます。

```mind:wordswithprop.src
メインとは　（・　→　・）
    １で　スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語をやってから、数値表示し　改行し、
    ～略～
    ８と
    ９で  スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語をやってから
                        ０桁と　１桁で　文字列変換・小数形式し　表示し　改行し、
                        ０桁と　１桁で　文字列変換・小数形式し　表示し  改行すること。    
```

```mind:wordswithprop.inf
wordswithprop.src 59 行目でエラー。行内容は、
    ９で  スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語をやってから
      要因１：処理単語"スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語"に与えるデータの型が誤りです。

1 個のエラーが有ります。
```
エラー箇所はあくまで処理単語側なので上記のような結果となりました。念のため、最初のスタック値の方（８．０の方）だけを整数にしてみます。

```mind:wordswithprop.src
メインとは　（・　→　・）
    １で　スタックから１つ整数を受け取りスタックに１つ整数を返す処理単語をやってから、数値表示し　改行し、
    ～略～
    ８と
    ９．０で  スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語をやってから
                        ０桁と　１桁で　文字列変換・小数形式し　表示し　改行し、
                        ０桁と　１桁で　文字列変換・小数形式し　表示し  改行すること。    
```
処理単語側の型エラーを検知しました。

```mind:wordswithprop.inf
wordswithprop.src 59 行目でエラー。行内容は、
    ９．０で  スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語をやってから
      要因１：処理単語"スタックから２つ小数を受け取りスタックに２つ小数を返す処理単語"に与えるデータの型が誤りです。

1 個のエラーが有ります。
```


# 参考情報
「処理単語の属性指定」を使った記事はまだありません。

「処理単語」自体はこちらの記事に解説がございます。

https://qiita.com/mylifewithviolin/items/d84639178e12519a3dca


下記の記事では「関数」定義の際の属性定義について説明しています。

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

# おわりに
いかがでしたでしょうか？なにかの参考になれば幸いです。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: