ExprASTPtr NumberExprOperation::operator_comp(ASTContext ctx, MathOperator op, ExprASTPtr lval, ExprASTPtr rval) { llvm::Value * LHS = lval->getval(ctx); llvm::Value * RHS = rval->getval(ctx); llvm::IRBuilder<> builder(ctx.block); llvm::Value * result; switch(op){ case OPERATOR_LESS: result = builder.CreateICmpSLT(LHS,RHS); break; case OPERATOR_LESSEQU: result = builder.CreateICmpSLE(LHS,RHS); break; case OPERATOR_GREATER: result = builder.CreateICmpSGT(LHS,RHS); break; case OPERATOR_GREATEREQUL: result = builder.CreateICmpSGE(LHS,RHS); break; case OPERATOR_EQUL: result = builder.CreateICmpEQ(LHS,RHS); break; } //TODO , 构造临时 Number 对象. return lval->type(ctx)->createtemp(ctx,result,NULL); }
ExprASTPtr StringExprOperation::operator_comp(ASTContext ctx,MathOperator op, ExprASTPtr lval, ExprASTPtr rval) { llvm::Value * LHS = lval->getval(ctx); llvm::Value * RHS = rval->getval(ctx); llvm::IRBuilder<> builder(ctx.block); llvm::Value * result; switch(op){ case OPERATOR_EQUL:{// call strcmp llvm::Constant * func_strcmp = qbc::getbuiltinprotype(ctx,"strcmp"); result = builder.CreateCall(func_strcmp, {LHS, RHS}); // 返回值是 int , not long , 执行转化. result = builder.CreateIntCast(result, qbc::getplatformlongtype(), true); result = builder.CreateICmpEQ(result, qbc::getconstlong(0)); } break; default: debug("string comp not supported"); exit(1); } //TODO , 构造临时 Number 对象. return NumberExprTypeAST::GetNumberExprTypeAST()->createtemp(ctx,result,NULL); }
// 数字除法. ExprASTPtr NumberExprOperation::operator_div(ASTContext ctx, ExprASTPtr lval, ExprASTPtr rval) { llvm::Value * LHS = lval->getval(ctx); llvm::Value * RHS = rval->getval(ctx); llvm::IRBuilder<> builder(ctx.block); llvm::Value * result = builder.CreateSDiv(LHS,RHS); //TODO , 构造临时 Number 对象. return lval->type(ctx)->createtemp(ctx,result,NULL); }
// 字符串加法. ExprASTPtr StringExprOperation::operator_add(ASTContext ctx, ExprASTPtr lval, ExprASTPtr rval) { llvm::IRBuilder<> builder(ctx.block); llvm::Constant * llvmfunc_calloc = qbc::getbuiltinprotype(ctx,"malloc"); llvm::Constant * llvmfunc_strlen = qbc::getbuiltinprotype(ctx,"strlen"); llvm::Constant * llvmfunc_strcpy = qbc::getbuiltinprotype(ctx,"strcpy"); llvm::Constant * llvmfunc_strcat = qbc::getbuiltinprotype(ctx,"strcat"); llvm::Value * string_left_length = builder.CreateCall(llvmfunc_strlen,lval->getval(ctx)); llvm::Value * string_right_length = builder.CreateCall(llvmfunc_strlen,rval->getval(ctx)); llvm::Value * result_length = builder.CreateAdd(string_left_length, string_right_length); llvm::Value * resultstring = builder.CreateCall(llvmfunc_calloc,result_length); builder.CreateCall(llvmfunc_strcpy, {resultstring, lval->getval(ctx)}); builder.CreateCall(llvmfunc_strcat, {resultstring, rval->getval(ctx)}); return lval->type(ctx)->createtemp(ctx, resultstring, NULL); }
// call get on lval and rval, then wrapper an value to NumberExprAST; ExprASTPtr NumberExprOperation::operator_assign(ASTContext ctx, NamedExprASTPtr lval, ExprASTPtr rval) { llvm::Value * LHS = lval->getptr(ctx); llvm::Value * RHS = rval->getval(ctx); llvm::IRBuilder<> builder(ctx.block); // 生成赋值语句,因为是简单的整型赋值,所以可以直接生成而不用调用 operator==() LHS = builder.CreateBitCast(LHS,qbc::getplatformlongtype()->getPointerTo()); builder.CreateStore(RHS,LHS); return lval->type(ctx)->createtemp(ctx,LHS,NULL); }
//TODO 添加 free + strdup 指令. ExprASTPtr StringExprOperation::operator_assign(ASTContext ctx, NamedExprASTPtr lval, ExprASTPtr rval) { llvm::IRBuilder<> builder(ctx.block); llvm::Constant * llvmfunc_free = qbc::getbuiltinprotype(ctx,"free"); llvm::Constant * llvmfunc_strdup = qbc::getbuiltinprotype(ctx,"strdup"); builder.CreateCall(llvmfunc_free,lval->getval(ctx)); llvm::Value * dupedstr = builder.CreateCall(llvmfunc_strdup,rval->getval(ctx),"dumpstring"); builder.CreateStore(dupedstr,lval->getptr(ctx)); return lval; }
llvm::Value* CallExprAST::getval(ASTContext ctx) { ExprASTPtr tmp = calltarget->type(ctx)->getop()->operator_call(ctx,calltarget,callargs); return tmp->getval(ctx); }