コンパイル、パース部分

MTemplate.xsのバイナリテンプレート読み込み部分を読んでいく前に、コンパイラの方を調べてみる。
MobaSiFでは、HTMLテンプレートをコンパイルしてバイナリ形式にする。このバイナリ形式のテンプレートを、プロセス間でmmapを用いてメモリを共有しながら参照する。

テンプレートの作成手順は、

  1. テンプレートを書く。
  2. 書いたテンプレートを「$MOBA_HOME/template/_system/」に置く。
  3. 「$MOBA_HOME/script/tool/compile_template」を起動してテンプレートをコンパイル
  4. 「$MOBA_HOME/data/html_bin/_system」にコンパイルされたテンプレートのバイナリテンプレートができる。

今回は2のcompile_templateを読んでみた。compile_templateは、実際にはコンパイルをしていない。実際にコンパイルをしている部分は、「$MOBA_HOME/src/xs/MTemplate/MTemplate/Compiler.pm」に書かれている。この中で定義されている「sub compile」が呼び出される。

この関数は、まず引数で渡されたHTMLテンプレートをパースして、配列に入れる。テストとして下記のテンプレートをパースさせてみる。

<html>
<head>
<title>echo</title>
</head>
<body>

<form action="_echo" method="POST">
<input type="text" name="message"><input type="submit">
</form>

$if (message) { $ $=h:message$ $ } $
$else { $ ここに表示させる $ } $
</body>
</html>

と思ったら、上記の書き方だとエラーが出た。なので、書き直し。

<html>
<head>
<title>echo</title>
</head>
<body>

<form action="_echo" method="POST">
<input type="text" name="message"><input type="submit">
</form>

$if (message) { $ $=h:message$ 
$ } else { $ ここに表示させる $ } $
</body>
</html>

パース結果が格納された配列をダンプした。

$VAR1 = {
          'text' => '<html>
<head>
<title>echo</title>
</head>
<body>

<form action="_echo" method="POST">
<input type="text" name="message"><input type="submit">
</form>

',
          'type' => 1
        };
$VAR2 = {
          'cond' => 'message',
          'onfalse' => 6,
          'type' => 4,
          'condtyp' => 1,
          'condval' => '',
          'condkey' => 'message',
          'ontrue' => 2
        };
$VAR3 = {
          'rbpos' => 6,
          'type' => 253
        };
$VAR4 = {
          'text' => ' ',
          'type' => 1
        };
$VAR5 = {
          'opt' => 2,
          'type' => 2,
          'key' => 'message'
        };
$VAR6 = {
          'text' => '
',
          'type' => 1
        };
$VAR7 = {
          'type' => 254
        };
$VAR8 = {
          'onfalse' => 10,
          'type' => 5,
          'ontrue' => 8
        };
$VAR9 = {
          'rbpos' => 10,
          'type' => 253
        };
$VAR10 = {
           'text' => ' ここに表示させる ',
           'type' => 1
         };
$VAR11 = {
           'type' => 254
         };
$VAR12 = {
           'text' => '

</body>
</html>
',
           'type' => 1
         };
$VAR13 = {
           'type' => 255
         };

この配列を基に、バイナリ化していく。

typeをキーにしている部分は下記のように、定義されている。

use constant {
   TYPE_PLAIN      => 1,
   TYPE_REPLACE    => 2,
   TYPE_LOOP       => 3,
   TYPE_IF         => 4,
   TYPE_ELSE       => 5,
   TYPE_QSA        => 6,
   TYPE_LB         => 253,
   TYPE_RB         => 254,
   TYPE_END        => 255,