2

我已经阅读了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指令将采用这种格式。如果我只使用一个简单的约束将ADDRRR格式联系起来,例如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子类型,但我只是没有使用正确的语法?

4

1 回答 1

0

原则上,当预先知道every ADD instruction实际上是 aADD RRR instruction时,并且希望编译器会自动将不太具体的声明类型的每个变量或表达式视为更具体(允许访问更具体类型的成员而不进行强制转换),那么您可以简单地首先使用更具体的类型进行任何此类声明。

如果事先不知道这一点,那么不幸的是,我看不到任何更好的通用方法来实现这一点。部分解决方法可能是定义一个<type>将转换ADD instruction为的宏ADD RRR instruction,但您需要非常仔细地定义此宏,因为它应该捕获确切使用的语法(例如,如果您希望它捕获短的和完整的 when-qualifiers ,您需要相应地定义它)。您可以尝试制作宏define as computed并在其代码中使用反射 API 来涵盖各种情况。

于 2016-01-03T09:33:29.690 回答