From 59367c96d1b674a76c6e898c99dd8af4b2801d58 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Sun, 23 Aug 2020 13:12:10 +0300 Subject: [PATCH] compiler: allow to use `+=` on strings --- pkg/compiler/assign_test.go | 10 ++++++++++ pkg/compiler/codegen.go | 12 +++++------- pkg/compiler/codegen_test.go | 13 +++++++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/pkg/compiler/assign_test.go b/pkg/compiler/assign_test.go index f521d3a4a..4c7007a0f 100644 --- a/pkg/compiler/assign_test.go +++ b/pkg/compiler/assign_test.go @@ -108,6 +108,16 @@ var assignTestCases = []testCase{ `, big.NewInt(15), }, + { + "add assign for string", + `package foo + func Main() string { + s := "Hello, " + s += "world!" + return s + }`, + []byte("Hello, world!"), + }, { "decl assign", ` diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 089660638..24669b72d 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -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) { 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 case token.SUB_ASSIGN: return opcode.SUB, nil @@ -1450,12 +1454,6 @@ func convertToken(tok token.Token, typ types.Type) (opcode.Opcode, error) { return opcode.DIV, nil case token.REM_ASSIGN: 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: return opcode.SUB, nil case token.MUL: diff --git a/pkg/compiler/codegen_test.go b/pkg/compiler/codegen_test.go index 9245edef9..3de3dea7f 100644 --- a/pkg/compiler/codegen_test.go +++ b/pkg/compiler/codegen_test.go @@ -18,12 +18,12 @@ func TestConvertToken(t *testing.T) { } testCases := []testCase{ - {"ADD (string)", + {"ADD (number)", token.ADD, opcode.ADD, types.Typ[types.Int], }, - {"ADD (number)", + {"ADD (string)", token.ADD, opcode.CAT, types.Typ[types.String], @@ -48,10 +48,15 @@ func TestConvertToken(t *testing.T) { opcode.MOD, nil, }, - {"ADD_ASSIGN", + {"ADD_ASSIGN (number)", token.ADD_ASSIGN, opcode.ADD, - nil, + types.Typ[types.Int], + }, + {"ADD_ASSIGN (string)", + token.ADD_ASSIGN, + opcode.CAT, + types.Typ[types.String], }, {"SUB_ASSIGN", token.SUB_ASSIGN,