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.
81 lines
2.0 KiB
81 lines
2.0 KiB
// 编译期常量求值与常量初始化展开。
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#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<int64_t> dims;
|
|
std::vector<ConstValue> 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<std::string, Binding>;
|
|
|
|
const Binding* LookupBinding(const std::string& name) const;
|
|
|
|
std::vector<Scope> 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<ConstValue> EvaluateConstInitList(
|
|
SysYParser::ConstInitValContext& init, SymbolDataType elem_type,
|
|
const std::vector<int64_t>& dims) const;
|
|
|
|
private:
|
|
const SymbolTable& table_;
|
|
const ConstEvalContext& ctx_;
|
|
};
|