Implemented NZ, MUL opcode (#235)
This commit is contained in:
parent
afe670f178
commit
139b770712
3 changed files with 99 additions and 0 deletions
|
@ -7,6 +7,8 @@ type stackInfo func(op stack.Instruction, ctx *stack.Context, istack *stack.Invo
|
|||
var opFunc = map[stack.Instruction]stackInfo{
|
||||
stack.INC: Inc,
|
||||
stack.DEC: Dec,
|
||||
stack.NZ: Nz,
|
||||
stack.MUL: Mul,
|
||||
stack.ABS: Abs,
|
||||
stack.NOT: Not,
|
||||
stack.SIGN: Sign,
|
||||
|
|
|
@ -94,6 +94,47 @@ func Dec(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rst
|
|||
return NONE, nil
|
||||
}
|
||||
|
||||
// Nz pops an integer from the stack.
|
||||
// Then pushes a boolean to the stack which evaluates to true
|
||||
// iff the integer was not zero.
|
||||
// Returns an error if the popped item cannot be casted to an integer
|
||||
// or if we cannot create a boolean.
|
||||
func Nz(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) {
|
||||
|
||||
i, err := ctx.Estack.PopInt()
|
||||
if err != nil {
|
||||
return FAULT, err
|
||||
}
|
||||
|
||||
b, err := i.Boolean()
|
||||
if err != nil {
|
||||
return FAULT, err
|
||||
}
|
||||
|
||||
ctx.Estack.Push(b)
|
||||
|
||||
return NONE, nil
|
||||
}
|
||||
|
||||
// Mul multiplies two stack Items together.
|
||||
// Returns an error if either items cannot be casted to an integer
|
||||
// or if integers cannot be multiplied together.
|
||||
func Mul(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) {
|
||||
|
||||
operandA, operandB, err := popTwoIntegers(ctx)
|
||||
if err != nil {
|
||||
return FAULT, err
|
||||
}
|
||||
res, err := operandA.Mul(operandB)
|
||||
if err != nil {
|
||||
return FAULT, err
|
||||
}
|
||||
|
||||
ctx.Estack.Push(res)
|
||||
|
||||
return NONE, nil
|
||||
}
|
||||
|
||||
// Abs pops an integer off of the stack and pushes its absolute value onto the stack.
|
||||
// Returns an error if the popped value is not an integer or if the absolute value cannot be taken
|
||||
func Abs(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) {
|
||||
|
|
|
@ -118,6 +118,62 @@ func TestSubOp(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestNzOp(t *testing.T) {
|
||||
|
||||
v := VM{}
|
||||
|
||||
a, err := stack.NewInt(big.NewInt(20))
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
ctx := stack.NewContext([]byte{})
|
||||
ctx.Estack.Push(a)
|
||||
|
||||
v.executeOp(stack.NZ, ctx)
|
||||
|
||||
// Stack should have one item
|
||||
assert.Equal(t, 1, ctx.Estack.Len())
|
||||
|
||||
item, err := ctx.Estack.PopBoolean()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
assert.Equal(t, true, item.Value())
|
||||
|
||||
}
|
||||
|
||||
func TestMulOp(t *testing.T) {
|
||||
|
||||
v := VM{}
|
||||
|
||||
a, err := stack.NewInt(big.NewInt(20))
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
b, err := stack.NewInt(big.NewInt(20))
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
ctx := stack.NewContext([]byte{})
|
||||
ctx.Estack.Push(a).Push(b)
|
||||
|
||||
v.executeOp(stack.MUL, ctx)
|
||||
|
||||
// Stack should have one item
|
||||
assert.Equal(t, 1, ctx.Estack.Len())
|
||||
|
||||
item, err := ctx.Estack.PopInt()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
assert.Equal(t, int64(400), item.Value().Int64())
|
||||
|
||||
}
|
||||
|
||||
func TestAbsOp(t *testing.T) {
|
||||
|
||||
v := VM{}
|
||||
|
|
Loading…
Reference in a new issue