umx_compiler

UMX virtual machine "Monkey" interpreter / bytecode compiler
git clone git://bsandro.tech/umx_compiler
Log | Files | Refs

commit b9ce320fafd72790fdc6a5d95b92f6f3587edb96
parent c887ec01da2d32fb90c22dd84fe104ce5d6fa624
Author: bsandro <email@bsandro.tech>
Date:   Mon, 27 Jun 2022 00:12:30 +0300

string concat support

Diffstat:
Meval/eval.go | 11+++++++++++
Meval/eval_test.go | 13+++++++++++++
2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/eval/eval.go b/eval/eval.go @@ -142,6 +142,8 @@ func evalInfixExpression(operator string, left, right object.Object, ctx *object switch { case left.Type() == object.INTEGER_OBJ && right.Type() == object.INTEGER_OBJ: return evalIntegerInfixExpression(operator, left, right, ctx) + case left.Type() == object.STRING_OBJ && right.Type() == object.STRING_OBJ: + return evalStringInfixExpression(operator, left, right, ctx) case operator == "==": return boolToObject(left == right) case operator == "!=": @@ -276,3 +278,12 @@ func unwrapReturnValue(obj object.Object) object.Object { } return obj } + +func evalStringInfixExpression(operator string, left, right object.Object, ctx *object.Context) object.Object { + if operator != "+" { + return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type()) + } + leftVal := left.(*object.String).Value + rightVal := right.(*object.String).Value + return &object.String{Value: leftVal + rightVal} +} diff --git a/eval/eval_test.go b/eval/eval_test.go @@ -164,6 +164,7 @@ func TestErrorHandling(t *testing.T) { {"true+false;", "unknown operator: BOOLEAN + BOOLEAN"}, {"if (10>1) { true + false; }", "unknown operator: BOOLEAN + BOOLEAN"}, {"foo", "identifier not found: foo"}, + {`"foo"-"bar"`, "unknown operator: STRING - STRING"}, } for _, tt := range tests { evaluated := testEval(tt.input) @@ -240,3 +241,15 @@ func TestStringLiteral(t *testing.T) { t.Errorf("String has wrong value: %s", str.Value) } } + +func TestStringsConcat(t *testing.T) { + input := `"hello" + " " + "world"` + evaluated := testEval(input) + str, ok := evaluated.(*object.String) + if !ok { + t.Fatalf("object is not a string") + } + if str.Value != "hello world" { + t.Fatalf("string value is wrong: %s", str.Value) + } +}