From 8b2dd60153466fae52740aa04b62bf78eadf28a6 Mon Sep 17 00:00:00 2001 From: llh21 Date: Wed, 20 Dec 2023 14:40:16 +0800 Subject: [PATCH] Part3 --- src/SysYFIRBuilder/IRBuilder.cpp | 925 +++++++++++++++++++++++++++++-- 1 file changed, 874 insertions(+), 51 deletions(-) diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 951bd45..91b0749 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -1,81 +1,904 @@ #include "IRBuilder.h" - +using namespace std; namespace SysYF { -namespace IR -{ + namespace IR + { #define CONST_INT(num) ConstantInt::create(num, module) #define CONST_FLOAT(num) ConstantFloat::create(num, module) -// You can define global variables here -// to store state - -// store temporary value -Ptr tmp_val = nullptr; - -// types -Ptr VOID_T; -Ptr INT1_T; -Ptr INT32_T; -Ptr FLOAT_T; -Ptr INT32PTR_T; -Ptr FLOATPTR_T; - -void IRBuilder::visit(SyntaxTree::Assembly &node) { - VOID_T = Type::get_void_type(module); - INT1_T = Type::get_int1_type(module); - INT32_T = Type::get_int32_type(module); - FLOAT_T = Type::get_float_type(module); - INT32PTR_T = Type::get_int32_ptr_type(module); - FLOATPTR_T = Type::get_float_ptr_type(module); - for (const auto &def : node.global_defs) { - def->accept(*this); - } -} + // You can define global variables here + // to store state + enum + { + INT = 0, + VOID, + STRING, + BOOL, + FLOAT + }; + + std::vector tmp_condbb_while; + std::vector tmp_falsebb_while; + std::vector tmp_truebb; + std::vector tmp_falsebb; + std::map> type_map; // 把类型转换成类型指针 + // store temporary value + Ptr tmp_val = nullptr; + vector> init_list; + // types + Ptr VOID_T; + Ptr INT1_T; + Ptr INT32_T; + Ptr FLOAT_T; + Ptr INT32PTR_T; + Ptr FLOATPTR_T; + + #define LVal_to_RVal(lval) \ + if(lval->get_type()==INT32PTR_T || lval->get_type()==FLOATPTR_T){\ + lval=builder->create_load(lval);\ + } + + void IRBuilder::visit(SyntaxTree::Assembly &node) + { + VOID_T = Type::get_void_type(module); + INT1_T = Type::get_int1_type(module); + INT32_T = Type::get_int32_type(module); + FLOAT_T = Type::get_float_type(module); + INT32PTR_T = Type::get_int32_ptr_type(module); + FLOATPTR_T = Type::get_float_ptr_type(module); + // type mapping + type_map[SyntaxTree::Type::VOID] = VOID_T; + type_map[SyntaxTree::Type::BOOL] = INT1_T; + type_map[SyntaxTree::Type::INT] = INT32_T; + type_map[SyntaxTree::Type::FLOAT] = FLOAT_T; + + for (const auto &def : node.global_defs) + { + def->accept(*this); + } + } + + // You need to fill them + + void IRBuilder::visit(SyntaxTree::InitVal &node) + { + if (!node.isExp) // is not exp, values are in node.elementList + { + for (const auto &element : node.elementList) + { + element->accept(*this); // 这里是嵌套定义,读取的是elementList里面的element,肯能会在下一次进入的时候赋值给元素 + } + } + else // is exp, values are in node.expr + { + node.expr->accept(*this); // 有可能是计算表达式,也有可能是赋值语句 + LVal_to_RVal(tmp_val); + init_list.push_back(tmp_val); // 把tmp_val放到init_list里面 + } + } // init values + + void IRBuilder::visit(SyntaxTree::FuncDef &node) // 考虑一下什么时候要用scope.enter()和scope.exit() + { + auto return_type = type_map[node.ret_type]; + auto func_name = node.name; + // deal with param_list + PtrVec params; + for (const auto ¶m : node.param_list->params) + { + if (param->array_index.empty()) // not array + { + params.push_back(type_map[param->param_type]); + } + else + { + params.push_back(type_map[param->param_type]->get_pointer_element_type()); // 这里是指针 + } + } + // build function + auto Func_Type = FunctionType::create(return_type, params); + auto func = Function::create(Func_Type, func_name, module); + scope.push(func_name, func); + // deal with block + auto block = BasicBlock::create(module, "entry", func); + builder->set_insert_point(block); + scope.enter(); + // read param_list + node.param_list->accept(*this); + // read body + bool is_return = false; + for (const auto &stmt : node.body->body) + { + stmt->accept(*this); + if (dynamic_cast(stmt.get())) + { + is_return = true; + break; // 如果有return语句,就不用再往下读了 + } + } + scope.exit(); + // 处理一些不写返回值的情况(不会有代码不写返回值吧,不会吧不会吧) + if (!is_return) + { + switch (node.ret_type) + { + case SyntaxTree::Type::VOID: + builder->create_void_ret(); + case SyntaxTree::Type::INT: + builder->create_ret(CONST_INT(0)); + case SyntaxTree::Type::FLOAT: + builder->create_ret(CONST_FLOAT(0)); + default: + break; + } + } + } + + void IRBuilder::visit(SyntaxTree::FuncFParamList &node) + { + auto func_arg_list = module->get_functions().back()->arg_begin(); // 取出堆栈中最后一个函数的参数列表,并且指向第一个参数 + for (const auto ¶m : node.params) + { + param->accept(*this); // 获取数据 + // 处理获取的数据 + if ((*func_arg_list)->get_type()->is_pointer_type()) // 如果是指针类型,传址调用 + { + scope.push(param->name, *func_arg_list); // 这里是指针 + } + else // 传值调用,要分配空间 + { + auto alloca = builder->create_alloca((*func_arg_list)->get_type()); + builder->create_store(*func_arg_list, alloca); + scope.push(param->name, alloca); + } + func_arg_list++; + } + } + + void IRBuilder::visit(SyntaxTree::FuncParam &node) + { + auto param_name = node.name; + auto param_type = node.param_type; + auto param_value = node.array_index; + // deal with array_index + if (!node.array_index.empty()) // array + { + for (const auto &exp : param_value) + { + exp->accept(*this); + } + } + } + + void IRBuilder::visit(SyntaxTree::VarDef &node) + { + bool is_const = node.is_constant; + auto var_name = node.name; + auto var_type = type_map[node.btype]; + auto is_initialized = node.is_inited; + auto length = node.array_length; + auto init_val = node.initializers; + // deal with array_length + if (length.empty()) // 说明不是数组 + { + if (scope.in_global()) // 如果是全局变量 + { + auto global_var = GlobalVariable::create(var_name, module, var_type, is_const, ConstantZero::create(var_type, module)); + if (is_initialized) + { + init_val->accept(*this); + LVal_to_RVal(tmp_val); + builder->create_store(tmp_val, global_var); + } + else if (is_const) // 说明是const,但是没有初始化 + cout << "const variable must be initialized" << endl; + scope.push(var_name, global_var); + } + else // 如果是局部变量 + { + auto var = builder->create_alloca(var_type); + if (is_initialized) + { + init_val->accept(*this); + LVal_to_RVal(tmp_val); + builder->create_store(tmp_val , var); + } + else if (is_const) // 说明是const,但是没有初始化 + cout << "const variable must be initialized" << endl; + scope.push(var_name, var); + } + } + else // 数组 + { + auto arrayType = ArrayType::get(var_type, length.size()); + + if (scope.in_global()) // 如果是全局变量 + { + auto global_array = GlobalVariable::create(var_name, module, arrayType, is_const, ConstantZero::create(var_type, module)); + + if (is_initialized) + { + init_list.clear(); // 清空init_list + init_val->accept(*this); // 把init_val里面的值放到init_list里面 + while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度,就把init_list其他的值补上0 + { + init_list.push_back(ConstantZero::create(type_map[node.btype], module)); + } + // initilize + for (auto i = 0; i < static_cast(init_list.size()); i++) + { + auto GEP = builder->create_gep(global_array, {CONST_INT(0), CONST_INT(i)}); + builder->create_store(init_list[i], GEP); + } + } + else if (is_const) // 说明是const,但是没有初始化 + cout << "const variable must be initialized" << endl; + + scope.push(var_name, global_array); + } + else + { + auto array = builder->create_alloca(arrayType); + + if (is_initialized) + { + init_list.clear(); // 清空init_list + init_val->accept(*this); // 把init_val里面的值放到init_list里面 + while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度,就把init_list其他的值补上0 + { + init_list.push_back(ConstantZero::create(type_map[node.btype], module)); + } + // initilize + for (int i = 0; i < static_cast(init_list.size()); i++) + { + auto GEP = builder->create_gep(array, {CONST_INT(0), CONST_INT(i)}); + builder->create_store(init_list[i], GEP); + } + } + else if (is_const) // 说明是const,但是没有初始化 + cout << "const variable must be initialized" << endl; + + scope.push(var_name, array); + } + } + } + + void IRBuilder::visit(SyntaxTree::LVal &node) + { + auto name = node.name; + auto index = node.array_index; + auto lval = scope.find(name, false); + if (lval) + { + if (!index.empty()) + { + for (const auto &exp : index) + { + exp->accept(*this); + auto tmp = tmp_val; + auto GEP = builder->create_gep(lval, {tmp}); + lval = GEP; + } + } + else + { // 从符号表中取出的是字面值 + tmp_val = lval; + } + } + else + { + std::cout << "LVal pointer or literal not found" << std::endl; + } + } // lval: Identifier|Identifier LeftBracket exp RightBracket + + void IRBuilder::visit(SyntaxTree::AssignStmt &node) + { + node.target->accept(*this); + auto target = builder->create_load(tmp_val);//? + auto name = target->get_name(); + node.value->accept(*this);//? + LVal_to_RVal(tmp_val); + auto value = tmp_val; -// You need to fill them + builder->create_store(value, target); + } -void IRBuilder::visit(SyntaxTree::InitVal &node) {} + void IRBuilder::visit(SyntaxTree::Literal &node) + { + auto type = node.literal_type; + switch (type) + { + case SyntaxTree::Type::INT: + tmp_val = CONST_INT(node.int_const); + case SyntaxTree::Type::FLOAT: + tmp_val = CONST_FLOAT(node.float_const); + default: + break; + } + } // literal: IntegerLiteral|FloatLiteral -void IRBuilder::visit(SyntaxTree::FuncDef &node) {} + void IRBuilder::visit(SyntaxTree::ReturnStmt &node) + { + auto return_value = node.ret; + if (return_value != nullptr) + { + return_value->accept(*this); + LVal_to_RVal(tmp_val); + auto value_type = tmp_val->get_type(); + auto ret_type = module->get_functions().back()->get_return_type(); + // 类型检查 + if(ret_type == INT32_T) + { + if(value_type == FLOAT_T) + tmp_val = builder->create_fptosi(tmp_val, INT32_T); + else if(value_type == INT1_T) + tmp_val = builder->create_zext(tmp_val, INT32_T); + } + auto value = tmp_val; + builder->create_ret(value); + } + else + { + builder->create_void_ret(); + } + } -void IRBuilder::visit(SyntaxTree::FuncFParamList &node) {} + void IRBuilder::visit(SyntaxTree::BlockStmt &node) + { + scope.enter(); + for (const auto &stmt : node.body) + { + stmt->accept(*this); + if (dynamic_cast(stmt.get()) != nullptr || dynamic_cast(stmt.get()) != nullptr || dynamic_cast(stmt.get()) != nullptr) + { // break,continue,return后面的语句不再编译 + break; + } + } + scope.exit(); + } -void IRBuilder::visit(SyntaxTree::FuncParam &node) {} + void IRBuilder::visit(SyntaxTree::EmptyStmt &node) + { + node.accept(*this); + } -void IRBuilder::visit(SyntaxTree::VarDef &node) {} + void IRBuilder::visit(SyntaxTree::ExprStmt &node) + { + node.exp->accept(*this); + } -void IRBuilder::visit(SyntaxTree::LVal &node) {} + void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) + { + node.rhs->accept(*this); + LVal_to_RVal(tmp_val); + auto rhs = tmp_val; + // 整数 + if (rhs->get_type() == INT32_T) + { + auto UnaryCondExpr = builder->create_icmp_eq(rhs, CONST_INT(0)); + scope.push("CondExpr", UnaryCondExpr); + } + else + { + auto UnaryCondExpr = builder->create_fcmp_eq(rhs, CONST_FLOAT(0)); + scope.push("CondExpr", UnaryCondExpr); + } + } -void IRBuilder::visit(SyntaxTree::AssignStmt &node) {} + void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) + { + node.rhs->accept(*this); + LVal_to_RVal(tmp_val); + auto rhs = tmp_val; + auto rhs_type = rhs->get_type(); + node.lhs->accept(*this); + LVal_to_RVal(tmp_val); + auto lhs = tmp_val; + auto lhs_type = lhs->get_type(); -void IRBuilder::visit(SyntaxTree::Literal &node) {} + if (node.op == SyntaxTree::BinaryCondOp::LAND) + { + auto falseBB = scope.find("falseBB", 0); + auto trueBB = BasicBlock::create(module, + "trueBB_lhs", module->get_functions().back()); -void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {} + if (lhs_type == INT1_T) + { + builder->create_cond_br(lhs, trueBB, dynamic_pointer_cast(falseBB)); + } + else if (lhs_type == INT32_T) + { + auto lhs_cond = builder->create_icmp_eq(lhs, CONST_INT(0)); + builder->create_cond_br(lhs_cond, trueBB, dynamic_pointer_cast(falseBB)); + } + else if (lhs_type == FLOAT_T) + { + auto lhs_cond = builder->create_fcmp_eq(lhs, CONST_FLOAT(0)); + builder->create_cond_br(lhs_cond, trueBB, dynamic_pointer_cast(falseBB)); + } + builder->set_insert_point(trueBB); + node.rhs->accept(*this); + } + else if (node.op == SyntaxTree::BinaryCondOp::LOR) + { + auto trueBB = scope.find("trueBB", 0); + auto falseBB = BasicBlock::create(module, + "falseBB_lhs", module->get_functions().back()); -void IRBuilder::visit(SyntaxTree::BlockStmt &node) {} + if (lhs_type == INT1_T) + { + builder->create_cond_br(lhs, dynamic_pointer_cast(trueBB), falseBB); + } + else if (lhs_type == INT32_T) + { + auto lhs_cond = builder->create_icmp_eq(lhs, CONST_INT(0)); + builder->create_cond_br(lhs_cond, dynamic_pointer_cast(trueBB), falseBB); + } + else if (lhs_type == FLOAT_T) + { + auto lhs_cond = builder->create_fcmp_eq(lhs, CONST_FLOAT(0)); + builder->create_cond_br(lhs_cond, dynamic_pointer_cast(trueBB), falseBB); + } + builder->set_insert_point(falseBB); + node.rhs->accept(*this); + } + else + { + auto expr_type = FLOAT_T; -void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {} + if (lhs_type == INT1_T && rhs_type == INT32_T) + { + lhs = dynamic_pointer_cast(builder->create_zext(lhs, INT32_T)); + } + else if (lhs_type == INT1_T && rhs_type == FLOAT_T) + { + lhs = dynamic_pointer_cast(builder->create_zext(lhs, FLOAT_T)); + } + else if (lhs_type == INT32_T && rhs_type == INT1_T) + { + rhs = dynamic_pointer_cast(builder->create_zext(rhs, INT32_T)); + } + else if (lhs_type == FLOAT_T && rhs_type == INT1_T) + { + rhs = dynamic_pointer_cast(builder->create_zext(rhs, FLOAT_T)); + } + else if (lhs_type == FLOAT_T && rhs_type == INT32_T) + { + rhs = dynamic_pointer_cast(builder->create_sitofp(rhs, FLOAT_T)); + } + else if (lhs_type == INT32_T && rhs_type == FLOAT_T) + { + lhs = dynamic_pointer_cast(builder->create_sitofp(lhs, FLOAT_T)); + } + else if (lhs_type == INT1_T && rhs_type == INT1_T) + { + lhs = dynamic_pointer_cast(builder->create_zext(lhs, INT32_T)); + rhs = dynamic_pointer_cast(builder->create_zext(rhs, INT32_T)); + } + // 整数 + if (rhs->get_type() == INT32_T) + { + switch (node.op) + { + case SysYF::SyntaxTree::BinaryCondOp::LT: + { + tmp_val = builder->create_icmp_lt(lhs, rhs); + break; + } -void IRBuilder::visit(SyntaxTree::ExprStmt &node) {} + case SysYF::SyntaxTree::BinaryCondOp::LTE: + { + tmp_val = builder->create_icmp_le(lhs, rhs); + break; + } -void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {} + case SysYF::SyntaxTree::BinaryCondOp::GT: + { + tmp_val = builder->create_icmp_gt(lhs, rhs); + break; + } -void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {} + case SysYF::SyntaxTree::BinaryCondOp::GTE: + { + tmp_val = builder->create_icmp_ge(lhs, rhs); + break; + } + case SysYF::SyntaxTree::BinaryCondOp::EQ: + { + tmp_val = builder->create_icmp_eq(lhs, rhs); + } + default: + break; + } + } + else + { + switch (node.op) + { + case SysYF::SyntaxTree::BinaryCondOp::LT: + { + tmp_val = builder->create_fcmp_lt(lhs, rhs); + break; + } -void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {} + case SysYF::SyntaxTree::BinaryCondOp::LTE: + { + tmp_val = builder->create_fcmp_le(lhs, rhs); + break; + } -void IRBuilder::visit(SyntaxTree::UnaryExpr &node) {} + case SysYF::SyntaxTree::BinaryCondOp::GT: + { + tmp_val = builder->create_fcmp_gt(lhs, rhs); + break; + } -void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {} + case SysYF::SyntaxTree::BinaryCondOp::GTE: + { + tmp_val = builder->create_fcmp_ge(lhs, rhs); + break; + } + case SysYF::SyntaxTree::BinaryCondOp::EQ: + { + tmp_val = builder->create_fcmp_eq(lhs, rhs); + } + default: + break; + } + } + scope.push("CondExpr", tmp_val); + } + } + void IRBuilder::visit(SyntaxTree::BinaryExpr &node) + { + // 整数 + node.rhs->accept(*this); + LVal_to_RVal(tmp_val); + auto rhs = tmp_val; + auto rhs_type = rhs->get_type(); + node.lhs->accept(*this); + LVal_to_RVal(tmp_val); + auto lhs = tmp_val; + auto lhs_type = lhs->get_type(); + if (lhs_type == FLOAT_T && rhs_type == INT32_T) + { + rhs = dynamic_pointer_cast(builder->create_sitofp(rhs, FLOAT_T)); + } + else if (lhs_type == INT32_T && rhs_type == FLOAT_T) + { + lhs = dynamic_pointer_cast(builder->create_sitofp(lhs, FLOAT_T)); + } + auto expr_type = lhs->get_type(); -void IRBuilder::visit(SyntaxTree::IfStmt &node) {} + // 计算出可以直接计算的值 + if ((dynamic_pointer_cast(lhs) || dynamic_pointer_cast(lhs)) && (dynamic_pointer_cast(rhs) || dynamic_pointer_cast(rhs))) + { // 简单字面量计算 + int lhs_int; + int rhs_int; + float lhs_float; + float rhs_float; + if (expr_type == INT32_T) + { + lhs_int = dynamic_pointer_cast(lhs)->get_value(); + rhs_int = dynamic_pointer_cast(rhs)->get_value(); + } + else + { + lhs_float = dynamic_pointer_cast(lhs)->get_value(); + rhs_float = dynamic_pointer_cast(rhs)->get_value(); + } -void IRBuilder::visit(SyntaxTree::WhileStmt &node) {} + switch (node.op) + { + case SyntaxTree::BinOp::PLUS: + if (expr_type == INT32_T) + { + tmp_val = CONST_INT(lhs_int + rhs_int); + } + else + { + tmp_val = CONST_FLOAT(lhs_float + rhs_float); + } + break; + case SyntaxTree::BinOp::MINUS: + if (expr_type == INT32_T) + { + tmp_val = CONST_INT(lhs_int - rhs_int); + } + else + { + tmp_val = CONST_FLOAT(lhs_float - rhs_float); + } + break; + case SyntaxTree::BinOp::MULTIPLY: + if (expr_type == INT32_T) + { + tmp_val = CONST_INT(lhs_int * rhs_int); + } + else + { + tmp_val = CONST_FLOAT(lhs_float * rhs_float); + } + break; + case SyntaxTree::BinOp::DIVIDE: + if (expr_type == INT32_T) + { + tmp_val = CONST_INT(lhs_int / rhs_int); + } + else + { + tmp_val = CONST_FLOAT(lhs_float / rhs_float); + } + break; + case SyntaxTree::BinOp::MODULO: + if (expr_type == INT32_T) + { + tmp_val = CONST_INT(lhs_int % rhs_int); + } + else + { + tmp_val = CONST_INT(static_cast(lhs_float) % static_cast(rhs_float)); + } + break; + } + return; + } + if (lhs_type == INT32_T) + { -void IRBuilder::visit(SyntaxTree::BreakStmt &node) {} + switch (node.op) + { + case SyntaxTree::BinOp::PLUS: + { + builder->create_iadd(lhs, rhs); + break; + } + case SyntaxTree::BinOp::MINUS: + { + builder->create_isub(lhs, rhs); + break; + } + case SyntaxTree::BinOp::MULTIPLY: + { + builder->create_imul(lhs, rhs); + break; + } + case SyntaxTree::BinOp::DIVIDE: + { + builder->create_isdiv(lhs, rhs); + break; + } + case SyntaxTree::BinOp::MODULO: + { + builder->create_isrem(lhs, rhs); + break; + } + } + } + else if (lhs_type == FLOAT_T) + { + switch (node.op) + { + case SyntaxTree::BinOp::PLUS: + { + builder->create_fadd(lhs, rhs); + break; + } + case SyntaxTree::BinOp::MINUS: + { + builder->create_fsub(lhs, rhs); + break; + } + case SyntaxTree::BinOp::MULTIPLY: + { + builder->create_fmul(lhs, rhs); + break; + } + case SyntaxTree::BinOp::DIVIDE: + { + builder->create_fdiv(lhs, rhs); + break; + } + case SyntaxTree::BinOp::MODULO: + { + // builder->create_isrem(static_pointer_cast(lhs), static_pointer_cast(rhs)); + break; + } + } + } + } -void IRBuilder::visit(SyntaxTree::ContinueStmt &node) {} + void IRBuilder::visit(SyntaxTree::UnaryExpr &node) + { + // 整数 + node.rhs->accept(*this); + LVal_to_RVal(tmp_val); + auto rhs = tmp_val; + auto rhs_type = rhs->get_type(); -} + // 直接计算的 + if (dynamic_pointer_cast(rhs) || dynamic_pointer_cast(rhs)) + { + int rhs_int; + float rhs_float; + if (rhs_type == INT32_T) + { + rhs_int = dynamic_pointer_cast(rhs)->get_value(); + } + else + { + rhs_float = dynamic_pointer_cast(rhs)->get_value(); + } + switch (node.op) + { + case SyntaxTree::UnaryOp::PLUS: + if (rhs_type == INT32_T) + { + tmp_val = CONST_INT(rhs_int); + } + else + { + tmp_val = CONST_FLOAT(rhs_float); + } + break; + case SyntaxTree::UnaryOp::MINUS: + if (rhs_type == INT32_T) + { + tmp_val = CONST_INT(-rhs_int); + } + else + { + tmp_val = CONST_FLOAT(-rhs_float); + } + break; + } + return; + } + if (rhs_type == INT32_T) + { + switch (node.op) + { + case SyntaxTree::UnaryOp::PLUS: + { + builder->create_iadd(rhs, CONST_INT(0)); + break; + } + case SyntaxTree::UnaryOp::MINUS: + { + builder->create_isub(CONST_INT(0), rhs); + break; + } + } + } + else if (rhs_type == FLOAT_T) + { + switch (node.op) + { + case SyntaxTree::UnaryOp::PLUS: + { + builder->create_fadd(rhs, CONST_FLOAT(0)); + break; + } + case SyntaxTree::UnaryOp::MINUS: + { + builder->create_fsub(CONST_FLOAT(0), rhs); + break; + } + } + } + } + + void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) + { + auto func = scope.find(node.name, true); + if (func) + { + PtrVec args{}; + + auto arg_func = dynamic_pointer_cast(func)->arg_begin(); + + for (auto &arg : node.params) + { + auto arg_func_type = (*arg_func)->get_type(); + + arg->accept(*this); + LVal_to_RVal(tmp_val); + auto value = tmp_val; + + // 数组 + if (arg_func_type == INT32PTR_T || arg_func_type == FLOATPTR_T) + { + // if(value->get_type() == INT32PTR_T || value->get_type() == FLOATPTR_T){ + // tmp_val = value; + // } + // else{ + // tmp_val = builder->create_alloca(arg_func_type); + // builder->create_store(value, tmp_val); + // } + } + else + { + if (value->get_type() == INT32_T && arg_func_type == FLOAT_T) + { + tmp_val = builder->create_sitofp(value, FLOAT_T); + } + else if (value->get_type() == FLOAT_T && arg_func_type == INT32_T) + { + tmp_val = builder->create_fptosi(value, INT32_T); + } + } + + args.push_back(tmp_val); + } + + builder->create_call(func, args); + } + } + + void IRBuilder::visit(SyntaxTree::IfStmt &node) + { + scope.enter(); + auto trueBB = BasicBlock::create(module, "trueBB_if", + module->get_functions().back()); + auto nextBB = BasicBlock::create(module, "nextBB_if", + module->get_functions().back()); + + scope.push("trueBB", trueBB); + scope.push("falseBB", nextBB); + + node.cond_exp->accept(*this); + LVal_to_RVal(tmp_val); + auto cond = tmp_val; + + builder->create_cond_br(cond, trueBB, nextBB); + builder->set_insert_point(trueBB); + node.if_statement->accept(*this); + + builder->set_insert_point(nextBB); + if (node.else_statement) + { + node.else_statement->accept(*this); + } + scope.exit(); + } + + void IRBuilder::visit(SyntaxTree::WhileStmt &node) + { + // auto func_name = scope.find("func", 0); + scope.enter(); + auto condBB = BasicBlock::create(module, "condBB_while", + module->get_functions().back()); + auto trueBB = BasicBlock::create(module, "trueBB_while", + module->get_functions().back()); + auto falseBB = BasicBlock::create(module, "falseBB_while", + module->get_functions().back()); + + scope.push("condBB", condBB); + scope.push("trueBB", trueBB); + scope.push("falseBB", falseBB); + + builder->create_br(condBB); + node.cond_exp->accept(*this); + LVal_to_RVal(tmp_val); + auto cond = tmp_val; + builder->create_cond_br(cond, trueBB, falseBB); + + auto cond_val = tmp_val; + scope.exit(); + } + + void IRBuilder::visit(SyntaxTree::BreakStmt &node) + { + node.accept(*this); + auto falseBB = scope.find("falseBB", 0); + builder->create_br(dynamic_pointer_cast(falseBB)); + } + + void IRBuilder::visit(SyntaxTree::ContinueStmt &node) + { + node.accept(*this); + auto condBB = scope.find("condBB", 0); + builder->create_br(dynamic_pointer_cast(condBB)); + } + } } \ No newline at end of file