#pragma once #include #include #include #include #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& dst_type) const; std::shared_ptr GetType() const; }; struct SymbolInfo { std::string name; SymbolKind kind = SymbolKind::Object; std::shared_ptr 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 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 ResolveExprType(const void* node) const; private: std::vector> owned_symbols_; std::unordered_map const_defs_; std::unordered_map var_defs_; std::unordered_map func_defs_; std::unordered_map lvals_; std::unordered_map calls_; std::unordered_map> expr_types_; }; SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);