305 require(!cmds2.exists(_.is_undefined)) |
305 require(!cmds2.exists(_.is_undefined)) |
306 cmds1.length == cmds2.length && |
306 cmds1.length == cmds2.length && |
307 (cmds1.iterator zip cmds2.iterator).forall({ case (c1, c2) => c1.id == c2.id }) |
307 (cmds1.iterator zip cmds2.iterator).forall({ case (c1, c2) => c1.id == c2.id }) |
308 } |
308 } |
309 } |
309 } |
|
310 |
|
311 |
|
312 /* resolve inlined files */ |
|
313 |
|
314 private def clean_tokens(tokens: List[Token]): List[(Token, Int)] = |
|
315 { |
|
316 def clean(toks: List[(Token, Int)]): List[(Token, Int)] = |
|
317 toks match { |
|
318 case (t1, i1) :: (t2, i2) :: rest => |
|
319 if (t1.is_keyword && (t1.source == "%" || t1.source == "--")) clean(rest) |
|
320 else (t1, i1) :: clean((t2, i2) :: rest) |
|
321 case _ => toks |
|
322 } |
|
323 clean(tokens.zipWithIndex.filter({ case (t, _) => t.is_proper })) |
|
324 } |
|
325 |
|
326 private def find_file(tokens: List[(Token, Int)]): Option[(String, Int)] = |
|
327 tokens match { |
|
328 case (tok, _) :: toks => |
|
329 if (tok.is_command) |
|
330 toks.collectFirst({ case (t, i) if t.is_name => (t.content, i) }) |
|
331 else None |
|
332 case Nil => None |
|
333 } |
|
334 |
|
335 def span_files(syntax: Prover.Syntax, span: Command_Span.Span): (List[String], Int) = |
|
336 span.kind match { |
|
337 case Command_Span.Command_Span(name, _) => |
|
338 syntax.load_command(name) match { |
|
339 case Some(exts) => |
|
340 find_file(clean_tokens(span.content)) match { |
|
341 case Some((file, i)) => |
|
342 if (exts.isEmpty) (List(file), i) |
|
343 else (exts.map(ext => file + "." + ext), i) |
|
344 case None => (Nil, -1) |
|
345 } |
|
346 case None => (Nil, -1) |
|
347 } |
|
348 case _ => (Nil, -1) |
|
349 } |
|
350 |
|
351 def resolve_files( |
|
352 resources: Resources, |
|
353 syntax: Prover.Syntax, |
|
354 node_name: Document.Node.Name, |
|
355 span: Command_Span.Span, |
|
356 get_blob: Document.Node.Name => Option[Document.Blob]) |
|
357 : (List[Command.Blob], Int) = |
|
358 { |
|
359 val (files, index) = span_files(syntax, span) |
|
360 val blobs = |
|
361 files.map(file => |
|
362 Exn.capture { |
|
363 val name = |
|
364 Document.Node.Name(resources.append(node_name.master_dir, Path.explode(file))) |
|
365 val blob = get_blob(name).map(blob => ((blob.bytes.sha1_digest, blob.chunk))) |
|
366 (name, blob) |
|
367 }) |
|
368 (blobs, index) |
|
369 } |
310 } |
370 } |
311 |
371 |
312 |
372 |
313 final class Command private( |
373 final class Command private( |
314 val id: Document_ID.Command, |
374 val id: Document_ID.Command, |