はじめに
学校教育の中でも使用されるようになった日本語プログラミング言語「なでしこ」は、日本語を書くようにプログラミングを行うことが出来ます。例えば以下の日本語の文章はなでしこ3で正常に動作します。
りんごは200円です
みかんは150円です
もし、りんごとみかんの合計 が400円未満なら「買おう!」と言います
一方で全てが全て、このような普通の日本語で書けるわけではありません。特に数学に関する部分は、(なでしこの構文解析の仕様上)難しい点も多いです。例えば、以下のプログラムはどの行も上手く動作しません。
ルート2を表示する
SIN30度を表示する
LOG3を表示する
正常に動作させるにはこのように書く必要があります
2の平方根を表示する
30度をラジアン変換してSINを表示する
LOG(3)を表示する
「ルート」は中学生、「SIN」は高校生で学習することを踏まえると、上記「実行できない例」で挙げたようなコードが通るようにするとなお良いと考えられます。
一方で、やはり構文解析が難しい(らしい)ので、公式にはそうした構文は使えないようになっています。
そこで今回は、せめて「ルート2」や「ルート3」など、「ルート」という文字 + 数値という場合に限り、値を返すプログラムを考えてみました。
解決策
真っ先に思いつくコードは「ルート2」「ルート3」などをプラグイン内で定数として定義しておく方法です。しかし、「ルート3249」など定義外の非常に大きい数値が入力された場合、対処できません。
そこで今回はなでしこの構文解析後に行われる、変数の呼び出しに着目して、「ルート2」や「ルート3249」を正しく呼び出せるようにしてみました。
以下のコードをなでしこの実行前に走らせます。
(() => {
const origGet=Map.prototype.get;
const re=/^.*__ルート(\d+)$/;
Map.prototype.get=function (key){
if(this.has(key)) return origGet.call(this, key);
const m=re.exec(key);
return m?Math.sqrt(m[1]-0):undefined;
};
})();
おわりに
この解決策はプロトタイプ汚染を引き起こすので、危険性を理解した上で、自己責任で実行してください。
また、なんとなく場当たり的な感じがするので,変数名や関数名にワイルドカードが使えるようになったら良いなって思っています。
以上