13-08.スクリプトの実行

 CLangProject側のmain.cppには以下の記述があります。
#include "proc.h"

//中略

int main(int argc, char** argv) {
    InputParser input(argc, argv);
    const string& filename = input.getCmdOption("-f");
    if (filename.empty()) {
        cout << "スクリプトファイルが指定されていません。" << endl;
        return 1;
    }
    errno_t err;
    FILE* fp;
    if ((err = fopen_s(&fp, filename.c_str(), "r")) != 0) {
        cout << "スクリプトファイルの読み込みに失敗しました。" << endl;
        return 1;
    }
    auto tntp = clg::StackMachine::get();
    if (tntp->compile(fp)) {
        return 1;
    }
    tntp->execute();
    tntp->destroy();
    return 0;
}
 赤くなっているところですが、tntpポインタStackMachineクラスのインスタンスのポインタを代入し、以降はそのポインタ経由で操作しています。
    if (tntp->compile(fp)) {
        return 1;
    }
 は、BisonやFlexの字句解析や構文解析を行います。失敗すれば終了します。
 前項で説明した内容が処理されます。
    tntp->execute();
 は実行です。この関数は以下のような内容になります。
    void StackMachine::execute() {
        if (m_pRoot) {
            m_pRoot->execute();
        }
    }
 m_pRootというのはRootクラスのインスタンスのポインタです。コンパイル時に構築されます。
            m_pRoot->execute();
 は以下の内容になります。
    Value Root::execute() {
        //  main関数を探して実行
        FunctionCallExp* pFunc = new FunctionCallExp("main");
        pFunc->execute();
        return Value();
    }
 ここでは、main関数スクリプトを探して、見つかったら実行します。
 関数は関数の定義リストとして、
        DeclarationList* m_pDeclarationList;
 というRootクラスのメンバ変数として保持しています。
 関数は、前項で説明した
clg::StackMachine::get()->createIntFunctionDeclaration関数;
 によって定義ずみです。この内容は
    //int型関数定義
    Declaration* StackMachine::createIntFunctionDeclaration(Expression* pExp, Statement* stm) {
        IdentifierExp* pIdent = dynamic_cast<IdentifierExp*>(pExp);
        CompoundStatement* pComp = dynamic_cast<CompoundStatement*>(stm);
        if (pIdent && stm) {
            auto pObj = new IntFunctionDeclaration(pIdent, stm);
            m_objPool.push_back(pObj);
            return pObj;
        }
        else {
            cout << "関数定義が間違っています" << endl;
            exit(1);
        }
        return nullptr;
    }
 のようになっています。この中でIntFunctionDeclarationクラスのインスタンスが構築されますが、そのオブジェクトはCLangProject.yにて
declaration_list
    : declaration
    {
        $$ = clg::StackMachine::get()->createDeclarationList($1);
    }
    | declaration_list declaration
    {
        $$ = clg::StackMachine::get()->createDeclarationList($1,$2);
    }
    ;
 と定義リストに追加されます。その内容は、最終的にはCLangProject.y
root
    : declaration_list
    {
        $$ = clg::StackMachine::get()->addRootDeclarationList($1);
    }
    ;
 とRootオブジェクト
        DeclarationList* m_pDeclarationList;
 に追加されます。そのコードは
    //ルートへのDeclarationListの追加
    Root* StackMachine::addRootDeclarationList(DeclarationList* decl) {
        if (m_pRoot) {
            m_pRoot->setDeclList(decl);
        }
        return m_pRoot;
    }
 です。
 スクリプトでは
int func() {
	dump 30;

}

int main () {
	dump 10;
	dump 20;
	func();
}
 のようにmain関数も存在します。
 さて、実行の前置きが長くなりました。
 いずれにせよ、
    Value Root::execute() {
        //  main関数を探して実行
        FunctionCallExp* pFunc = new FunctionCallExp("main");
        pFunc->execute();
        return Value();
    }
 のようにmain関数を実行します。関数の実行式
    Value FunctionCallExp::execute() {
        bool flg = false;
        auto pRoot = StackMachine::get()->getRoot();
        auto pos = pRoot->getDeclList();
        do {
            auto decl = pos->getDecl();
            auto tgt = dynamic_cast<IntFunctionDeclaration*>(decl);
            if (tgt) {
                string str = tgt->getIdentity();
                if (str == m_Identity) {
                    flg = true;
                    tgt->excute();
                    break;
                }
            }
            pos = pos->getNext();
        } while (pos);
        if (!flg) {
            cout << "関数が見つかりません。: " << m_Identity << endl;
            exit(1);
        }
        return Value();
    }
 となります。

実行結果

 ここまでの実装で、
int func() {
	dump 30;

}

int main () {
	dump 10;
	dump 20;
	func();
}
 というスクリプトは
10
20
30

...\Debug\CLangProject.exe (プロセス 18652) は、コード 0 で終了しました。
このウィンドウを閉じるには、任意のキーを押してください...
 という実行結果になります。
 なーんだ、つまんない、とか思わないでください。
 これが言語の開発です。ゆっくりゆっくり進むのです。

 次項からは、いよいよ変数を実装したいと思います。
 ゆっくりお付き合いいただければ幸いです。