異世界の難解プログラミング言語「lex」の紹介
これは悠里・大宇宙界隈 Advent Calendar 2019の12日目の記事です。
異世界とはなんぞや?
「悠里」とは?
まず、 総合創作界隈『悠里』 について説明。
「悠里(Jurli/Yuuri)」とは、人工言語ユーゴック語と、人工言語リパライン語を主軸として架空世界を展開していくものです。架空世界の持つ文化、風土、歴史、宗教、人種など、さまざまな観点から創作していく総合創作です。
(悠里概説 - 悠里総合サイトより引用)
つまるところ、人工言語を中心に世界観を創作する界隈です。
ユーゴック語やリパライン語のほかにも、ざっくり十数言語以上は創作されています。
他にも、科学的なことから果てはボドゲまで作られてたり。
「FAFss」とは?
FAFss とは、悠里内の組織の一つで、主に計算機科学をやっていく集団。
様々なプログラミング言語やらアセンブリやらCPUやらが作られている。ヤバ。
架空世界の方にもFAFssという組織があり、そっちでは †革新的計算機† が作られたという設定。
なぜか筆者はFAFssとかいう頭おかしい集団にねじ込まれているので、ブログに頭おかしい成果を残そうと思いました。
「lex」とは?
悠里の主要言語の一つであるリパライン語には、“lex” という頭おかしい単語があります。
リパライン語辞書にはこのように記載されています。
【接続詞】【名詞】【前置詞】特別な三つの用法を持つ
[語法]
la lex
後置した文の前の文全体、一部を主語、目的語にする
eo lex
助動詞の意味を後に来る句の動詞に適用しない
lex V
動詞の連体形を作る。
これを悪用活用しました。
異世界の難解プログラミング言語「lex」
「lex」概要
lex はスタック指向の難解プログラミング言語です。これは草稿段階なのでいろいろできないことあります。
lexは基本的には全てのデータがFILO(First-In Last-Out)のデータ構造であるスタックに保存されます。 そしてそのスタック上のデータをこねくり回していろいろします。
以下のプログラムは、lexで最も簡単なプログラムの一つです。
lex vintifarlirges la lex .
このプログラムでは、自分自身を返すvintifarlirges
(リパライン語で「自己同一化する」)という関数を定義しています。
プログラミング言語「lex」って何の略?
「lex」とは、
lex es xlaisoss
の略で、「『lex』は命令列」と、「~を行う命令列」という二つの意味があります。
関数定義
関数を定義するには、lex V
というキーワードを用います。以下のVには関数名を、続けてプログラムの内容を、最後にピリオドで区切ります。
lex V プログラム .
基本的にlexのプログラムは関数定義の集合で書かれます。
データ
スタックにデータを積む方法は3種類あります。
- 即値
- スタックから取り出したデータを積む
- 関数を呼ぶ
基本的にはプログラムでは即値もしくはスタックから取り出したデータ(後述)を記述すると、そのままスタックに積むことができます。
以下のプログラムでは、3という即値と4という即値を積む関数を定義しています。
lex ekcan3 3 4 .
積まれる順番は左から順です。なので、この値を取り出す順番は4、3になります。
スタックから取り出す
基本的にはプログラマは、スタックの上から3つまでのデータを取り出し、自由に扱うことができます。
la lex
la la lex
la la la lex
la
の数が、上から何番目のデータかを示します。つまり、la lex
が一番最初に取り出されるデータで、la la la lex
が上から三番目のデータです。
ここが一番難しいところなのですが、プログラム内の節(後述)で最も多いla
の数のデータ分だけスタックからデータが取り出されます。
例えば、以下の関数は、一番上のデータは破棄されつつ、二番目のデータがスタックに積まれなおします。
lex ysev1 la la lex .
また、la lex
の内容は節の間保存され続けます。
以下の関数では、一番上のデータを取り出して積んで取り出して積んでいるわけではなく、一番上のデータをコピーして2つ積んでいます。
lex therda la lex la lex .
次の例では、スタック上の上2つの値を交換しています。
lex inferln la lex la la lex .
節
la lex
の示すスタックの位置を現在位置に更新したいとき、elx
というキーワードを用いることでリセットすることができます。
先ほどの、一番上のデータを取り出して積んで取り出して積むような関数を作りたければ、このように書きます。
lex etxaataes la lex elx la lex .
節は、関数を実行した際は区切らなければならず、またプログラム中でジャンプを行う目印になります。
関数の実行
例えば、lex ata
と定義された関数があったとしましょう。この関数は、2つの値をとり、1つの値を返します。勿論、引数のやり取りもスタック上で行われます。
この関数を実行するには、関数名の前にlex
を置きましょう。以下の関数では、受け取った値を2倍にしています。
lex 2tva la lex la lex lex ata .
だんだんと難解になってきましたね。この書き方は現世(悠里での現実世界の呼び方)では「逆ポーランド記法」と呼ばれています。 演算子や関数呼び出しが後置になります。面白いですね。
関数を実行した後は、節を区切るか、関数を終了するまでは、即値しかスタックに積めません。これは、関数を実行するとla lex
のような値が崩れるためです。
lex 4tva la lex la lex lex ata
elx la lex la lex lex ata .
今回は見やすいようにインデントしています。l空白文字はキーワードを区切るのに用いられ、改行やタブ文字などは区別しません。
ジャンプ
条件分岐をするには、melx
というキーワードを用います。これは、スタックの位置をリセットしつつ、スタックの二番目の値を見て、0ならばスタックの一番目の値だけ節を飛ばします。なお、2つの値は消費されます。
以下の関数では、2つの値を受け取り、二番目の値が0でなければ一番目の2倍します。
lex mal2tva la lex la la lex
1 melx la lex la lex lex ata
elx la lex .
また、素直にジャンプだけしたいときは、pelx
というキーワードを用います。使い方は、スタックの二番目の値を見なくなったmelx
のようなものです。
以下の関数では、先ほどの関数に、0であれば3倍するということをやってみましょう。
lex fhasfa la lex la la lex
1 melx la lex la lex lex ata
2 pelx la lex la lex la lex lex ata
elx la lex la la lex lex ata
elx la lex .
変数と参照
この言語では、データはスタックにしか存在しません。しかし、世の中には3つの値をこねくり回すだけでは事足りないことなどいくつもあります。
そういう時は、l'
というキーワードを用います。用い方はまだ考察中…ごめんなさい
標準出力
では、何か出力してみましょう。出力するには、lex xel
という関数を用います。この関数は、受け取った値を出力し、何も返しません。
lex xel1 1 lex xel.
たくさん何かを出力したい場合は再帰関数を用いるとよいでしょう。
lex xeless la lex -1 lex ata
elx la lex la lex
2 melx la lex la la lex lex xel
elx lex xeless
1 pelx la la lex
elx la lex .
lex salar 114 97 108 97 115 6 lex xeless .
最後に
なんやこれ。
非文でもゆるしてくだしあ