SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

MASMとなでしこによるオリジナルコンパイラの制作

MASMとなでしこによるオリジナルコンパイラの制作 3

コンパイラを作成してコンパイルをする

  • このエントリーをはてなブックマークに追加

今回は、簡易インタープリタ言語で複数の関数がきちんと使用できるようにした後、コンパイラを作成して、実際にコンパイルしてみます。コードジェネレータについても説明します。

  • このエントリーをはてなブックマークに追加

はじめに

 本連載では、最近の日本語プログラミング言語の中で高いシェアを占める「なでしこ」を使用して、BASICライクな自作言語のコンパイラを作成します。

 前回、「MASMとなでしこによるオリジナルコンパイラの制作 2」では、自作プログラミング言語「VEFBL」の言語仕様に沿った、簡単なインタプリタ環境を作りました。今回は、そのインタプリタ環境に用いたプログラムを応用して、いよいよコンパイラを作成します。

過去の記事

対象読者

 技術レベルは特に問いませんが、なでしこの簡単な文法を前もって習得していることが望ましいです。「自分で作ったプログラミング言語でソフトを作りたい!」と考えている方も歓迎します。

 また、プラットフォームはWindows XPを推奨します。MASMアセンブラのインストーラが、現在Windows XP以降のWindows NT系OSでしか動作確認できていないからです。これは、インストーラの起動時に使うWin32APIがWindows 9x系OSにないため、Windows保護例外エラーが発生するのが原因です。また、MASMはMac OSやLinuxなどでは動作しません。

作成の流れ

 コンパイラを作成するにあたって、本稿では次の順で説明していきます。

  1. print関数の理解
  2. 今回、コンパイラで作成するのは文字列を表示するだけの単純なものです。しかし、その文字列を表示するために使われるprint関数について、使い方を理解しておく必要があるので、解説していきます。
  1. コードジェネレータの設定
  2. コンパイルで使用するコードジェネレータをダウンロードし、配置します。
  1. コンパイラの作成
  2. アセンブリコードを記述しながらコンパイラを作成します。
  1. コンパイラの実行
  2. 最後にコンパイラを実行します。

print関数を理解する

「VEFBL」と表示してみる

 前回の記事では次の内容の「tokentest.nako」を作成し、「Hello Word!」を表示させることができました。

前回作成したtokentest.nako
バッファは空。
文字列中は、いいえ。
最新命令は、空。

「print "Hello Word!"」を文字列分解して、反復
 もし、バッファが「print」ならば、
  「printを検出しました」と言う。
  最新命令はバッファ。
  バッファは空。

 違えば、もし、対象が「"」ならば、
  もし、文字列中がはいならば、
   文字列中は、いいえ。
   もし、最新命令が「print」ならば、
    バッファを表示。
    バッファは空。
  違えば、
   文字列中は、はい。
   バッファは空。 //文字列の最初についてしまう「"」対策
 違えば              //ここは対象が「"」じゃない時の処理です
  バッファは「{バッファ}{対象}」。
   //上記以外の場合
   //printの後の半角スペースとかは
   //この行から5行上で対処してしまっています

 今回はまず、print関数の使い方を説明していきます。例えば表示させる文字列を「VEFBL」にしたいときは、どこを修正すればいいのでしょうか。「tokentest.nako」を見てみると(できれば、なでしこエディタ-nakopad.exeで開くことをおすすめします)、文字列を表示しているプログラムの部分は5行目であることが分かります。

「print "Hello Word!"」を文字列分解して、反復

 この部分を変更すれば、他の文字列を表示することが出来そうです。試しにやってみます。

tokentest.nako 5行目修正し、他の文字列を表示する
「print "VEFBL"」を文字列分解して、反復
実行結果
VEFBL

 きちんと他の文字列も表示できることができました。

 さらに改行して、もう1つprint関数を行使してみるとどうなるでしょう?

tokentest.nako 5行目修正1行追加し、print関数複数回実行する
「print "VEFBL"
print "Hello Me!"」を文字列分解して、反復
結果
VEFBL
Hello Me!

 予想通り、2つの文字列が改行されて表示されました。なお、「print検出しました」の行は今後必要ないので、9行目は消しておきます。

 今度は、メッセージボックスを表示する関数msgbox関数を作ります。作り方は、print関数と似たプログラムになります。

