Skip to content

Commit

Permalink
feat(Gen): 现在可以使用全局变量了
Browse files Browse the repository at this point in the history
  • Loading branch information
wangziwenhk committed Jul 29, 2024
1 parent 3aa160b commit 0d445c9
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 32 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ file(GLOB AST_FILES "parser/*.cpp" "parser/*.h")
file(GLOB SOURCE_FILES
"src/*"
"src/Tools/*"
"src/Tools/Managers/*"
"src/Types/*"
"src/Visitors/*")

Expand Down
8 changes: 8 additions & 0 deletions src/Tools/Managers/ClassManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Created by wangz on 24-7-29.
//

#include "ClassManager.h"

namespace Riddle {
}// namespace Riddle
18 changes: 18 additions & 0 deletions src/Tools/Managers/ClassManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Created by wangz on 24-7-29.
//

#ifndef RIDDLE_LANGUAGE_CLASSMANAGER_H
#define RIDDLE_LANGUAGE_CLASSMANAGER_H
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Value.h>
namespace Riddle {
/// @brief 管理类
class ClassManager {
/// @brief 存储数据字段
llvm::StructType *data;
};

}// namespace Riddle

#endif//RIDDLE_LANGUAGE_CLASSMANAGER_H
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@ namespace Riddle {
}
Defined.pop();
}
void VarManager::defineVar(const std::string &name, const bool &isConst, llvm::AllocaInst *value, const std::string &type) {
void VarManager::defineVar(const std::string &name, const bool &isConst, llvm::Value *value) {
if(Defined.top().count(name)) {
throw std::logic_error("The variable has been defined multiple times");
}
NamedVar[name].push(Variable(name, value, type, isConst));
NamedVar[name].push(Variable(name, value, isConst));
Defined.top()[name] = true;
}
Variable VarManager::getVar(const std::string &name) {
if(!isDefined(name))
throw std::logic_error("The variable does not exist");
if(NamedVar[name].top().type == Null)
throw std::logic_error("Unclear variables");

return NamedVar[name].top();
}
bool VarManager::isGlobal() {
return Defined.size() == 1;
}

}// namespace Riddle
5 changes: 4 additions & 1 deletion src/Tools/VarManager.h → src/Tools/Managers/VarManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ namespace Riddle {
/// @param type 类型,当类型为 null 时说明在下一次赋值时判断,在被引用之前必须有类型
/// @param isConst 是否不变
/// @param value 指某个局部变量的地址
void defineVar(const std::string &name, const bool &isConst, llvm::AllocaInst *value = nullptr, const std::string &type = "null");
void defineVar(const std::string &name, const bool &isConst, llvm::Value *value = nullptr);
/// @brief 获取一个变量的属性
/// @param name 变量名
/// @returns 变量的属性
Variable getVar(const std::string &name);
/// @brief 获取当前是否为全局
/// @returns 是否为全局
bool isGlobal();
};

}// namespace Riddle
Expand Down
8 changes: 3 additions & 5 deletions src/Types/Variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ namespace Riddle {
class Variable {
public:
const std::string name;
std::string type;
llvm::AllocaInst *value;
llvm::Value *value;
const bool isConst;
Variable() = delete;
Variable(const std::string &name,
llvm::AllocaInst *value,
const std::string &type = Null,
const bool isConst = false): name(name), value(value), type(type), isConst(isConst){};
llvm::Value *value,
const bool isConst = false): name(name), value(value), isConst(isConst){};
};

}// namespace Riddle
Expand Down
47 changes: 26 additions & 21 deletions src/Visitors/GenVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ namespace Riddle {
return p;
}
std::any GenVisitor::visitObjectExpr(RiddleParser::ObjectExprContext *ctx) {
llvm::AllocaInst *value = varManager.getVar(ctx->id()->getText()).value;
llvm::Value *rv = value;
return rv;
llvm::Value *value = varManager.getVar(ctx->id()->getText()).value;
return value;
}
std::any GenVisitor::visitProgram(RiddleParser::ProgramContext *ctx) {
varManager.push();
Expand Down Expand Up @@ -96,7 +95,7 @@ namespace Riddle {
for(int i = 0; i < args.names.size(); i++, argIter++) {
llvm::AllocaInst *Alloca = Builder.CreateAlloca(args.types[i], nullptr, args.names[i]);
Builder.CreateStore(argIter, Alloca);
varManager.defineVar(args.names[i], false, Alloca, getTypeName(args.types[i]));
varManager.defineVar(args.names[i], false, Alloca);
}

visit(ctx->funcBody());
Expand All @@ -114,29 +113,35 @@ namespace Riddle {
}
std::any GenVisitor::visitVarDefineStatement(RiddleParser::VarDefineStatementContext *ctx) {
std::string name = ctx->name->getText();
if(ctx->type == nullptr) {
auto value = any_cast<llvm::Value *>(visit(ctx->value));
llvm::AllocaInst *Alloca = Builder.CreateAlloca(value->getType(), nullptr, name);
assignBinaryOp(Alloca, value, "=");
varManager.defineVar(name, false, Alloca, getTypeName(value->getType()));
} else if(ctx->value == nullptr) {
llvm::Value *value = nullptr;
llvm::Type *type = nullptr;
llvm::Value *size = nullptr;

if(ctx->type != nullptr) {
auto tuple = any_cast<std::tuple<llvm::Type *, llvm::Value *>>(visit(ctx->type));
auto [type, size] = tuple;
llvm::AllocaInst *Alloca = Builder.CreateAlloca(type, size, name);
varManager.defineVar(name, false, Alloca, getTypeName(type));
auto [_type, _size] = tuple;
type = _type;
size = _size;
} else if(ctx->value != nullptr) {
value = any_cast<llvm::Value *>(visit(ctx->value));
type = value->getType();
}

llvm::Value *var;
if(varManager.isGlobal()) {
auto CV = llvm::dyn_cast<llvm::Constant>(value);
var = new llvm::GlobalVariable(*module, type, false, llvm::GlobalVariable::LinkageTypes::ExternalLinkage, CV, name);
} else {
auto tuple = any_cast<std::tuple<llvm::Type *, llvm::Value *>>(visit(ctx->type));
auto [type, size] = tuple;
auto value = any_cast<llvm::Value *>(visit(ctx->value));
llvm::AllocaInst *Alloca = Builder.CreateAlloca(type, size, name);
assignBinaryOp(Alloca, value, "=");
varManager.defineVar(name, false, Alloca, getTypeName(type));
var = Builder.CreateAlloca(type, size, name);
if(ctx->value != nullptr)
assignBinaryOp(var, value, "=");
}
varManager.defineVar(name, false, var);
return nullptr;
}
std::any GenVisitor::visitObjValExpr(RiddleParser::ObjValExprContext *ctx) {
llvm::AllocaInst *var = varManager.getVar(ctx->id()->getText()).value;
llvm::Value *LoadedValue = Builder.CreateLoad(var->getAllocatedType(), var, "tempVar");
llvm::Value *var = varManager.getVar(ctx->id()->getText()).value;
llvm::Value *LoadedValue = Builder.CreateLoad(var->getType(), var, "tempVar");
return LoadedValue;
}
std::any GenVisitor::visitIfStatement(RiddleParser::IfStatementContext *ctx) {
Expand Down
2 changes: 1 addition & 1 deletion src/Visitors/GenVisitor.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef RIDDLE_LANGUAGE_GENVISITOR_H
#define RIDDLE_LANGUAGE_GENVISITOR_H

#include "Tools/Managers/VarManager.h"
#include "Tools/Setup.h"
#include "Tools/VarManager.h"
#include <RiddleParserBaseVisitor.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h>
Expand Down

0 comments on commit 0d445c9

Please sign in to comment.