163 def parse_spans(toks: List[Token]): List[Command_Span.Span] = |
163 def parse_spans(toks: List[Token]): List[Command_Span.Span] = |
164 { |
164 { |
165 val result = new mutable.ListBuffer[Command_Span.Span] |
165 val result = new mutable.ListBuffer[Command_Span.Span] |
166 val content = new mutable.ListBuffer[Token] |
166 val content = new mutable.ListBuffer[Token] |
167 val ignored = new mutable.ListBuffer[Token] |
167 val ignored = new mutable.ListBuffer[Token] |
168 |
168 var start = 0 |
169 def ship(span: List[Token]) |
169 |
|
170 def ship(content: List[Token]) |
170 { |
171 { |
171 val kind = |
172 val kind = |
172 if (span.forall(_.is_ignored)) Command_Span.Ignored_Span |
173 if (content.forall(_.is_ignored)) Command_Span.Ignored_Span |
173 else if (span.exists(_.is_error)) Command_Span.Malformed_Span |
174 else if (content.exists(_.is_error)) Command_Span.Malformed_Span |
174 else |
175 else |
175 span.find(_.is_command) match { |
176 content.find(_.is_command) match { |
176 case None => Command_Span.Malformed_Span |
177 case None => Command_Span.Malformed_Span |
177 case Some(cmd) => |
178 case Some(cmd) => |
178 val name = cmd.source |
179 val name = cmd.source |
179 val offset = |
180 val offset = |
180 (0 /: span.takeWhile(_ != cmd)) { |
181 (0 /: content.takeWhile(_ != cmd)) { |
181 case (i, tok) => i + Symbol.length(tok.source) } |
182 case (i, tok) => i + Symbol.length(tok.source) } |
182 val end_offset = offset + Symbol.length(name) |
183 val end_offset = offset + Symbol.length(name) |
183 val pos = Position.Range(Text.Range(offset, end_offset) + 1) |
184 val range = Text.Range(offset, end_offset) + 1 |
184 Command_Span.Command_Span(name, pos) |
185 val pos = Position.Range(range) |
|
186 val abs_pos = Position.Range(range + start) |
|
187 Command_Span.Command_Span(name, pos, abs_pos) |
185 } |
188 } |
186 result += Command_Span.Span(kind, span) |
189 for (tok <- content) start += Symbol.length(tok.source) |
|
190 result += Command_Span.Span(kind, content) |
187 } |
191 } |
188 |
192 |
189 def flush() |
193 def flush() |
190 { |
194 { |
191 if (content.nonEmpty) { ship(content.toList); content.clear } |
195 if (content.nonEmpty) { ship(content.toList); content.clear } |