nihongo.pmy

(12/05 追記、コードも少し加筆)
メタプログラミングの会でk.inabaさんが発表されたプログラミング言語Polemyで、資料中の例にあったnihongoレイヤを作ってみました。
http://www.kmonos.net/repos/polemy/


とりえあず動いた。

@@nihongo = fun(x)
{
  if @value(x) == 1 then
    "いち"
  else if @value(x) == 2 then
    "に"
  else
    "まちがい"
}
@nihongo + = fun(x, y)
{
  @value(@value(@nihongo(x) ~ "たす") ~ @nihongo(y))
}
@value( 1 + 2 )
@nihongo( 1 + 2 )
exit

実行結果

Welcome to Polemy 0.1.0
>> >> >> >> >> >> >> (function:12bffe0:12b4cc0)
>> >> >> >> (function:12c5e80:12b4cc0)
>> 3
>> いちたすに
>>

BBv2の警告メッセージ抑制

Boost.勉強会で時間がなくて話せなかった「警告メッセージ抑制」について説明しておきます。

import path ;
local broot =
	[ modules.peek : BOOST_ROOT ] ;
local bdir = [ path.make $(broot) ] ;
for local lib in graph mpi python regex {
	module Jamfile<$(bdir)/libs/$(lib)/build> {
		rule ECHO { }
	}
}

これをuser-config.jam等に書いておくと、「ICUがない」等の警告メッセージを抑止できます。

仕組みが分からずとも使えますが、理解するにはJamfileが個別のモジュール内で動作していることを知る必要があります。

ECHO $(__name__) ;

のようなJamfileを用意して実行してみると、

Jamfile

のような出力が得られるはずです。
変数__name__には現在のモジュール名が入っているので、サブプロジェクト毎に上記のような名前のモジュールが使われていることが分かります。

また、

  • モジュールはオープンである(モジュールにルールや変数を追加できる)
  • 警告メッセージはECHOルールで出力されている
  • ルールは「現在のモジュール」→「グローバルモジュール」の順で検索される

なので、警告メッセージを出力しているモジュール内でECHOを上書きすることで、その呼び出しをフックすることが可能です。
つまり、ECHOを空のルールで上書きすれば警告メッセージが出力されなくなるというわけです。

最近はconfigureというモジュールもメッセージを出力するので、

module configure {
    rule ECHO { }
}

も追加するとよいでしょう。
ただし、バージョンアップした際などは一度警告メッセージを見ておくのがよいです。

Boost.勉強会#3

Boost.勉強会#3でBoost.Buildについて発表しました。
発表資料
http://www12.ocn.ne.jp/~dante98/BoostBuild-pre.pptx
サンプルコード
http://www12.ocn.ne.jp/~dante98/zip/bbv2.zip
名前を言ってはいけないあのプログラミング言語インタプリタ
http://www12.ocn.ne.jp/~dante98/zip/bf.zip

PowerPoint/プレゼンテーション/大阪で緊張しました。
蛇足(蛇足大好きなもので、、、)ばかり話して時間配分も失敗してしまい、Tipsの部分は喋れませんでした。
次やるならラウンドテーブルとかの方がいいかなぁ。

Dante98 for Windowsクラッシュ回避パッチ

ワイド液晶になってからDante98 for Windowsが動いてなかったのですが、ようやく重い腰を上げて調査しました。
640x480x256色のDirectDrawサーフェイスのピッチが640以外の環境で動いていませんでした。
Ver. 2.0.1.10用のパッチです。

0x00016AC3: D4 -> D0
0x00016AC6: D0 -> D4

普通にビルドしたら実行ファイルのサイズが大きくなったので、そのままリリースは怖くてとりあえずパッチだけです。


(12:50 追記)
http://www12.ocn.ne.jp/~dante98/#20100925
に修正プログラムを置きました。

The AATT Programming Language

先日、kinabaさんと朗読劇を観に行ったときに話していたネタ言語を実装してみました。
元ネタ:「kinaba さんが Cryolite を洗脳してパターンマッチ厨に仕立て上げるリスト」
http://togetter.com/li/6990

確かにパターンマッチがあれば木の操作を簡潔に書けるのですが、
コメントにAAで木を書いておかないと何をやっているのかよく分からないので、
AAがそのままプログラムになればいいんではないかという発想です。
とりあえず、「ASCII Art Tree Transform」を略してAATTと呼ぶことにします。
「Tree」と言っても今のところ「赤黒木」専用です。

