(* *********************************************************************)
(* *)
(* The Compcert verified compiler *)
(* *)
(* Xavier Leroy, INRIA Paris-Rocquencourt *)
(* *)
(* Copyright Institut National de Recherche en Informatique et en *)
(* Automatique. All rights reserved. This file is distributed *)
(* under the terms of the GNU General Public License as published by *)
(* the Free Software Foundation, either version 2 of the License, or *)
(* (at your option) any later version. This file is also distributed *)
(* under the terms of the INRIA Non-Commercial License Agreement. *)
(* *)
(* *********************************************************************)
{
open Printf
(** Cross-referencing *)
let current_module = ref ""
type xref =
| Def of string * string (* path, type *)
| Ref of string * string * string (* unit, path, type *)
let xref_table : (string * int, xref) Hashtbl.t = Hashtbl.create 273
let xref_modules : (string, unit) Hashtbl.t = Hashtbl.create 29
let path sp id =
match sp, id with
| "<>", "<>" -> ""
| "<>", _ -> id
| _ , "<>" -> sp
| _ , _ -> sp ^ "." ^ id
let add_module m =
(*eprintf "add_module %s\n" m;*)
Hashtbl.add xref_modules m ()
let add_reference curmod pos dp sp id ty =
(*eprintf "add_reference %s %d %s %s %s %s\n" curmod pos dp sp id ty;*)
if not (Hashtbl.mem xref_table (curmod, pos))
then Hashtbl.add xref_table (curmod, pos) (Ref(dp, path sp id, ty))
let add_definition curmod pos sp id ty =
if not (Hashtbl.mem xref_table (curmod, pos))
then Hashtbl.add xref_table (curmod, pos) (Def(path sp id, ty))
type link = Link of string | Anchor of string | Nolink
let coqlib_url = "http://coq.inria.fr/library/"
let re_coqlib = Str.regexp "Coq\\."
let re_sane_path = Str.regexp "[A-Za-z0-9_.]+$"
let re_shortname = Str.regexp "^.*\\."
let shortname m = Str.replace_first re_shortname "" m
let crossref m pos =
(*eprintf "crossref %s %d\n" m pos;*)
try match Hashtbl.find xref_table (m, pos) with
| Def(p, ty) ->
Anchor p
| Ref(m', p, ty) ->
let url =
if Hashtbl.mem xref_modules m' then
shortname m' ^ ".html"
else if Str.string_match re_coqlib m' 0 then
coqlib_url ^ m' ^ ".html"
else
raise Not_found in
if p = "" then
Link url
else if Str.string_match re_sane_path p 0 then
Link(url ^ "#" ^ p)
else
Nolink
with Not_found ->
Nolink
(** Keywords, etc *)
module StringSet = Set.Make(String)
let mkset l = List.fold_right StringSet.add l StringSet.empty
let coq_keywords = mkset [
"forall"; "match"; "as"; "in"; "return"; "with"; "end"; "let";
"dest"; "fun"; "if"; "then"; "else"; "Prop"; "Set"; "Type"; ":=";
"where"; "struct"; "wf"; "measure";
"AddPath"; "Axiom"; "Abort"; "Boxed"; "Chapter"; "Check";
"Coercion"; "CoFixpoint"; "CoInductive"; "Corollary"; "Defined";
"Definition"; "End"; "Eval"; "Example"; "Export"; "Fact"; "Fix";
"Fixpoint"; "Global"; "Grammar"; "Goal"; "Hint"; "Hypothesis";
"Hypotheses"; "Resolve"; "Unfold"; "Immediate"; "Extern";
"Implicit"; "Import"; "Inductive"; "Infix"; "Lemma"; "Let"; "Load";
"Local"; "Ltac"; "Module"; "Module Type"; "Declare Module";
"Include"; "Mutual"; "Parameter"; "Parameters"; "Print"; "Proof";
"Qed"; "Record"; "Recursive"; "Remark"; "Require";
"Save"; "Scheme"; "Induction"; "for"; "Sort"; "Section"; "Show";
"Structure"; "Syntactic"; "Syntax"; "Tactic"; "Theorem"; "Set";
"Types"; "Undo"; "Unset"; "Variable"; "Variables"; "Context";
"Notation"; "Reserved"; "Tactic"; "Delimit"; "Bind"; "Open";
"Scope"; "Boxed"; "Unboxed"; "Inline"; "Implicit Arguments"; "Add";
"Strict"; "Typeclasses"; "Instance"; "Global Instance"; "Class";
"Instantiation"; "subgoal"; "Program"; "Example"; "Obligation";
"Obligations"; "Solve"; "using"; "Next"; "Instance"; "Equations";
"Equations_nocomp"
]
let coq_tactics = mkset [
"intro"; "intros"; "apply"; "rewrite"; "refine"; "case"; "clear";
"injection"; "elimtype"; "progress"; "setoid_rewrite"; "destruct";
"destruction"; "destruct_call"; "dependent"; "elim";
"extensionality"; "f_equal"; "generalize"; "generalize_eqs";
"generalize_eqs_vars"; "induction"; "rename"; "move"; "omega";
"set"; "assert"; "do"; "repeat"; "cut"; "assumption"; "exact";
"split"; "subst"; "try"; "discriminate"; "simpl"; "unfold"; "red";
"compute"; "at"; "in"; "by"; "reflexivity"; "symmetry";
"transitivity"; "replace"; "setoid_replace"; "inversion";
"inversion_clear"; "pattern"; "intuition"; "congruence"; "fail";
"fresh"; "trivial"; "exact"; "tauto"; "firstorder"; "ring";
"clapply"; "program_simpl"; "program_simplify"; "eapply"; "auto";
"eauto"
]
(** HTML generation *)
let oc = ref stdout
let character = function
| '<' -> output_string !oc "<"
| '>' -> output_string !oc ">"
| '&' -> output_string !oc "&"
| c -> output_char !oc c
let section_level = function
| "*" -> 1
| "**" -> 2
| _ -> 3
let start_section sect =
fprintf !oc "
\n" let end_verbatim () = fprintf !oc "\n" let start_bracket () = fprintf !oc "" let end_bracket () = fprintf !oc "" let proof_counter = ref 0 let start_proof kwd = incr proof_counter; fprintf !oc "