Class Op
There is no separate "SCALE" instruction with a unit operand: every unit type gets its own opcode, OP_SCALE+ut. The whole space therefore fits in the values 1 to OP_LAST (38 with the current 29 units), comfortably below 63, which is what SendTransaction.appendUnsigned(int) encodes in a single byte. Every instruction on the wire is thus exactly one byte, plus the constant triple that follows an OP_CONST.
The only instruction carrying an operand is OP_CONST. In the in-memory code array it occupies TWO slots: the opcode itself followed by the index of the constant in the parallel constant arrays of the Formula. On the wire the constant value follows the opcode inline instead, since constants are emitted in code order and there is no constant pool.
Stack effects:
| Opcode | Pops | Pushes |
|---|---|---|
OP_CONST | 0 | 1 |
OP_SCALE+ut | 1 | 1 |
OP_NEG | 1 | 1 |
OP_ADD OP_SUB OP_MUL OP_DIV OP_MIN2 OP_MAX2 | 2 | 1 |
- Author:
- Christopher Mindus
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intAddition.static final intPush a constant.static final intDivision.static final intThe numerically largest legal opcode.static final intBinary maximum, used to fold the variadicmax()pairwise.static final intBinary minimum, used to fold the variadicmin()pairwise.static final intMultiplication.static final intUnary negation.static final intThe base of the per-unit scale opcodes: the opcode that multiplies the top of the stack byscaleTable[ut]isOP_SCALE+ut, so the scale opcodes occupyOP_SCALE+1toOP_SCALE+UnitType.UNIT_COUNT.static final intSubtraction.Method Summary
Modifier and TypeMethodDescriptionstatic booleanisScale(int op) Checks if an opcode is one of the scale opcodes.static intscaleOp(int ut) Returns the scale opcode for a unit type.static intstackEffect(int op) Returns the net stack effect of an opcode, i.e.static StringtoString(int op) Returns a short mnemonic for an opcode, for debugging and error text.static intunitOf(int op) Returns the unit type of a scale opcode.
Field Details
OP_ADD
public static final int OP_ADDAddition. Pops two values, pushesa+b.- See Also:
OP_SUB
public static final int OP_SUBSubtraction. Pops two values, pushesa-b.- See Also:
OP_MUL
public static final int OP_MULMultiplication. Pops two values, pushesa*b.- See Also:
OP_DIV
public static final int OP_DIVDivision. Pops two values, pushesa/b. Division by zero produces an infinity, which is clamped to zero once at the end of the evaluation.- See Also:
OP_NEG
public static final int OP_NEGUnary negation. Pops one value, pushes-a.- See Also:
OP_MIN2
public static final int OP_MIN2Binary minimum, used to fold the variadicmin()pairwise. Implemented as a plain compare rather thanMath.min, both because a compare is faster and because it avoids having to replicate JavaScript's-0and NaN rules exactly in Java. SeeFormulafor the NaN consequence.- See Also:
OP_MAX2
public static final int OP_MAX2Binary maximum, used to fold the variadicmax()pairwise. SeeOP_MIN2.- See Also:
OP_CONST
public static final int OP_CONSTPush a constant. In the in-memory code array this opcode is followed by the index of the constant in theFormulaconstant arrays; on the wire it is followed by the constant triple itself.- See Also:
OP_SCALE
public static final int OP_SCALEThe base of the per-unit scale opcodes: the opcode that multiplies the top of the stack byscaleTable[ut]isOP_SCALE+ut, so the scale opcodes occupyOP_SCALE+1toOP_SCALE+UnitType.UNIT_COUNT.OP_SCALEitself, i.e.ut==0, is never a valid opcode. Neither isOP_SCALE+UnitType.UT_PX:pxis the identity scale of 1.0 and the emitter deliberately emits nothing for it.- See Also:
OP_LAST
public static final int OP_LASTThe numerically largest legal opcode. Must stay below 64 for the single-byte wire encoding to hold; this is asserted in the static initializer.- See Also:
Method Details
scaleOp
public static int scaleOp(int ut) Returns the scale opcode for a unit type.- Parameters:
ut- The unit type, 1 toUnitType.UNIT_COUNT.- Returns:
- The opcode.
- Throws:
IllegalArgumentException- If the unit type is out of range.
unitOf
public static int unitOf(int op) Returns the unit type of a scale opcode.- Parameters:
op- The opcode.- Returns:
- The unit type 1 to
UnitType.UNIT_COUNT, or -1 if the opcode is not a scale opcode.
isScale
public static boolean isScale(int op) Checks if an opcode is one of the scale opcodes.- Parameters:
op- The opcode.- Returns:
truefor a scale opcode,falseotherwise.
stackEffect
public static int stackEffect(int op) Returns the net stack effect of an opcode, i.e. pushes minus pops.- Parameters:
op- The opcode.- Returns:
- +1 for
OP_CONST, 0 for the unary and scale opcodes, -1 for the binary opcodes. - Throws:
FormulaFormatException- If the opcode is unknown, carrying the stable reason tokenFormulaFormatException.UNKNOWN_OPCODE. It is anIllegalArgumentException, so existing catches are unaffected.
toString
Returns a short mnemonic for an opcode, for debugging and error text.- Parameters:
op- The opcode.- Returns:
- The mnemonic, e.g.
"ADD"or"SCALE %w".