@@ -232,6 +232,14 @@ if (10 > 1) {
232232 "foobar" ,
233233 "identifier not found: foobar" ,
234234 },
235+ {
236+ `{"name": "Monkey"}[fn(x) { x }];` ,
237+ "unusable as hash key: FUNCTION" ,
238+ },
239+ {
240+ `999[1]` ,
241+ "index operator not supported: INTEGER" ,
242+ },
235243 }
236244
237245 for _ , tt := range tests {
@@ -495,6 +503,92 @@ func TestArrayIndexExpressions(t *testing.T) {
495503 }
496504}
497505
506+ func TestHashLiterals (t * testing.T ) {
507+ input := `let two = "two";
508+ {
509+ "one": 10 - 9,
510+ two: 1 + 1,
511+ "thr" + "ee": 6 / 2,
512+ 4: 4,
513+ true: 5,
514+ false: 6
515+ }`
516+
517+ evaluated := testEval (input )
518+ result , ok := evaluated .(* object.Hash )
519+ if ! ok {
520+ t .Fatalf ("Eval didn't return Hash. got=%T (%+v)" , evaluated , evaluated )
521+ }
522+
523+ expected := map [object.HashKey ]int64 {
524+ (& object.String {Value : "one" }).HashKey (): 1 ,
525+ (& object.String {Value : "two" }).HashKey (): 2 ,
526+ (& object.String {Value : "three" }).HashKey (): 3 ,
527+ (& object.Integer {Value : 4 }).HashKey (): 4 ,
528+ TRUE .HashKey (): 5 ,
529+ FALSE .HashKey (): 6 ,
530+ }
531+
532+ if len (result .Pairs ) != len (expected ) {
533+ t .Fatalf ("Hash has wrong num of pairs. got=%d" , len (result .Pairs ))
534+ }
535+
536+ for expectedKey , expectedValue := range expected {
537+ pair , ok := result .Pairs [expectedKey ]
538+ if ! ok {
539+ t .Errorf ("no pair for given key in Pairs" )
540+ }
541+
542+ testIntegerObject (t , pair .Value , expectedValue )
543+ }
544+ }
545+
546+ func TestHashIndexExpressions (t * testing.T ) {
547+ tests := []struct {
548+ input string
549+ expected interface {}
550+ }{
551+ {
552+ `{"foo": 5}["foo"]` ,
553+ 5 ,
554+ },
555+ {
556+ `{"foo": 5}["bar"]` ,
557+ nil ,
558+ },
559+ {
560+ `let key = "foo"; {"foo": 5}[key]` ,
561+ 5 ,
562+ },
563+ {
564+ `{}["foo"]` ,
565+ nil ,
566+ },
567+ {
568+ `{5: 5}[5]` ,
569+ 5 ,
570+ },
571+ {
572+ `{true: 5}[true]` ,
573+ 5 ,
574+ },
575+ {
576+ `{false: 5}[false]` ,
577+ 5 ,
578+ },
579+ }
580+
581+ for _ , tt := range tests {
582+ evaluated := testEval (tt .input )
583+ integer , ok := tt .expected .(int )
584+ if ok {
585+ testIntegerObject (t , evaluated , int64 (integer ))
586+ } else {
587+ testNullObject (t , evaluated )
588+ }
589+ }
590+ }
591+
498592func testEval (input string ) object.Object {
499593 l := lexer .New (input )
500594 p := parser .New (l )
0 commit comments