forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.7 KiB
78 lines
2.7 KiB
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "SysYParser.h"
|
|
#include "ir/IR.h"
|
|
|
|
enum class SymbolKind { Object, Function };
|
|
|
|
struct ConstantData {
|
|
enum class Kind { Int, Float };
|
|
|
|
Kind kind = Kind::Int;
|
|
int int_value = 0;
|
|
float float_value = 0.0f;
|
|
|
|
static ConstantData FromInt(int value);
|
|
static ConstantData FromFloat(float value);
|
|
|
|
bool IsInt() const { return kind == Kind::Int; }
|
|
bool IsFloat() const { return kind == Kind::Float; }
|
|
int AsInt() const;
|
|
float AsFloat() const;
|
|
ConstantData CastTo(const std::shared_ptr<ir::Type>& dst_type) const;
|
|
std::shared_ptr<ir::Type> GetType() const;
|
|
};
|
|
|
|
struct SymbolInfo {
|
|
std::string name;
|
|
SymbolKind kind = SymbolKind::Object;
|
|
std::shared_ptr<ir::Type> type;
|
|
bool is_const = false;
|
|
bool is_global = false;
|
|
bool is_parameter = false;
|
|
bool is_array_parameter = false;
|
|
bool is_builtin = false;
|
|
|
|
SysYParser::ConstDefContext* const_def = nullptr;
|
|
SysYParser::VarDefContext* var_def = nullptr;
|
|
SysYParser::FuncDefContext* func_def = nullptr;
|
|
|
|
bool has_const_value = false;
|
|
ConstantData const_value{};
|
|
};
|
|
|
|
class SemanticContext {
|
|
public:
|
|
SymbolInfo* CreateSymbol(SymbolInfo symbol);
|
|
|
|
void BindConstDef(SysYParser::ConstDefContext* node, const SymbolInfo* symbol);
|
|
void BindVarDef(SysYParser::VarDefContext* node, const SymbolInfo* symbol);
|
|
void BindFuncDef(SysYParser::FuncDefContext* node, const SymbolInfo* symbol);
|
|
void BindLVal(SysYParser::LValContext* node, const SymbolInfo* symbol);
|
|
void BindCall(SysYParser::UnaryExpContext* node, const SymbolInfo* symbol);
|
|
void SetExprType(const void* node, std::shared_ptr<ir::Type> type);
|
|
|
|
const SymbolInfo* ResolveConstDef(const SysYParser::ConstDefContext* node) const;
|
|
const SymbolInfo* ResolveVarDef(const SysYParser::VarDefContext* node) const;
|
|
const SymbolInfo* ResolveFuncDef(const SysYParser::FuncDefContext* node) const;
|
|
const SymbolInfo* ResolveLVal(const SysYParser::LValContext* node) const;
|
|
const SymbolInfo* ResolveCall(const SysYParser::UnaryExpContext* node) const;
|
|
std::shared_ptr<ir::Type> ResolveExprType(const void* node) const;
|
|
|
|
private:
|
|
std::vector<std::unique_ptr<SymbolInfo>> owned_symbols_;
|
|
std::unordered_map<const SysYParser::ConstDefContext*, const SymbolInfo*> const_defs_;
|
|
std::unordered_map<const SysYParser::VarDefContext*, const SymbolInfo*> var_defs_;
|
|
std::unordered_map<const SysYParser::FuncDefContext*, const SymbolInfo*> func_defs_;
|
|
std::unordered_map<const SysYParser::LValContext*, const SymbolInfo*> lvals_;
|
|
std::unordered_map<const SysYParser::UnaryExpContext*, const SymbolInfo*> calls_;
|
|
std::unordered_map<const void*, std::shared_ptr<ir::Type>> expr_types_;
|
|
};
|
|
|
|
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);
|