|
必見!! ブラウザで動く言語インタプリタ |
2016年11月10日公開,あとは気が向いたら適宜更新 | 2023年5月5日UPDATE |
ブラウザだけでプログラムを組めてしかもその場で実行もできるというオールインワンインタプリタを作ってみました。javascriptで書いたC言語類似の自作プログラム言語インタプリタですが、複素数の計算や高精度計算ができ、変数、配列、各種制御構造、関数なども使えます。またSVGとCANVASのグラフィックも使えます。 ほんの遊び程度のものですが、「計算用紙 "CalcPad"」と名付けてここに公開いたします。 |
他に類を見ない、純粋にブラウザ上のjavascriptで動くC言語類似の言語インタプリタ作成の記録です。
無謀とも思えるこんなおバカな?チャレンジをやる人もまずいないと思うので、大変貴重な内容および成果と言っていいかと思います。
まずは成果から。
上記アイコンを右クリックで「名前をつけてリンク先を保存」などでローカルに保存すれば保存したプログラムはいつでもそのままブラウザで実行できます。外部参照は一切していませんのでインターネット接続環境も必要ありません。
いったん開いてブラウザの「ページを保存」メニューを使って保存するとブラウザによってはjavascriptが実行されたあとの結果のページが保存されるためうまく動作しません。
プログラムはローカルに保存し読み込めます。ただプログラムの言語コードがUTF-8なのでWindowsパソコンで他のソフトを使って別途編集したりしようとすると少しやりにくいかもしれません。
CALCプログラム | 概要 |
---|---|
まずはお薦めのプログラムをいくつか | |
式の計算 | 入力された式を計算し結果を表示します。複素数の計算もできます。 上記のものと同じですがオートスタートをセットしてみました。 |
多桁高精度計算 | 多桁数字の文字列式で四則演算や累乗、階乗、累乗根などの計算を行います。 複素数は使えませんが計算の桁数はブラウザの許す限り任意です。 |
マンデルブロ集合 | グラフィック機能を使ってかの有名なマンデルブロ集合を描きます。 当初のから速度を改良し、さらに拡大位置などをマウスで簡単に設定できるようにしてあります。 |
マンデルアート展 | 上記マンデルブロ集合描画プログラムで得られた見応えのあるところをいくつか集めてみました。お暇なときにでもご覧ください。 |
二次方程式 | 二次方程式を解きます。係数での入力はもちろん、なんと式そのものを入力して解くこともできます。 |
その他いろいろ | |
分数計算 | 分数のままで四則演算を行います。 |
連立方程式 | 多元連立一次方程式を解きます。 |
素因数分解 | 正の整数を素因数分解します。 |
階乗計算 | 指定の範囲の整数の階乗の値を計算して表示します。ディフォルトで0から1000の階乗まで表示します。 |
素数の表示 | 与えられた範囲の素数を求めます。 |
最大公約数 | 2つの正の整数の最大公約数を求めます。 |
数値積分 | 与えられた数式の定積分を数値積分して求めます。 |
級数の和 | 与えられた級数の指定範囲での和を求めます。 |
カレンダーの作成 | 指定された年のカレンダーを作成します。 |
単位換算 | 長さ、面積、重量などの単位を換算します。 |
関数グラフ | グラフィック機能を使って関数のグラフを描きます。グラフィックの定番なのにうっかり忘れてました。 |
面積計算 | 代表的な図形の面積とできれば周囲の長さを計算します。 |
樹を描く | グラフィックを使って簡単な樹の樹形を描きます。ただし実際に樹を育てるよりは速いですがすごく時間がかかりますので(数時間から1日)、お暇な方だけどうぞ。 |
乱堕無 | グラフィック機能を使ってランダムに図形を描き続けます。 なんの役にもたたない最高にしょうもないプログラムの見本です。 |
変数テーブルなどが大きくなって少し遅くなるかなと思っていたがほとんど変わらず全く支障はない。
今はダウンロードしてデスクトップに置いて使っている。
以下は今回のチャレンジの発端、経過、実現のポイントなどの記録です。
おバカなチャレンジにもそれなりの苦労がありましたので、読んでいただけるとたいへんうれしいです。
でもちょっと計算をするときには電卓も机の上においてあり、それでやります。少し計算が複雑になるとそれにメモ用紙が加わります。
パソコンに電卓アクセサリーも入っていますが本物の電卓の方が使いやすいので電卓アクセサリーはほとんど使いません。
考えてみればもともとは計算するために作られた機械ですから計算に使わない手はないのですが、少し複雑な計算になると手軽にできるかといえばそうでもありません。
で、ブラウザはほぼ常時開いているので、試しにブラウザで計算するプログラムを組んでみます。
計算式 : の窓の部分に 四則演算(+, -, *, /)やかっこ()などで数式を書いてEnterすると結果を表示します。
計算式: →結果: |
<table style="width:100%;border-collapse:separate;background-color:#EEEEBB;" role="presentation"> <tr><td><div style="margin-left:0px;"><br /> 計算式:<input id="siki" type="text" value="" onkeydown="enter_submit(event)" style="width:70%;" /> <input type="button" value="計算" onclick="keisan();" /> <div style="width:100%;height:8px;"></div> →結果:<input id="kekka" type="text" style="width:70%;" value="" /><br /> <script type="text/javascript"><!-- function keisan(){ siki = document.getElementById("siki").value; // 入力された式を取得。 kekka = (eval)(siki); // 計算をする(してもらう)。 document.getElementById("kekka").value = kekka; // 結果を表示する。 } function enter_submit(evt){ if(!evt){ evt = window.event; } if(evt.keyCode == 13){ keisan(); } } //--></script><br /> </div></td></tr></table> |
それに四則演算はいいとしても、sinやcosなどの数学関数を使おうとするとMath.sin()だのMath.cos()などとしなくてはなりません。javascriptはオブジェクト指向言語とやらで各種数学関数はMathオブジェクトの一部なのでこう書かなくてはならないということのようですが、よけいなお世話と押し付けも甚だしい。
Mathオブジェクトにしようがなんにしようが利用者には関係ないことで、Mathオブジェクト以外にもいろいろなsin,cosがあるのならともかく、普通の人にとってはsinはsin、cosはcosなのだから、引数の()はまあいいとしてもオブジェクト操作などはそちらでやってくれて sinはsin()、cosはcos()で使えるようにしてくれたほうがずっとありがたい。javascriptのオブジェクト指向というのは利用者のためではなく作り手の都合を押し付けている部分が多いような気がします。せめてRubyの十分の一でも見習ってくれるといいんですけどね。
それに対話的に値を入力して計算し結果をいろいろ比較してみたいなどということも簡単にはできません。たとえば2次方程式を解こうと思ったら根の公式に事前に値を代入してそれをそっくりすべて打ち込まなくてはなりません。
...使い勝手はあまりよくありません。
…実をいうと少し前にこの本(素人向け?科学雑誌 Newton別冊 "魔法の数"虚数)を読んだのでした。→
そうだ、複素数計算もできるプログラムを作ってみよう。
javascriptには数学演算や数学関数もいちおう組み込まれてます。やってやれないことはないでしょう。
...というわけで、複素数計算プログラムをつくり始めたのでした。
単なる暇つぶしのプログラム遊び程度のつもりでした。
…長かった寒い冬が過ぎて春のうららかな日差しにうきうきしながら開始したのでした。
言語に四則演算や三角関数、対数・指数関数などが備わっていれば、やる気になればだれでもできます。
で、実際に使ってみると...、
同じ値をいちいち幾度も打ち込まなくていいように変数がほしいな。
比較判定などの条件判定や分岐処理もしたい。繰り返し計算もしたいな。
配列や関数が定義できて使えればいいな。
簡単なグラフィック機能も装備してグラフなど描ければいいな。
....
となります。つまり構造化言語の基本機能はやっぱりほしくなります。
ついでだ、みんなやっちゃえ!! ... プログラム遊びもなんだか本格味をおびてきました。
すなわち、ここから先は言い換えれば javascriptで言語インタプリタを書く ということになります。
いよいよjavascriptの超高度なプログラミングへの挑戦です。
でもこういうものは昔からだいたいC言語でというのが常識みたいなもんだが、はたしてjavascriptでもできるかな?
インタプリタでインタプリタを動かすとなるとめちゃ遅いのは覚悟の上だが、基本的にできないということはないだろう。
言語ソフトもサーバーもコンパイルする手間も、パソコンがあればとにかくセンス以外は何もいりません。
…梅の花が咲いてじきに桜も楽しめそうです。
…桜も咲いて春うらら。こんな陽気が続くといいけど。
次にif, for, whileなどの制御構造も加えてみました。このへんから少し雲行きがあやしくなってきました。for,whileなどでループしている間ブラウザは固まったようになり、ループが長いと「このページのスクリプトは処理に時間がかかっているか応答しなくなっています。今すぐスクリプトを停止....」などという警告が出ます。
…桜の花とともにできる自信がはらはらと...少しづつ散りはじめました。
さらにprintやinputなどブラウザ画面との入出力関数を書いたところ、まともに動作しません。スクリプトが完全に終了してからどっとまとめて出力されたりinput欄が表示されたりで全く実用に耐えません。
ずいぶん長いこといろいろとコードを書き換えたりして悪戦苦闘していましたが、一向にらちがあきません。
このあたりまできて、普通の言語だったら全く意識すらしないこと、すなわちjavascriptは同期非同期、割込などの基本的な制御がまともにできないということにやっと気がついたのです。(そんな記事はちらほら見てはいたのですが、まさかこれほどひどいとは思ってもいませんでした。)
…ついに梅雨に入りました。しとしとと雨が降っています。気分が滅入ります。
どうりで世の中にjavascriptで書いたまともな(長時間かかるループやプログラムと同期した入出力がちゃんとできる)構造化言語のインタプリタが存在しないはずだ。(私が知る限り構造化言語という枠を外しても Applesoft BASIC というごく初期のBASIC程度のものしか見たことはない。)
プログラム遊びをしていれば当然似たようなことを考えてやる人がいるはずですが、今まで多くの人がここらあたりで涙をのんで諦めたのでしょう。でもここで諦めてはおもしろくありません。仕事だったらとっくに諦めているところですが、これは遊びですからそうもいきません。(ん、逆か?)
会社で仕事をするふり...じゃなかった...仕事をしながらも方策をあれこれ考え、帰ってはそれを試す日々がしばらく続きました。
そして...、ついに、不可能を可能にする年寄りの知恵、な、なんと秘伝の最高奥義と秘技まで繰り出して、やっと何とかこれをのりきったのでした。プログラムはほとんどそっくり書き換えになりました。
不可能を可能にした秘伝の最高奥義とその技とは?...
このへんまでくるともうあとは意地でしかありません。
外は猛暑でどうせ出歩く気にもならないので、せめてクーラーの効いた部屋で悪戦苦闘していました。
…こうして暑い夏は過ぎていきます。
…例年どおり彼岸花が咲いています。ほぼきっちりお彼岸になると咲くから不思議です。
そしていよいよグラフィックの段に入りました。SVGとかCANVASとかいうのを使います。
予想通り今度はブラウザの互換性に悩まされます。
昔に比べればずいぶん良くなったとは言え、Microsoft系のブラウザMSIE11, Edgeはだめ。(MSIE10以下はないのでわからないがたぶん全くだめ。)
Microsoft系以外のブラウザ、Firefox, Chrome, Operaなどはみな一発でOK!。
Microsoft系は相手にしたくないけど知人友人で使っている人がいるから仕方なく何とかEdgeだけは対応しました。
MacintoshのSafariはわかりません(近くに全然ないんだもん)。
やってみると、インタプリタでインタプリタを動かすだけあって予想通り予想もできないほど遅い!?。
あまりに遅くて不評だったので少しずるして高速化したがあまりこういうのには向かんかな(マンデルブロ描画)。
まあふつうのちょっとした計算やグラフなら全然問題はないし、そこそこきれいなグラフィックが描けたからよしとしよう。
思えば開始してからずいぶん長い時間がたってしまいました。
もともと自己満足の遊びの世界のもので、とうてい大手を振って世に出すような代物でもないのですが、せっかく作ったのだから「計算用紙 "CalcPad"」(以下CALCと略)と名付け、ここに公開させていただきます。
普通に計算や既存言語の勉強をしたいならプログラムソースを書けば専用サーバーでしっかりコンパイルしたり実行して結果を表示してくれるオンラインサービスも多々あるのでそちらを使っていただくことにして、こちらは言語そのものから自分でつくる、より純粋で高度なプログラム遊びの世界として見て楽しんでいただければと思います。
しかし単なる遊びでただそれだけかというとそうでもありません。
まず自分で言語をつくってみるというのはすさまじく勉強になります(やりきるには相当の覚悟が必要だけど)。さらに自分の用途に合った言語を作成すれば楽に高度な処理を書くこともできそうです。
プログラムや余計なボタンなどを隠してオートスタートをかけてしまえば、自分でつくった自分好みの言語でインタラクティブな相当おもしろいページもつくれると思います。
ターゲット言語は最初なるべくC言語互換を目指していたのですが、ついつい楽をしようとjavascriptの処理系をそのまま使った部分も多々あり、かなりjavascriptに引っ張られています。でもjavascriptもCの派生言語ですから、C, php, java, javascriptなどのどれかを知っている人ならほとんどすぐに理解できると思います。機能としては本当に基礎的なもののみで、たとえば構造体やオブジェクトのような高度なデータ構造機能はありません。
● | いわゆる構造体やオブジェクトのようなより高度なデータ構造はありません。たぶん私自身がほとんど使わないせいです。 |
どうしても必要なら関数や配列、new、copy、アクセス演算子(.)などを使えば同等のことはできるでしょう。 | |
● | そもそも数学計算からスタートしたので文字列操作系の関数はあまり充実していません。また配列操作も同様です。 |
これらは言語によっても非常にちがうため、とりあえず後回しにしてそのままになっているふしもあります。欲しくなったら追加すればいいし。 | |
● | プログラムエディタやステップ実行、トレースモードなど、よりプログラミングをしやすい機能はほしいところです。 |
もっともこれで本格的にプログラム開発するようなこともないだろうから、ま、いいか。 |
御礼
…山はもみじに色づきはじめました。そろそろ冬眠の支度をしなくてはなりません。
(追記:2016.12.30)年賀状をやってみた
せっかくグラフィック機能をつけたので試しに年賀状を書いてみようと思い立ってやってみました。
座標をいちいち数字で指定して絵を描くというのはけっこう大変だったけど何とか間に合うよう完成!
ただし絵はおもしろさを出すためわざと下手っぽく描いているのでその点くれぐれも誤解なきよう。
で、謹賀新年 → 2017年 年賀状 ...ではよいお年を。
(追記:2017.7.30)プログラムエディタをつけてみたけどあまりうまくいかなかった。
ふだんはパソコン(Linuxサーバー)のプログラムエディタを使っているが、それには言語のキーワードを色付けしたり語句の検索や置換をしたり括弧などの対応を表示する程度の機能はあり、せめてそれくらいの機能はほしい。
で、Aceというブラウザ上で動くプログラムエディタが公開されていたので、これをCALC用に少々改造して組み込んでみた。
でも残念なことにブラウザとの相性なのか日本語との相性なのかブラウザによって、編集位置とカーソルがずれたり、プログラムエディタがブラウザの動作を少し書き換えるのかグラフィックの文字表示がうまく動かなくなったりするので残念だけどあきらめた。
別途使い慣れたプログラムエディタでプログラムを編集すればすぐに読み込めるので、そうするのが一番確かでやりやすいと判断。プログラムエディタの搭載はやめた。
ここまでいろいろやってきたけど、プログラムもだいぶ大きくなり、もう今の劣化した頭ではそろそろ限界に近い。
このあたりでいちおうよしとしよう。
...だれか続きをやってくれるという人でもいれば嬉しいけど...。