Skip to content

Commit

Permalink
fix #121 (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaidesu authored Oct 26, 2023
1 parent 2d45f24 commit 4817810
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 11 deletions.
10 changes: 10 additions & 0 deletions evaluator/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ func evaluateMap(node *ast.Map, scope *object.Scope) object.Object {
pairs := make(map[object.MapKey]object.MapPair)

for keyNode, valueNode := range node.Pairs {
// if keyNode is an identifier, convert it to a string
identifier, ok := keyNode.(*ast.Identifier)

if ok {
keyNode = &ast.String{
Token: identifier.Token,
Value: identifier.Value,
}
}

key := Evaluate(keyNode, scope)

if isError(key) {
Expand Down
16 changes: 5 additions & 11 deletions examples/hello.ghost
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
print("hello world")
print(1 + 2)
foo = 'hello'

if (true) {
print("true!!")
} else {
print("false :(")
bar = {
foo: 'bar'
}

class Animal {
function speak() {
print("Animals speaks.")
}
}
print(bar.foo)
print(foo)
131 changes: 131 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,137 @@ func TestMapLiteralsWithStringKeys(t *testing.T) {
}
}

func TestMapLiteralsWithBooleanKeys(t *testing.T) {
input := `{true: 1, false: 2}`

scanner := scanner.New(input, "test.ghost")
parser := New(scanner)
program := parser.Parse()

failIfParserHasErrors(t, parser)

statement, ok := program.Statements[0].(*ast.Expression)

if !ok {
t.Fatalf("program.Statements[0] is not ast.Expression. got=%T", program.Statements[0])
}

mapLiteral, ok := statement.Expression.(*ast.Map)

if !ok {
t.Fatalf("statement is not ast.Map. got=%T", statement.Expression)
}

if len(mapLiteral.Pairs) != 2 {
t.Fatalf("map.Pairs has wrong length. got=%d", len(mapLiteral.Pairs))
}

expected := map[bool]int64{
true: 1,
false: 2,
}

for key, value := range mapLiteral.Pairs {
boolean, ok := key.(*ast.Boolean)

if !ok {
t.Errorf("key is not ast.Boolean. got=%T", key)
}

expectedValue := expected[boolean.Value]

isNumberLiteral(t, value, expectedValue)
}
}

func TestMapLiteralsWithIntegerKeys(t *testing.T) {
input := `{1: 1, 2: 2, 3: 3}`

scanner := scanner.New(input, "test.ghost")
parser := New(scanner)
program := parser.Parse()

failIfParserHasErrors(t, parser)

statement, ok := program.Statements[0].(*ast.Expression)

if !ok {
t.Fatalf("program.Statements[0] is not ast.Expression. got=%T", program.Statements[0])
}

mapLiteral, ok := statement.Expression.(*ast.Map)

if !ok {
t.Fatalf("statement is not ast.Map. got=%T", statement.Expression)
}

if len(mapLiteral.Pairs) != 3 {
t.Fatalf("map.Pairs has wrong length. got=%d", len(mapLiteral.Pairs))
}

expected := map[int64]int64{
1: 1,
2: 2,
3: 3,
}

for key, value := range mapLiteral.Pairs {
number, ok := key.(*ast.Number)

if !ok {
t.Errorf("key is not ast.Number. got=%T", key)
}

expectedValue := expected[number.Value.IntPart()]

isNumberLiteral(t, value, expectedValue)
}
}

func TestMapLiteralsWithVariableKeys(t *testing.T) {
input := `{foo: 1, bar: 2, baz: 3}`

scanner := scanner.New(input, "test.ghost")
parser := New(scanner)
program := parser.Parse()

failIfParserHasErrors(t, parser)

statement, ok := program.Statements[0].(*ast.Expression)

if !ok {
t.Fatalf("program.Statements[0] is not ast.Expression. got=%T", program.Statements[0])
}

mapLiteral, ok := statement.Expression.(*ast.Map)

if !ok {
t.Fatalf("statement is not ast.Map. got=%T", statement.Expression)
}

if len(mapLiteral.Pairs) != 3 {
t.Fatalf("map.Pairs has wrong length. got=%d", len(mapLiteral.Pairs))
}

expected := map[string]int64{
"foo": 1,
"bar": 2,
"baz": 3,
}

for key, value := range mapLiteral.Pairs {
identifier, ok := key.(*ast.Identifier)

if !ok {
t.Errorf("key is not ast.Identifier. got=%T", key)
}

expectedValue := expected[identifier.Value]

isNumberLiteral(t, value, expectedValue)
}
}

func TestEmptyMapLiterals(t *testing.T) {
input := `{}`

Expand Down

0 comments on commit 4817810

Please sign in to comment.