Revert slices back to having just two fields

This commit is contained in:
Sasha Koshka 2023-12-05 03:07:54 -05:00
parent 7f866d102d
commit 8085da442b
7 changed files with 42 additions and 66 deletions

View File

@ -114,7 +114,7 @@ func (this *generator) generateAssignmentSource (
case *entity.TypeSlice:
switch fromBase := analyzer.ReduceToBase(from.Type()).(type) {
case *entity.TypeArray:
return this.generateSlice(to, source, 0, int64(fromBase.Length))
return this.generateSlice(to, source, int64(fromBase.Length))
}
}
return source, nil

View File

@ -3,7 +3,7 @@ package generator
import "git.tebibyte.media/sashakoshka/fspl/llvm"
import "git.tebibyte.media/sashakoshka/fspl/entity"
func (this *generator) generateSlice (ty entity.Type, data llvm.Value, start, end int64) (llvm.Value, error) {
func (this *generator) generateSlice (ty entity.Type, data llvm.Value, length int64) (llvm.Value, error) {
irType, err := this.generateType(ty)
if err != nil { return nil, err }
@ -13,22 +13,15 @@ func (this *generator) generateSlice (ty entity.Type, data llvm.Value, start, en
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
this.blockManager.NewStore(data, dataField)
startField := this.blockManager.NewGetElementPtr (
lengthField := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
endField := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 2))
sizeType, err := this.typedef("Index")
if err != nil { return nil, err }
this.blockManager.NewStore (
llvm.NewConstInt(sizeType.(*llvm.TypeInt), start),
startField)
this.blockManager.NewStore (
llvm.NewConstInt (sizeType.(*llvm.TypeInt), end),
endField)
llvm.NewConstInt(sizeType.(*llvm.TypeInt), length),
lengthField)
return slice, nil
}

View File

