Skip to content

Commit 84e3f9b

Browse files
added array return for len with multiple arguments
1 parent a13346f commit 84e3f9b

File tree

4 files changed

+39
-24
lines changed

4 files changed

+39
-24
lines changed

MyCode/evaluator/evaluator_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,14 @@ func TestBuiltinFunctions(t *testing.T) {
332332
input string
333333
expected interface{}
334334
}{
335+
{`len()`, "at least one argument required. got=0"},
335336
{`len("")`, 0},
336337
{`len("four")`, 4},
337338
{`len("hello world")`, 11},
338-
{`len(1)`, "argument to `len` not supported, got INTEGER"},
339-
{`len("one", "two")`, "wrong number of arguments. got=2, want=1"},
340-
{`len(1)`, "argument to `len` not supported, got INTEGER"},
341-
{`len("one", "two")`, "wrong number of arguments. got=2, want=1"},
339+
{`len(1)`, "argument to `len` not supported, got INTEGER, position 0"},
340+
{`len("one", "two")`, []int{3, 3}},
341+
{`len("one", [1, 2])`, []int{3, 2}},
342+
{`len("one", [1, 2], 5)`, "argument to `len` not supported, got INTEGER, position 2"},
342343
{`len([1, 2, 3])`, 3},
343344
{`len([])`, 0},
344345
{`puts("hello", "world!")`, nil},
@@ -486,8 +487,8 @@ func TestHashLiterals(t *testing.T) {
486487
(&object.String{Value: "two"}).HashKey(): 2,
487488
(&object.String{Value: "three"}).HashKey(): 3,
488489
(&object.Integer{Value: 4}).HashKey(): 4,
489-
TRUE.HashKey(): 5,
490-
FALSE.HashKey(): 6,
490+
TRUE.HashKey(): 5,
491+
FALSE.HashKey(): 6,
491492
}
492493

493494
if len(result.Pairs) != len(expected) {
@@ -574,7 +575,6 @@ func testIntegerObject(t *testing.T, obj object.Object, expected int64) bool {
574575
return true
575576
}
576577

577-
578578
func testBooleanObject(t *testing.T, obj object.Object, expected bool) bool {
579579
result, ok := obj.(*object.Boolean)
580580
if !ok {
@@ -597,4 +597,4 @@ func testNullObject(t *testing.T, obj object.Object) bool {
597597
}
598598

599599
return true
600-
}
600+
}

MyCode/object/builtins.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,30 @@ var Builtins = []struct {
77
Builtin *Builtin
88
}{
99
{
10-
// TODO if passed multiple arguments, return length of all values?
1110
"len",
1211
&Builtin{
1312
Fn: func(args ...Object) Object {
14-
if len(args) != 1 {
15-
return newError("wrong number of arguments. got=%d, want=1", len(args))
13+
if len(args) < 1 {
14+
return newError("at least one argument required. got=%d", len(args))
15+
}
16+
17+
lengths := make([]Object, len(args))
18+
for i, v := range args {
19+
20+
switch arg := v.(type) {
21+
case *Array:
22+
lengths[i] = &Integer{Value: int64(len(arg.Elements))}
23+
case *String:
24+
lengths[i] = &Integer{Value: int64(len(arg.Value))}
25+
default:
26+
return newError("argument to `len` not supported, got %s, position %d", v.Type(), i)
27+
}
1628
}
1729

18-
switch arg := args[0].(type) {
19-
case *Array:
20-
return &Integer{Value: int64(len(arg.Elements))}
21-
case *String:
22-
return &Integer{Value: int64(len(arg.Value))}
23-
default:
24-
return newError("argument to `len` not supported, got %s", args[0].Type())
30+
if len(lengths) == 1 {
31+
return lengths[0]
32+
} else {
33+
return &Array{Elements: lengths}
2534
}
2635
},
2736
},

MyCode/test.mky

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ let fibonacci = fn(x) {
2828
}
2929
};
3030

31+
let arg = ["one", "hello", [1, 2, 3]]
32+
puts(len(arg))
33+
puts(len(arg, "byebye", "hi"))
34+
3135
let map = fn(arr, f) {
3236
let iter = fn(arr, accumulated) {
3337
if (len(arr) == 0) {

MyCode/vm/vm_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -416,22 +416,24 @@ func TestCallingFunctionsWithWrongArguments(t *testing.T) {
416416

417417
func TestBuiltinFunctions(t *testing.T) {
418418
tests := []vmTestCase{
419+
{`len()`, &object.Error{
420+
Message: "at least one argument required. got=0",
421+
}},
419422
{`len("")`, 0},
420423
{`len("four")`, 4},
421424
{`len("hello world")`, 11},
422425
{
423426
`len(1)`,
424427
&object.Error{
425-
Message: "argument to `len` not supported, got INTEGER",
426-
},
427-
},
428-
{`len("one", "two")`,
429-
&object.Error{
430-
Message: "wrong number of arguments. got=2, want=1",
428+
Message: "argument to `len` not supported, got INTEGER, position 0",
431429
},
432430
},
431+
{`len("one", "two")`, []int{3, 3}},
433432
{`len([1, 2, 3])`, 3},
434433
{`len([])`, 0},
434+
{`len("one", [1, 2], 5)`, &object.Error {
435+
Message: "argument to `len` not supported, got INTEGER, position 2",
436+
}},
435437
{`puts("hello", "world!")`, Null},
436438
{`first([1, 2, 3])`, 1},
437439
{`first([])`, Null},

0 commit comments

Comments
 (0)