独自言語の検討 [PIC]
年末に書いた記事 でちょっと書いたように独自のコンパイラ作成に興味が沸いてきました。
最初に式の評価処理から始めたいと思いますが GAME言語 では二項演算子に優先度がなかったので優先度付きの式評価処理を作成しました。
以前にも同様なことをやったことがあって「yaccで遊ぼう」では kmyacc を使って数式入力可能な電卓を作成しました。yaccを使用するとパーサーが楽にできるのですが内部処理がブラックボックス的になってしまいます。
また、「コンパイラ/インタープリッタの制作」では構文木を作成する方法を使いました(この時は構文解析までで作業中断 ^^;)
今回は PIC に実装するコンパイラを目指すので処理を簡略化するため1パスでのコンパイルを目標とします。このため上記の方法は使わず、再帰呼出しを駆使することで式を評価します。
いきなり PIC のマシン語を出力しても確認が大変過ぎるのでまずはインタープリタ式に実行して処理の妥当性を確認します。
開発環境としてはディバッグ環境として最も使いやすい環境の一つと考えられる Visual C++ を使います。最終的には MPLABX に移行して PIC24FJ に実装する予定です。
本来ならば言語仕様をきちんと設計し、機能設計した上でコーディングすべきなのでしょうが、個人的な趣味での作業なので「楽しさ」を最優先しアジャイル的にちょこまかといじりながら進めていきます。
まだインタープリタでの動作ですが式の評価処理は割合すんなりと完成し、制御文処理と処理呼出しまでできました。^^
しかし、ローカル変数、配列、バイトアクセス機能、マシン語生成等、まだまだ先は長そうです。
テストソース(独自言語)
処理名の最後が '_' である処理は組込み処理です。1パスなので処理名や変数の前方参照はできません。
上記のテストソースの実行結果は次のとおりです。
テストソース実行結果
[ 前へ ] 連載記事 [ 次へ ]
最初に式の評価処理から始めたいと思いますが GAME言語 では二項演算子に優先度がなかったので優先度付きの式評価処理を作成しました。
以前にも同様なことをやったことがあって「yaccで遊ぼう」では kmyacc を使って数式入力可能な電卓を作成しました。yaccを使用するとパーサーが楽にできるのですが内部処理がブラックボックス的になってしまいます。
また、「コンパイラ/インタープリッタの制作」では構文木を作成する方法を使いました(この時は構文解析までで作業中断 ^^;)
今回は PIC に実装するコンパイラを目指すので処理を簡略化するため1パスでのコンパイルを目標とします。このため上記の方法は使わず、再帰呼出しを駆使することで式を評価します。
いきなり PIC のマシン語を出力しても確認が大変過ぎるのでまずはインタープリタ式に実行して処理の妥当性を確認します。
開発環境としてはディバッグ環境として最も使いやすい環境の一つと考えられる Visual C++ を使います。最終的には MPLABX に移行して PIC24FJ に実装する予定です。
本来ならば言語仕様をきちんと設計し、機能設計した上でコーディングすべきなのでしょうが、個人的な趣味での作業なので「楽しさ」を最優先しアジャイル的にちょこまかといじりながら進めていきます。
まだインタープリタでの動作ですが式の評価処理は割合すんなりと完成し、制御文処理と処理呼出しまでできました。^^
しかし、ローカル変数、配列、バイトアクセス機能、マシン語生成等、まだまだ先は長そうです。
var i,sum, x1,x2, ans; proc test() { PrnStr_( "\nfor loop test" ); sum = 0; for ( i = 1; i <= 10; i=i+1 ) { sum = sum + i; } PrnStr_( "\n sum until 10 = " ); PrnDec_( sum ); PrnStr_( "\n\nif sentence test" ); if ( sum < 50 ) { PrnStr_( "\n sum < 50" ); } else { PrnStr_( "\n sum >= 50" ); } PrnStr_( "\n\ndo loop test" ); i = 0; do { i = i - 1; sum = sum - 1; } while ( sum > 0 ); PrnStr_( "\n -sum = " ); PrnDec_( i ); PrnStr_( "\n\ncalculation test" ); x1 = 1; x2 = 2; ans = x1 + x2 * 3; PrnStr_( "\n 1+2*3 = " ); PrnDec_( ans ); PrnStr_( "\n (1+2)*3 = " ); PrnDec_( ( x1 + x2 ) * 3 ); } proc main() { test(); PrnStr_( "\n\nbye !!" ); } |
処理名の最後が '_' である処理は組込み処理です。1パスなので処理名や変数の前方参照はできません。
上記のテストソースの実行結果は次のとおりです。
C:\src\vc\2010Express\tscl\tscl\Debug>tscl test.pid for loop test sum until 10 = 55 if sentence test sum >= 50 do loop test -sum = -55 calculation test 1+2*3 = 7 (1+2)*3 = 9 bye !! C:\src\vc\2010Express\tscl\tscl\Debug> |
[ 前へ ] 連載記事 [ 次へ ]
コメント 0