Skip to content

Commit

Permalink
✨ feat(Gen): 类中的函数可以被正常定义
Browse files Browse the repository at this point in the history
  • Loading branch information
wangziwenhk committed Aug 8, 2024
1 parent 7652f47 commit 5fe63e8
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 33 deletions.
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ file(GLOB SOURCE_FILES
"src/Tools/*"
"src/Tools/Managers/*"
"src/Types/*"
"src/Visitors/*")
"src/Visitors/*"
"src/ext/*")

add_executable(Riddle_Language ${SOURCE_FILES} ${AST_FILES})

target_compile_definitions(Riddle_Language PRIVATE ${PLATFORM_DEFINES})

target_link_libraries(Riddle_Language LLVMCore)
target_link_libraries(Riddle_Language antlr4_shared)
target_link_libraries(Riddle_Language antlr4_shared)
17 changes: 13 additions & 4 deletions src/Tools/GenTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#include <antlr4-runtime.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/Value.h>
#include <string>
namespace Riddle {
#include <variant>
#include <Types/ClassNode.h>

namespace Riddle{
/// @brief 获取简单类型
/// @param type 简单类型的名称
/// @param Builder 生成器
Expand All @@ -23,10 +25,11 @@ namespace Riddle {
/// @param tree 节点
bool isIdentifier(antlr4::tree::ParseTree *tree);

struct DefineArgsType {
struct DefineArgsType{
std::vector<llvm::Type *> types;
std::vector<std::string> names;
};

/// @brief 判断是否为简单类型
/// @param type 类型名称
bool isSampleType(const std::string &type);
Expand All @@ -35,6 +38,12 @@ namespace Riddle {
/// @param var 变量
bool isArray(llvm::Value *var);

}// namespace Riddle
/// @brief 判断当前是否在类的定义中
/// @param parent 父栈
/// @return 是否在类的定义中
inline bool isClassDefine(const std::variant<llvm::Function *, ClassNode> parent){
return std::holds_alternative<ClassNode>(parent);
}
} // namespace Riddle

#endif//RIDDLE_LANGUAGE_GENTOOLS_H
16 changes: 6 additions & 10 deletions src/Tools/Managers/ClassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@

#include "ClassManager.h"

namespace Riddle {
namespace Riddle{
/// @brief 查找相关的类
/// <p>
/// a
/// </p>
Class ClassManager::getClass(const std::string &name) {
const auto it = Classes.find(name);
if (it == Classes.end()) {
ClassNode ClassManager::getClass(const std::string &name){
if (const auto it = Classes.find(name);it == Classes.end()) {
throw std::logic_error("没有这个类或者使用了不支持的路径");
}
return Classes.find(name)->second;
}

void ClassManager::createClass(Class theClass) {
Classes[theClass.types->getName().str()] = theClass;
void ClassManager::createClass(const ClassNode &theClass){
Classes[theClass.get().types->getName().str()] = theClass;
}
}// namespace Riddle
} // namespace Riddle
15 changes: 8 additions & 7 deletions src/Tools/Managers/ClassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
#include <llvm/IR/IRBuilder.h>

#include "Types/Class.h"
#include "Types/ClassNode.h"

namespace Riddle {
namespace Riddle{
/// @brief 管理类
class ClassManager {
class ClassManager{
/// @brief 存储数据字段
std::unordered_map<std::string, Class> Classes;
std::unordered_map<std::string, ClassNode> Classes;

public:
Class getClass(const std::string &name);
ClassNode getClass(const std::string &name);

void createClass(Class theClass);
void createClass(const ClassNode &theClass);
};

}// namespace Riddle
} // namespace Riddle

#endif//RIDDLE_LANGUAGE_CLASSMANAGER_H
4 changes: 4 additions & 0 deletions src/Types/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
#ifndef CLASS_H
#define CLASS_H

#include <map>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Function.h>

namespace Riddle{

class Class {
public:
llvm::StructType *types = nullptr;
std::vector<std::string> names;
std::map<std::string, llvm::FunctionCallee> funcs;
};

} // Riddle
Expand Down
8 changes: 8 additions & 0 deletions src/Types/ClassNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Created by wangz on 24-8-8.
//

#include "ClassNode.h"

namespace Riddle {
} // Riddle
27 changes: 27 additions & 0 deletions src/Types/ClassNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Created by wangz on 24-8-8.
//

#ifndef CLASSNODE_H
#define CLASSNODE_H
#include "Class.h"

namespace Riddle{
// 防止内存泄漏,启用 RAII 思想
class ClassNode{
public:
Class *theClass;

ClassNode(): theClass(new Class()){
}

~ClassNode(){
}

Class &get() const{
return *theClass;
}
};
} // Riddle

#endif //CLASSNODE_H
27 changes: 18 additions & 9 deletions src/Visitors/GenVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ namespace Riddle{
const auto type = any_cast<llvm::Type *>(visit(ctx->returnType));
resultType = type;
}
if (isClassDefine(ParentStack.top())) {
args.names.insert(args.names.begin(), "this");
args.types.insert(args.types.begin(), std::get<ClassNode>(ParentStack.top()).get().types);
}

const std::string funcPkgName = packStack.top() + ctx->funcName->getText();

Expand All @@ -89,8 +93,13 @@ namespace Riddle{
llvm::BasicBlock *entry = llvm::BasicBlock::Create(globalContext, "entry", func);
llvm::BasicBlock *oldBlock = Builder.GetInsertBlock();
Builder.SetInsertPoint(entry);
FuncCalls[ctx->funcName->getText()] = module->getOrInsertFunction(funcPkgName, funcType);

// 对于类中方法的定义
if (isClassDefine(ParentStack.top())) {
const auto theClass = std::get<ClassNode>(ParentStack.top());
theClass.get().funcs[ctx->funcName->getText()] = module->getOrInsertFunction(funcPkgName, funcType);
} else {
FuncCalls[ctx->funcName->getText()] = module->getOrInsertFunction(funcPkgName, funcType);
}
ParentStack.push(func);
varManager.push();

Expand Down Expand Up @@ -133,9 +142,9 @@ namespace Riddle{
}

// 对于类中成员的定义
if (std::holds_alternative<llvm::StructType *>(ParentStack.top())) {
if (isClassDefine(ParentStack.top())) {
// todo 增加初始值设定
const auto structTy = std::get<llvm::StructType *>(ParentStack.top());
const auto structTy = std::get<ClassNode>(ParentStack.top()).get().types;
std::vector<llvm::Type *> newMember = structTy->elements();
newMember.push_back(type);
structTy->setBody(newMember);
Expand Down Expand Up @@ -495,8 +504,8 @@ namespace Riddle{
return getSampleType(name, Builder);
}
// 自定义类型
auto type = classManager.getClass(name);
return llvm::dyn_cast<llvm::Type>(type.types);
const auto theClass = classManager.getClass(name);
return llvm::dyn_cast<llvm::Type>(theClass.get().types);
}

std::any GenVisitor::visitPtrExpr(RiddleParser::PtrExprContext *ctx){
Expand All @@ -519,11 +528,11 @@ namespace Riddle{

std::any GenVisitor::visitClassDefine(RiddleParser::ClassDefineContext *ctx){
const std::string name = packStack.top() + ctx->className->getText();
Class theClass;
theClass.types = llvm::StructType::create(globalContext, name);
const ClassNode theClass;
theClass.get().types = llvm::StructType::create(globalContext, name);
packStack.push(packStack.top() + ctx->className->getText());
varManager.push();
ParentStack.push(theClass.types);
ParentStack.push(theClass);
visit(ctx->body);
packStack.pop();
varManager.pop();
Expand Down
2 changes: 1 addition & 1 deletion src/Visitors/GenVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Riddle {
llvm::LLVMContext globalContext;
llvm::Module *module;
// stack
std::stack<std::variant<llvm::Function *, llvm::StructType *> > ParentStack;
std::stack<std::variant<llvm::Function *, ClassNode> > ParentStack;
std::stack<std::string> packStack;
// manager
VarManager varManager;
Expand Down
4 changes: 4 additions & 0 deletions src/ext/doubleMap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "doubleMap.h"

namespace Riddle{
} // Riddle
43 changes: 43 additions & 0 deletions src/ext/doubleMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef RIDDLE_LANGUAGE_DOUBLEMAP_H
#define RIDDLE_LANGUAGE_DOUBLEMAP_H
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

namespace Riddle{
template<typename KeyTy, typename Tp>
class doubleMap{
__gnu_pbds::tree<KeyTy, Tp, std::less<int>, __gnu_pbds::rb_tree_tag,
__gnu_pbds::tree_order_statistics_node_update> tree;

public:
auto findByKey(KeyTy key){
return tree.find(key);
}

auto findByValue(Tp value){
auto it = tree.lower_bound(value);
if (it->second != value) {
return tree.end();
}
return it;
}

void insert(KeyTy key, Tp value){
tree.insert({key, value});
}

auto erase(KeyTy key){
return tree.erase(key);
}

bool countByKey(KeyTy key){
return findByKey(key) != tree.end();
}

bool countByValue(Tp value){
return findByValue(value) != tree.end();
}
};
} // Riddle

#endif //RIDDLE_LANGUAGE_DOUBLEMAP_H

0 comments on commit 5fe63e8

Please sign in to comment.