bugfix
This commit is contained in:
parent
dd48562daa
commit
1bbad18f52
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug",
|
||||
"program": "${workspaceFolder}/build/sysy",
|
||||
"args": ["testcases/functional/55_sort_test1.sy", "-S", "-o", "sss"],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -20,6 +20,11 @@
|
||||
|
||||
namespace antlrSysY {
|
||||
|
||||
template <typename T>
|
||||
std::ostream &operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type &stream, const T &e) {
|
||||
return stream << static_cast<typename std::underlying_type<T>::type>(e);
|
||||
}
|
||||
|
||||
class GrammarException : public std::exception {
|
||||
public:
|
||||
GrammarException() : message("Unknown Grammar Exception") {}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
namespace antlrSysY {
|
||||
|
||||
@ -19,6 +20,24 @@ public:
|
||||
TypeTag type_tag;
|
||||
Type(TypeTag type_tag) : type_tag(type_tag) {}
|
||||
virtual ~Type() = default;
|
||||
virtual std::string to_string() {
|
||||
switch (type_tag) {
|
||||
case TypeTag::IntegerType:
|
||||
return "IntegerType";
|
||||
case TypeTag::FunctionType:
|
||||
return "FunctionType";
|
||||
case TypeTag::ArrayType:
|
||||
return "ArrayType";
|
||||
case TypeTag::PointerType:
|
||||
return "PointerType";
|
||||
case TypeTag::VectorType:
|
||||
return "VectorType";
|
||||
case TypeTag::VoidType:
|
||||
return "VoidType";
|
||||
case TypeTag::LabelType:
|
||||
return "LabelType";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class IntegerType : public Type {
|
||||
@ -78,6 +97,9 @@ public:
|
||||
}
|
||||
return std::dynamic_pointer_cast<ArrayType>(array_type);
|
||||
}
|
||||
virtual std::string to_string() override {
|
||||
return "Array[" + std::to_string(element_count) + " x " + element_type->to_string() + "]";
|
||||
}
|
||||
};
|
||||
|
||||
class PointerType : public Type {
|
||||
@ -85,6 +107,12 @@ public:
|
||||
TypePtr_t pointed_type = TypeHelper::TYPE_I32;
|
||||
PointerType() : Type(TypeTag::PointerType) {}
|
||||
PointerType(TypePtr_t pointed_type) : Type(TypeTag::PointerType), pointed_type(pointed_type) {}
|
||||
static auto make_shared(TypePtr_t pointed_type) {
|
||||
return std::make_shared<PointerType>(pointed_type);
|
||||
}
|
||||
virtual std::string to_string() override {
|
||||
return "Pointer->" + pointed_type->to_string();
|
||||
}
|
||||
};
|
||||
|
||||
class FunctionType : public Type {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "3rdparty/easylogging++.h"
|
||||
#include "common.h"
|
||||
#include "llir_type.h"
|
||||
|
||||
@ -16,6 +17,17 @@ public:
|
||||
TypePtr_t type;
|
||||
Value(const std::string &name, TypePtr_t type) : name(name), type(type) {}
|
||||
virtual ~Value() = default;
|
||||
template <typename TT> static bool isType(std::shared_ptr<Value> ptr) {
|
||||
if (ptr.get()) {
|
||||
auto &r = *ptr.get();
|
||||
return typeid(r) == typeid(TT);
|
||||
}
|
||||
LOG(WARNING) << "Comparing with nullptr";
|
||||
return false;
|
||||
}
|
||||
virtual std::string to_string() {
|
||||
return name + ": " + type->to_string();
|
||||
}
|
||||
};
|
||||
|
||||
class User : public Value {
|
||||
@ -34,10 +46,21 @@ class Function : public Value {
|
||||
public:
|
||||
std::vector<std::shared_ptr<FParam>> fparam_list;
|
||||
std::vector<std::shared_ptr<BasicBlock>> bb_list;
|
||||
// we use empty basic_block to represent lib function
|
||||
Function(const std::string &name, TypePtr_t ret_type) : Value(name, std::make_shared<FunctionType>(ret_type)) {}
|
||||
std::shared_ptr<FunctionType> get_type() {
|
||||
return std::dynamic_pointer_cast<FunctionType>(type);
|
||||
}
|
||||
bool is_libfunc() {
|
||||
return bb_list.size() == 0;
|
||||
}
|
||||
virtual std::string to_string() override {
|
||||
std::string params_str;
|
||||
for (auto fparam : fparam_list) {
|
||||
params_str += fparam->to_string() + ",";
|
||||
}
|
||||
return name + "(" + params_str + ") -> " + type->to_string();
|
||||
}
|
||||
};
|
||||
|
||||
class BasicBlock : public Value {
|
||||
@ -82,12 +105,13 @@ public:
|
||||
|
||||
typedef std::shared_ptr<Constant> ConstantPtr_t;
|
||||
|
||||
// emmm, actually it is more of a Instruction type
|
||||
class GlobalVar : public Value {
|
||||
public:
|
||||
ConstantPtr_t init_value;
|
||||
bool is_const;
|
||||
GlobalVar(const std::string &name, ConstantPtr_t init_value, bool is_const)
|
||||
: Value(name, init_value->type), init_value(init_value), is_const(is_const) {}
|
||||
: Value(name, PointerType::make_shared(init_value->type)), init_value(init_value), is_const(is_const) {}
|
||||
static std::shared_ptr<GlobalVar> make_shared(const std::string &name, ConstantPtr_t init_value, bool is_const) {
|
||||
return std::make_shared<GlobalVar>(name, init_value, is_const);
|
||||
}
|
||||
@ -129,6 +153,62 @@ public:
|
||||
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 {
|
||||
@ -215,14 +295,17 @@ public:
|
||||
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 (typeid(pointer) == typeid(std::shared_ptr<InstGEP>)) {
|
||||
if (Value::isType<InstGEP>(pointer)) {
|
||||
aim_to = std::dynamic_pointer_cast<InstGEP>(pointer)->aim_to;
|
||||
}
|
||||
else {
|
||||
sysy_assert(typeid(pointer) == typeid(std::shared_ptr<InstAlloca>) ||
|
||||
typeid(pointer) == typeid(std::shared_ptr<GlobalVar>));
|
||||
else if (Value::isType<InstAlloca>(pointer) || Value::isType<GlobalVar>(pointer)){
|
||||
aim_to = pointer;
|
||||
}
|
||||
else {
|
||||
LOG(WARNING) << "Unexpected pointer type" << pointer->to_string();
|
||||
aim_to = pointer;
|
||||
panic("message");
|
||||
}
|
||||
element_type = extract_type(pointer, indices);
|
||||
operand_list.push_back(pointer);
|
||||
operand_list.insert(operand_list.end(), indices.begin(), indices.end());
|
||||
@ -232,8 +315,9 @@ public:
|
||||
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() - 1; ++i) {
|
||||
for (int i = 1; i < indices.size(); ++i) {
|
||||
pointed_type = std::dynamic_pointer_cast<ArrayType>(pointed_type)->element_type;
|
||||
}
|
||||
}
|
||||
@ -241,7 +325,8 @@ public:
|
||||
return pointed_type;
|
||||
}
|
||||
else {
|
||||
panic("Unmatch indices and array pointer");
|
||||
LOG(WARNING) << "not returning an int-type";
|
||||
return pointed_type;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,10 +90,7 @@ public:
|
||||
}
|
||||
CONST0 = std::make_shared<ConstantInt>("CONST0", 0);
|
||||
}
|
||||
std::any visitProgram(SysyParser::ProgramContext *ctx) override {
|
||||
// before visiting, we add some lib functions
|
||||
return this->SysyBaseVisitor::visitProgram(ctx);
|
||||
}
|
||||
std::any visitProgram(SysyParser::ProgramContext *ctx) override;
|
||||
|
||||
// std::any visitCompUnit(SysyParser::CompUnitContext *ctx) override;
|
||||
|
||||
@ -158,7 +155,7 @@ public:
|
||||
|
||||
std::any visitReturnStmt(SysyParser::ReturnStmtContext *ctx) override;
|
||||
|
||||
// std::any visitCond(SysyParser::CondContext *ctx) override;
|
||||
std::any visitCond(SysyParser::CondContext *ctx) override;
|
||||
|
||||
// std::any visitFuncRParams(SysyParser::FuncRParamsContext *ctx) override;
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ class Compiler:
|
||||
for testcase in self.testcases:
|
||||
Print_C.print_subheader(f"[Compiling {self.scheme} | {testcase}]")
|
||||
self.sy_to_ir(frontend_instr=frontend_instr, testcase=testcase, category=category)
|
||||
if self.count_error >= 10:
|
||||
if self.count_error >= 5:
|
||||
Print_C.print_error(f"Test script stopped due to too many errors")
|
||||
return
|
||||
|
||||
|
||||
140
src/visitor.cpp
140
src/visitor.cpp
@ -39,10 +39,80 @@ static ValuePtr_t any_to_Value(const std::any &fuck_any) {
|
||||
ANY2VALUE(InstBranch)
|
||||
ANY2VALUE(InstReturn)
|
||||
ANY2VALUE(InstCall)
|
||||
ANY2VALUE(InstGEP)
|
||||
LOG(ERROR) << fuck_any.type().name();
|
||||
panic("Unreachable");
|
||||
}
|
||||
|
||||
static TypePtr_t any_to_Type(const std::any &fuck_any) {
|
||||
ANY2VALUE(Type)
|
||||
ANY2VALUE(ArrayType)
|
||||
ANY2VALUE(FunctionType)
|
||||
ANY2VALUE(IntegerType)
|
||||
ANY2VALUE(PointerType)
|
||||
LOG(ERROR) << fuck_any.type().name();
|
||||
panic("Unreachable");
|
||||
}
|
||||
|
||||
/*
|
||||
int getint(),getch(),getarray(int a[]);
|
||||
void putint(int a),putch(int a),putarray(int n,int a[]);
|
||||
#define starttime() _sysy_starttime(__LINE__)
|
||||
#define stoptime() _sysy_stoptime(__LINE__)
|
||||
__attribute((constructor)) void before_main();
|
||||
__attribute((destructor)) void after_main();
|
||||
void _sysy_starttime(int lineno);
|
||||
void _sysy_stoptime(int lineno);
|
||||
*/
|
||||
|
||||
std::any Visitor::visitProgram(SysyParser::ProgramContext *ctx) {
|
||||
|
||||
#pragma region RegisterLibFunc
|
||||
auto fparam_i32 = std::make_shared<FParam>("", TypeHelper::TYPE_I32);
|
||||
auto pointer_type = std::make_shared<PointerType>(TypeHelper::TYPE_I32);
|
||||
auto fparam_ptr_i32 = std::make_shared<FParam>("", pointer_type);
|
||||
|
||||
auto func_getint = std::make_shared<Function>("getint", TypeHelper::TYPE_I32);
|
||||
// void param
|
||||
_func_tab.push_name("getint", func_getint);
|
||||
|
||||
auto func_getch = std::make_shared<Function>("getch", TypeHelper::TYPE_I32);
|
||||
// void param
|
||||
_func_tab.push_name("getch", func_getch);
|
||||
|
||||
auto func_getarray = std::make_shared<Function>("getarray", TypeHelper::TYPE_I32);
|
||||
func_getarray->fparam_list.push_back(fparam_ptr_i32);
|
||||
_func_tab.push_name("getarray", func_getarray);
|
||||
|
||||
auto func_putint = std::make_shared<Function>("putint", TypeHelper::TYPE_VOID);
|
||||
func_putint->fparam_list.push_back(fparam_i32);
|
||||
_func_tab.push_name("putint", func_putint);
|
||||
|
||||
auto func_putch = std::make_shared<Function>("putch", TypeHelper::TYPE_VOID);
|
||||
func_putch->fparam_list = {fparam_i32};
|
||||
_func_tab.push_name("putch", func_putch);
|
||||
|
||||
auto func_putarray = std::make_shared<Function>("putarray", TypeHelper::TYPE_VOID);
|
||||
func_putarray->fparam_list = {fparam_ptr_i32, fparam_i32};
|
||||
_func_tab.push_name("putarray", func_putarray);
|
||||
|
||||
// auto func_putf = std::make_shared<Function>("putf", TypeHelper::TYPE_VOID);
|
||||
// should not be used
|
||||
|
||||
auto func_starttime = std::make_shared<Function>("_sysy_starttime", TypeHelper::TYPE_VOID);
|
||||
func_starttime->fparam_list = {fparam_i32};
|
||||
_func_tab.push_name("starttime", func_starttime);
|
||||
|
||||
auto func_stoptime = std::make_shared<Function>("_sysy_stoptime", TypeHelper::TYPE_VOID);
|
||||
func_stoptime->fparam_list = {fparam_i32};
|
||||
_func_tab.push_name("stoptime", func_stoptime);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
SysyBaseVisitor::visitProgram(ctx);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::any Visitor::visitConstDecl(SysyParser::ConstDeclContext *ctx) {
|
||||
for (auto constDef : ctx->constDef()) {
|
||||
visitConstDef(constDef);
|
||||
@ -222,7 +292,7 @@ std::any Visitor::visitInitVal(SysyParser::InitValContext *ctx) {
|
||||
if (_state.isGlobalIint) {
|
||||
auto const_value = any_to_Value(visitInitVal(init_val));
|
||||
// should evaluate to const int
|
||||
sysy_assert(typeid(const_value) == typeid(std::shared_ptr<ConstantInt>));
|
||||
sysy_assert(Value::isType<ConstantInt>(const_value));
|
||||
cur_arr.push_back(const_value);
|
||||
}
|
||||
else {
|
||||
@ -347,9 +417,9 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) {
|
||||
|
||||
std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) {
|
||||
if (_state.isConstInt) {
|
||||
auto result = std::any_cast<std::shared_ptr<ConstantInt>>(visitUnaryExp(ctx->unaryExp()));
|
||||
auto result = std::dynamic_pointer_cast<ConstantInt>(any_to_Value(visitUnaryExp(ctx->unaryExp())));
|
||||
if (ctx->mulExp()) {
|
||||
auto mul_result = std::any_cast<std::shared_ptr<ConstantInt>>(visitMulExp(ctx->mulExp()));
|
||||
auto mul_result = std::dynamic_pointer_cast<ConstantInt>(any_to_Value(visitMulExp(ctx->mulExp())));
|
||||
if (ctx->MUL()) {
|
||||
result->value = mul_result->value * result->value;
|
||||
}
|
||||
@ -392,25 +462,25 @@ std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) {
|
||||
// relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp;
|
||||
std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) {
|
||||
auto add_exp = any_to_Value(visitAddExp(ctx->addExp()));
|
||||
// should always has type I32
|
||||
sysy_assert(TypeHelper::isIntegerTypeI32(add_exp->type));
|
||||
if (ctx->relExp()) {
|
||||
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
||||
sysy_assert(TypeHelper::isIntegerTypeI32(rel_exp->type));
|
||||
if (ctx->relExp()->LE()) {
|
||||
if (ctx->LE()) {
|
||||
add_exp = build_InstBinary(InstTag::Le, rel_exp, add_exp, _state.current_bb);
|
||||
}
|
||||
else if (ctx->relExp()->LT()) {
|
||||
else if (ctx->LT()) {
|
||||
add_exp = build_InstBinary(InstTag::Lt, rel_exp, add_exp, _state.current_bb);
|
||||
}
|
||||
else if (ctx->relExp()->GE()) {
|
||||
else if (ctx->GE()) {
|
||||
add_exp = build_InstBinary(InstTag::Ge, rel_exp, add_exp, _state.current_bb);
|
||||
}
|
||||
else if (ctx->relExp()->GT()) {
|
||||
else if (ctx->GT()) {
|
||||
add_exp = build_InstBinary(InstTag::Gt, rel_exp, add_exp, _state.current_bb);
|
||||
}
|
||||
else
|
||||
else {
|
||||
LOG(ERROR) << ctx->relExp()->getStart()->getLine() << ":" << ctx->relExp()->getText();
|
||||
panic("Unreachable");
|
||||
}
|
||||
}
|
||||
return add_exp;
|
||||
}
|
||||
@ -418,10 +488,10 @@ std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) {
|
||||
// eqExp: relExp | eqExp ('==' | '!=') relExp;
|
||||
std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) {
|
||||
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
||||
sysy_assert(TypeHelper::isIntegerTypeI1(rel_exp->type));
|
||||
// sysy_assert(TypeHelper::isIntegerTypeI1(rel_exp->type));
|
||||
if (ctx->eqExp()) {
|
||||
auto eq_exp = any_to_Value(visitEqExp(ctx->eqExp()));
|
||||
sysy_assert(TypeHelper::isIntegerTypeI1(eq_exp->type));
|
||||
// sysy_assert(TypeHelper::isIntegerTypeI1(eq_exp->type));
|
||||
if (ctx->EQ()) {
|
||||
rel_exp = build_InstBinary(InstTag::Eq, eq_exp, rel_exp, _state.current_bb);
|
||||
}
|
||||
@ -444,7 +514,6 @@ std::any Visitor::visitLAndExp(SysyParser::LAndExpContext *ctx) {
|
||||
for (int i = 0; i < eq_exp_list.size(); ++i) {
|
||||
auto next_block = build_BasicBlock("", _state.current_func);
|
||||
auto eq_exp = any_to_Value(visitEqExp(eq_exp_list[i]));
|
||||
sysy_assert(TypeHelper::isIntegerTypeI1(eq_exp->type)); // expect a boolean
|
||||
auto condition = build_InstBinary(InstTag::Ne, eq_exp, CONST0, _state.current_bb);
|
||||
build_InstBranch(condition, next_block, ctx->false_block, _state.current_bb);
|
||||
_state.current_bb = next_block;
|
||||
@ -456,16 +525,26 @@ std::any Visitor::visitLAndExp(SysyParser::LAndExpContext *ctx) {
|
||||
// @retval: Bool
|
||||
// lOrExp: lAndExp ('||' lAndExp)*;
|
||||
std::any Visitor::visitLOrExp(SysyParser::LOrExpContext *ctx) {
|
||||
auto n_and_exp = ctx->lAndExp().size();
|
||||
LOG(DEBUG) << "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) {
|
||||
auto next_block = build_BasicBlock("", _state.current_func);
|
||||
ctx->lAndExp(i)->true_block = ctx->true_block;
|
||||
ctx->lAndExp(i)->false_block = next_block;
|
||||
visitLAndExp(ctx->lAndExp(i));
|
||||
visitLAndExp(and_exp_list[i]);
|
||||
_state.current_bb = next_block;
|
||||
}
|
||||
ctx->lAndExp(n_and_exp - 1)->true_block = ctx->true_block;
|
||||
ctx->lAndExp(n_and_exp - 1)->false_block = ctx->false_block;
|
||||
visitLAndExp(ctx->lAndExp(n_and_exp-1));
|
||||
return {};
|
||||
}
|
||||
|
||||
std::any Visitor::visitCond(SysyParser::CondContext *ctx) {
|
||||
_state.isCondExp = true;
|
||||
visitLOrExp(ctx->lOrExp());
|
||||
_state.isCondExp = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -551,9 +630,10 @@ std::any Visitor::visitPrimaryExp(SysyParser::PrimaryExpContext *ctx) {
|
||||
}
|
||||
else if (ctx->lVal()) {
|
||||
auto value = any_to_Value(visitLVal(ctx->lVal()));
|
||||
auto constint = std::dynamic_pointer_cast<ConstantInt>(value);
|
||||
// auto constint = std::dynamic_pointer_cast<ConstantInt>(value);
|
||||
// actually, it is only a type assertion
|
||||
return constint->value;
|
||||
// return constint->value;
|
||||
return value;
|
||||
}
|
||||
else if (ctx->number()) {
|
||||
return visitNumber(ctx->number());
|
||||
@ -579,7 +659,7 @@ std::any Visitor::visitPrimaryExp(SysyParser::PrimaryExpContext *ctx) {
|
||||
}
|
||||
// @retval: InstLoad
|
||||
else {
|
||||
LOG(WARNING) << "lval type is pointer";
|
||||
LOG(WARNING) << "lval type is pointer: " << lval->type->type_tag;
|
||||
// should be InstAlloca
|
||||
auto ptr_type = std::dynamic_pointer_cast<PointerType>(lval->type);
|
||||
return build_InstLoad(lval, ptr_type->pointed_type, _state.current_bb);
|
||||
@ -618,10 +698,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;
|
||||
LOG(DEBUG) << "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();
|
||||
// @retval: ConstantInt
|
||||
if (lval->type->type_tag == Type::TypeTag::IntegerType) {
|
||||
return {lval};
|
||||
@ -653,18 +734,19 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
||||
// ??? Pointer
|
||||
// @retval: InstLoad
|
||||
LOG(WARNING) << "Unexpected pointer";
|
||||
auto pointed_type = std::dynamic_pointer_cast<PointerType>(lval)->pointed_type;
|
||||
auto pointed_type = std::dynamic_pointer_cast<PointerType>(lval->type)->pointed_type;
|
||||
auto inst_load = build_InstLoad(lval, pointed_type, _state.current_bb);
|
||||
return inst_load;
|
||||
}
|
||||
else {
|
||||
// fparam array, whose first dim is represented by a pointer
|
||||
auto pointed_type = std::dynamic_pointer_cast<PointerType>(lval)->pointed_type;
|
||||
sysy_assert(pointed_type->type_tag == Type::TypeTag::ArrayType);
|
||||
auto pointed_type = std::dynamic_pointer_cast<PointerType>(lval->type)->pointed_type;
|
||||
auto inst_load = build_InstLoad(lval, pointed_type, _state.current_bb);
|
||||
|
||||
auto ptr = build_InstGEP(inst_load, {CONST0}, _state.current_bb);
|
||||
pointed_type = std::dynamic_pointer_cast<PointerType>(ptr->type)->pointed_type;
|
||||
LOG(INFO) << pointed_type->to_string();
|
||||
sysy_assert(pointed_type->type_tag == Type::TypeTag::ArrayType);
|
||||
ValuePtr_t offset = ConstantInt::make_shared(0);
|
||||
auto exp_list = ctx->exp();
|
||||
// calculate offset by hand: offset = (offset + exp[i]) * dim_size[i]
|
||||
@ -704,7 +786,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
||||
auto exp_list = ctx->exp();
|
||||
// calculate offset by hand: offset = (offset + exp[i]) * dim_size[i]
|
||||
for (int i = 0; i < exp_list.size() - 1; ++i) {
|
||||
sysy_assert(typeid(pointed_type) == typeid(std::shared_ptr<ArrayType>));
|
||||
sysy_assert(pointed_type->type_tag == Type::TypeTag::ArrayType);
|
||||
auto array_type = std::dynamic_pointer_cast<ArrayType>(pointed_type);
|
||||
auto exp_val = any_to_Value(visitExp(exp_list[i]));
|
||||
auto dim_size = ConstantInt::make_shared(array_type->element_count);
|
||||
@ -752,6 +834,7 @@ std::any Visitor::visitFuncDef(SysyParser::FuncDefContext *ctx) {
|
||||
if (ctx->funcFParams()) {
|
||||
visitFuncFParams(ctx->funcFParams());
|
||||
}
|
||||
LOG(DEBUG) << func_obj->to_string();
|
||||
visitBlock(ctx->block());
|
||||
// add return
|
||||
// _scope_tab.leave_scope();
|
||||
@ -769,10 +852,9 @@ std::any Visitor::visitFuncDef(SysyParser::FuncDefContext *ctx) {
|
||||
// Directly add to function, rather than return something...
|
||||
std::any Visitor::visitFuncFParams(SysyParser::FuncFParamsContext *ctx) {
|
||||
for (auto fparam_ctx : ctx->funcFParam()) {
|
||||
auto fparam_type = std::any_cast<TypePtr_t>(visitFuncFParam(fparam_ctx));
|
||||
auto fparam_name = fparam_ctx->getText();
|
||||
auto fparam_type = any_to_Type(visitFuncFParam(fparam_ctx));
|
||||
auto fparam_name = fparam_ctx->IDENT()->getText();
|
||||
auto fparam = std::make_shared<FParam>(fparam_name, fparam_type);
|
||||
_state.current_func->fparam_list.push_back(fparam);
|
||||
auto alloca_ = build_InstAlloca(fparam_type, _state.current_bb);
|
||||
build_InstStore(fparam, alloca_, _state.current_bb);
|
||||
_scope_tab.push_name(fparam_name, alloca_);
|
||||
@ -789,7 +871,7 @@ std::any Visitor::visitFuncFParam(SysyParser::FuncFParamContext *ctx) {
|
||||
}
|
||||
else {
|
||||
// array type
|
||||
std::vector<int> dim_list; // the first dim must be empty, though
|
||||
std::vector<int> dim_list = {0}; // the first dim must be empty, though
|
||||
for (auto exp_ctx : ctx->exp()) {
|
||||
_state.isConstInt = true;
|
||||
auto exp_val = std::dynamic_pointer_cast<ConstantInt>(any_to_Value(visitExp(exp_ctx)));
|
||||
@ -833,6 +915,8 @@ std::any Visitor::visitAssignStmt(SysyParser::AssignStmtContext *ctx) {
|
||||
|
||||
// TODO: Remove RETURN in else stmt
|
||||
std::any Visitor::visitIfStmt(SysyParser::IfStmtContext *ctx) {
|
||||
LOG(DEBUG) << "Visiting IfStmt "
|
||||
<< "; lineno=" << ctx->getStart()->getLine();
|
||||
auto true_block = build_BasicBlock("_then", _state.current_func);
|
||||
auto next_block = build_BasicBlock("_next", _state.current_func);
|
||||
auto false_block = next_block;
|
||||
@ -857,6 +941,8 @@ 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 "
|
||||
<< "; 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);
|
||||
auto body_block = build_BasicBlock("_loop_body_" + while_id, _state.current_func);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user