write all functions

This commit is contained in:
2024-08-24 01:28:40 +00:00
parent 8781d58776
commit 2168e402d3
3 changed files with 186 additions and 5 deletions

View File

@ -798,6 +798,37 @@ void IRBuilder::ActuralVisit(RLExpr_ASTNode *node) {
void IRBuilder::ActuralVisit(GGLLExpr_ASTNode *node) {
node->left->accept(this);
node->right->accept(this);
ExprTypeInfo string_std = IdentifierType("string");
if (node->left->expr_type_info == string_std) {
auto strcmp_call = std::make_shared<CallItem>();
cur_block->actions.push_back(strcmp_call);
strcmp_call->func_name_raw = "strcmp";
strcmp_call->return_type = LLVMIRIntType(32);
strcmp_call->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
strcmp_call->args_ty.push_back(LLVMIRPTRType());
strcmp_call->args_val_full.push_back(node->left->IR_result_full);
strcmp_call->args_ty.push_back(LLVMIRPTRType());
strcmp_call->args_val_full.push_back(node->right->IR_result_full);
auto cmp_act = std::make_shared<ICMPAction>();
cur_block->actions.push_back(cmp_act);
if (node->op == ">=") {
cmp_act->op = "sge";
} else if (node->op == ">") {
cmp_act->op = "sgt";
} else if (node->op == "<=") {
cmp_act->op = "sle";
} else if (node->op == "<") {
cmp_act->op = "slt";
} else {
throw std::runtime_error("unknown GGLL operator");
}
cmp_act->operand1_full = strcmp_call->result_full;
cmp_act->operand2_full = "0";
cmp_act->type = LLVMIRIntType(32);
cmp_act->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
node->IR_result_full = cmp_act->result_full;
return;
}
auto act = std::make_shared<ICMPAction>();
cur_block->actions.push_back(act);
if (node->op == ">=") {
@ -816,12 +847,36 @@ void IRBuilder::ActuralVisit(GGLLExpr_ASTNode *node) {
act->type = Type_AST2LLVM(node->left->expr_type_info);
act->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
node->IR_result_full = act->result_full;
// TODO: string comparison
}
void IRBuilder::ActuralVisit(NEExpr_ASTNode *node) {
node->left->accept(this);
node->right->accept(this);
ExprTypeInfo string_std = IdentifierType("string");
if (node->left->expr_type_info == string_std) {
auto strcmp_call = std::make_shared<CallItem>();
cur_block->actions.push_back(strcmp_call);
strcmp_call->func_name_raw = "strcmp";
strcmp_call->return_type = LLVMIRIntType(32);
strcmp_call->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
strcmp_call->args_ty.push_back(LLVMIRPTRType());
strcmp_call->args_val_full.push_back(node->left->IR_result_full);
strcmp_call->args_ty.push_back(LLVMIRPTRType());
strcmp_call->args_val_full.push_back(node->right->IR_result_full);
auto cmp_act = std::make_shared<ICMPAction>();
cur_block->actions.push_back(cmp_act);
if (node->op == "!=") {
cmp_act->op = "ne";
} else {
cmp_act->op = "eq";
}
cmp_act->operand1_full = strcmp_call->result_full;
cmp_act->operand2_full = "0";
cmp_act->type = LLVMIRIntType(32);
cmp_act->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
node->IR_result_full = cmp_act->result_full;
return;
}
auto act = std::make_shared<ICMPAction>();
cur_block->actions.push_back(act);
if (node->op == "!=") {
@ -836,7 +891,6 @@ void IRBuilder::ActuralVisit(NEExpr_ASTNode *node) {
act->type = Type_AST2LLVM(node->left->expr_type_info);
act->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
node->IR_result_full = act->result_full;
// TODO: string comparison
}
void IRBuilder::ActuralVisit(BAndExpr_ASTNode *node) {
@ -1123,8 +1177,81 @@ void IRBuilder::ActuralVisit(FunctionCallExpr_ASTNode *node) {
}
void IRBuilder::ActuralVisit(FormattedStringExpr_ASTNode *node) {
// TODO: Implement function body
throw std::runtime_error("formatted string not supported");
for (size_t i = 0; i < node->literals.size(); i++) {
std::string str;
if (i == 0)
str = node->literals[i].substr(2, node->literals[i].size() - 3);
else
str = node->literals[i].substr(1, node->literals[i].size() - 2);
str = FmtStrLiteralDeEscape(str);
if (const_str_dict.find(str) == const_str_dict.end()) {
const_str_dict[str] = const_str_counter++;
auto const_str_item = std::make_shared<ConstStrItem>();
prog->const_strs.push_back(const_str_item);
const_str_item->string_raw = str;
const_str_item->const_str_id = const_str_dict[str];
}
}
ExprTypeInfo string_std = IdentifierType("string");
ExprTypeInfo int_std = IdentifierType("int");
ExprTypeInfo bool_std = IdentifierType("bool");
std::string res =
"@.str." +
std::to_string(const_str_dict[FmtStrLiteralDeEscape(node->literals[0].substr(2, node->literals[0].size() - 3))]);
if (node->exprs.size() + 1 != node->literals.size()) throw std::runtime_error("formatted string error");
for (size_t i = 0; i < node->exprs.size(); i++) {
node->exprs[i]->accept(this);
std::string str_res = node->exprs[i]->IR_result_full;
if (node->exprs[i]->expr_type_info == string_std) {
; // just do nothing
} else if (node->exprs[i]->expr_type_info == int_std) {
auto call = std::make_shared<CallItem>();
cur_block->actions.push_back(call);
call->func_name_raw = "toString";
call->return_type = LLVMIRPTRType();
call->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
call->args_ty.push_back(LLVMIRIntType(32));
call->args_val_full.push_back(str_res);
str_res = call->result_full;
} else if (node->exprs[i]->expr_type_info == bool_std) {
auto select = std::make_shared<SelectItem>();
cur_block->actions.push_back(select);
select->result_full = "%.var.tmp." + std::to_string(tmp_var_counter++);
select->ty = LLVMIRPTRType();
select->cond_full = str_res;
select->true_val_full = "@.str." + std::to_string(const_str_dict["true"]);
select->false_val_full = "@.str." + std::to_string(const_str_dict["false"]);
str_res = select->result_full;
} else {
throw std::runtime_error("formatted string error");
}
std::string tmp = "%.var.tmp." + std::to_string(tmp_var_counter++);
auto strcat1 = std::make_shared<CallItem>();
cur_block->actions.push_back(strcat1);
strcat1->func_name_raw = ".builtin.strcat";
strcat1->return_type = LLVMIRPTRType();
strcat1->result_full = tmp;
strcat1->args_ty.push_back(LLVMIRPTRType());
strcat1->args_val_full.push_back(res);
strcat1->args_ty.push_back(LLVMIRPTRType());
strcat1->args_val_full.push_back(str_res);
res = tmp;
tmp = "%.var.tmp." + std::to_string(tmp_var_counter++);
auto strcat2 = std::make_shared<CallItem>();
cur_block->actions.push_back(strcat2);
strcat2->func_name_raw = ".builtin.strcat";
strcat2->return_type = LLVMIRPTRType();
strcat2->result_full = tmp;
strcat2->args_ty.push_back(LLVMIRPTRType());
strcat2->args_val_full.push_back(res);
strcat2->args_ty.push_back(LLVMIRPTRType());
strcat2->args_val_full.push_back(
"@.str." +
std::to_string(
const_str_dict[FmtStrLiteralDeEscape(node->literals[i + 1].substr(1, node->literals[i + 1].size() - 2))]));
res = tmp;
}
node->IR_result_full = res;
}
void IRBuilder::ActuralVisit(ConstantExpr_ASTNode *node) {
@ -1273,6 +1400,25 @@ std::shared_ptr<ModuleItem> BuildIR(std::shared_ptr<Program_ASTNode> src) {
tmp->args.push_back(LLVMIRPTRType());
visitor.prog->function_declares.push_back(tmp);
tmp = std::make_shared<FunctionDeclareItem>(); // int strcmp(const char *str1, const char *str2);
tmp->func_name_raw = "strcmp";
tmp->return_type = LLVMIRIntType(32);
tmp->args.push_back(LLVMIRPTRType());
tmp->args.push_back(LLVMIRPTRType());
visitor.prog->function_declares.push_back(tmp);
visitor.const_str_dict["true"] = visitor.const_str_counter++;
auto const_str_item = std::make_shared<ConstStrItem>();
visitor.prog->const_strs.push_back(const_str_item);
const_str_item->string_raw = "true";
const_str_item->const_str_id = visitor.const_str_dict["true"];
visitor.const_str_dict["false"] = visitor.const_str_counter++;
const_str_item = std::make_shared<ConstStrItem>();
visitor.prog->const_strs.push_back(const_str_item);
const_str_item->string_raw = "false";
const_str_item->const_str_id = visitor.const_str_dict["false"];
visitor.global_scope = std::dynamic_pointer_cast<GlobalScope>(src->current_scope);
if (!(visitor.global_scope)) throw std::runtime_error("global scope not found");
visitor.visit(src.get());