Merge pull request #567 from nspcc-dev/feature/codegen_add_mod

compiler: Add Mod token, closes #563
This commit is contained in:
Roman Khimov 2019-12-19 15:32:18 +03:00 committed by GitHub
commit 79323cc10b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 148 additions and 1 deletions

View file

@ -236,7 +236,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
switch t := n.Lhs[i].(type) {
case *ast.Ident:
switch n.Tok {
case token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN:
case token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN, token.REM_ASSIGN:
c.emitLoadLocal(t.Name)
ast.Walk(c, n.Rhs[0]) // can only add assign to 1 expr on the RHS
c.convertToken(n.Tok)
@ -751,6 +751,8 @@ func (c *codegen) convertToken(tok token.Token) {
emitOpcode(c.prog.BinWriter, opcode.MUL)
case token.QUO_ASSIGN:
emitOpcode(c.prog.BinWriter, opcode.DIV)
case token.REM_ASSIGN:
emitOpcode(c.prog.BinWriter, opcode.MOD)
case token.ADD:
emitOpcode(c.prog.BinWriter, opcode.ADD)
case token.SUB:
@ -759,6 +761,8 @@ func (c *codegen) convertToken(tok token.Token) {
emitOpcode(c.prog.BinWriter, opcode.MUL)
case token.QUO:
emitOpcode(c.prog.BinWriter, opcode.DIV)
case token.REM:
emitOpcode(c.prog.BinWriter, opcode.MOD)
case token.LSS:
emitOpcode(c.prog.BinWriter, opcode.LT)
case token.LEQ:

View file

@ -0,0 +1,72 @@
package compiler
import (
"go/token"
"testing"
"github.com/CityOfZion/neo-go/pkg/io"
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
"github.com/stretchr/testify/assert"
)
func TestConvertToken(t *testing.T) {
type testCase struct {
name string
token token.Token
opcode opcode.Opcode
}
testCases := []testCase{
{"ADD",
token.ADD,
opcode.ADD,
},
{"SUB",
token.SUB,
opcode.SUB,
},
{"MUL",
token.MUL,
opcode.MUL,
},
{"QUO",
token.QUO,
opcode.DIV,
},
{"REM",
token.REM,
opcode.MOD,
},
{"ADD_ASSIGN",
token.ADD_ASSIGN,
opcode.ADD,
},
{"SUB_ASSIGN",
token.SUB_ASSIGN,
opcode.SUB,
},
{"MUL_ASSIGN",
token.MUL_ASSIGN,
opcode.MUL,
},
{"QUO_ASSIGN",
token.QUO_ASSIGN,
opcode.DIV,
},
{"REM_ASSIGN",
token.REM_ASSIGN,
opcode.MOD,
},
}
for _, tcase := range testCases {
t.Run(tcase.name, func(t *testing.T) { eval(t, tcase.token, tcase.opcode) })
}
}
func eval(t *testing.T, token token.Token, opcode opcode.Opcode) {
codegen := &codegen{prog: io.NewBufBinWriter()}
codegen.convertToken(token)
readOpcode := codegen.prog.Bytes()
assert.Equal(t, []byte{byte(opcode)}, readOpcode)
}

View file

@ -39,6 +39,17 @@ var binaryExprTestCases = []testCase{
`,
big.NewInt(1),
},
{
"simple mod",
`
package testcase
func Main() int {
x := 3 % 2
return x
}
`,
big.NewInt(1),
},
{
"simple mul",
`
@ -186,6 +197,66 @@ var binaryExprTestCases = []testCase{
`,
big.NewInt(1),
},
{
"simple add and assign",
`
package testcase
func Main() int {
x := 2
x += 1
return x
}
`,
big.NewInt(3),
},
{
"simple sub and assign",
`
package testcase
func Main() int {
x := 2
x -= 1
return x
}
`,
big.NewInt(1),
},
{
"simple mul and assign",
`
package testcase
func Main() int {
x := 2
x *= 2
return x
}
`,
big.NewInt(4),
},
{
"simple div and assign",
`
package testcase
func Main() int {
x := 2
x /= 2
return x
}
`,
big.NewInt(1),
},
{
"simple mod and assign",
`
package testcase
func Main() int {
x := 5
x %= 2
return x
}
`,
big.NewInt(1),
},
}
func TestBinaryExprs(t *testing.T) {