Strings
This commit is contained in:
@@ -94,6 +94,9 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
|
||||
|
||||
return applyFunction(function, args)
|
||||
|
||||
case *ast.StringLiteral:
|
||||
return &object.String{Value: node.Value}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -178,6 +181,8 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
|
||||
switch {
|
||||
case left.Type() == object.INTEGER_OBJ && right.Type() == object.INTEGER_OBJ:
|
||||
return evalIntegerInfixExpression(operator, left, right)
|
||||
case left.Type() == object.STRING_OBJ && right.Type() == object.STRING_OBJ:
|
||||
return evalStringInfixExpression(operator, left, right)
|
||||
case operator == "==":
|
||||
return nativeBoolToBooleanObject(left == right)
|
||||
case operator == "!=":
|
||||
@@ -189,6 +194,17 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
|
||||
}
|
||||
}
|
||||
|
||||
func evalStringInfixExpression(operator string, left object.Object, right object.Object) 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}
|
||||
}
|
||||
|
||||
func evalIntegerInfixExpression(operator string, left, right object.Object) object.Object {
|
||||
leftVal := left.(*object.Integer).Value
|
||||
rightVal := right.(*object.Integer).Value
|
||||
|
||||
@@ -205,6 +205,10 @@ func TestErrorHandling(t *testing.T) {
|
||||
"foobar",
|
||||
"identifier not found: foobar",
|
||||
},
|
||||
{
|
||||
`"Hello" - "World"`,
|
||||
"unknown operator: STRING - STRING",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@@ -294,6 +298,34 @@ func TestClosures(t *testing.T) {
|
||||
testIntegerObject(t, testEval(input), 4)
|
||||
}
|
||||
|
||||
func TestStringLiteral(t *testing.T) {
|
||||
input := `"Hello World!"`
|
||||
|
||||
evaluated := testEval(input)
|
||||
str, ok := evaluated.(*object.String)
|
||||
if !ok {
|
||||
t.Fatalf("object is not String. got=%T (+%v)", evaluated, evaluated)
|
||||
}
|
||||
|
||||
if str.Value != "Hello World!" {
|
||||
t.Errorf("String has wrong value. got=%q", str.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringConcatenation(t *testing.T) {
|
||||
input := `"Hello" + " " + "World!"`
|
||||
|
||||
evaluated := testEval(input)
|
||||
str, ok := evaluated.(*object.String)
|
||||
if !ok {
|
||||
t.Fatalf("object is not String. got=%T (+%v)", evaluated, evaluated)
|
||||
}
|
||||
|
||||
if str.Value != "Hello World!" {
|
||||
t.Errorf("String has wrong value. got=%q", str.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func testEval(input string) object.Object {
|
||||
l := lexer.New(input)
|
||||
p := parser.New(l)
|
||||
|
||||
Reference in New Issue
Block a user