compiler: allow to use += on strings

This commit is contained in:
Evgenii Stratonikov 2020-08-23 13:12:10 +03:00
parent fd7af77895
commit 59367c96d1
3 changed files with 24 additions and 11 deletions

View file

@ -108,6 +108,16 @@ var assignTestCases = []testCase{
`, `,
big.NewInt(15), big.NewInt(15),
}, },
{
"add assign for string",
`package foo
func Main() string {
s := "Hello, "
s += "world!"
return s
}`,
[]byte("Hello, world!"),
},
{ {
"decl assign", "decl assign",
` `

View file

@ -1440,7 +1440,11 @@ func (c *codegen) emitToken(tok token.Token, typ types.Type) {
func convertToken(tok token.Token, typ types.Type) (opcode.Opcode, error) { func convertToken(tok token.Token, typ types.Type) (opcode.Opcode, error) {
switch tok { switch tok {
case token.ADD_ASSIGN: case token.ADD_ASSIGN, token.ADD:
// VM has separate opcodes for number and string concatenation
if isString(typ) {
return opcode.CAT, nil
}
return opcode.ADD, nil return opcode.ADD, nil
case token.SUB_ASSIGN: case token.SUB_ASSIGN:
return opcode.SUB, nil return opcode.SUB, nil
@ -1450,12 +1454,6 @@ func convertToken(tok token.Token, typ types.Type) (opcode.Opcode, error) {
return opcode.DIV, nil return opcode.DIV, nil
case token.REM_ASSIGN: case token.REM_ASSIGN:
return opcode.MOD, nil return opcode.MOD, nil
case token.ADD:
// VM has separate opcodes for number and string concatenation
if isString(typ) {
return opcode.CAT, nil
}
return opcode.ADD, nil
case token.SUB: case token.SUB:
return opcode.SUB, nil return opcode.SUB, nil
case token.MUL: case token.MUL:

View file

@ -18,12 +18,12 @@ func TestConvertToken(t *testing.T) {
} }
testCases := []testCase{ testCases := []testCase{
{"ADD (string)", {"ADD (number)",
token.ADD, token.ADD,
opcode.ADD, opcode.ADD,
types.Typ[types.Int], types.Typ[types.Int],
}, },
{"ADD (number)", {"ADD (string)",
token.ADD, token.ADD,
opcode.CAT, opcode.CAT,
types.Typ[types.String], types.Typ[types.String],
@ -48,10 +48,15 @@ func TestConvertToken(t *testing.T) {
opcode.MOD, opcode.MOD,
nil, nil,
}, },
{"ADD_ASSIGN", {"ADD_ASSIGN (number)",
token.ADD_ASSIGN, token.ADD_ASSIGN,
opcode.ADD, opcode.ADD,
nil, types.Typ[types.Int],
},
{"ADD_ASSIGN (string)",
token.ADD_ASSIGN,
opcode.CAT,
types.Typ[types.String],
}, },
{"SUB_ASSIGN", {"SUB_ASSIGN",
token.SUB_ASSIGN, token.SUB_ASSIGN,