電卓コンパイラできた
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 }