fspl/generator/data.go

89 lines
2.5 KiB
Go

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, length llvm.Value) (llvm.Value, error) {
irType, err := this.generateType(ty)
if err != nil { return nil, err }
slice := this.blockManager.newAllocaFront(irType)
dataField := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
this.blockManager.NewStore(data, dataField)
lengthField := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 1))
this.blockManager.NewStore(length, lengthField)
return slice, nil
}
func (this *generator) generateSliceDefinedLength (ty entity.Type, data llvm.Value, length int64) (llvm.Value, error) {
sizeType, err := this.typedef("Index")
if err != nil { return nil, err }
return this.generateSlice(ty, data, llvm.NewConstInt(sizeType.(*llvm.TypeInt), length))
}
func (this *generator) getSliceDataAddress (slice llvm.Value, irType llvm.Type) llvm.Value {
dataAddressFieldAddress := this.blockManager.NewGetElementPtr (
irType, slice,
llvm.NewConstInt(llvm.I32, 0),
llvm.NewConstInt(llvm.I32, 0))
return this.blockManager.NewLoad (
new(llvm.TypePointer),
dataAddressFieldAddress)
}
func (this *generator) getInterfaceData (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) getInterfaceBehavior (
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
}