もしも面接官があなたのブログを見ていたら。

http://www.itmedia.co.jp/news/articles/0610/25/news070.html


うーん。もし、Jが会社バレとか面接官バレとかしたらどうなるかは際どいところのような気が。

面接官(以下、面)「あなたのブログ拝見させていただきました。」
w「ブログじゃないと書いておいたはずですが?」
面「めっちゃ喧嘩腰やん!」
w「…」
面「ところで、すごくおっぱいが大きいけど、得するの?」
w「いや、おっぱいなんて無いですが?」
面「ふーん。なるほど。ぺたんこ…と」
w「いや、ぺたんこて」
面「ふむふむ…ところで、ぺたんこ属性はありますか?」
w「面接で属性を尋ねるのはセクハラにあたりますよ」*1
面「いや、でも、ほら、ブログに…シエスタよりもルイズのほうがよいって…」
w「書いてないです」

参考


まあ…それはいいとして。
特にオチは無い。

*1:欧米では最近、面接中に属性を尋ねた面接官がセクハラで訴えられるケースが増えており、その多くで、実際に有罪判決が下っている

expression template

go-(http://d.hatena.ne.jp/w_o/20061018#p1)を書いてたときに、右結合ができなくて、無理矢理左結合の演算子を右結合にするというのをやったんだけど、多分それがexpression templateなんじゃないかとふと思ったのだった。


expression template については適当にぐぐって(ぐぐられるexpression templateたち)。要するに、構文木がいじれちゃうわけ。まあ、なんてことかしら。構文木を変換するマクロを書けるのは、Lispだけの特権じゃないんだよ。

なんか例を書こうと思ったけどめんどうなのでやめた。


go- でいうと、gos.hppの

static inline detail::ConsConstructor<CScmObj> operator >>(CScmObj a, CScmObj b) {
	return detail::ConsConstructor<CScmObj>(a,b);
}
static inline detail::ConsConstructor<CScmObj> operator >>(Symbol a, CScmObj b) {
	return detail::ConsConstructor<CScmObj>( CScmObj(a), b );
}

このへんとか

template <typename T>
struct ConsConstructor {
	T car;
	CScmObj cdr;

	CScmObj construct( CScmObj cdr ) {
		ScmPair *pair = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair, this->cdr );
		SCM_SET_CDR( pair, cdr );

		return car.construct( CScmObj( reinterpret_cast<ScmObj>(pair)) );
	}

	ConsConstructor ( const ConsConstructor<T> &c )
		:car(c.car), cdr(c.cdr) {}

	ConsConstructor(T car,CScmObj cdr)
		:car(car), cdr(cdr) {}

	operator CScmObj() {
		ScmPair *pair = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair, cdr );
		SCM_SET_CDR( pair, SCM_NIL );
		
		return car.construct( CScmObj(reinterpret_cast<ScmObj>(pair)) );
	}
};
template <>
struct ConsConstructor<CScmObj> {
	CScmObj car;
	CScmObj cdr;

	CScmObj construct( CScmObj cdr ) {
		ScmPair *pair1 = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair1, this->cdr );
		SCM_SET_CDR( pair1, cdr );
		ScmPair *pair2 = SCM_NEW(ScmPair);

		SCM_SET_CAR( pair2, car );
		SCM_SET_CDR( pair2, reinterpret_cast<ScmObj>(pair1) );

		return reinterpret_cast<ScmObj>(pair2);
	}

	ConsConstructor ( const ConsConstructor<CScmObj> &c )
		:car(c.car), cdr(c.cdr) {}

	ConsConstructor(CScmObj car,CScmObj cdr)
		:car(car), cdr(cdr) {}

	operator CScmObj() {
		ScmPair *last = SCM_NEW(ScmPair);
		SCM_SET_CAR( last, cdr );
		SCM_SET_CDR( last, SCM_NIL );

		ScmPair *pair = SCM_NEW(ScmPair);
		SCM_SET_CAR( pair, car );
		SCM_SET_CDR( pair, (ScmObj)last );

		return reinterpret_cast<ScmObj>(pair);
	}
};

このへん。全く説明無しなんだけど…operator >>が構文木を作ってるだけ。評価はしない。
そうすると、

a >> b >> c >> d

こういうのが、

((a >> b) >> c) >> d

     /\
    /\ d
   /\ c
  a  d

こうなるよね。そんでconstruct()すると…やっぱめんどうだからいいや。説明になってねー。


http://www.radiumsoftware.com/0306.html#030611
おっと。手を出してはいけないらしい。

asmxp(あせむえっくすぴー) -- assembly expression

http://morihyphen.hp.infoseek.co.jp/files/asmxp.tar.gz
でも出しちゃうよ!
asmxpは式感覚でJITアセンブリが書けちゃうなんかです。昨今のらいとうぇいつならんげーじとかそういうネタふりでした。

int
main( int argc, char **argv )
{
	using namespace asmxp;
	using namespace asmxp::x86;

	if ( argc < 2 )
		throw "e-";

	std::ofstream out( argv[1] );
	if ( !out )
		throw argv[1];

	typedef std::vector<unsigned char> v_t;
	v_t v;

	(mov( eax, *(eax+4))
	 | add( eax, *(eax+4) )
	 | mov( *(eax+4), eax)
	 | add( *(ecx+4), eax )
	 | mov(ecx,eax)
	 | add(ecx,eax)
	 | mov(eax,0x08)
	 | add(eax,0x08)
	 | mov(*dword(4),eax)
	 | add(*dword(4),eax)
	 | mov(esi,*dword(4))
	 | add(ecx,*dword(4))
	 | mov(*dword(4),8)
	 | add(*dword(4),8)
	 | mov(*(eax + 4),8)
	 | add(*(ebp + 4),8)).emit( std::back_inserter(v) );
	std::ostream_iterator<char> os(out);

	std::copy( v.begin(), v.end(), os );
}

こんな感じでアレするとアレだよ!なんかそんなこんなあんな。


expression template の力によって、

int test( char *buf )
{
	using namespace asmxp;
	using namespace asmxp::x86;
	int addr = 4;

	( mov(eax,0x08) | mov(ecx, *dword(addr) ) ).emit( buf );

	return 0;
}

こんなのは、

_Z13constant_testPc:
.LFB1785:
	pushl	%ebp
.LCFI2:
	movl	%esp, %ebp
.LCFI3:
	movl	8(%ebp), %eax
	movb	$-72, (%eax)
	movb	$8, 1(%eax)
	movb	$0, 2(%eax)
	movb	$0, 3(%eax)
	movb	$0, 4(%eax)
	movb	$-117, 5(%eax)
	movb	$13, 6(%eax)
	movb	$4, 7(%eax)
	movb	$0, 8(%eax)
	movb	$0, 9(%eax)
	movb	$0, 10(%eax)
	xorl	%eax, %eax
	popl	%ebp
	ret

こんなんにコンパイルされます。GCCは偉い。


いまのところmov,add,xor,sub,sbb,adc,or,andぐらい使えます。SIBが使えないのでもうちょっと頑張ると思ったけどネムいので寝ますおやすみなさい。説明はラベルが使えるぐらいになったら書く。
おっと、ディスプレースメント無しのレジスタ間接が無い。

asmxp_detail.hpp:23:   instantiated from 'OutputIterator asmxp::detail::instr_compound<Lhs, Rhs>::emit(OutputIterator) [with OutputIterator = std::back_insert_iterator<std::vector<unsigned char, std::allocator<unsigned char> > 
 >, Lhs = asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::detail::instr_compound<asmxp::x86::detail::mov_instr<asmxp::x86::detail::ref_reg_with_disp32, asmxp::x86::detail::ref_reg_with_disp32>, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::reg32_eax_value_t, asmxp::x86::detail::ref_reg_with_disp32, 0u> > 
, asmxp::x86::detail::mov_instr<asmxp::x86::detail::ref_reg_with_disp32, asmxp::x86::detail::reg32_eax_value_t> > 
, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::ref_reg_with_disp32, asmxp::x86::detail::reg32_eax_value_t, 0u> > 
, asmxp::x86::detail::mov_instr<asmxp::x86::detail::reg32_index_value_t, asmxp::x86::detail::reg32_eax_value_t> > 
, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::reg32_index_value_t, asmxp::x86::detail::reg32_eax_value_t, 0u> > 
, asmxp::x86::detail::mov_instr<asmxp::x86::detail::reg32_eax_value_t, unsigned int> > 
, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::reg32_eax_value_t, unsigned int, 0u> > 
, asmxp::x86::detail::mov_instr<asmxp::x86::detail::ref_addr32<asmxp::x86::detail::addr_ref<32> > 
, asmxp::x86::detail::reg32_eax_value_t> > 
, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::ref_addr32<asmxp::x86::detail::addr_ref<32> > 
, asmxp::x86::detail::reg32_eax_value_t, 0u> > 
, asmxp::x86::detail::mov_instr<asmxp::x86::detail::reg32_index_value_t, asmxp::x86::detail::ref_addr32<asmxp::x86::detail::addr_ref<32> > 
 > > 
, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::reg32_index_value_t, asmxp::x86::detail::ref_addr32<asmxp::x86::detail::addr_ref<32> > 
, 0u> > 
, asmxp::x86::detail::mov_instr<asmxp::x86::detail::ref_addr32<asmxp::x86::detail::addr_ref<32> > 
, unsigned int> > 
, asmxp::x86::detail::arith_logic_instr<asmxp::x86::detail::ref_addr32<asmxp::x86::detail::addr_ref<32> > 
, unsigned int, 0u> > 
, Rhs = asmxp::x86::detail::mov_instr<asmxp::x86::detail::ref_reg_with_disp32, unsigned int>]'

僕もすごいエラーメッセージが出せるようになりました!