Added overloaded support for array * int
This commit is contained in:
@@ -306,6 +306,25 @@ func evalIntegerPrefixOperatorExpression(operator string, right object.Object) o
|
|||||||
func evalInfixExpression(operator string, left, right object.Object) object.Object {
|
func evalInfixExpression(operator string, left, right object.Object) object.Object {
|
||||||
switch {
|
switch {
|
||||||
|
|
||||||
|
// [1] * 3
|
||||||
|
case left.Type() == object.ARRAY_OBJ && right.Type() == object.INTEGER_OBJ:
|
||||||
|
leftVal := left.(*object.Array).Elements
|
||||||
|
rightVal := int(right.(*object.Integer).Value)
|
||||||
|
elements := leftVal
|
||||||
|
for i := rightVal; i > 1; i-- {
|
||||||
|
elements = append(elements, leftVal...)
|
||||||
|
}
|
||||||
|
return &object.Array{Elements: elements}
|
||||||
|
// 3 * [1]
|
||||||
|
case left.Type() == object.INTEGER_OBJ && right.Type() == object.ARRAY_OBJ:
|
||||||
|
leftVal := int(left.(*object.Integer).Value)
|
||||||
|
rightVal := right.(*object.Array).Elements
|
||||||
|
elements := rightVal
|
||||||
|
for i := leftVal; i > 1; i-- {
|
||||||
|
elements = append(elements, rightVal...)
|
||||||
|
}
|
||||||
|
return &object.Array{Elements: elements}
|
||||||
|
|
||||||
// " " * 4
|
// " " * 4
|
||||||
case left.Type() == object.STRING_OBJ && right.Type() == object.INTEGER_OBJ:
|
case left.Type() == object.STRING_OBJ && right.Type() == object.INTEGER_OBJ:
|
||||||
leftVal := left.(*object.String).Value
|
leftVal := left.(*object.String).Value
|
||||||
|
|||||||
@@ -481,6 +481,25 @@ func TestArrayLiterals(t *testing.T) {
|
|||||||
testIntegerObject(t, result.Elements[2], 6)
|
testIntegerObject(t, result.Elements[2], 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArrayDuplication(t *testing.T) {
|
||||||
|
input := "[1] * 3"
|
||||||
|
|
||||||
|
evaluated := testEval(input)
|
||||||
|
result, ok := evaluated.(*object.Array)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("object is not Array. got=%T (%+v)", evaluated, evaluated)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.Elements) != 3 {
|
||||||
|
t.Fatalf("array has wrong num of elements. got=%d",
|
||||||
|
len(result.Elements))
|
||||||
|
}
|
||||||
|
|
||||||
|
testIntegerObject(t, result.Elements[0], 1)
|
||||||
|
testIntegerObject(t, result.Elements[1], 1)
|
||||||
|
testIntegerObject(t, result.Elements[2], 1)
|
||||||
|
}
|
||||||
|
|
||||||
func TestArrayIndexExpressions(t *testing.T) {
|
func TestArrayIndexExpressions(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
input string
|
input string
|
||||||
|
|||||||
19
vm/vm.go
19
vm/vm.go
@@ -527,6 +527,25 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|
||||||
|
// [1] * 3
|
||||||
|
case left.Type() == object.ARRAY_OBJ && right.Type() == object.INTEGER_OBJ:
|
||||||
|
leftVal := left.(*object.Array).Elements
|
||||||
|
rightVal := int(right.(*object.Integer).Value)
|
||||||
|
elements := leftVal
|
||||||
|
for i := rightVal; i > 1; i-- {
|
||||||
|
elements = append(elements, leftVal...)
|
||||||
|
}
|
||||||
|
return vm.push(&object.Array{Elements: elements})
|
||||||
|
// 3 * [1]
|
||||||
|
case left.Type() == object.INTEGER_OBJ && right.Type() == object.ARRAY_OBJ:
|
||||||
|
leftVal := int(left.(*object.Integer).Value)
|
||||||
|
rightVal := right.(*object.Array).Elements
|
||||||
|
elements := rightVal
|
||||||
|
for i := leftVal; i > 1; i-- {
|
||||||
|
elements = append(elements, rightVal...)
|
||||||
|
}
|
||||||
|
return vm.push(&object.Array{Elements: elements})
|
||||||
|
|
||||||
// " " * 4
|
// " " * 4
|
||||||
case left.Type() == object.STRING_OBJ && right.Type() == object.INTEGER_OBJ:
|
case left.Type() == object.STRING_OBJ && right.Type() == object.INTEGER_OBJ:
|
||||||
leftVal := left.(*object.String).Value
|
leftVal := left.(*object.String).Value
|
||||||
|
|||||||
@@ -343,6 +343,17 @@ func TestArrayLiterals(t *testing.T) {
|
|||||||
runVmTests(t, tests)
|
runVmTests(t, tests)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArrayDuplication(t *testing.T) {
|
||||||
|
tests := []vmTestCase{
|
||||||
|
{"[1] * 3", []int{1, 1, 1}},
|
||||||
|
{"3 * [1]", []int{1, 1, 1}},
|
||||||
|
{"[1, 2] * 2", []int{1, 2, 1, 2}},
|
||||||
|
{"2 * [1, 2]", []int{1, 2, 1, 2}},
|
||||||
|
}
|
||||||
|
|
||||||
|
runVmTests(t, tests)
|
||||||
|
}
|
||||||
|
|
||||||
func TestHashLiterals(t *testing.T) {
|
func TestHashLiterals(t *testing.T) {
|
||||||
tests := []vmTestCase{
|
tests := []vmTestCase{
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user