我已经阅读了e中有关“类型”约束的主题。我看到可以限制结构字段的类型,就像在这个例子中一样:
extend DATA packet {
keep type header is a COP header;
};
这意味着每当我处理DATA 数据包时,我不需要将标头转换为COP 标头,因为编译器会为我假设这一点。
我尝试使用“类型”约束来绑定两个不同的行列式字段。例如,假设我们有一个指令 结构,其中包含一个对操作码进行编码的种类字段和一个确定指令采用哪些参数的格式字段:
type instruction_kind : [ ADD, SUB, JMP, BE ] (bits:4);
type format_e : [ RRR, RI, RRI ];
struct instruction {
const kind : instruction_kind;
const format : format_e;
};
例如,RRR格式需要以下参数:
type register_e : [ R0, R1, R2, R3 ] (bits:4);
extend RRR instruction {
rd : register_e;
rs1 : register_e;
rs2 : register_e;
};
ADD指令将采用这种格式。如果我只使用一个简单的约束将ADD与RRR格式联系起来,例如keep kind == ADD => format == RRR
,那么要约束ADD的参数,我需要执行以下操作:
extend sys {
run() is also {
var instr : instruction;
gen instr keeping {
it is a ADD RRR instruction (add) and all of {
add.rd == R3;
add.rs1 == R1;
add.rs2 == R2;
};
};
print instr;
};
};
因为参数是在RRR子类型下定义的,所以我需要显式地转换为它。这很烦人,因为我总是需要查看每条指令的格式。只需要强制转换为ADD 指令会更自然。
为此,我尝试使用“类型”约束,但没有成功。如果我写以下内容:
extend ADD instruction {
keep type me is a RRR instruction;
};
我收到以下错误消息:
*** Error: Type constraints may only be put on fields of this struct
如果我这样写:
extend ADD instruction {
keep type format == RRR;
};
我收到一条不同的错误消息:
*** Error: Type constraints may only equate a property (enum field) of
the context struct with that of an associated struct
第二个错误明确禁止我尝试做的事情,但第一个错误允许解释的余地。
我可以将参数提取到自己的结构中:
struct instruction_args {
const format : format_e;
};
extend RRR instruction_args {
rd : register_e;
rs1 : register_e;
rs2 : register_e;
};
并设置“类型”约束,如文档中所示:
extend instruction {
when ADD { keep type args is a RRR instruction_args };
};
但现在在约束时,我总是需要在每个参数前面加上.args:
extend sys {
run() is also {
var instr : instruction;
gen instr keeping {
it is a ADD instruction (add) and all of {
add.args.rd == R3;
add.args.rs1 == R1;
add.args.rs2 == R2;
};
};
print instr;
};
};
在编写约束时这没什么大不了的,但是在打印时,args
不会打印的内容。这是一个可以接受的解决方法,但我仍然对最初的想法感兴趣。
是否可以关联同一结构中的when子类型,但我只是没有使用正确的语法?