hash
Some checks failed
Build / build (push) Failing after 1m13s
Test / build (push) Failing after 2m1s

This commit is contained in:
Chuck Smith
2024-02-26 16:59:37 -05:00
parent 8721665bc1
commit 0a1201f1bc
5 changed files with 152 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ import (
"monkey/ast"
"monkey/code"
"monkey/object"
"sort"
)
type EmittedInstruction struct {
@@ -204,6 +205,28 @@ func (c *Compiler) Compile(node ast.Node) error {
c.emit(code.OpArray, len(node.Elements))
case *ast.HashLiteral:
keys := []ast.Expression{}
for k := range node.Pairs {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return keys[i].String() < keys[j].String()
})
for _, k := range keys {
err := c.Compile(k)
if err != nil {
return err
}
err = c.Compile(node.Pairs[k])
if err != nil {
return err
}
}
c.emit(code.OpHash, len(node.Pairs)*2)
}
return nil

View File

@@ -345,6 +345,51 @@ func TestArrayLiterals(t *testing.T) {
runCompilerTests(t, tests)
}
func TestHashLiterals(t *testing.T) {
tests := []compilerTestCase{
{
input: "{}",
expectedConstants: []interface{}{},
expectedInstructions: []code.Instructions{
code.Make(code.OpHash, 0),
code.Make(code.OpPop),
},
},
{
input: "{1: 2, 3: 4, 5: 6}",
expectedConstants: []interface{}{1, 2, 3, 4, 5, 6},
expectedInstructions: []code.Instructions{
code.Make(code.OpConstant, 0),
code.Make(code.OpConstant, 1),
code.Make(code.OpConstant, 2),
code.Make(code.OpConstant, 3),
code.Make(code.OpConstant, 4),
code.Make(code.OpConstant, 5),
code.Make(code.OpHash, 6),
code.Make(code.OpPop),
},
},
{
input: "{1: 2 + 3, 4: 5 * 6}",
expectedConstants: []interface{}{1, 2, 3, 4, 5, 6},
expectedInstructions: []code.Instructions{
code.Make(code.OpConstant, 0),
code.Make(code.OpConstant, 1),
code.Make(code.OpConstant, 2),
code.Make(code.OpAdd),
code.Make(code.OpConstant, 3),
code.Make(code.OpConstant, 4),
code.Make(code.OpConstant, 5),
code.Make(code.OpMul),
code.Make(code.OpHash, 4),
code.Make(code.OpPop),
},
},
}
runCompilerTests(t, tests)
}
func runCompilerTests(t *testing.T, tests []compilerTestCase) {
t.Helper()