fspl/generator/data.go

134 lines
4.0 KiB
Go

package generator
import "git.tebibyte.media/fspl/fspl/llvm"
import "git.tebibyte.media/fspl/fspl/entity"
func (this *generator) generateSlice (ty entity.Type, data llvm.Value, length llvm.Value) (llvm.Value, error) {
irType, err := this.generateType(ty)
if err != nil { return nil, err }
slice := this.blockManager.newAllocaFront(irType)
this.sliceSetData(ty, slice, data)
this.sliceSetLength(ty, slice, length)
return slice, nil
}
func (this *generator) generateSliceDefinedLength (ty entity.Type, data llvm.Value, length int64) (llvm.Value, error) {
indexType, err := this.generateTypeIndex()
if err != nil { return nil, err }
return this.generateSlice(ty, data, llvm.NewConstInt(indexType, length))
}
func (this *generator) sliceSetData (ty entity.Type, slice llvm.Value, data llvm.Value) error {
irType, err := this.generateType(ty)
if err != nil { return err }
dataField := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
this.blockManager.NewStore(data, dataField)
return nil
}
func (this *generator) sliceSetLength (ty entity.Type, slice llvm.Value, length llvm.Value) error {
irType, err := this.generateType(ty)
if err != nil { return err }
lengthField := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
this.blockManager.NewStore(length, lengthField)
return nil
}
func (this *generator) sliceSetDefinedLength (ty entity.Type, slice llvm.Value, length int64) error {
indexType, err := this.generateTypeIndex()
if err != nil { return err }
return this.sliceSetLength(ty, slice, llvm.NewConstInt(indexType, length))
}
func (this *generator) getSliceDataAddress (slice llvm.Value, irType llvm.Type) llvm.Value {
return this.blockManager.NewLoad (
new(llvm.TypePointer),
this.getSliceDataFieldLoc(slice, irType))
}
func (this *generator) getSliceDataFieldLoc (slice llvm.Value, irType llvm.Type) llvm.Value {
return this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
}
func (this *generator) getSliceLengthFieldLoc (slice llvm.Value, irType llvm.Type) llvm.Value {
return this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
}
func (this *generator) getInterfaceDataFieldLoc (iface llvm.Value, irType llvm.Type) llvm.Value {
return this.blockManager.NewGetElementPtr (
irType, iface,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
}
func (this *generator) getInterfaceBehaviorFieldLoc (
ty *entity.TypeInterface,
iface llvm.Value,
irType llvm.Type,
name string,
) llvm.Value {
offset := this.getInterfaceBehaviorIndex(ty, name)
if offset > -1 {
return this.blockManager.NewGetElementPtr (
irType, iface,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, int64(offset + 1)))
} else {
return nil
}
}
func (this *generator) getInterfaceBehaviorSignature (ty *entity.TypeInterface, name string) (llvm.Type, error) {
return this.generateTypeFunction(ty.BehaviorMap[name])
}
func (this *generator) getInterfaceBehaviorIndex (ty *entity.TypeInterface, name string) int {
offset := -1
for index, nm := range ty.BehaviorOrder {
if nm == name {
offset = index
break
}
}
return offset
}
func (this *generator) getStructMemberIndex (ty *entity.TypeStruct, name string) int {
offset := -1
for index, nm := range ty.MemberOrder {
if nm == name {
offset = index
break
}
}
return offset
}
func (this *generator) getUnionTypeFieldLoc (union llvm.Value, irType llvm.Type) llvm.Value {
irType = llvm.ReduceToBase(irType)
return this.blockManager.NewGetElementPtr (
irType, union,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
}
func (this *generator) getUnionDataFieldLoc (union llvm.Value, irType llvm.Type) llvm.Value {
irType = llvm.ReduceToBase(irType)
return this.blockManager.NewGetElementPtr (
irType, union,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
}