From 64e048dfcd85a6ee4acaaafd67e3c6772e8c2c07 Mon Sep 17 00:00:00 2001 From: tijani Date: Tue, 9 May 2023 23:57:45 +0000 Subject: [PATCH] String concatenation now a thing. git-svn-id: https://svn.tlawal.org/svn/monkey@64 f6afcba9-9ef1-4bdd-9b72-7484f5705bac --- evaluator/evaluator.go | 16 ++++++++++++++-- evaluator/evaluator_test.go | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index 8f8990c..fef25ea 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -86,9 +86,8 @@ func Eval(node ast.Node, env *object.Environment) object.Object { } return apply_function(function, args) - case *ast.StringLiteral: - return &object.String { Value: node.Value } + return &object.String{Value: node.Value} } return nil @@ -232,6 +231,9 @@ func eval_infix_expression(operator string, left object.Object, right object.Obj case left.Type() != right.Type(): return new_error("type mismatch: %s %s %s", left.Type(), operator, right.Type()) + + case left.Type() == object.STRING_OBJECT && right.Type() == object.STRING_OBJECT: + return eval_string_infix_expression(operator, left, right) default: return new_error("unknown operator: %s %s %s", left.Type(), operator, right.Type()) } @@ -287,6 +289,16 @@ func eval_if_expression(ie *ast.IfExpression, env *object.Environment) object.Ob } } +func eval_string_infix_expression(operator string, left, right object.Object) object.Object { + if operator != "+" { + return new_error("unknown operator: %s %s %s", left.Type(), operator, right.Type()) + } + + left_value := left.(*object.String).Value + right_value := right.(*object.String).Value + return &object.String{Value: left_value + right_value} +} + func is_truthy(object object.Object) bool { switch object { case NULL: diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index eb228af..058ae42 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -56,6 +56,10 @@ func TestErrorHandling(l_test *testing.T) { } `, "unknown operator: BOOLEAN + BOOLEAN"}, {"foobar", "identifier not found: foobar"}, + { + `"Hello" - "World"`, + "unknown operator: STRING - STRING", + }, } for _, tt := range tests { @@ -252,6 +256,20 @@ func TestStringLiteral(l_test *testing.T) { } } +func TestStringConcatenation(l_test *testing.T) { + input := `"Hello" + " " + "World!"` + + evaluated := test_eval(input) + string, ok := evaluated.(*object.String) + if !ok { + l_test.Fatalf("object is not String. got=%T (%+v)", evaluated, evaluated) + } + + if string.Value != "Hello World!" { + l_test.Errorf("String has wrong value. got=%q", string.Value) + } +} + // Helpers func test_eval(input string) object.Object { l_lexer := lexer.New(input)