【日本語プログラミング言語】Re:Mindのシンタックスハイライトを作ってみた【Re:Mind / VSCode Extensions】

本記事は「日本語プログラミング仕様記述言語 Re:Mind（リマインド） Advent Calendar 2024」の13日目の記事です。今年もカレンダーに招待いただきありがとうございます。

https://qiita.com/advent-calendar/2024/remind

# はじめに

昨年のアドベントカレンダーでは、Re:Mind（や類似する日本語プログラミングの）VSCode拡張機能についてのアイデアと小さなデモを投稿しました。

https://qiita.com/Syuparn/items/e8dbbfc29b588ddb45df


switch文のデモを紹介したところで力尽きてしまったので、今年は一通りの構文で動くところまで作ってみました。

# 作ったもの

こちらの拡張機能です。シンタックスハイライトとスニペットが使用可能です。
公開していますので、ぜひダウンロードして試してみてください。
（拡張機能から検索する場合は `remind-vscode` で出てきます）

https://marketplace.visualstudio.com/items?itemName=Syuparn.remind-vscode

Lv1.1ドラフトの仕様に準拠しました。

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

## シンタックスハイライト

サンプルコードを表示するとこのようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239887/b33c84ad-0048-834b-2587-9fa40545c42d.png)

Re:mindでは `/** */` 形式のコメントでトランスパイルする際の（英語の）変数名を定義可能なため、そちらにもハイライトを付けています。

暫定的に、`.remind` という拡張子を対象にしています。

手っ取り早く試したい場合は、こちらのテストコードを表示してみてください。
~~for文の型名の色が少しおかしいですが治らず...~~

https://github.com/Syuparn/remind-vscode-extension/blob/main/tests/%E3%82%B7%E3%83%B3%E3%82%BF%E3%83%83%E3%82%AF%E3%82%B9%E3%83%8F%E3%82%A4%E3%83%A9%E3%82%A4%E3%83%88%E3%83%86%E3%82%B9%E3%83%88.remind

## スニペット

スニペットも用意しています。

![function.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239887/221d00b9-f266-7ac6-0513-edadfe85c55a.gif)

日本語プログラミングなので、全角のままでも使いやすいよう記号(ex: `▽`)やその読み方(ex: `さんかく`)で辞書登録しています。
一方、初学者にとっては他の（英語）プログラミング言語の概念で探せた方が扱いやすいので、英語での意味(ex: `function`) も登録しています。

```js:snippets/remind.json
{
  "function": {
    "prefix": ["▽", "さんかく", "function"],
    "body": [
      "▽public 型1 関数1($1)",
      "△"
    ]
  },
  // ...
}
```

https://github.com/Syuparn/remind-vscode-extension/blob/main/snippets/remind.json

辞書登録の方針について詳細は昨年のアドベントカレンダーをご覧ください。

https://qiita.com/Syuparn/items/e8dbbfc29b588ddb45df

### スニペットで出てくるテンプレート

また、スニペットではあえて変数名、型名等にダミー要素を入れ完全な形で出てくるようにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239887/670c567d-9bd9-bcb7-07ad-53f38fcd334a.png)

ダミー要素は入れずに穴あきのスニペットを表示した方が修正の手間が減り作業効率が上がると思われますが、あえてこのようにしています。

```remind:ダミー要素あり
▽public クラス クラス1
    ・変数型1 メンバ1

    ▽public 関数1()
        
    △
△
```

```remind:ダミー要素なし
▽public クラス 
    ・変数 メンバ1

    ▽public ()
        
    △
△
```

Re:Mindのユースケースとして、以下のような状況を考えた際、スニペットを使うアーキテクトはプログラミングにはあまり馴染みがない可能性があります。

- 設計: アーキテクトがRe:Mindで記述
- 実装: プログラマがターゲット言語(Java等)で記述

ダミー変数を消す手間よりも、何を書けばいいか分からず戸惑う時間の方が長いのではと考えたため、構文が分かりやすい上記の方法を取りました。

# 仕様に対する所感

今回拡張機能実装に当たり、仕様を読んで構文を実際に一通り書いてみました。
最後に、その際仕様について感じたことを以下にまとめます。

## `・` と `□` の使い分け

`・` と `□`  両者の構文的な役割の違いが気になりました。

- `・` が宣言と初期化、`□` が再代入？
- `□` は関数呼び出し用の構文？

関連して、関数呼び出しが `□` でしかできない（ようにすべき）のかどうかも気になりました。

```remind:定義と関数呼び出し
・変数int 税込価格
□税込価格 = 消費税を計算する(価格, 軽減税率適用可否)
```

```remind:これは可能？
・変数int 税込価格 = 消費税を計算する(価格, 軽減税率適用可否)
```

## ターゲット言語ごとのフォールスルーの挙動の違い
switch文のフォールスルー（`□脱出する` (break)を書かない場合脱出せず次のcaseに移る）の有無はターゲット言語の仕様に合わせるという仕様について、個人的には一律どちらかに合わせてしまったほうが安全かなと思いました。

（例えば、VB.NET向けにトランスパイルしていたものをJavaへ移植（ターゲット言語を変える）際に意図せず挙動が変わってしまうと気づきづらいと思います）

# おわりに

以上、Re:MindのVSCode拡張機能の紹介でした。
サンプルコードを書いていて、母語起点でドメインモデルを考えられるのは楽しいと改めて感じました。
この拡張機能が、Re:Mindや日本語プログラミングに少しでも貢献できれば幸いです。

# 参考サイト

https://qiita.com/OrukRed/items/03f0e38e0f8553ee35d2

https://qiita.com/tkts_knr/items/92a15a9fe7475418b333