如何在Nim宏中获取无类型标识符的sizeof以验证位范围?
位字段DSL宏的静态验证问题
我完全接受这是一个X:Y问题,以下是背景:
DSL结构与目标
我正在构建一个用于解析特定DSL的辅助宏,代码结构如下:
type FieldDescription[T; bitrange: static Slice[int]] = object UnderlyingBitfield[size:static int, endianness: static Endianness, fields: tuple] = array[size,byte] macro bitfield*(size:int,endianness:Endianness,fields:varargs[untyped]) = ... type MyEnum = enum A,B,C Foo = bitfield(size=4,bigEndian, field1 : uint8 31..28, field2 : MyEnum 27..25, )
静态验证需求
我希望实现静态验证,确保给定类型的位范围有效,核心逻辑示例如下:
let fieldtype = getField(untyped_node) let (hi,lo) = getRange(untyped_node) if (hi - lo) >= sizeof(fieldtype)*8: error(&"bitrange {hi}..{lo} insufficient for type {fieldtype}")
疑问
我想知道:是否有办法实现类似下面的逻辑,直接对untyped节点对应的类型计算大小?
macro foo(x:untyped) = var dummy:typeify(x) echo sizeof(dummy)
还是说必须将DSL中的fields参数改为typed类型传入?如果是这样,该如何操作?
备选方案的不足
我当然可以直接构造底层元组来完成验证:
type Foo = UnderlyingBitfield[4,bigEndian,tuple[ field1:FieldDescription[uint8,31..28], field2:FieldDescription[MyEnum, 27..25]]]
但项目的核心目标是提供简洁清晰的DSL接口,这种写法过于繁琐。
另外,我了解Nim的{.bitsize.}编译指示,但它存在以下问题:
- 不支持不可见的填充字段
- 依赖底层C/C++编译器实现,仍需手动检查每个类型的对齐、字节序和偏移
- 无法按照数据手册中的
hi..lo形式指定位字段 - 会给类型定义带来大量视觉干扰
内容的提问来源于stack exchange,提问作者shirleyquirk
相关产品推荐
相关产品推荐