tokentest.nako
バッファは空。
文字列中は、いいえ。    //現在の位置が文字列の中であるか
最新命令は、空。        //さっき指定されたばかりの命令

「msgbox "やってみました"」を文字列分解して、反復
    // このようにすれば文字列に変数を埋め込めます
 もし、バッファが「print」ならば、
  最新命令はバッファ。
  バッファは空。
     // まだ他の場所にprintがあっても
     // 「print(なんとか)print」などとなってしまい
     // 検出できなくなる
 違えば、もし、バッファが「msgbox」ならば、
  最新命令はバッファ。
  バッファは空。
 違えば、もし、対象が「"」ならば、
            // 「"」は一般的な言語では文字列の最初を表す
  もし、文字列中がはいならば、
   文字列中は、いいえ。
   もし、最新命令が「print」ならば、
    バッファを表示。
    バッファは空。
   違えば、もし、最新命令が「msgbox」ならば、
    バッファを言う。
    バッファは空。
  違えば、
   文字列中は、はい。
   バッファは空。    // 文字列の最初についてしまう「"」対策
 違えば、
  バッファは「{バッファ}{対象}」。

 作成したら実行してみましょう。さらに、5行目に1行追加してみます。

tokentest.nako 5行目を修正し、1行追加
「msgbox "やってみました"
print "やってみました"」を文字列分解して、反復

 これを実行してみると、「やってみました」のメッセージボックスが2つも出てきました。2行目のprint関数は働いていないらしく、何も表示されていません。

デバッグ

 原因を探るためにデバッグを行います。なでしこにも当然、デバッガが搭載されており、今回の場合は8行目に、

tokentest.nako 8行目に追加
 デバッグ。

 と書くだけでデバッグを行えます(デバッグ。の前に、インデントをそろえるための全角スペースが入っていることに注意してください)。

 実行し、デバッグダイアログの[続ける]をクリックしながらバッファの中身を見てみると、肝心の「msgbox」関数が実行された後、{\n}(改行コード)が入っており、{\n}printを命令として認識してしまったようです。そのため、{\n}printは条件分岐の中にはないので、そのまま変数最新命令に格納されているmsgboxを実行してしまったのです。

 ということで、次のように修正しました。

tokentest.nako(太字が修正箇所)
バッファは空。
文字列中は、いいえ。
最新命令は、空。

「msgbox "やってみました"
print "やってみました"」を文字列分解して、反復
 もし、バッファが「print」ならば、
  最新命令はバッファ。
  バッファは空。
 違えば、もし、バッファが「msgbox」ならば、
  最新命令はバッファ。
  バッファは空。
 違えば、もし、対象が「"」ならば、
  もし、文字列中がはいならば、
   文字列中は、いいえ。
   もし、最新命令が「print」ならば、
    バッファを表示。
    バッファは空。
   違えば、もし、最新命令が「msgbox」ならば、
    バッファを言う。
    バッファは空。
  違えば、
   文字列中は、はい。
   バッファは空。
 違えば、もし、対象が改行でなければ、
  バッファは「{バッファ}{対象}」。

 変更部分は、最終行直前の違えば違えば、もし、対象が改行でなければ、したことです。さっきのデバッガで出てきた「{\n}」は改行を意味しますので、変更部分では変数「改行」が反復されていない時にバッファに文字を追加することにしました。つまり、改行コード以外の時に文字を追加するわけです。これを実行してみると、

msgbox 「やってみました」
msgbox 「やってみました」
print 「やってみました」
print 「やってみました」

 思い通りの動作をしました。

 print関数の使い方を理解したところで、いよいよコンパイラを作成していきましょう。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
コードジェネレータ

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
MASMとなでしこによるオリジナルコンパイラの制作連載記事一覧

もっと読む

この記事の著者

KMY(かみぃ)

とあるごく平凡な中学生。兵庫県在住。日本語プログラミング言語「なでしこ」に惹かれ、たくさんのプログラムを作り利用している。なでしこ以外にも、他の言語を心得ており、HTMLがなでしこの次に得意であり、Perlが第3位(かも)。ベクターにも多彩な作品を残している。作文がど苦手。KMYpage

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/766 2007/03/08 19:10

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング