esbasic0011
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* ES-BASIC #11
-(by [[K]], 2019.11.19)
** (13) ES-BASIC ver.0.1b のソースコード規模
-全体(すべてC言語で書かれています)
|ファイル名|行数|説明|
|''kcl03'' [川合用汎用ライブラリ]|RIGHT:1360行|高速なmall...
|''kll00'' [川合用汎用言語ライブラリ]|RIGHT:890行|ストリ...
|''bla'' [川合用汎用グラフィックライブラリ]|RIGHT:719行|...
|''bla2'' [川合用汎用グラフィックライブラリ]|RIGHT:105行|...
|''chr''|RIGHT:105行|bla2用のキャラクタデータ|
|''esbasic''|RIGHT:1748行|''ES-BASIC本体''(今回は主にこ...
|(合計)|RIGHT:4927行|実行ファイルサイズは64bit版が102.0KB...
-esbasicの内訳(主要なもののみ)
|関数名|行数|説明|
|sub_~|RIGHT:245行|生成した機械語から呼ばれるための関数...
|loadReg|RIGHT:257行|式の記述から機械語を生成するための関...
|||演算対象がメモリかレジスタか定数なのかで機械語を作り分...
|OpCall_put|RIGHT:64行|sub_~を呼び出すためのコードを生成...
|eval0|RIGHT:60行|機械語のエントリ部分のコード生成。|
|evalAdd|RIGHT:408行|指定された1行を機械語に翻訳。以下の...
|eval1|RIGHT:50行|機械語のジャンプ先の確定処理や、実行処...
|eval2|RIGHT:26行|機械語生成のために使用したメモリ域など...
|cmplTimeRun0|RIGHT:26行|@cmplTimeやCONST()の実現のための...
|sub_run|RIGHT:77行|上記の関数群を使ってプログラムを機械...
|cmdlineLoop|RIGHT:115行|REPL(Read-Exec-Print-Loop)のため...
|bla_main|RIGHT:74行|ちょっとblaライブラリの都合で名前が...
|(小計)|RIGHT:1402行|これで全体の80.2%を説明できたことに...
-このセクションでアピールしたいことは、ES-BASICが小規模で...
-高速なスクリプト言語を作るのは、世間で思われているほどに...
** (14) ES-BASIC ver.0.1b の主な機能
-[1]かなり高速、コンパクト
--gccに近い速度が簡単に出ます。スクリプト言語(インタプリ...
--たぶんこの点が最大の特徴です。
--言語処理系は''100KB程度''であり、この規模の言語としては...
--もちろんスクリプト言語なので、実行ファイルを作るなどの...
--なお、内部でJITコンパイラを持つことで、高速な実行と言語...
-[2]基本構文
--すべての行に行番号を付けなければいけないタイプのBASIC言...
--一つの行に複数の文を書くことができます。その場合は、セ...
--テキストエディタなどがなくても、コンソールだけでプログ...
--言語としては、静的型付き言語です(そもそもBASICはそうい...
-[3]サポートしている演算子
|+|-|*|/|%|<<|>>|&|||^|array[i]|
|加算|減算|乗算|除算|剰余|左シフト|右シフト|ビットAND|ビ...
--このほかにも A*:B>>C のような演算子も持っていますが、説...
--配列アクセスは添え字が宣言の範囲外になると、実行時エラ...
-[4]サポートしている命令
|命令|ver|説明|
|A=B|01b|単純な代入文です。Bの部分は式になっていてもOKで...
|PRINT ...|01b|式の値をコンソールに表示します。|
|FOR A=B,C ... NEXT|01b|定番の繰り返し命令です。終値の後...
|FORNE A=B,C ... NEXT|01b|FOR I=0,10 ... NEXT は、I=10も...
|DOLOOP ... ENDDO 条件|01b|do~while相当のループです。条...
|IF 条件 THEN ... ELSE ... FI|01b|定番のIF文です。ELSE節...
|LABEL ラベル名|01b|GOTOやGOSUBの飛び先のためにラベルを宣...
|IF 条件 GOTO 行番号orラベル|01b|条件ジャンプです。|
|GOTO 行番号orラベル|01b|無条件ジャンプです。|
|GOSUB 行番号orラベル|01b|サブルーチンを呼び出します。|
|RETURN|01b|サブルーチンから復帰します。|
|NORETURN|01b|サブルーチンから復帰しますが、呼び出し元に...
|PUSH 式|01b|式の値をスタックに保存します。|
|POP 変数名|01b|スタックから値を取り出します。今のES-BASI...
|LIST|01b|プログラムを表示します。|
|RUN|01b|プログラムを実行します。|
|RENUM|01b|行番号を付け直します。BASICが好きな人には定番...
|NEW|01b|プログラムを全行消去します。ただし変数の値は消え...
|EXIT|01b|ES-BASICを終了します。|
|END|01b|プログラムを正常終了します。|
|STOP|01b|プログラムを中断します。どの行で中断したのかも...
|PAUSE|01b|プログラムを一時停止します。どの行で中断したの...
|LOAD ファイル名|01b|ファイルからプログラムを読み込みます...
|ALIAS|01b|変数名や予約語や演算子に別名を与えます。|
|RAND|01b|0~32767の乱数を生成します。たいていは%で適当な...
|INPUT|01b|コンソールから数値を入力します。|
|OPENWIN|01b|グラフィックウィンドウのサイズを指定します。|
|A=RGBCOL(red,green,blue)|01b|RGB値からカラーコードを取得...
|GCLS|01b|グラフィックウィンドウ全体を一色で塗りつぶしま...
|SETPIX|01b|グラフィックウィンドウに点を描画します。|
|FILLRECT|01b|グラフィックウィンドウに塗りつぶした長方形...
|DRAWRECT|01b|グラフィックウィンドウに塗りつぶさない長方...
|FILLOVAL|01b|グラフィックウィンドウに塗りつぶした楕円形...
|DRAWOVAL|01b|グラフィックウィンドウに塗りつぶさない楕円...
|DRAWLINE|01b|グラフィックウィンドウに直線を描画します。|
|FILL|01b|グラフィックウィンドウの任意の領域を塗りつぶし...
|GPRINTI|01b|グラフィックウィンドウ内に数値を描画します。|
|GPRINTS|01d|グラフィックウィンドウ内に文字列を描画します...
|EWAIT|01b|指定した時間だけ待機します(sleep)。単位はミ...
|EINKEY|01b|グラフィックウィンドウへのキー入力を得ます。...
|FLUSHWIN|01b|描画結果を確実に画面に反映させます。たいて...
|ECHR|01b|グラフィックウィンドウ内にキャラクタを描画しま...
|GETCHR|01b|グラフィックウィンドウ内の指定された座標に表...
|GETCOL|01b|グラフィックウィンドウ内の指定された座標に表...
|CHRBOX|01b|ECHRを繰り返してキャラクタで長方形を描画しま...
|ARY INT NEW A[B]|01b|B個の要素を持つ配列Aを準備します。B...
|ARY INT DEL A|01b|配列Aを破棄します。|
|FF16SIN|01b|三角関数の値を計算します。角度はラジアンでは...
|FF16COS|01b|FF16SINのコサイン版です。|
|REGS|01b|現在のレジスタの値を簡単に確認できます。|
|CODE|01b|これは必殺技みたいな命令で、16進数列を書くとそ...
|||試してみたい機械語があったとき、これで試して、REGSで結...
|LWAIT|01b|実行速度を指定します。-1が一番高速でいくつかの...
|TIMEMODE|01b|1を指定すると、コマンドやプログラムの実行に...
|CODEDUMP|01b|1を指定すると、コマンドやプログラムがどんな...
|LINECOUNTER|01b|プログラムを実行した後にこの命令を実行す...
|||これで「ここは通ったかな?」などとPRINTデバッグする必...
|NODEBUG|01b|これはプログラム内で使う命令で、1を指定する...
|||これで怪しくない部分を高速に実行できるようになります。|
|DEBUGTRAP 行番号orラベル|01b|この命令で指定されたサブル...
|||デバッグトラップルーチンは、各行を実行する前に必ず呼び...
|||これにより、変数の値を監視したり、ある行の実行の前だけ...
|||デバッグトラップルーチンの中にデバッグ対象行があると、...
|PROGSEL|01b|実はES-BASICは複数のプログラムを同時に管理す...
|||PAUSE中に変数をいろいろ表示したいのなら、別スロットに...
|PROGRUN スロット番号|01b|PROGSELでアクティブなスロット番...
|PROGNEW スロット番号|01b|PROGSELでアクティブなスロット番...
|PROGLIST|01b|現在プログラムが格納されているスロット番号...
|PROGDEL スロット番号|01b|指定されたプログラムスロットを...
|CONST(式)|01b|式の内容をコンパイル時に計算して定数として...
|||したがってCONSTの中で変数を参照していて、その変数の値...
|@CMPLTIME ~ @EXECTIME|01b|@CMPLTIMEのあとに書かれた行は...
|||その演算結果を$RETVALに格納して、以降のプログラムでCON...
|||ES-BASICはスクリプト言語なので、プログラムを実行して値...
|||これにより、複雑な計算結果を定数として使いたいときに、...
|FF16SQRT|01d|固定小数点での平方根を計算します。|
|CLRKEYBUF|01d|キーバッファをクリアします。|
|KWAIT|01d|指定されたキーが押されるまで待ちます。|
|SETGMODE|01d|描画モードを指定します。|
|GETPIX|01d|画面上の点の色を取得します。|
|BITBLT|01d|配列データを画面の矩形範囲に転送します。|
** (15) 実プログラム例
-[[esbasic0010]]を見てください。
** (16) ベンチマーク
-詳細は[[esbasic0013]]を見てください。
|言語|処理系のインストールサイズ|タイプ|実行時間|GCC x64 ...
|GCC x64 8.1.0 -O3|RIGHT:449256KB|コンパイラ言語|RIGHT:1....
|ES-BASIC ver.0.1b 64bit版|RIGHT:102KB|スクリプト言語|RIG...
|Ruby 2.6.4p104 x64|RIGHT:75323KB|スクリプト言語|RIGHT:76...
|Python 3.7.4|RIGHT:85771KB|スクリプト言語|RIGHT:344.891...
|Python+Numba||スクリプト言語||RIGHT:2倍?|以前類似のテス...
|JavaScript(Node.js)||スクリプト言語||RIGHT:15倍?|以前類...
-一般に、Rubyはこの手の計算だとGCCの30倍程度の時間がかか...
--mrubyのJITコンパイラもあるので、これもいつかやってみた...
-Node.jsを使えばJavaScriptでも同様の計算をすることができ...
** (17) どうしてそんなに速いの?
-まず、世間で有名な言語がいろいろ最適を頑張っているのは知...
-ES-BASICでは最適化をがんばらない代わりに、レジスタを直接...
-どの変数にどのレジスタを割り当てればいいのか、どの変数は...
-つまり言語が自動であれこれとやってくれる言語ではなく、人...
** (18) デバッグ支援機能
-ES-BASICではデバッグ支援も大事な要素です(SecHack365の教...
-そもそも、一般に開発時間の4~7割はデバッグの時間になって...
-プログラムをRUNしてみて、動作が怪しいと思ったらグラフィ...
-そうではなく、デバッグ中にもう怪しいところの目星がついて...
-配列で添え字を間違えて対象の変数以外を書き換えて大惨事に...
----
-そしてES-BASICのデバッグにおける目玉機能はなんといっても...
-原理はとても単純で、各行を実行する直前に、指定しておいた...
9000 NODEBUG 1
9010 LABEL TRAP
9020 IF I>=20 THEN
9030 PRINT "I>=20 IN ",$LINE
9040 PAUSE
9050 FI
9060 RETURN
-たったこれだけで、変数iをすべての行で監視できるようにな...
-今回は簡単な条件でしたが、もっとややこしい条件でももちろ...
-プログラム中に出てきた変数$LINEは特別な変数で、どこの行...
9051 IF $LINE==2340 THEN PRINT "[2340] "; FI
-みたいなこともできます。これは2340行の行頭に PRINT "[234...
-また、
9052 IF $LINE==3450 THEN NORETURN 3460; FI
-ということもできます。これは3450行を実行せずに3460行へ帰...
-こうしてプログラム本体には一切手を入れずに、デバッグのた...
* こめんと欄
#comment
終了行:
* ES-BASIC #11
-(by [[K]], 2019.11.19)
** (13) ES-BASIC ver.0.1b のソースコード規模
-全体(すべてC言語で書かれています)
|ファイル名|行数|説明|
|''kcl03'' [川合用汎用ライブラリ]|RIGHT:1360行|高速なmall...
|''kll00'' [川合用汎用言語ライブラリ]|RIGHT:890行|ストリ...
|''bla'' [川合用汎用グラフィックライブラリ]|RIGHT:719行|...
|''bla2'' [川合用汎用グラフィックライブラリ]|RIGHT:105行|...
|''chr''|RIGHT:105行|bla2用のキャラクタデータ|
|''esbasic''|RIGHT:1748行|''ES-BASIC本体''(今回は主にこ...
|(合計)|RIGHT:4927行|実行ファイルサイズは64bit版が102.0KB...
-esbasicの内訳(主要なもののみ)
|関数名|行数|説明|
|sub_~|RIGHT:245行|生成した機械語から呼ばれるための関数...
|loadReg|RIGHT:257行|式の記述から機械語を生成するための関...
|||演算対象がメモリかレジスタか定数なのかで機械語を作り分...
|OpCall_put|RIGHT:64行|sub_~を呼び出すためのコードを生成...
|eval0|RIGHT:60行|機械語のエントリ部分のコード生成。|
|evalAdd|RIGHT:408行|指定された1行を機械語に翻訳。以下の...
|eval1|RIGHT:50行|機械語のジャンプ先の確定処理や、実行処...
|eval2|RIGHT:26行|機械語生成のために使用したメモリ域など...
|cmplTimeRun0|RIGHT:26行|@cmplTimeやCONST()の実現のための...
|sub_run|RIGHT:77行|上記の関数群を使ってプログラムを機械...
|cmdlineLoop|RIGHT:115行|REPL(Read-Exec-Print-Loop)のため...
|bla_main|RIGHT:74行|ちょっとblaライブラリの都合で名前が...
|(小計)|RIGHT:1402行|これで全体の80.2%を説明できたことに...
-このセクションでアピールしたいことは、ES-BASICが小規模で...
-高速なスクリプト言語を作るのは、世間で思われているほどに...
** (14) ES-BASIC ver.0.1b の主な機能
-[1]かなり高速、コンパクト
--gccに近い速度が簡単に出ます。スクリプト言語(インタプリ...
--たぶんこの点が最大の特徴です。
--言語処理系は''100KB程度''であり、この規模の言語としては...
--もちろんスクリプト言語なので、実行ファイルを作るなどの...
--なお、内部でJITコンパイラを持つことで、高速な実行と言語...
-[2]基本構文
--すべての行に行番号を付けなければいけないタイプのBASIC言...
--一つの行に複数の文を書くことができます。その場合は、セ...
--テキストエディタなどがなくても、コンソールだけでプログ...
--言語としては、静的型付き言語です(そもそもBASICはそうい...
-[3]サポートしている演算子
|+|-|*|/|%|<<|>>|&|||^|array[i]|
|加算|減算|乗算|除算|剰余|左シフト|右シフト|ビットAND|ビ...
--このほかにも A*:B>>C のような演算子も持っていますが、説...
--配列アクセスは添え字が宣言の範囲外になると、実行時エラ...
-[4]サポートしている命令
|命令|ver|説明|
|A=B|01b|単純な代入文です。Bの部分は式になっていてもOKで...
|PRINT ...|01b|式の値をコンソールに表示します。|
|FOR A=B,C ... NEXT|01b|定番の繰り返し命令です。終値の後...
|FORNE A=B,C ... NEXT|01b|FOR I=0,10 ... NEXT は、I=10も...
|DOLOOP ... ENDDO 条件|01b|do~while相当のループです。条...
|IF 条件 THEN ... ELSE ... FI|01b|定番のIF文です。ELSE節...
|LABEL ラベル名|01b|GOTOやGOSUBの飛び先のためにラベルを宣...
|IF 条件 GOTO 行番号orラベル|01b|条件ジャンプです。|
|GOTO 行番号orラベル|01b|無条件ジャンプです。|
|GOSUB 行番号orラベル|01b|サブルーチンを呼び出します。|
|RETURN|01b|サブルーチンから復帰します。|
|NORETURN|01b|サブルーチンから復帰しますが、呼び出し元に...
|PUSH 式|01b|式の値をスタックに保存します。|
|POP 変数名|01b|スタックから値を取り出します。今のES-BASI...
|LIST|01b|プログラムを表示します。|
|RUN|01b|プログラムを実行します。|
|RENUM|01b|行番号を付け直します。BASICが好きな人には定番...
|NEW|01b|プログラムを全行消去します。ただし変数の値は消え...
|EXIT|01b|ES-BASICを終了します。|
|END|01b|プログラムを正常終了します。|
|STOP|01b|プログラムを中断します。どの行で中断したのかも...
|PAUSE|01b|プログラムを一時停止します。どの行で中断したの...
|LOAD ファイル名|01b|ファイルからプログラムを読み込みます...
|ALIAS|01b|変数名や予約語や演算子に別名を与えます。|
|RAND|01b|0~32767の乱数を生成します。たいていは%で適当な...
|INPUT|01b|コンソールから数値を入力します。|
|OPENWIN|01b|グラフィックウィンドウのサイズを指定します。|
|A=RGBCOL(red,green,blue)|01b|RGB値からカラーコードを取得...
|GCLS|01b|グラフィックウィンドウ全体を一色で塗りつぶしま...
|SETPIX|01b|グラフィックウィンドウに点を描画します。|
|FILLRECT|01b|グラフィックウィンドウに塗りつぶした長方形...
|DRAWRECT|01b|グラフィックウィンドウに塗りつぶさない長方...
|FILLOVAL|01b|グラフィックウィンドウに塗りつぶした楕円形...
|DRAWOVAL|01b|グラフィックウィンドウに塗りつぶさない楕円...
|DRAWLINE|01b|グラフィックウィンドウに直線を描画します。|
|FILL|01b|グラフィックウィンドウの任意の領域を塗りつぶし...
|GPRINTI|01b|グラフィックウィンドウ内に数値を描画します。|
|GPRINTS|01d|グラフィックウィンドウ内に文字列を描画します...
|EWAIT|01b|指定した時間だけ待機します(sleep)。単位はミ...
|EINKEY|01b|グラフィックウィンドウへのキー入力を得ます。...
|FLUSHWIN|01b|描画結果を確実に画面に反映させます。たいて...
|ECHR|01b|グラフィックウィンドウ内にキャラクタを描画しま...
|GETCHR|01b|グラフィックウィンドウ内の指定された座標に表...
|GETCOL|01b|グラフィックウィンドウ内の指定された座標に表...
|CHRBOX|01b|ECHRを繰り返してキャラクタで長方形を描画しま...
|ARY INT NEW A[B]|01b|B個の要素を持つ配列Aを準備します。B...
|ARY INT DEL A|01b|配列Aを破棄します。|
|FF16SIN|01b|三角関数の値を計算します。角度はラジアンでは...
|FF16COS|01b|FF16SINのコサイン版です。|
|REGS|01b|現在のレジスタの値を簡単に確認できます。|
|CODE|01b|これは必殺技みたいな命令で、16進数列を書くとそ...
|||試してみたい機械語があったとき、これで試して、REGSで結...
|LWAIT|01b|実行速度を指定します。-1が一番高速でいくつかの...
|TIMEMODE|01b|1を指定すると、コマンドやプログラムの実行に...
|CODEDUMP|01b|1を指定すると、コマンドやプログラムがどんな...
|LINECOUNTER|01b|プログラムを実行した後にこの命令を実行す...
|||これで「ここは通ったかな?」などとPRINTデバッグする必...
|NODEBUG|01b|これはプログラム内で使う命令で、1を指定する...
|||これで怪しくない部分を高速に実行できるようになります。|
|DEBUGTRAP 行番号orラベル|01b|この命令で指定されたサブル...
|||デバッグトラップルーチンは、各行を実行する前に必ず呼び...
|||これにより、変数の値を監視したり、ある行の実行の前だけ...
|||デバッグトラップルーチンの中にデバッグ対象行があると、...
|PROGSEL|01b|実はES-BASICは複数のプログラムを同時に管理す...
|||PAUSE中に変数をいろいろ表示したいのなら、別スロットに...
|PROGRUN スロット番号|01b|PROGSELでアクティブなスロット番...
|PROGNEW スロット番号|01b|PROGSELでアクティブなスロット番...
|PROGLIST|01b|現在プログラムが格納されているスロット番号...
|PROGDEL スロット番号|01b|指定されたプログラムスロットを...
|CONST(式)|01b|式の内容をコンパイル時に計算して定数として...
|||したがってCONSTの中で変数を参照していて、その変数の値...
|@CMPLTIME ~ @EXECTIME|01b|@CMPLTIMEのあとに書かれた行は...
|||その演算結果を$RETVALに格納して、以降のプログラムでCON...
|||ES-BASICはスクリプト言語なので、プログラムを実行して値...
|||これにより、複雑な計算結果を定数として使いたいときに、...
|FF16SQRT|01d|固定小数点での平方根を計算します。|
|CLRKEYBUF|01d|キーバッファをクリアします。|
|KWAIT|01d|指定されたキーが押されるまで待ちます。|
|SETGMODE|01d|描画モードを指定します。|
|GETPIX|01d|画面上の点の色を取得します。|
|BITBLT|01d|配列データを画面の矩形範囲に転送します。|
** (15) 実プログラム例
-[[esbasic0010]]を見てください。
** (16) ベンチマーク
-詳細は[[esbasic0013]]を見てください。
|言語|処理系のインストールサイズ|タイプ|実行時間|GCC x64 ...
|GCC x64 8.1.0 -O3|RIGHT:449256KB|コンパイラ言語|RIGHT:1....
|ES-BASIC ver.0.1b 64bit版|RIGHT:102KB|スクリプト言語|RIG...
|Ruby 2.6.4p104 x64|RIGHT:75323KB|スクリプト言語|RIGHT:76...
|Python 3.7.4|RIGHT:85771KB|スクリプト言語|RIGHT:344.891...
|Python+Numba||スクリプト言語||RIGHT:2倍?|以前類似のテス...
|JavaScript(Node.js)||スクリプト言語||RIGHT:15倍?|以前類...
-一般に、Rubyはこの手の計算だとGCCの30倍程度の時間がかか...
--mrubyのJITコンパイラもあるので、これもいつかやってみた...
-Node.jsを使えばJavaScriptでも同様の計算をすることができ...
** (17) どうしてそんなに速いの?
-まず、世間で有名な言語がいろいろ最適を頑張っているのは知...
-ES-BASICでは最適化をがんばらない代わりに、レジスタを直接...
-どの変数にどのレジスタを割り当てればいいのか、どの変数は...
-つまり言語が自動であれこれとやってくれる言語ではなく、人...
** (18) デバッグ支援機能
-ES-BASICではデバッグ支援も大事な要素です(SecHack365の教...
-そもそも、一般に開発時間の4~7割はデバッグの時間になって...
-プログラムをRUNしてみて、動作が怪しいと思ったらグラフィ...
-そうではなく、デバッグ中にもう怪しいところの目星がついて...
-配列で添え字を間違えて対象の変数以外を書き換えて大惨事に...
----
-そしてES-BASICのデバッグにおける目玉機能はなんといっても...
-原理はとても単純で、各行を実行する直前に、指定しておいた...
9000 NODEBUG 1
9010 LABEL TRAP
9020 IF I>=20 THEN
9030 PRINT "I>=20 IN ",$LINE
9040 PAUSE
9050 FI
9060 RETURN
-たったこれだけで、変数iをすべての行で監視できるようにな...
-今回は簡単な条件でしたが、もっとややこしい条件でももちろ...
-プログラム中に出てきた変数$LINEは特別な変数で、どこの行...
9051 IF $LINE==2340 THEN PRINT "[2340] "; FI
-みたいなこともできます。これは2340行の行頭に PRINT "[234...
-また、
9052 IF $LINE==3450 THEN NORETURN 3460; FI
-ということもできます。これは3450行を実行せずに3460行へ帰...
-こうしてプログラム本体には一切手を入れずに、デバッグのた...
* こめんと欄
#comment
ページ名: