電卓コンパイラできた

echo '8+7*3+4-8/2-9' | ./calc > t.ll
rm -f t.bc
llvm-as t.ll
lli t.bc
20

意味はないが!


ちなみにcaperのセマンティックアクションを
こんな感じにした。

struct SemanticAction {
	typedef llvm::Value* value_t;

	llvm::BasicBlock*	bb;
	int					regi;

	SemanticAction( llvm::BasicBlock* b ) { bb = b; regi = 0; }

	void make_name( char* p )
	{
		sprintf( p, "reg%d", regi );
		regi++;
	}

	void syntax_error(){}
	void stack_overflow(){}

	template < class T >
	void downcast( T& x, T y ) { x = y; }

	template < class T>
	void upcast( T& x, T y ) { x = y; }

	value_t Identity( value_t n ) { return n; }

	value_t MakeAdd( value_t x, value_t y )
	{
		char name[256]; make_name( name );
		llvm::Instruction* p = llvm::BinaryOperator::create(
			llvm::Instruction::Add, x, y, name );
		bb->getInstList().push_back(p);
		return p;
	}

	value_t MakeSub( value_t x, value_t y )
	{
		char name[256]; make_name( name );
		llvm::Instruction* p = llvm::BinaryOperator::create(
			llvm::Instruction::Sub, x, y, name );
		bb->getInstList().push_back(p);
		return p;
	}

	value_t MakeMul( value_t x, value_t y )
	{
		char name[256]; make_name( name );
		llvm::Instruction* p = llvm::BinaryOperator::create(
			llvm::Instruction::Mul, x, y, name );
		bb->getInstList().push_back(p);
		return p;
	}
	value_t MakeDiv( value_t x, value_t y )
	{
		char name[256]; make_name( name );
		llvm::Instruction* p = llvm::BinaryOperator::create(
			llvm::Instruction::SDiv, x, y, name );
		bb->getInstList().push_back(p);
		return p;
	}
};

電卓だからこそ可能って話だけど。
(BasicBlockの更新がいらないから)


出力コードはこんなん。

; ModuleID = 'test'
@format0 = internal constant [4 x i8] c"%d\0A\00"

declare i32 @printf(i8*, ...)

define void @puti(i32 %arg0) {
  %format0_address = getelementptr [4 x i8]* @format0, i32 0, i32 0
  call i32 (i8*, ...)* @printf( i8* %format0_address, i32 %arg0 )
  ret void
}

define i32 @main() {
EntryBlock:
  %reg0 = mul i32 7, 3
  %reg1 = add i32 8, %reg0
  %reg2 = add i32 %reg1, 4
  %reg3 = sdiv i32 8, 2
  %reg4 = sub i32 %reg2, %reg3
  %reg5 = sub i32 %reg4, 9
  call void @puti( i32 %reg5 )
  ret i32 0
}