なんだこれは
みなさんはorelangを知ってますか?
プログラミング言語を作る。1時間で。という素晴らしい記事で実際に作られている言語です。
今回はdartを使って勝手にorelangを実装してみました。
できたもの
これが完成品を置いているリポジトリです。
だいぶテキトーだしエラー処理も甘いし抽象化も雑魚いので大目に見てやって下さい。
https://github.com/Uchijo/orelang_dart
工夫を試みた箇所
Object
をなるべく使わない
Javaの実装ではObject
型が多用されています。どうせなので型に守られてプログラミングしたいなぁと思い、できるだけObject
型を使わないようにしました。
その結果、EvalResult
とかいう謎のresultクラスが完成しました。
orelangでは全てが式であり、式を評価していくと最終的に以下の3つにたどり着きます。
- 整数
- ブール
- 値なし
これらを全てObjectでまとめるよりは、ということでEvalResultというクラスを作成しました。
int, bool, EvalResultTypeのフィールドを持ち、EvalResultTypeで保存されている型が何なのかを確認することができます。
整数ならintのフィールドに値が入り、ブールならboolのフィールドに値が入り‥という感じです。
(dartにユニオンがあればもっときれいに実装できるんだけどなぁ‥)
また、IOperator#call
の第二引数の型をList<IExpression>
に変更しました。結果から書くと、これは大きな間違いでした。
IOperator
の実装には、変数のset, getなどの処理も含まれています。その際、set, getに渡される引数は変数の識別子なのです。
これを式(つまりIExpression)にするとなにかがおかしい感じになってしまいます。
今回はあまり時間をかけて作る気分ではなかったので、しょうがなくIExpression
を実装したIdentifier
型をつくり、渋々それを使うという形を取りました。
何個か機能を追加してみた
orelang元記事では1時間で完成させるという制約がある関係上、機能は非常に限られています。(その制約のお陰でお手軽さと充実感の両立が実現できているはずなので本当にありがたいことです。決して機能が少ないことをディスりたい訳では無いです。)
しかし私には時間的制約はありません。ということで、最後楽しくなって追加したいくつかの機能をご紹介します。
if
式
皆さんご存知のif
式です。["if", cond, exp1, exp2]
という形で書くことができ、cond
がtrue
ならexp1
の評価結果が、false
ならexp2
の評価結果が返るというだけの式です。
and
, or
これもだいたいどの言語でもある機能ですね。["and", exp1, exp2]
みたいな感じで書けます。
>
, <
大小比較です。ないよりあったほうが良いかな~と。
skip
何もしない命令です。値としてはnovalue
、つまり値なしが返ります。
if
が式である以上else
句の実装は強制したかったのですが、どうせなので命令型言語的にskipもできたほうが良いかな、と思いこれを追加しました。軸ブレブレですね‥
今後やる気が続けばやること
そういえばwhileを作って満足したせいでuntilを作ってなかったので、それの実装はしたいですね。
識別子のところは納得いってないので、いつかリファクタリングしたいなと思っております。
あとは構文解析バチバチにしたやつとかも作りたいかも‥