github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/ast/location.go (about) 1 package ast 2 3 import "github.com/arnodel/golua/token" 4 5 // A Location is a span between two token in the source code. 6 type Location struct { 7 start *token.Pos 8 end *token.Pos 9 } 10 11 var _ Locator = Location{} 12 13 // StartPos returns the start position of the location. 14 func (l Location) StartPos() *token.Pos { 15 return l.start 16 } 17 18 // EndPos returns the end position of the location. 19 func (l Location) EndPos() *token.Pos { 20 return l.end 21 } 22 23 // Locate returns the receiver. 24 func (l Location) Locate() Location { 25 return l 26 } 27 28 // LocFromToken returns a location that starts and ends at the token's position. 29 func LocFromToken(tok *token.Token) Location { 30 if tok == nil || tok.Pos.Offset < 0 { 31 return Location{} 32 } 33 pos := tok.Pos 34 return Location{&pos, &pos} 35 } 36 37 // LocFromTokens returns a location that starts at t1 and ends at t2 (t1 and t2 38 // may be nil). 39 func LocFromTokens(t1, t2 *token.Token) Location { 40 var p1, p2 *token.Pos 41 if t1 != nil && t1.Pos.Offset >= 0 { 42 p1 = new(token.Pos) 43 *p1 = t1.Pos 44 } 45 if t2 != nil && t2.Pos.Offset >= 0 { 46 p2 = new(token.Pos) 47 *p2 = t2.Pos 48 } 49 return Location{p1, p2} 50 } 51 52 // MergeLocations takes two locators and merges them into one Location, starting 53 // at the earliest start and ending at the latest end. 54 func MergeLocations(l1, l2 Locator) Location { 55 l := l1.Locate() 56 ll := l2.Locate() 57 if ll.start != nil && (l.start == nil || l.start.Offset > ll.start.Offset) { 58 l.start = ll.start 59 } 60 if ll.end != nil && (l.end == nil || l.end.Offset < ll.end.Offset) { 61 l.end = ll.end 62 } 63 return l 64 }