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

#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);