trivial update
This commit is contained in:
parent
ae32334ccc
commit
547651676c
218
include/llir_instruction.h
Normal file
218
include/llir_instruction.h
Normal file
@ -0,0 +1,218 @@
|
||||
#pragma once
|
||||
#include "llir_value.h"
|
||||
|
||||
namespace antlrSysY {
|
||||
enum class InstTag {
|
||||
Add,
|
||||
Sub,
|
||||
Mod,
|
||||
Mul,
|
||||
Div,
|
||||
Lt,
|
||||
Le,
|
||||
Ge,
|
||||
Gt,
|
||||
Eq,
|
||||
Ne,
|
||||
And,
|
||||
Or,
|
||||
Br,
|
||||
Call,
|
||||
Ret,
|
||||
Alloca,
|
||||
Load,
|
||||
Store,
|
||||
GEP,
|
||||
Zext,
|
||||
Phi,
|
||||
MemPhi,
|
||||
LoadDep,
|
||||
InsertEle,
|
||||
ExtractEle
|
||||
};
|
||||
|
||||
class Instruction : public Value {
|
||||
public:
|
||||
InstTag tag;
|
||||
std::shared_ptr<BasicBlock> parent_bb;
|
||||
std::vector<std::shared_ptr<Value>> operand_list;
|
||||
Instruction(InstTag inst_tag, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Value("", type), tag(inst_tag), parent_bb(parent_bb) {}
|
||||
virtual std::string to_string() override {
|
||||
switch (tag) {
|
||||
case InstTag::Add:
|
||||
return "Add";
|
||||
case InstTag::Sub:
|
||||
return "Sub";
|
||||
case InstTag::Mod:
|
||||
return "Mod";
|
||||
case InstTag::Mul:
|
||||
return "Mul";
|
||||
case InstTag::Div:
|
||||
return "Div";
|
||||
case InstTag::Lt:
|
||||
return "Lt";
|
||||
case InstTag::Le:
|
||||
return "Le";
|
||||
case InstTag::Ge:
|
||||
return "Ge";
|
||||
case InstTag::Gt:
|
||||
return "Gt";
|
||||
case InstTag::Eq:
|
||||
return "Eq";
|
||||
case InstTag::Ne:
|
||||
return "Ne";
|
||||
case InstTag::And:
|
||||
return "And";
|
||||
case InstTag::Or:
|
||||
return "Or";
|
||||
case InstTag::Br:
|
||||
return "Br";
|
||||
case InstTag::Call:
|
||||
return "Call";
|
||||
case InstTag::Ret:
|
||||
return "Ret";
|
||||
case InstTag::Alloca:
|
||||
return "Alloca";
|
||||
case InstTag::Load:
|
||||
return "Load";
|
||||
case InstTag::Store:
|
||||
return "Store";
|
||||
case InstTag::GEP:
|
||||
return "GEP";
|
||||
case InstTag::Zext:
|
||||
return "Zext";
|
||||
case InstTag::Phi:
|
||||
return "Phi";
|
||||
case InstTag::MemPhi:
|
||||
return "MemPhi";
|
||||
case InstTag::LoadDep:
|
||||
return "LoadDep";
|
||||
case InstTag::InsertEle:
|
||||
return "InsertEle";
|
||||
case InstTag::ExtractEle:
|
||||
return "ExtractEle";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class InstAlloca : public Instruction {
|
||||
public:
|
||||
InstAlloca(TypePtr_t alloc_type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Alloca, std::make_shared<PointerType>(alloc_type), parent_bb) {}
|
||||
};
|
||||
|
||||
class InstStore : public Instruction {
|
||||
public:
|
||||
InstStore(std::shared_ptr<Value> value, std::shared_ptr<Value> pointer, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Store, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
operand_list.push_back(value);
|
||||
operand_list.push_back(pointer);
|
||||
}
|
||||
};
|
||||
|
||||
class InstLoad : public Instruction {
|
||||
public:
|
||||
InstLoad(std::shared_ptr<Value> value, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Load, type, parent_bb) {
|
||||
operand_list.push_back(value);
|
||||
}
|
||||
};
|
||||
|
||||
class InstBinary : public Instruction {
|
||||
public:
|
||||
InstBinary(InstTag inst_tag, TypePtr_t val_type, std::shared_ptr<Value> op1, std::shared_ptr<Value> op2,
|
||||
std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(inst_tag, val_type, parent_bb) {
|
||||
operand_list.push_back(op1);
|
||||
operand_list.push_back(op2);
|
||||
}
|
||||
};
|
||||
|
||||
class InstZext : public Instruction {
|
||||
public:
|
||||
InstZext(std::shared_ptr<Value> op, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Zext, TypeHelper::TYPE_I32, parent_bb) {
|
||||
operand_list.push_back(op);
|
||||
}
|
||||
};
|
||||
|
||||
class InstBranch : public Instruction {
|
||||
public:
|
||||
// conditional branch
|
||||
InstBranch(ValuePtr_t cond, BasicBlockPtr_t true_block, BasicBlockPtr_t false_block, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(cond);
|
||||
this->operand_list.push_back(true_block);
|
||||
this->operand_list.push_back(false_block);
|
||||
}
|
||||
// unconditional branch
|
||||
InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(target_block);
|
||||
}
|
||||
};
|
||||
|
||||
class InstReturn : public Instruction {
|
||||
public:
|
||||
InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(ret_val);
|
||||
}
|
||||
InstReturn(BasicBlockPtr_t parent_bb) : Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {}
|
||||
};
|
||||
|
||||
class InstCall : public Instruction {
|
||||
public:
|
||||
InstCall(FunctionPtr_t func, const std::vector<ValuePtr_t> &args, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Call, func->get_type()->return_type, parent_bb) {
|
||||
operand_list.push_back(func);
|
||||
operand_list.insert(operand_list.end(), args.begin(), args.end());
|
||||
}
|
||||
};
|
||||
|
||||
// getelementptr <ty>, ptr <ptrval>{, [inrange] <ty> <idx>}*
|
||||
// Example: lea arr[2][3] from arr[5][4]:
|
||||
// &arr[2][3] = GEP [5x[4xi32]], [5x[4xi32]]* arr, i32 0, i32 2, i32 3
|
||||
class InstGEP : public Instruction {
|
||||
public:
|
||||
ValuePtr_t aim_to;
|
||||
TypePtr_t element_type;
|
||||
InstGEP(ValuePtr_t pointer, const std::vector<ValuePtr_t> &indices, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::GEP, std::make_shared<PointerType>(extract_type(pointer, indices)), parent_bb) {
|
||||
if (Value::isType<InstGEP>(pointer)) {
|
||||
aim_to = std::dynamic_pointer_cast<InstGEP>(pointer)->aim_to;
|
||||
}
|
||||
else if (Value::isType<InstAlloca>(pointer) || Value::isType<GlobalVar>(pointer)){
|
||||
aim_to = pointer;
|
||||
}
|
||||
else {
|
||||
LOG(WARNING) << "Unexpected pointer type" << pointer->to_string();
|
||||
aim_to = nullptr;
|
||||
}
|
||||
element_type = extract_type(pointer, indices);
|
||||
operand_list.push_back(pointer);
|
||||
operand_list.insert(operand_list.end(), indices.begin(), indices.end());
|
||||
}
|
||||
|
||||
// get the inner
|
||||
static TypePtr_t extract_type(ValuePtr_t pointer, const std::vector<ValuePtr_t> &indices) {
|
||||
auto pointer_type = std::dynamic_pointer_cast<PointerType>(pointer->type);
|
||||
auto pointed_type = pointer_type->pointed_type;
|
||||
// ptr->array
|
||||
if (pointed_type->type_tag == Type::TypeTag::ArrayType) {
|
||||
for (int i = 1; i < indices.size(); ++i) {
|
||||
pointed_type = std::dynamic_pointer_cast<ArrayType>(pointed_type)->element_type;
|
||||
}
|
||||
}
|
||||
if (pointed_type->type_tag == Type::TypeTag::IntegerType) {
|
||||
return pointed_type;
|
||||
}
|
||||
else {
|
||||
LOG(WARNING) << "not returning an int-type";
|
||||
return pointed_type;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
14
include/llir_module.h
Normal file
14
include/llir_module.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "llir_type.h"
|
||||
#include "llir_value.h"
|
||||
#include "llir_instruction.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace antlrSysY {
|
||||
struct Module {
|
||||
std::vector<std::shared_ptr<Function>> function_list;
|
||||
std::vector<std::shared_ptr<GlobalVar>> global_var_list;
|
||||
std::vector<std::shared_ptr<Instruction>> instruction_list;
|
||||
};
|
||||
}
|
||||
@ -117,217 +117,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum class InstTag {
|
||||
Add,
|
||||
Sub,
|
||||
Mod,
|
||||
Mul,
|
||||
Div,
|
||||
Lt,
|
||||
Le,
|
||||
Ge,
|
||||
Gt,
|
||||
Eq,
|
||||
Ne,
|
||||
And,
|
||||
Or,
|
||||
Br,
|
||||
Call,
|
||||
Ret,
|
||||
Alloca,
|
||||
Load,
|
||||
Store,
|
||||
GEP,
|
||||
Zext,
|
||||
Phi,
|
||||
MemPhi,
|
||||
LoadDep,
|
||||
InsertEle,
|
||||
ExtractEle
|
||||
};
|
||||
|
||||
class Instruction : public Value {
|
||||
public:
|
||||
InstTag tag;
|
||||
std::shared_ptr<BasicBlock> parent_bb;
|
||||
std::vector<std::shared_ptr<Value>> operand_list;
|
||||
Instruction(InstTag inst_tag, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Value("", type), tag(inst_tag), parent_bb(parent_bb) {}
|
||||
virtual std::string to_string() override {
|
||||
switch (tag) {
|
||||
case InstTag::Add:
|
||||
return "Add";
|
||||
case InstTag::Sub:
|
||||
return "Sub";
|
||||
case InstTag::Mod:
|
||||
return "Mod";
|
||||
case InstTag::Mul:
|
||||
return "Mul";
|
||||
case InstTag::Div:
|
||||
return "Div";
|
||||
case InstTag::Lt:
|
||||
return "Lt";
|
||||
case InstTag::Le:
|
||||
return "Le";
|
||||
case InstTag::Ge:
|
||||
return "Ge";
|
||||
case InstTag::Gt:
|
||||
return "Gt";
|
||||
case InstTag::Eq:
|
||||
return "Eq";
|
||||
case InstTag::Ne:
|
||||
return "Ne";
|
||||
case InstTag::And:
|
||||
return "And";
|
||||
case InstTag::Or:
|
||||
return "Or";
|
||||
case InstTag::Br:
|
||||
return "Br";
|
||||
case InstTag::Call:
|
||||
return "Call";
|
||||
case InstTag::Ret:
|
||||
return "Ret";
|
||||
case InstTag::Alloca:
|
||||
return "Alloca";
|
||||
case InstTag::Load:
|
||||
return "Load";
|
||||
case InstTag::Store:
|
||||
return "Store";
|
||||
case InstTag::GEP:
|
||||
return "GEP";
|
||||
case InstTag::Zext:
|
||||
return "Zext";
|
||||
case InstTag::Phi:
|
||||
return "Phi";
|
||||
case InstTag::MemPhi:
|
||||
return "MemPhi";
|
||||
case InstTag::LoadDep:
|
||||
return "LoadDep";
|
||||
case InstTag::InsertEle:
|
||||
return "InsertEle";
|
||||
case InstTag::ExtractEle:
|
||||
return "ExtractEle";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class InstAlloca : public Instruction {
|
||||
public:
|
||||
InstAlloca(TypePtr_t alloc_type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Alloca, std::make_shared<PointerType>(alloc_type), parent_bb) {}
|
||||
};
|
||||
|
||||
class InstStore : public Instruction {
|
||||
public:
|
||||
InstStore(std::shared_ptr<Value> value, std::shared_ptr<Value> pointer, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Store, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
operand_list.push_back(value);
|
||||
operand_list.push_back(pointer);
|
||||
}
|
||||
};
|
||||
|
||||
class InstLoad : public Instruction {
|
||||
public:
|
||||
InstLoad(std::shared_ptr<Value> value, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Load, type, parent_bb) {
|
||||
operand_list.push_back(value);
|
||||
}
|
||||
};
|
||||
|
||||
class InstBinary : public Instruction {
|
||||
public:
|
||||
InstBinary(InstTag inst_tag, TypePtr_t val_type, std::shared_ptr<Value> op1, std::shared_ptr<Value> op2,
|
||||
std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(inst_tag, val_type, parent_bb) {
|
||||
operand_list.push_back(op1);
|
||||
operand_list.push_back(op2);
|
||||
}
|
||||
};
|
||||
|
||||
class InstZext : public Instruction {
|
||||
public:
|
||||
InstZext(std::shared_ptr<Value> op, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Zext, TypeHelper::TYPE_I32, parent_bb) {
|
||||
operand_list.push_back(op);
|
||||
}
|
||||
};
|
||||
|
||||
class InstBranch : public Instruction {
|
||||
public:
|
||||
// conditional branch
|
||||
InstBranch(ValuePtr_t cond, BasicBlockPtr_t true_block, BasicBlockPtr_t false_block, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(cond);
|
||||
this->operand_list.push_back(true_block);
|
||||
this->operand_list.push_back(false_block);
|
||||
}
|
||||
// unconditional branch
|
||||
InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(target_block);
|
||||
}
|
||||
};
|
||||
|
||||
class InstReturn : public Instruction {
|
||||
public:
|
||||
InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(ret_val);
|
||||
}
|
||||
InstReturn(BasicBlockPtr_t parent_bb) : Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {}
|
||||
};
|
||||
|
||||
class InstCall : public Instruction {
|
||||
public:
|
||||
InstCall(FunctionPtr_t func, const std::vector<ValuePtr_t> &args, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Call, func->get_type()->return_type, parent_bb) {
|
||||
operand_list.push_back(func);
|
||||
operand_list.insert(operand_list.end(), args.begin(), args.end());
|
||||
}
|
||||
};
|
||||
|
||||
// getelementptr <ty>, ptr <ptrval>{, [inrange] <ty> <idx>}*
|
||||
// Example: lea arr[2][3] from arr[5][4]:
|
||||
// &arr[2][3] = GEP [5x[4xi32]], [5x[4xi32]]* arr, i32 0, i32 2, i32 3
|
||||
class InstGEP : public Instruction {
|
||||
public:
|
||||
ValuePtr_t aim_to;
|
||||
TypePtr_t element_type;
|
||||
InstGEP(ValuePtr_t pointer, const std::vector<ValuePtr_t> &indices, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::GEP, std::make_shared<PointerType>(extract_type(pointer, indices)), parent_bb) {
|
||||
if (Value::isType<InstGEP>(pointer)) {
|
||||
aim_to = std::dynamic_pointer_cast<InstGEP>(pointer)->aim_to;
|
||||
}
|
||||
else if (Value::isType<InstAlloca>(pointer) || Value::isType<GlobalVar>(pointer)){
|
||||
aim_to = pointer;
|
||||
}
|
||||
else {
|
||||
LOG(WARNING) << "Unexpected pointer type" << pointer->to_string();
|
||||
aim_to = nullptr;
|
||||
}
|
||||
element_type = extract_type(pointer, indices);
|
||||
operand_list.push_back(pointer);
|
||||
operand_list.insert(operand_list.end(), indices.begin(), indices.end());
|
||||
}
|
||||
|
||||
// get the inner
|
||||
static TypePtr_t extract_type(ValuePtr_t pointer, const std::vector<ValuePtr_t> &indices) {
|
||||
auto pointer_type = std::dynamic_pointer_cast<PointerType>(pointer->type);
|
||||
auto pointed_type = pointer_type->pointed_type;
|
||||
// ptr->array
|
||||
if (pointed_type->type_tag == Type::TypeTag::ArrayType) {
|
||||
for (int i = 1; i < indices.size(); ++i) {
|
||||
pointed_type = std::dynamic_pointer_cast<ArrayType>(pointed_type)->element_type;
|
||||
}
|
||||
}
|
||||
if (pointed_type->type_tag == Type::TypeTag::IntegerType) {
|
||||
return pointed_type;
|
||||
}
|
||||
else {
|
||||
LOG(WARNING) << "not returning an int-type";
|
||||
return pointed_type;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace antlrSysY
|
||||
@ -13,8 +13,10 @@
|
||||
#include "antlrgen/SysyLexer.h"
|
||||
#include "antlrgen/SysyParser.h"
|
||||
#include "common.h"
|
||||
#include "llir_module.h"
|
||||
#include "llir_type.h"
|
||||
#include "llir_value.h"
|
||||
#include "llir_instruction.h"
|
||||
#include "scopetable.h"
|
||||
|
||||
namespace antlrSysY {
|
||||
@ -71,26 +73,17 @@ private:
|
||||
std::vector<loop_record> loop_stack = {};
|
||||
};
|
||||
|
||||
struct Module {
|
||||
std::vector<std::shared_ptr<Function>> functions;
|
||||
};
|
||||
|
||||
private:
|
||||
ScopeTable<std::shared_ptr<Value>> _scope_tab;
|
||||
ScopeTable<std::shared_ptr<Function>> _func_tab; // var can have same name as func
|
||||
VisitorState _state = {};
|
||||
Module _module = {};
|
||||
std::map<std::string, size_t> token_type_map;
|
||||
std::shared_ptr<ConstantInt> CONST0;
|
||||
inline static std::shared_ptr<ConstantInt> CONST0 = std::make_shared<ConstantInt>("CONST0", 0);
|
||||
|
||||
public:
|
||||
Visitor(SysyLexer &lexer) {
|
||||
for (auto item : lexer.getTokenTypeMap()) {
|
||||
token_type_map[std::string(item.first)] = item.second;
|
||||
}
|
||||
CONST0 = std::make_shared<ConstantInt>("CONST0", 0);
|
||||
}
|
||||
std::any visitProgram(SysyParser::ProgramContext *ctx) override;
|
||||
Module module = {};
|
||||
|
||||
Visitor(SysyLexer &lexer);
|
||||
|
||||
// std::any visitProgram(SysyParser::ProgramContext *ctx) override;
|
||||
|
||||
// std::any visitCompUnit(SysyParser::CompUnitContext *ctx) override;
|
||||
|
||||
@ -104,21 +97,18 @@ public:
|
||||
|
||||
std::any visitInitVal(SysyParser::InitValContext *ctx) override;
|
||||
|
||||
// constDef : IDENT ('[' constExp ']')* '=' constInitVal ';'
|
||||
std::any visitConstDef(SysyParser::ConstDefContext *ctx) override;
|
||||
|
||||
std::any visitConstInitVal(SysyParser::ConstInitValContext *ctx) override;
|
||||
|
||||
std::any visitConstExp(SysyParser::ConstExpContext *ctx) override;
|
||||
// addExp: mulExp | addExp ('+' | '-') mulExp;
|
||||
|
||||
std::any visitAddExp(SysyParser::AddExpContext *ctx) override;
|
||||
|
||||
std::any visitMulExp(SysyParser::MulExpContext *ctx) override;
|
||||
|
||||
// unaryExp: primaryExp | IDENT '(' (funcRParams)? ')' | unaryOp unaryExp;
|
||||
std::any visitUnaryExp(SysyParser::UnaryExpContext *ctx) override;
|
||||
|
||||
// primaryExp: ('(' exp ')') | lVal | number;
|
||||
std::any visitPrimaryExp(SysyParser::PrimaryExpContext *ctx) override;
|
||||
|
||||
// std::any visitExp(SysyParser::ExpContext *ctx) override { }
|
||||
@ -168,6 +158,8 @@ public:
|
||||
std::any visitLAndExp(SysyParser::LAndExpContext *ctx) override;
|
||||
|
||||
std::any visitLOrExp(SysyParser::LOrExpContext *ctx) override;
|
||||
|
||||
void llir_gen();
|
||||
};
|
||||
|
||||
} // namespace antlrSysY
|
||||
@ -34,6 +34,7 @@ int main(int argc, const char **argv) {
|
||||
arg_parser.add_argument("-S").implicit_value(true).help("Useless but required by the contest").required();
|
||||
arg_parser.add_argument("-o").help("Output file name").required();
|
||||
arg_parser.add_argument("-O1").implicit_value(true).default_value(false).help("Performance mode");
|
||||
arg_parser.add_argument("--v").default_value(0);
|
||||
try {
|
||||
arg_parser.parse_args(argc, argv);
|
||||
} catch (const std::runtime_error &err) {
|
||||
@ -47,7 +48,7 @@ int main(int argc, const char **argv) {
|
||||
// std::cout << source_file << " " << output_file << " " << flg_O1 <<
|
||||
// std::endl;
|
||||
#pragma endregion
|
||||
|
||||
START_EASYLOGGINGPP(argc, argv);
|
||||
#pragma region Logger
|
||||
el::Configurations defaultConf;
|
||||
defaultConf.setToDefault();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "visitor.h"
|
||||
#include "3rdparty/easylogging++.h"
|
||||
#include "SysyLexer.h"
|
||||
#include "common.h"
|
||||
#include "llir_type.h"
|
||||
#include "llir_value.h"
|
||||
@ -65,8 +66,7 @@ void _sysy_starttime(int lineno);
|
||||
void _sysy_stoptime(int lineno);
|
||||
*/
|
||||
|
||||
std::any Visitor::visitProgram(SysyParser::ProgramContext *ctx) {
|
||||
|
||||
Visitor::Visitor(SysyLexer&) {
|
||||
#pragma region RegisterLibFunc
|
||||
auto fparam_i32 = std::make_shared<FParam>("", TypeHelper::TYPE_I32);
|
||||
auto pointer_type = std::make_shared<PointerType>(TypeHelper::TYPE_I32);
|
||||
@ -108,9 +108,6 @@ std::any Visitor::visitProgram(SysyParser::ProgramContext *ctx) {
|
||||
_func_tab.push_name("stoptime", func_stoptime);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
SysyBaseVisitor::visitProgram(ctx);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::any Visitor::visitConstDecl(SysyParser::ConstDeclContext *ctx) {
|
||||
@ -124,7 +121,7 @@ std::any Visitor::visitConstDecl(SysyParser::ConstDeclContext *ctx) {
|
||||
// constDef : IDENT ('[' constExp ']')* '=' constInitVal ';'
|
||||
std::any Visitor::visitConstDef(SysyParser::ConstDefContext *ctx) {
|
||||
const auto const_name = ctx->IDENT()->getText();
|
||||
LOG(DEBUG) << "Visiting ConstDef " << const_name;
|
||||
VLOG(5) << "Visiting ConstDef " << const_name;
|
||||
if (_scope_tab.get_name(const_name, _scope_tab.get_level()).has_value())
|
||||
throw GrammarException("Duplicate const def");
|
||||
|
||||
@ -172,6 +169,7 @@ std::any Visitor::visitConstDef(SysyParser::ConstDefContext *ctx) {
|
||||
// global const array
|
||||
auto const_arr = ConstantArr::make_shared("const_arr", array_value, array_type);
|
||||
auto global_var = GlobalVar::make_shared(const_name, const_arr, true);
|
||||
module.global_var_list.push_back(global_var);
|
||||
_scope_tab.push_name(const_name, global_var);
|
||||
}
|
||||
}
|
||||
@ -182,7 +180,7 @@ std::any Visitor::visitConstDef(SysyParser::ConstDefContext *ctx) {
|
||||
// varDef: IDENT ('[' constExp ']')* ('=' initVal)?;
|
||||
std::any Visitor::visitVarDef(SysyParser::VarDefContext *ctx) {
|
||||
auto var_name = ctx->IDENT()->getText();
|
||||
LOG(DEBUG) << "Visiting VarDef " << var_name;
|
||||
VLOG(5) << "Visiting VarDef " << var_name;
|
||||
if (_scope_tab.get_name(var_name, _scope_tab.get_level()).has_value())
|
||||
panic("Duplicate const def");
|
||||
// Not Array
|
||||
@ -195,10 +193,12 @@ std::any Visitor::visitVarDef(SysyParser::VarDefContext *ctx) {
|
||||
auto result = std::any_cast<std::shared_ptr<ConstantInt>>(visitInitVal(ctx->initVal()));
|
||||
_state.isGlobalIint = false;
|
||||
auto global_var_int = std::make_shared<GlobalVar>(var_name, result, false);
|
||||
module.global_var_list.push_back(global_var_int);
|
||||
_scope_tab.push_name(var_name, global_var_int);
|
||||
}
|
||||
else {
|
||||
auto global_var_int = std::make_shared<GlobalVar>(var_name, CONST0, false);
|
||||
module.global_var_list.push_back(global_var_int);
|
||||
_scope_tab.push_name(var_name, global_var_int);
|
||||
}
|
||||
}
|
||||
@ -258,10 +258,12 @@ std::any Visitor::visitVarDef(SysyParser::VarDefContext *ctx) {
|
||||
_state.isGlobalIint = false;
|
||||
auto const_arr = ConstantArr::make_shared("var_arr", array_value, array_type);
|
||||
auto global_var = GlobalVar::make_shared(var_name, const_arr, false);
|
||||
module.global_var_list.push_back(global_var);
|
||||
_scope_tab.push_name(var_name, global_var);
|
||||
}
|
||||
else {
|
||||
auto global_var = GlobalVar::make_shared(var_name, CONST0, false);
|
||||
module.global_var_list.push_back(global_var);
|
||||
_scope_tab.push_name(var_name, global_var);
|
||||
}
|
||||
}
|
||||
@ -373,7 +375,7 @@ std::any Visitor::visitConstExp(SysyParser::ConstExpContext *ctx) {
|
||||
_state.isConstInt = true;
|
||||
auto result = std::any_cast<std::shared_ptr<ConstantInt>>(visitAddExp(ctx->addExp()));
|
||||
_state.isConstInt = false;
|
||||
LOG(DEBUG) << "ConstExp Eval to " << result->value;
|
||||
VLOG(5) << "ConstExp Eval to " << result->value;
|
||||
return {result};
|
||||
}
|
||||
|
||||
@ -525,7 +527,7 @@ std::any Visitor::visitLAndExp(SysyParser::LAndExpContext *ctx) {
|
||||
// @retval: Bool
|
||||
// lOrExp: lAndExp ('||' lAndExp)*;
|
||||
std::any Visitor::visitLOrExp(SysyParser::LOrExpContext *ctx) {
|
||||
LOG(DEBUG) << "Eval to Cond(lOrExp); lineno=" << ctx->getStart()->getLine();
|
||||
VLOG(5) << "Eval to Cond(lOrExp); lineno=" << ctx->getStart()->getLine();
|
||||
auto and_exp_list = ctx->lAndExp();
|
||||
auto n_and_exp = and_exp_list.size();
|
||||
for (int i = 0; i < n_and_exp - 1; ++i) {
|
||||
@ -596,7 +598,7 @@ std::any Visitor::visitUnaryExp(SysyParser::UnaryExpContext *ctx) {
|
||||
// TODO: buildCall/isRealParam
|
||||
// TODO: Handle string & putf()
|
||||
auto func_name = ctx->IDENT()->getText();
|
||||
LOG(DEBUG) << "Calling Func: " << func_name;
|
||||
VLOG(5) << "Calling Func: " << func_name;
|
||||
auto _result = _func_tab.get_name(func_name);
|
||||
sysy_assert(_result.has_value());
|
||||
auto func = _result.value();
|
||||
@ -698,11 +700,11 @@ std::any Visitor::visitIntConst(SysyParser::IntConstContext *ctx) {
|
||||
|
||||
std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
||||
auto name = ctx->IDENT()->getText();
|
||||
LOG(DEBUG) << "Eval to lVal " << name << "; lineno=" << ctx->getStart()->getLine();
|
||||
VLOG(5) << "Eval to lVal " << name << "; lineno=" << ctx->getStart()->getLine();
|
||||
auto _lval = _scope_tab.get_name(name);
|
||||
sysy_assert(_lval.has_value());
|
||||
auto lval = _lval.value();
|
||||
LOG(DEBUG) << "lVal found: " << lval->to_string();
|
||||
VLOG(5) << "lVal found: " << lval->to_string();
|
||||
// @retval: ConstantInt
|
||||
if (lval->type->type_tag == Type::TypeTag::IntegerType) {
|
||||
return {lval};
|
||||
@ -829,14 +831,14 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
||||
|
||||
std::any Visitor::visitFuncDef(SysyParser::FuncDefContext *ctx) {
|
||||
auto func_name = ctx->IDENT()->getText();
|
||||
LOG(DEBUG) << "Visit FuncDef " << func_name;
|
||||
VLOG(5) << "Visit FuncDef " << func_name;
|
||||
auto func_ret_type = TypeHelper::TYPE_VOID;
|
||||
if (ctx->funcType()->INT()) {
|
||||
func_ret_type = TypeHelper::TYPE_I32;
|
||||
}
|
||||
// param list will get collected as well as locally allocated in FuncFParam
|
||||
auto func_obj = std::make_shared<Function>(func_name, func_ret_type);
|
||||
_module.functions.push_back(func_obj);
|
||||
module.function_list.push_back(func_obj);
|
||||
_func_tab.push_name(func_name, func_obj);
|
||||
auto basic_block = build_BasicBlock(func_name + "_ENTRY", func_obj);
|
||||
_scope_tab.enter_scope(true);
|
||||
@ -845,7 +847,7 @@ std::any Visitor::visitFuncDef(SysyParser::FuncDefContext *ctx) {
|
||||
if (ctx->funcFParams()) {
|
||||
visitFuncFParams(ctx->funcFParams());
|
||||
}
|
||||
LOG(DEBUG) << func_obj->to_string();
|
||||
VLOG(5) << func_obj->to_string();
|
||||
visitBlock(ctx->block());
|
||||
// add return
|
||||
// _scope_tab.leave_scope();
|
||||
@ -927,7 +929,7 @@ std::any Visitor::visitAssignStmt(SysyParser::AssignStmtContext *ctx) {
|
||||
|
||||
// TODO: Remove RETURN in else stmt
|
||||
std::any Visitor::visitIfStmt(SysyParser::IfStmtContext *ctx) {
|
||||
LOG(DEBUG) << "Visiting IfStmt "
|
||||
VLOG(5) << "Visiting IfStmt "
|
||||
<< "; lineno=" << ctx->getStart()->getLine();
|
||||
auto true_block = build_BasicBlock("_then", _state.current_func);
|
||||
auto next_block = build_BasicBlock("_next", _state.current_func);
|
||||
@ -953,7 +955,7 @@ std::any Visitor::visitIfStmt(SysyParser::IfStmtContext *ctx) {
|
||||
|
||||
// TODO: backpatching? I am not sure whether it is necessary
|
||||
std::any Visitor::visitWhileStmt(SysyParser::WhileStmtContext *ctx) {
|
||||
LOG(DEBUG) << "Visiting WhileStmt "
|
||||
VLOG(5) << "Visiting WhileStmt "
|
||||
<< "; lineno=" << ctx->getStart()->getLine();
|
||||
auto while_id = std::to_string(_state.loop_stmt_count);
|
||||
auto cond_block = build_BasicBlock("_loop_cond_" + while_id, _state.current_func);
|
||||
|
||||
9
src/visitor_llir_gen.cpp
Normal file
9
src/visitor_llir_gen.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "visitor.h"
|
||||
|
||||
namespace antlrSysY {
|
||||
|
||||
void Visitor::llir_gen() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user