漢文風プログラミング言語「文言」の基本文法を読み解いてみた

# 導入
以下のツイートを見かけまして。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「漢文風プログラミング言語」とかいう古代文明SFモノみたいな激ヤバなブツが流れてきてて滅茶苦茶興奮してしまった<a href="https://t.co/8yV8uRWFlX">https://t.co/8yV8uRWFlX</a> <a href="https://t.co/UwrT6MdGHI">pic.twitter.com/UwrT6MdGHI</a></p>&mdash; 避雷 (@lucknknock) <a href="https://twitter.com/lucknknock/status/1206956422073729026?ref_src=twsrc%5Etfw">2019年12月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
すごい。そしてGitHubで公開されているみたいなので早速触ってみました。

# 概要
- 言語名：文言
    * Wenyan-lang
- 公式リポジトリ：https://github.com/wenyan-lang/wenyan
- 拡張子：`.wy`
- 実行方法：JavaScriptかPythonに変換
    * [オンラインIDE](http://wenyan-lang.lingdong.works/ide.html)
    * リポジトリの`./build/wenyan.js`
- ライセンス：[MIT License](https://github.com/LingDong-/wenyan-lang/blob/master/LICENSE)
- その他：`src/render.js`でソースコードを原稿用紙にレンダリングできる

# 基礎文法
READMEに掲載されている例に基づき、取り急ぎ変数・関数・条件分岐・繰り返しのみ読解し、意味を読み解いてみました。これである程度のことは書けるはず。
原文READMEの文言例とJavaScript例は変数名や文字列を適宜翻訳して対応付けていますが、今回はわかりやすいように両者ともアルファベットにしました。アルファベットでも動きます。文法を覚えたらぜひ漢字で変数名や関数名などを付けてみてください。

## 変数宣言
### 例
|文言|JavaScript|
|---|---|
|吾有一數。曰三。名之曰「a」。|var a = 3;|
|吾有一言。曰「「text_text_text」」。名之曰「str」。|var str = "text_text_text";|
|吾有一爻。曰陰。名之曰「flag」。|var flag = false;|
|吾有一列。名之曰「array」。|var array = [];|
|有數五十。名之曰「b」。|var b = 50;|

### 対応表
|文言|意味|
|---|---|
|漢数字（一二三……）|英数字（123...）|
|零|0|
|數|数値型|
|文|文字列型|
|爻|真偽値型|
|列|配列|
|「」で囲まれた部分|変数名|
|「「」」で囲まれた部分|文字列|
|。|半角スペース|

### 解説
* `吾有一數。曰num。名之曰「var_name」。`
* `有數num。名之曰「var_name」。`

で変数`var_name`に数字`num`を代入して変数宣言できます。変数名は`「」`で囲む。初期値なしの変数宣言はできない。
前者の書き方の場合は、冒頭の`吾有一數`の`一`で宣言する変数の数を表しているため、ここの数字の分だけ後ろに`曰num。名之曰「var_name」。`を書き連ねる必要があります。
~~面倒なので`有【型】～名之曰「【変数名】」`だけ使えば良いと思う。~~

### 補足
実は`數`、`文`、`爻`、`列`は全部`var`になるので間違っても動くには動きます。

## 変数代入
### 例
|文言|JavaScript|
|---|---|
|昔之「a」者。今「b」是也。|a = b;|

### 対応表
|文言|意味|
|---|---|
|昔之～者。今～是也。|=（代入）|

## 条件分岐
### 例
|文言|JavaScript|
|---|---|
|若三大於二者。乃得「「true_text」」也。|if (3>2){ return "true_text"; }|
|若三不大於五者。乃得「「true_text」」。若非。乃得「「false_text」」也。|if(3<=5){return "true_text"}else{return "false_text"}|

### 対応表（条件分岐）
|文言|意味|
|---|---|
|若|if|
|乃得|then|
|若非|else|
|也|end（条件分岐用）|

### 対応表（真偽値）
|文言|意味|
|---|---|
|a等於b|a == b|
|a不等於b|a != b|
|a大於b者|a > b|
|a不大於b者|a <= b|
|a小於b者|a < b|
|a不小於b者|a >= b|
|中無陰乎|and|
|中有陽乎|or|
|變|not|

### 解説
スペースはいくら入れてもよいのでインデントも可能です。インデント例は下記の通り。

```
若三不大於五者。乃得
    「「true_text」」。
若非。乃得
    「「false_text」」
也。
```

## 繰り返し
文法的な近さの関係上この項目のみJavaScriptではなくRubyと対応付けます。ちなみに最初にこの記事を執筆した2019年12月18日には文言をRubyにコンパイルすることはできなかったのですが、いつの間にかRubyへのコンパイルも可能になっていました。

### 例
|文言|Ruby|
|---|---|
|為是n遍。⋯⋯ 云云。|n.times do ... end|
|恆為是。⋯⋯ 云云。|loop do ... end|
|凡「array」中之「elem」。⋯⋯ 云云。|for elem in array do ... end|
|乃止。|break;|

### 対応表
|文言|意味|
|---|---|
|為是n遍|云云（end）までの処理をn回繰り返す|
|恆為是|云云（end）までの処理を無限に繰り返す|
|云云|end（繰り返し用）|
|乃止|break|

### 補足
実は`也`と`云云`はどちらも`end`に変換されるためどちらでもよい。

# おわりに
文言の基礎文法だけ読み解いてみました。さらに発展的な書き方については、[公式のREADME](https://github.com/LingDong-/wenyan-lang)または[ソースコード](https://github.com/LingDong-/wenyan-lang/blob/master/src/parser.js)をお読みください。
とにかく`src/render.js`でソースコードを原稿用紙に出力できるのが楽しみすぎるので何か書きたい。皆さんも漢字文化圏の特典を享受してプログラミング言語「文言」を楽しんでください！

# 参考文献
- [文言 wenyan-lang](https://github.com/LingDong-/wenyan-lang/blob/master/README.md)