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 }