forked from TrueCloudLab/neoneo-go
Implemented DIV, MOD opcode (#237)
This commit is contained in:
parent
139b770712
commit
84b4b41288
4 changed files with 105 additions and 2 deletions
|
@ -46,6 +46,13 @@ func (i *Int) Mul(s *Int) (*Int, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Div will divide one stackInteger by an other.
|
||||||
|
func (i *Int) Div(s *Int) (*Int, error) {
|
||||||
|
return &Int{
|
||||||
|
val: new(big.Int).Div(i.val, s.val),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Mod will take the mod of two stackIntegers together
|
// Mod will take the mod of two stackIntegers together
|
||||||
func (i *Int) Mod(s *Int) (*Int, error) {
|
func (i *Int) Mod(s *Int) (*Int, error) {
|
||||||
return &Int{
|
return &Int{
|
||||||
|
|
|
@ -7,6 +7,8 @@ type stackInfo func(op stack.Instruction, ctx *stack.Context, istack *stack.Invo
|
||||||
var opFunc = map[stack.Instruction]stackInfo{
|
var opFunc = map[stack.Instruction]stackInfo{
|
||||||
stack.INC: Inc,
|
stack.INC: Inc,
|
||||||
stack.DEC: Dec,
|
stack.DEC: Dec,
|
||||||
|
stack.DIV: Div,
|
||||||
|
stack.MOD: Mod,
|
||||||
stack.NZ: Nz,
|
stack.NZ: Nz,
|
||||||
stack.MUL: Mul,
|
stack.MUL: Mul,
|
||||||
stack.ABS: Abs,
|
stack.ABS: Abs,
|
||||||
|
|
|
@ -94,6 +94,44 @@ func Dec(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rst
|
||||||
return NONE, nil
|
return NONE, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Div divides one stack Item by an other.
|
||||||
|
// Returns an error if either items cannot be casted to an integer
|
||||||
|
// or if the division of the integers cannot be performed.
|
||||||
|
func Div(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 := operandB.Div(operandA)
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Estack.Push(res)
|
||||||
|
|
||||||
|
return NONE, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mod returns the mod of two stack Items.
|
||||||
|
// Returns an error if either items cannot be casted to an integer
|
||||||
|
// or if the mode of the integers cannot be performed.
|
||||||
|
func Mod(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 := operandB.Mod(operandA)
|
||||||
|
if err != nil {
|
||||||
|
return FAULT, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Estack.Push(res)
|
||||||
|
|
||||||
|
return NONE, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Nz pops an integer from the stack.
|
// Nz pops an integer from the stack.
|
||||||
// Then pushes a boolean to the stack which evaluates to true
|
// Then pushes a boolean to the stack which evaluates to true
|
||||||
// iff the integer was not zero.
|
// iff the integer was not zero.
|
||||||
|
|
|
@ -118,6 +118,64 @@ func TestSubOp(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDivOp(t *testing.T) {
|
||||||
|
|
||||||
|
v := VM{}
|
||||||
|
|
||||||
|
a, err := stack.NewInt(big.NewInt(10))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
b, err := stack.NewInt(big.NewInt(4))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := stack.NewContext([]byte{})
|
||||||
|
ctx.Estack.Push(a).Push(b)
|
||||||
|
|
||||||
|
v.executeOp(stack.DIV, 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(2), item.Value().Int64())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestModOp(t *testing.T) {
|
||||||
|
|
||||||
|
v := VM{}
|
||||||
|
|
||||||
|
a, err := stack.NewInt(big.NewInt(15))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
b, err := stack.NewInt(big.NewInt(4))
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := stack.NewContext([]byte{})
|
||||||
|
ctx.Estack.Push(a).Push(b)
|
||||||
|
|
||||||
|
v.executeOp(stack.MOD, 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(3), item.Value().Int64())
|
||||||
|
}
|
||||||
|
|
||||||
func TestNzOp(t *testing.T) {
|
func TestNzOp(t *testing.T) {
|
||||||
|
|
||||||
v := VM{}
|
v := VM{}
|
||||||
|
@ -141,7 +199,6 @@ func TestNzOp(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, true, item.Value())
|
assert.Equal(t, true, item.Value())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMulOp(t *testing.T) {
|
func TestMulOp(t *testing.T) {
|
||||||
|
@ -171,7 +228,6 @@ func TestMulOp(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, int64(400), item.Value().Int64())
|
assert.Equal(t, int64(400), item.Value().Int64())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAbsOp(t *testing.T) {
|
func TestAbsOp(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue