134 lines
4.0 KiB
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))
|
|
}
|