AATTのソースコードは次のようになります。

    G        P    
   / \      / \   
  p   U -> n   g  
 / \          / \ 
n   3        3   U
^                 

大文字が黒ノード、小文字が赤ノード、数字は任意のノード(空ノード含む)で、それぞれのノードは「/」か「\」で繋ぎます。
変形前と変形後の木は「->」のある列で区切られます。
「赤黒木」の挿入操作では追加したノードから探索する必要があるため、「^」で探索開始ノードを指定できるようにしています。
「^」がない場合は(部分木の)ルートから探索します。

このソースコードコンパイルすると、以下のようなC++コードが出力されます。

inline tree_node* balance(tree_node* root, tree_node* node)
{
    //   G            P   
    //  / \          / \  
    // U   p   ->   g   n 
    //    / \      / \    
    //   3   n    U   3   
    //       ^            
    {
        tree_node* pN = node;
        if ((pN != 0) && (pN->color == RED))
        {
            tree_node* pP = pN->parent;
            if ((pP != 0) && (pP->right == pN) && (pP->color == RED))
            {
                tree_node* p3 = pP->left;
                tree_node* pG = pP->parent;
                if ((pG != 0) && (pG->right == pP) && (pG->color == BLACK))
                {
                    tree_node* pU = pG->left;
                    if ((pU != 0) && (pU->color == BLACK))
                    {
                        tree_node* parent = pG->parent;
                        pP->parent = parent;
                        pP->color  = BLACK;
                        pP->left   = pG;
                        pG->color  = RED;
                        pG->parent = pP;
                        pG->right  = p3;
                        if (p3 != 0)
                        {
                            p3->parent = pG;
                        }
                        if (parent != 0)
                        {
                            if (parent->left == pG)
                                parent->left = pP;
                            else
                                parent->right = pP;
                        }
                        else
                            root = pP;
                        return root;
                    }
                }
            }
        }
    }
    return root;
}

関数名はソースファイル名から自動生成されます。
元のAAはコメントとして残ります。
引数rootは木のルート、nodeは探索開始ノードで、戻り値は変形後のルートになります。空行区切りでパターンを書いておけば、上から順にマッチングを行うコードが出力されます。
「tree_node」とか「BLACK」とか決め打ちなのは手抜きです。

再帰も書けます。

    G          g  
   / \        /^\ 
  p   u ->   P   U
 /          /     
n          n      
^                 

変形後の木のノードに「^」でマークすると、その位置をnodeとして再び変換を行います。

また、ルートかどうかの判定機能もあります。

*
n -> N
^     

ノードの上に「*」を付けると、そのノードが(部分木でなく全体の)ルートの場合のみマッチするようになります。

ちなみに、

  • エディタの設定で大文字の背景を黒、小文字の背景を赤にする
  • キャラクタセットを「欧文」などにする

とソースが読みやすくなります。

一応、ソースコードを置いておきます。
http://www12.ocn.ne.jp/~dante98/zip/aattc.zip (CR/LF改行)
http://www12.ocn.ne.jp/~dante98/zip/aattc.tar.bz2 (LF改行)


(23:30 追記)
#以降行末まではコメントです
バックスラッシュが出ないのでシンタックスハイライトしたものをこちらに貼りました
http://www12.ocn.ne.jp/~dante98/balance.aatt.html

xor_list

暇つぶしにSTL風にXOR連結リストを書いてみました。
<hamigaki/xor_list.hpp>
ドキュメント
wikipedia:XOR連結リスト
要するに、某巨大掲示板で昔話題になった「マジックリスト」のことです。
そのときアップされていた某氏のコードを参考にしました。
自分も途中まで書いていたので、それも参考にしつつ、「XOR連結リスト」の方が一般的みたいなので、xor_listと改名しています。

実用性はあまりないと思うのですが、割とまじめに書いています。
以下、特徴。

  • Boostなしで1ファイルだけで利用可能(一部Boostの劣化コピー品含む)
  • 等価でないアロケータ対応
  • sort()も実装(マージソート)
  • VC++9.0(32/64bit)、g++4.4.0で動作確認済み
  • 一応ドキュメントも書いた

コンテナ実装の参考になればと。
気が向いたら解説書きます。