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  }