@ -110,21 +110,12 @@ func (this *generator) generateLength (length *entity.Length) (llvm.Value, error
irSourceType, err := this.generateType(sourceType)
if err != nil { return nil, err }
startFieldAddress := this.blockManager.NewGetElementPtr (
lengthFieldAddress := this.blockManager.NewGetElementPtr (
irSourceType,
source,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
start := this.blockManager.NewLoad(sizeType, startFieldAddress)
endFieldAddress := this.blockManager.NewGetElementPtr (
irSourceType,
source,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 2))
end := this.blockManager.NewLoad(sizeType, endFieldAddress)
return this.blockManager.NewSub(end, start), nil
return this.blockManager.NewLoad(sizeType, lengthFieldAddress), nil
case *entity.TypeArray:
return llvm.NewConstInt(sizeType, int64(sourceType.Length)), nil

View File

@ -49,7 +49,7 @@ func (this *generator) generateLiteralArrayLoc (literal *entity.LiteralArray) (l
case *entity.TypeSlice:
array, err := makeData(ty.Element)
if err != nil { return nil, err }
return this.generateSlice(ty, array, 0, int64(len(literal.Elements)))
return this.generateSlice(ty, array, int64(len(literal.Elements)))
case *entity.TypePointer:
array, err := makeData(ty.Referenced)
@ -184,7 +184,7 @@ func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString)
case *entity.TypeSlice:
array, length, err := makeData(base.Element, false)
if err != nil { return nil, err }
return this.generateSlice(base, array, 0, length)
return this.generateSlice(base, array, length)
case *entity.TypePointer:
array, _, err := makeData(base.Referenced, true)

View File

@ -12,15 +12,14 @@ func (this *generator) generateVariableLoc (variable *entity.Variable) (llvm.Val
func (this *generator) generateSliceLoc (slice *entity.Slice) (llvm.Value, error) {
var err error
var start, end, dataAddress llvm.Value
var elementType llvm.Type
var sizeType *llvm.TypeInt; {
ty, err := this.typedef("Index")
if err != nil { return nil, err }
sizeType = ty.(*llvm.TypeInt)
}
if slice.Start == nil {
start = llvm.NewConstInt(sizeType, 0)
} else {
if slice.Start != nil {
start, err = this.generateExpression(slice.Start)
if err != nil { return nil, err }
}
@ -36,21 +35,26 @@ func (this *generator) generateSliceLoc (slice *entity.Slice) (llvm.Value, error
if err != nil { return nil, err }
irSourceType, err := this.generateType(sourceType)
if err != nil { return nil, err }
elementType, err = this.generateType(sourceType.Element)
if err != nil { return nil, err }
dataAddress = this.blockManager.NewGetElementPtr (
irSourceType,
source,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
lengthAddress := this.blockManager.NewGetElementPtr (
irSourceType,
source,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
if end == nil {
endAddr := this.blockManager.NewGetElementPtr (
irSourceType,
source,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 2))
end = this.blockManager.NewLoad(sizeType, endAddr)
end = this.blockManager.NewLoad(sizeType, lengthAddress)
}
case *entity.TypeArray:
elementType, err = this.generateType(sourceType.Element)
if err != nil { return nil, err }
dataAddress, err = this.generateExpressionLoc(slice.Slice)
if err != nil { return nil, err }
if end == nil {
@ -63,41 +67,39 @@ func (this *generator) generateSliceLoc (slice *entity.Slice) (llvm.Value, error
slice.Slice))
}
// figure out starting position and length
var length llvm.Value
if start == nil {
length = end
} else {
length = this.blockManager.NewSub(end, start)
dataAddress = this.blockManager.NewGetElementPtr (
elementType,
dataAddress,
start)
}
// create new slice descriptor
destinationType, err := this.generateType(slice.Type())
if err != nil { return nil, err }
newSlice := this.blockManager.newAllocaFront(destinationType)
// create new slice descriptor
dataAddressFieldAddress := this.blockManager.NewGetElementPtr (
destinationType,
newSlice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
startFieldAddress := this.blockManager.NewGetElementPtr (
lengthFieldAddress := this.blockManager.NewGetElementPtr (
destinationType,
newSlice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
endFieldAddress := this.blockManager.NewGetElementPtr (
destinationType,
newSlice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 2))
this.blockManager.NewStore(dataAddress, dataAddressFieldAddress)
this.blockManager.NewStore(start, startFieldAddress)
this.blockManager.NewStore(end, endFieldAddress)
this.blockManager.NewStore(length, lengthFieldAddress)
return newSlice, nil
}
func (this *generator) generateSubscriptLoc (subscript *entity.Subscript) (llvm.Value, error) {
var sizeType *llvm.TypeInt; {
ty, err := this.typedef("Index")
if err != nil { return nil, err }
sizeType = ty.(*llvm.TypeInt)
}
source, err := this.generateExpressionLoc(subscript.Slice)
if err != nil { return nil, err }
offset, err := this.generateExpression(subscript.Offset)
@ -111,16 +113,7 @@ func (this *generator) generateSubscriptLoc (subscript *entity.Subscript) (llvm.
case *entity.TypeSlice:
irSourceType, err := this.generateType(sourceType)
if err != nil { return nil, err }
// add index to slice start
startFieldAddress := this.blockManager.NewGetElementPtr (
irSourceType,
source,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
start := this.blockManager.NewLoad(sizeType, startFieldAddress)
offset = this.blockManager.NewAdd(start, offset)
// get slice element
elementType = sourceType.Element
dataAddress = this.blockManager.NewGetElementPtr (

View File

@ -19,9 +19,8 @@ func (this *generator) generateTypeSlice (ty *entity.TypeSlice) (llvm.Type, erro
if err != nil { return nil, err }
return &llvm.TypeStruct {
Fields: []llvm.Type {
/* data */ llvm.Pointer,
/* start */ indexType,
/* end */ indexType,
/* data */ llvm.Pointer,
/* len */ indexType,
},
}, nil
}

View File

@ -5,7 +5,7 @@ import "testing"
func TestType (test *testing.T) {
testString (test,
`%Index = type i64
%String = type { ptr, %Index, %Index }
%String = type { ptr, %Index }
%Pegasus = type { ptr, ptr, ptr, ptr, ptr }
%Point = type { i64, i64 }
%Rectangle = type { %Point, %Point }
@ -14,7 +14,7 @@ testString (test,
%Rune = type i32
%AllInts = type { %Bool, %Byte, %Index, %Rune, i64, i64, i8, i16, i32, i64, i8, i16, i32, i64 }
%AllFloats = type { float, double }
%Path = type { ptr, %Index, %Index }
%Path = type { ptr, %Index }
%Quadrangle = type [4 x %Point]
%AllTypes = type { %String, %Pegasus, %Rectangle, %AllInts, %AllFloats, %Path, %Quadrangle }
declare %AllTypes @x()