Java8表示条件作为方法引用数组

时间:2015-11-26 11:09:59

标签: java dictionary currying method-reference partial-application

我代表了大量的对象(特别是MIPS32指令)。我的最小工作示例将描述R格式的指令。

MIPS32背景(R型指令)

R型指令由组合唯一确定 其操作码及其功能(功能)字段。操作码是 当表示为32位时,指令的最左边的6位 数字和最右边的6位组成功能字段。

R型指令的常见分解是位域 长度(6,5,5,5,5,6)。然后比特字段代表 以下单位

--------------------------------------------------------
| 6 bits  | 5 bits | 5 bits | 5 bits | 5 bits | 6 bits |
|:-------:|:------:|:------:|:------:|:------:|:------:|
| op      | rs     | rt     | rd     | shamt  | funct  |
--------------------------------------------------------

因此,R型指令的唯一标识符(密钥) 是元组(操作码,函数),它具有一对一的关系 使用R型指令

示例:mul

考虑32位数0x71014802。它被分解 进入不同长度的字段,取决于format 指令。

对于MIPS32指令中的所有数字,设置最左边的6位 始终代表指令的操作码。仅操作码就是 并不总是足以识别特定指令, 始终足以识别其格式 指令。

0x71014802的最左边六位是0x1c。它是 已知该数字对应于中的指令 R-格式。格式指定剩余位的哪些字段 分解成。

如前所述,所有说明都可能无法辨别 他们的操作码单独。这适用于所有R型指令。

0x71014802分解为显示的字段 上表生成rs=8rt=1rd=9shamt=0funct=2。该指令的分解表示形式,以十六进制表示 因此,形式[0x1c 8 1 9 0 2]。相应的 十进制表示[28 8 1 9 0 2]

识别由...表示的特定指令 功能字段必须为0x71014802 咨询。配对操作码,0x1c和值中的值 funct 字段唯一标识指令a mul指令。

在我的源代码中,我以下列方式表示mul指令

/**
 * Multiply (without overflow). Put the low-order 32 bits of
 * the product of rs and rt into register rd.
 */
// TODO: Validate that shamt is 0
MUL(0x1c, 2, R::rd, R::rs, R::rt),

方法引用R::rd, R::rs, R::rt用于通过从分解的表示中提取适当的字段并在表中查找寄存器名称来创建指令的人工清晰表示(这对我们来说并不重要,但它解释了为什么它存在。)

TODO注释表示这些对象还应满足0或更多条件才能被视为有效。正如您所看到的,我们已经在一个地方存储了大量有关MUL的信息,其操作码及其功能字段可以唯一地标识它以及如何生成人类清晰的表示。

剩下的内容也包括验证步骤。

在Python中我会使用字典。

{'shamt': 0, 
 other conditions
}

我稍后会解析。

在Java中我要么必须有一个静态初始化HashMap来表示这个,或者可以想象一个二维数组(Object[][])可以服务然后做一些内部解析和评估那个。 根据我的说法,Java的冗长会使意图更难以理解。

我想表达的是以某种方式声明当使用某个参数调用某个特定函数时,我希望它返回true

我希望所有这些条件都能评估为true,所以我稍后会对它们进行评估。

所以我在思考某种形式的部分应用,比如我有一个功能

shamt(int expectedValue) {
    // Check that the value of shamt matched the expected value
}

然后类似于

new Supplier<Boolean>[] {
    0x00 -> RTypeInstruction::shamt
}

显然不起作用,可能是正确的方向。 在这里以某种方式具有命名引用是重要的,因为指定整数之间的排序关系是不够的,因为这没有给出关于哪个位域必须满足特定条件的任何指示。

我不希望有一个数组为每个位字段指定一个条件,因为条件很少会影响一个或两个位字段,但它确实发生了。

可以说,识别步骤(操作码,功能)也是条件,但这使得难以区分识别指令的失败和指令只是半有效。这意味着我们希望能够将指令识别为mul指令,即使shamt非零并且通知用户输入有些格式错误(半有效)。

shamt方法可以操作的值存储在enum内部。不指定过多方法的原因是

boolean shamtIsZero() { ... }

因为有很多不同的条件。请参阅后面的示例。 Java是不是很适合这个?我应该使用HashMap来评估那个或者是否有一些整齐的FunctionalInterface可以帮助我做到这一点?

示例:mtc1

操作码mtc1标识了另一条指令0x11,并且功能字段设置为0x00

/**
 * Move to coprocessor 0, move CPU register rt to register
 * fs in the FPU. fs occupies the rd field. Note the pattern that
 * the MTC and MTF operations share the same opcode and funct
 * field. The rs field distinguishes them.
 */
// TODO: Validate that rs = 4 and funct and shamt = 0
MTC1(0x11, 0x00, R::rt, R::fs)

正如你在这里看到的,我们必须满足几个条件,其中一个位域必须是0以外的东西。正因为这个原因,我们不希望为每个条件设置一个单独的方法,因为它们将成为众多。

1 个答案:

答案 0 :(得分:0)

您可以在构造函数中传递多个条件 - 您甚至可以将它们Predicates

enum MIPS32Instructions {

    MUL("MUL", (v) -> v > 0),
    DIV("DIV", (v) -> v > 1, (v) -> v != 9);
    final String id;
    final Predicate<Integer>[] conditions;

    MIPS32Instructions(String id, Predicate<Integer>... conditions) {
        this.id = id;
        this.conditions = conditions;
    }

    public boolean checkConditions(int v) {
        return Arrays.stream(conditions)
                .allMatch((c) -> c.test(v));
    }

}