Skip to content

Commit

Permalink
fix slice after slice a slice
Browse files Browse the repository at this point in the history
  • Loading branch information
douyixuan committed Sep 6, 2024
1 parent 81e4c0d commit 1272e9b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 14 deletions.
31 changes: 17 additions & 14 deletions compiler/compiler/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,40 +99,39 @@ func (c *Compiler) compileSubstring(src value.Value, v *parser.SliceArrayNode) v

func (c *Compiler) compileSliceArray(src value.Value, v *parser.SliceArrayNode, isSliceSlice bool) value.Value {
sliceType := internal.Slice(src.Type.LLVM())
// array pointer as receiver, do nothing
// type B [1]byte
// func (b *B) foo() {}
_, isSrcArray := src.Value.Type().(*llvmTypes.ArrayType)

alloc := c.contextBlock.NewAlloca(sliceType)

// actual start index = old offset + new start index
startIndexValue := c.compileValue(v.Start)
startIndex := internal.LoadIfVariable(c.contextBlock, startIndexValue)
offsetBefore := llvmValue.Value(constant.NewInt(llvmTypes.I32, 0))
if isSliceSlice {
offsetBefore = c.contextBlock.NewExtractValue(src.Value, 2)
}
if startIndex.Type() != llvmTypes.I64 {
startIndex = c.contextBlock.NewZExt(startIndex, i64.LLVM())
}
if offsetBefore.Type() != llvmTypes.I64 {
offsetBefore = c.contextBlock.NewZExt(offsetBefore, i64.LLVM())
}
startIndex = c.contextBlock.NewAdd(startIndex, offsetBefore)
// end index
var endIndexValue value.Value
if v.HasEnd {
endIndexValue = c.compileValue(v.End)
} else {
srcVal := src.Value
if isSliceSlice {
endIndexValue.Value = c.contextBlock.NewExtractValue(srcVal, 0)
offsetBefore = c.contextBlock.NewExtractValue(srcVal, 2)
} else {
arrTy := src.Type.LLVM().(*llvmTypes.ArrayType)
endIndexValue.Value = constant.NewInt(llvmTypes.I32, int64(arrTy.Len))
}
}
if startIndex.Type() != llvmTypes.I64 {
startIndex = c.contextBlock.NewZExt(startIndex, i64.LLVM())
}
if offsetBefore.Type() != llvmTypes.I64 {
offsetBefore = c.contextBlock.NewZExt(offsetBefore, i64.LLVM())
}
startIndex = c.contextBlock.NewAdd(startIndex, offsetBefore)
endIndex := internal.LoadIfVariable(c.contextBlock, endIndexValue)
if endIndex.Type() != llvmTypes.I64 {
endIndex = c.contextBlock.NewZExt(endIndex, i64.LLVM())
}
// len
sliceLen := c.contextBlock.NewSub(endIndex, startIndex)
var sliceLen32 llvmValue.Value
sliceLen32 = sliceLen
Expand Down Expand Up @@ -171,6 +170,10 @@ func (c *Compiler) compileSliceArray(src value.Value, v *parser.SliceArrayNode,
backingArrayItem.SetName(name.Var("backing"))

itemPtr := src.Value
// array pointer as receiver, do nothing
// type B [1]byte
// func (b *B) foo() {}
_, isSrcArray := src.Value.Type().(*llvmTypes.ArrayType)
if !isSrcArray {
itemPtr = c.contextBlock.NewExtractValue(src.Value, 3)
}
Expand Down
23 changes: 23 additions & 0 deletions tests/examples/make-slice.cell
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,28 @@ func main() {
return 1
}
}
a := []byte{'0','1','2','3','4','5','6','7'}
b := a[3:7] // 3 4 5 6
okb := []byte{'3', '4', '5', '6'}
if len(b) != len(okb) {
return 1
}
for i, v := range b {
if v != okb[i] {
return 2
}
}
c := b[0:2] // 3 4
okc := []byte{'3', '4'}
if len(c) != len(okc) {
return 3
}
for i, v := range c {
if v != okc[i] {
return 4
}
}
debug.Printf("%d%d",b[0], c[0])
debug.Printf("%d%d",b[0], c[0])
return 0
}

0 comments on commit 1272e9b

Please sign in to comment.