diff --git a/src/core/decomposeSlice.go b/src/core/decomposeSlice.go index c5ea2e2..5534f00 100644 --- a/src/core/decomposeSlice.go +++ b/src/core/decomposeSlice.go @@ -11,21 +11,31 @@ func (f *Function) decomposeSlice(addressValue ssa.Value) (ssa.Value, types.Type switch addressType := types.Unwrap(addressValue.Type()).(type) { case *types.Struct: if addressType.IsArray() { - pointerType := &types.Pointer{To: addressType.Fields[0].Type} + pointerType := f.Env.Pointer(addressType.Fields[0].Type) memory := addressValue.(*ssa.Memory) address := memory.Address if memory.Index != nil { - index, isInt := memory.Index.(*ssa.Int) + integer, isInt := memory.Index.(*ssa.Int) - if isInt && index.Int == 0 { + if isInt && integer.Int == 0 { return address, pointerType, nil, nil } + index := memory.Index + + if memory.Scale { + size := memory.Typ.Size() + + if size != 1 { + index = f.Append(&ssa.BinaryOp{Op: token.Mul, Left: memory.Index, Right: f.Append(&ssa.Int{Int: size})}) + } + } + address = f.Append(&ssa.BinaryOp{ Op: token.Add, Left: address, - Right: memory.Index, + Right: index, }) } @@ -42,6 +52,12 @@ func (f *Function) decomposeSlice(addressValue ssa.Value) (ssa.Value, types.Type length := structure.Arguments[1] return pointer, pointer.Type(), length, nil case *types.Pointer: + structure, isStructure := addressType.To.(*types.Struct) + + if isStructure && structure.IsArray() { + return addressValue, f.Env.Pointer(structure.Fields[0].Type), nil, nil + } + return addressValue, addressType, nil, nil default: panic("not implemented") diff --git a/tests/array-static-global-grid.q b/tests/array-static-global-grid.q new file mode 100644 index 0000000..b8aa38b --- /dev/null +++ b/tests/array-static-global-grid.q @@ -0,0 +1,23 @@ +global { + grid [4][3]int +} + +main() { + grid[2][1] = 42 + + assert grid[0][0] == 0 + assert grid[0][1] == 0 + assert grid[0][2] == 0 + + assert grid[1][0] == 0 + assert grid[1][1] == 0 + assert grid[1][2] == 0 + + assert grid[2][0] == 0 + assert grid[2][1] == 42 + assert grid[2][2] == 0 + + assert grid[3][0] == 0 + assert grid[3][1] == 0 + assert grid[3][2] == 0 +} \ No newline at end of file diff --git a/tests/array-static-global.q b/tests/array-static-global.q new file mode 100644 index 0000000..ee399ad --- /dev/null +++ b/tests/array-static-global.q @@ -0,0 +1,15 @@ +global { + data [4]byte +} + +main() { + data[0] = 1 + data[1] = 2 + data[2] = 3 + data[3] = 4 + + assert data[0] == 1 + assert data[1] == 2 + assert data[2] == 3 + assert data[3] == 4 +} \ No newline at end of file diff --git a/tests/tests_test.go b/tests/tests_test.go index 59f6d38..6e24958 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -165,6 +165,8 @@ var tests = []run{ {"array-struct-copy-call", nil, "", "", 0}, {"array-string", nil, "", "HelloWorld", 0}, {"array-static", nil, "", "", 0}, + {"array-static-global", nil, "", "", 0}, + {"array-static-global-grid", nil, "", "", 0}, {"signed-load-8", nil, "", "", 0}, {"signed-load-16", nil, "", "", 0}, {"signed-load-32", nil, "", "", 0},