1
2
3
4
5
6
7
8 package src
9
10
11 type XPos struct {
12 index int32
13 lico
14 }
15
16
17 var NoXPos XPos
18
19
20
21
22 func (p XPos) IsKnown() bool {
23 return p.index != 0 || p.Line() != 0
24 }
25
26
27
28 func (p XPos) Before(q XPos) bool {
29 n, m := p.index, q.index
30 return n < m || n == m && p.lico < q.lico
31 }
32
33
34 func (p XPos) SameFile(q XPos) bool {
35 return p.index == q.index
36 }
37
38
39 func (p XPos) SameFileAndLine(q XPos) bool {
40 return p.index == q.index && p.lico.SameLine(q.lico)
41 }
42
43
44
45 func (p XPos) After(q XPos) bool {
46 n, m := p.index, q.index
47 return n > m || n == m && p.lico > q.lico
48 }
49
50
51 func (p XPos) WithNotStmt() XPos {
52 p.lico = p.lico.withNotStmt()
53 return p
54 }
55
56
57 func (p XPos) WithDefaultStmt() XPos {
58 p.lico = p.lico.withDefaultStmt()
59 return p
60 }
61
62
63 func (p XPos) WithIsStmt() XPos {
64 p.lico = p.lico.withIsStmt()
65 return p
66 }
67
68
69
70
71
72
73 func (p XPos) WithBogusLine() XPos {
74 if p.index == 0 {
75
76 panic("Assigning a bogus line to XPos with no file will cause mysterious downstream failures.")
77 }
78 p.lico = makeBogusLico()
79 return p
80 }
81
82
83 func (p XPos) WithXlogue(x PosXlogue) XPos {
84 p.lico = p.lico.withXlogue(x)
85 return p
86 }
87
88
89 func (p XPos) LineNumber() string {
90 if !p.IsKnown() {
91 return "?"
92 }
93 return p.lico.lineNumber()
94 }
95
96
97
98
99 func (p XPos) FileIndex() int32 {
100 return p.index
101 }
102
103 func (p XPos) LineNumberHTML() string {
104 if !p.IsKnown() {
105 return "?"
106 }
107 return p.lico.lineNumberHTML()
108 }
109
110
111 func (p XPos) AtColumn1() XPos {
112 p.lico = p.lico.atColumn1()
113 return p
114 }
115
116
117
118 type PosTable struct {
119 baseList []*PosBase
120 indexMap map[*PosBase]int
121 nameMap map[string]int
122 }
123
124
125
126 func (t *PosTable) XPos(pos Pos) XPos {
127 m := t.indexMap
128 if m == nil {
129
130
131 t.baseList = append(t.baseList, nil)
132 m = map[*PosBase]int{nil: 0}
133 t.indexMap = m
134 t.nameMap = make(map[string]int)
135 }
136 i, ok := m[pos.base]
137 if !ok {
138 i = len(t.baseList)
139 t.baseList = append(t.baseList, pos.base)
140 t.indexMap[pos.base] = i
141 if _, ok := t.nameMap[pos.base.symFilename]; !ok {
142 t.nameMap[pos.base.symFilename] = len(t.nameMap)
143 }
144 }
145 return XPos{int32(i), pos.lico}
146 }
147
148
149
150 func (t *PosTable) Pos(p XPos) Pos {
151 var base *PosBase
152 if p.index != 0 {
153 base = t.baseList[p.index]
154 }
155 return Pos{base, p.lico}
156 }
157
158
159 func (t *PosTable) FileIndex(filename string) int {
160 if v, ok := t.nameMap[filename]; ok {
161 return v
162 }
163 return -1
164 }
165
166
167 func (t *PosTable) FileTable() []string {
168
169
170
171 fileLUT := make([]string, len(t.nameMap))
172 for str, i := range t.nameMap {
173 fileLUT[i] = str
174 }
175 return fileLUT
176 }
177
View as plain text