// 编译期常量求值与常量初始化展开。 #pragma once #include #include #include #include #include "SysYParser.h" #include "sem/SymbolTable.h" struct ConstValue { SymbolDataType type = SymbolDataType::Unknown; int64_t int_value = 0; double float_value = 0.0; bool bool_value = false; static ConstValue FromInt(int64_t value); static ConstValue FromFloat(double value); static ConstValue FromBool(bool value); bool IsScalar() const; bool IsNumeric() const; int64_t AsInt() const; double AsFloat() const; bool AsBool() const; }; struct ConstArrayValue { SymbolDataType elem_type = SymbolDataType::Unknown; std::vector dims; std::vector elements; }; class ConstEvalContext { public: ConstEvalContext(); void EnterScope(); void ExitScope(); bool DefineScalar(const std::string& name, ConstValue value); bool DefineArray(const std::string& name, ConstArrayValue value); const ConstValue* LookupScalar(const std::string& name) const; const ConstArrayValue* LookupArray(const std::string& name) const; private: struct Binding { bool is_array = false; ConstValue scalar; ConstArrayValue array; }; using Scope = std::unordered_map; const Binding* LookupBinding(const std::string& name) const; std::vector scopes_; }; class ConstEvaluator { public: ConstEvaluator(const SymbolTable& table, const ConstEvalContext& ctx); ConstValue EvaluateConstExp(SysYParser::ConstExpContext& ctx) const; ConstValue EvaluateExp(SysYParser::ExpContext& ctx) const; // 数组维度必须是正整数。 int64_t EvaluateArrayDim(SysYParser::ConstExpContext& ctx) const; // 展平 const 初始化列表,结果按行优先顺序存放。 std::vector EvaluateConstInitList( SysYParser::ConstInitValContext& init, SymbolDataType elem_type, const std::vector& dims) const; private: const SymbolTable& table_; const ConstEvalContext& ctx_; };