165 lines
6.7 KiB
C++
165 lines
6.7 KiB
C++
/**
|
||
* @file MachineConfig.h
|
||
* @brief 机器定义(machine.toml)加载与强校验
|
||
* @author
|
||
* @date 2026-08-21
|
||
*
|
||
* @details 见 Doc/isa/指令配置.md:
|
||
* - 配置只给编译器(toml++ 运行时加载);vm 不读配置(内建全指令集)
|
||
* - 强校验 5 项:字段必填 / type.base 命中内建基元·range 合法·tag 契约 /
|
||
* op opcode 唯一·类别-格式互锁 / fb.opcode 与 op 一致·字段类型命中 type 表
|
||
* - 基元内置(bit/int8..uint64/float32/float64,元数据在代码)
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <cstdint>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
namespace compiler {
|
||
|
||
/**
|
||
* @brief 内建基元(编译器内建,C 语义)。
|
||
* @details 元数据写在代码而非 machine.toml;配置类型的 base 必须命中本表。
|
||
*/
|
||
struct PrimType {
|
||
const char* name; ///< 基元名(bit / int8..uint64 / float32 / float64)
|
||
uint32_t width; ///< 宽度(字节)
|
||
bool is_signed; ///< 是否带符号
|
||
bool is_float; ///< 是否浮点
|
||
};
|
||
|
||
/**
|
||
* @brief 配置类型 = 基元别名(+ 值域约束 + .stb 契约 tag)。
|
||
* @details 对应 machine.toml [[type]] 行:base 必为内建基元名;range 可选且
|
||
* min ≤ max;tag 与 .stb 常量表契约一致(0=BOOL、1=INT、2=TIME,唯一)。
|
||
*/
|
||
struct ConfigType {
|
||
std::string name; ///< 配置类型名(大写,如 BOOL/INT/TIME)
|
||
std::string base; ///< 基元名(命中内建基元表)
|
||
bool has_range = false; ///< 是否有值域约束
|
||
int64_t range_min = 0; ///< 值域下界(含)
|
||
int64_t range_max = 0; ///< 值域上界(含)
|
||
uint32_t tag = 0; ///< .stb 常量表契约 tag
|
||
};
|
||
|
||
/**
|
||
* @brief 配置指令。
|
||
* @details 对应 machine.toml [[op]] 行:opcode 唯一且 0..255;class 与 format
|
||
* 互锁(INSTANCE ↔ CAL);params 数量与 format 期望一致。
|
||
*/
|
||
struct ConfigOp {
|
||
std::string name; ///< 助记符(与 .stb / isa 一致)
|
||
uint32_t opcode = 0; ///< 操作码(0..255,表内唯一)
|
||
bool is_instance = false; ///< class:instance / plain
|
||
std::string format; ///< 操作数形态:RR/RRR/IMM/SLOT/JMP/JC/CALL/CAL/NONE
|
||
std::vector<std::string> params; ///< 参数名(数量与 format 一致)
|
||
bool enabled = false; ///< 是否启用
|
||
};
|
||
|
||
/**
|
||
* @brief 内建 FB 的一个字段。
|
||
*/
|
||
struct ConfigFbField {
|
||
std::string name; ///< 字段名(如 in/pt/q/et/cu/cv)
|
||
std::string type; ///< 配置类型名(BOOL/INT/TIME)
|
||
};
|
||
|
||
/**
|
||
* @brief 内建功能块(FB)布局登记。
|
||
* @details 对应 machine.toml [[fb]] 行;opcode 必须命中 instance 类 op 行。
|
||
*/
|
||
struct ConfigFb {
|
||
std::string name; ///< FB 名(小写,如 ton/ctu)
|
||
uint32_t opcode = 0; ///< 对应 op 行 opcode(CAL_*)
|
||
std::vector<ConfigFbField> fields; ///< 字段列表(名称唯一,类型命中 type 表)
|
||
};
|
||
|
||
/**
|
||
* @brief 机器定义:加载 machine.toml 并做强校验。
|
||
* @details 编译器指令集 / 类型的唯一事实来源;校验失败时 ok() 为 false,
|
||
* err 前缀 "machine error"。vm 不读配置(内建全指令集)。
|
||
*/
|
||
class MachineConfig {
|
||
public:
|
||
/**
|
||
* @brief 加载 + 强校验。
|
||
* @param path machine.toml 路径
|
||
* @param err 错误输出;可为 nullptr(静默)
|
||
* @return true 成功;false(err 已写,前缀 "machine error")
|
||
* @details 强校验项:字段必填 / type.base 命中内建基元·range 合法·tag 契约 /
|
||
* op opcode 唯一·类别-格式互锁 / fb.opcode 与 op 一致·字段类型命中
|
||
* type 表(清单见文件头)。
|
||
*/
|
||
bool load(const std::string& path, std::string* err);
|
||
|
||
/// @brief 加载是否成功(校验通过)。
|
||
bool ok() const { return ok_; }
|
||
/// @brief 型号名(meta.name,参与 .stb 型号标识)。
|
||
const std::string& model_name() const { return model_name_; }
|
||
/// @brief 指令集版本(meta.version,参与 .stb 型号标识)。
|
||
uint32_t version() const { return version_; }
|
||
|
||
/// @brief 配置类型表([[type]])。
|
||
const std::vector<ConfigType>& types() const { return types_; }
|
||
/// @brief 配置指令表([[op]])。
|
||
const std::vector<ConfigOp>& ops() const { return ops_; }
|
||
/// @brief 内建 FB 表([[fb]])。
|
||
const std::vector<ConfigFb>& fbs() const { return fbs_; }
|
||
|
||
/**
|
||
* @brief 按配置类型名查类型行。
|
||
* @param name 配置类型名
|
||
* @return 命中指针;未找到返回 nullptr
|
||
*/
|
||
const ConfigType* find_type(const std::string& name) const;
|
||
|
||
/**
|
||
* @brief 按助记符查指令行。
|
||
* @param name 助记符(如 "MOVE")
|
||
* @return 命中指针;未找到返回 nullptr
|
||
*/
|
||
const ConfigOp* find_op(const std::string& name) const;
|
||
|
||
/**
|
||
* @brief 按 opcode 查指令行。
|
||
* @param opcode 操作码(0..255)
|
||
* @return 命中指针;未找到返回 nullptr
|
||
*/
|
||
const ConfigOp* find_op_by_code(uint32_t opcode) const;
|
||
|
||
/**
|
||
* @brief 查询某 opcode 是否启用。
|
||
* @param opcode 操作码
|
||
* @return 指令存在且 enabled 为 true;未知 opcode 返回 false
|
||
*/
|
||
bool op_enabled(uint32_t opcode) const;
|
||
|
||
/**
|
||
* @brief 按名称查内建 FB。
|
||
* @param name FB 名(小写,如 "ton")
|
||
* @return 命中指针;未找到返回 nullptr
|
||
*/
|
||
const ConfigFb* find_fb(const std::string& name) const;
|
||
|
||
/// @brief 内建基元表(bit / int8..uint64 / float32 / float64)。
|
||
static const std::vector<PrimType>& prims();
|
||
|
||
/**
|
||
* @brief 按名称查内建基元。
|
||
* @param name 基元名
|
||
* @return 命中指针;未找到返回 nullptr
|
||
*/
|
||
static const PrimType* find_prim(const std::string& name);
|
||
|
||
private:
|
||
bool ok_ = false; ///< 加载成功标志
|
||
std::string model_name_; ///< 型号名(meta.name)
|
||
uint32_t version_ = 0; ///< 指令集版本(meta.version)
|
||
std::vector<ConfigType> types_; ///< 配置类型表
|
||
std::vector<ConfigOp> ops_; ///< 配置指令表
|
||
std::vector<ConfigFb> fbs_; ///< 内建 FB 表
|
||
};
|
||
}
|