- String Concatenation is now possible.
- Added test to ensure only '+' will work for concatenating strings - Likkle reformatting. git-svn-id: https://svn.tlawal.org/svn/monkey@58 f6afcba9-9ef1-4bdd-9b72-7484f5705bac
This commit is contained in:
parent
2c2c936b29
commit
b028741d75
@ -175,13 +175,6 @@ func eval_block_statement(block *ast.BlockStatement, env *object.Environment) ob
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func native_bool_to_boolean_object(input bool) *object.Boolean {
|
|
||||||
if input {
|
|
||||||
return TRUE
|
|
||||||
}
|
|
||||||
return FALSE
|
|
||||||
}
|
|
||||||
|
|
||||||
func eval_prefix_expression(operator string, right object.Object) object.Object {
|
func eval_prefix_expression(operator string, right object.Object) object.Object {
|
||||||
switch operator {
|
switch operator {
|
||||||
case "!":
|
case "!":
|
||||||
@ -231,6 +224,9 @@ func eval_infix_expression(operator string, left object.Object, right object.Obj
|
|||||||
|
|
||||||
case left.Type() != right.Type():
|
case left.Type() != right.Type():
|
||||||
return new_error("type mismatch: %s %s %s", left.Type(), operator, 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:
|
default:
|
||||||
return new_error("unknown operator: %s %s %s", left.Type(), operator, right.Type())
|
return new_error("unknown operator: %s %s %s", left.Type(), operator, right.Type())
|
||||||
}
|
}
|
||||||
@ -270,6 +266,19 @@ func eval_integer_infix_expression(operator string, left object.Object, right ob
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
FEATURES TODO:
|
||||||
|
- Add support for string comparision '==' and '!='.
|
||||||
|
*/
|
||||||
|
func eval_string_infix_expression(operator string, left object.Object, 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 eval_if_expression(ie *ast.IfExpression, env *object.Environment) object.Object {
|
func eval_if_expression(ie *ast.IfExpression, env *object.Environment) object.Object {
|
||||||
condition := Eval(ie.Condition, env)
|
condition := Eval(ie.Condition, env)
|
||||||
|
|
||||||
@ -286,6 +295,13 @@ func eval_if_expression(ie *ast.IfExpression, env *object.Environment) object.Ob
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func native_bool_to_boolean_object(input bool) *object.Boolean {
|
||||||
|
if input {
|
||||||
|
return TRUE
|
||||||
|
}
|
||||||
|
return FALSE
|
||||||
|
}
|
||||||
|
|
||||||
func is_truthy(object object.Object) bool {
|
func is_truthy(object object.Object) bool {
|
||||||
switch object {
|
switch object {
|
||||||
case NULL:
|
case NULL:
|
||||||
|
@ -56,6 +56,9 @@ func TestErrorHandling(l_test *testing.T) {
|
|||||||
}
|
}
|
||||||
`, "unknown operator: BOOLEAN + BOOLEAN"},
|
`, "unknown operator: BOOLEAN + BOOLEAN"},
|
||||||
{"foobar", "identifier not found: foobar"},
|
{"foobar", "identifier not found: foobar"},
|
||||||
|
|
||||||
|
// Test to only make sure there is only support for + operator in string concatenation, anything else would be wrong.
|
||||||
|
{`"Hello" - "World"`, "unknown operator: STRING - STRING"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -251,6 +254,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
|
// Helpers
|
||||||
func test_eval(input string) object.Object {
|
func test_eval(input string) object.Object {
|
||||||
l_lexer := lexer.New(input)
|
l_lexer := lexer.New(input)
|
||||||
@ -266,6 +283,7 @@ func test_integer_object(l_test *testing.T, l_object object.Object, expected int
|
|||||||
if !ok {
|
if !ok {
|
||||||
l_test.Errorf("object is not integer, got=%T (%+v)", l_object, l_object)
|
l_test.Errorf("object is not integer, got=%T (%+v)", l_object, l_object)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
}
|
}
|
||||||
if result.Value != expected {
|
if result.Value != expected {
|
||||||
l_test.Errorf("object has wrong value, got=%d, want=%d", result.Value, expected)
|
l_test.Errorf("object has wrong value, got=%d, want=%d", result.Value, expected)
|
||||||
|
Loading…
Reference in New Issue
Block a user