TODO
-* gestione priorita'/associativita'
- - triplicare livelli nella grammatica?
* implementare type-checker per le trasformazioni
* prestazioni trasformazioni 3 => 2 e 2 => 1
* magic per gestione degli array?
-* gestione speciale dei numeri
+* gestione della notazione per i numeri
* sintassi concreta
- studiare/implementare sintassi con ... per i magic fold
* integrazione
- portare le trasformazioni al nuovo ast
- - salvare la notazione nei file .moo
- togliere file non piu' utilizzati (caterva di cvs remove)
+ - gestire i problemi di ridefinizione della stessa notazione?
DONE
+* gestione priorita'/associativita'
+ - triplicare livelli nella grammatica?
* implementare trasformazione 1 => 0
* implementare istanziazione dei magic a livello 1 (2 => 1)
* implementare compilazione dei default in 2 => 1
- porting della disambiguazione al nuovo ast
- refactoring: unico punto di accesso allo stato imperativo della notazione
- gestire cast
+ - salvare la notazione nei file .moo
let min_precedence = 0
let max_precedence = 100
-let default_precedence = 50
let level1_pattern =
Grammar.Entry.create level1_pattern_grammar "level1_pattern"
in
aux pattern
-let level_of_int precedence =
+let level_of precedence associativity =
if precedence < min_precedence || precedence > max_precedence then
raise (Level_not_found precedence);
- string_of_int precedence
+ let assoc_string =
+ match associativity with
+ | Gramext.NonA -> "N"
+ | Gramext.LeftA -> "L"
+ | Gramext.RightA -> "R"
+ in
+ string_of_int precedence ^ assoc_string
type rule_id = Token.t Gramext.g_symbol list
(* mapping: rule_id -> owned keywords. (rule_id, string list) Hashtbl.t *)
let owned_keywords = Hashtbl.create 23
-let extend level1_pattern ?(precedence = default_precedence)
- ?associativity action
-=
+let extend level1_pattern ~precedence ~associativity action =
let p_bindings, p_atoms =
List.split (extract_term_production level1_pattern)
in
- let level = level_of_int precedence in
+ let level = level_of precedence associativity in
let p_names = flatten_opt p_bindings in
let _ =
Grammar.extend
[ Grammar.Entry.obj (term: 'a Grammar.Entry.e),
Some (Gramext.Level level),
[ None,
- associativity,
+ Some associativity,
[ p_atoms,
(make_action
(fun (env: CicNotationEnv.t) (loc: location) -> (action env loc))
let mk_level_list first last =
let rec aux acc = function
| i when i < first -> acc
- | i -> aux ((Some (string_of_int i), None, []) :: acc) (i - 1)
+ | i ->
+ aux
+ ((Some (string_of_int i ^ "N"), Some Gramext.NonA, [])
+ :: (Some (string_of_int i ^ "L"), Some Gramext.LeftA, [])
+ :: (Some (string_of_int i ^ "R"), Some Gramext.RightA, [])
+ :: acc)
+ (i - 1)
in
aux [] last
in
END
(* }}} *)
-
+(* {{{ Grammar for ast magics, notation level 2 *)
EXTEND
GLOBAL: level2_meta;
l2_variable: [
]
];
END
+(* }}} *)
+(* {{{ Grammar for ast patterns, notation level 2 *)
EXTEND
GLOBAL: level2_ast term let_defs;
-(* {{{ Grammar for ast patterns, notation level 2 *)
level2_ast: [ [ p = term -> p ] ];
sort: [
[ "Prop" -> `Prop
RPAREN -> (vars, typ)
]
];
- term: LEVEL "10" (* let in *)
- [ "10" NONA
- [ "let"; var = possibly_typed_name; SYMBOL <:unicode<def>> (* ≝ *);
- p1 = term; "in"; p2 = term ->
- return_term loc (LetIn (var, p1, p2))
- | "let"; k = induction_kind; defs = let_defs; "in";
- body = term ->
- return_term loc (LetRec (k, defs, body))
- ]
- ];
- term: LEVEL "20" (* binder *)
- [ "20" RIGHTA
+ term: LEVEL "10N" [ (* let in *)
+ [ "let"; var = possibly_typed_name; SYMBOL <:unicode<def>> (* ≝ *);
+ p1 = term; "in"; p2 = term ->
+ return_term loc (LetIn (var, p1, p2))
+ | "let"; k = induction_kind; defs = let_defs; "in";
+ body = term ->
+ return_term loc (LetRec (k, defs, body))
+ ]
+ ];
+ term: LEVEL "20R" (* binder *)
+ [
[ b = binder; (vars, typ) = binder_vars; SYMBOL "."; body = term ->
return_term loc (fold_cluster b vars typ body)
]
];
- term: LEVEL "70" (* apply *)
- [ "70" LEFTA
+ term: LEVEL "70L" (* apply *)
+ [
[ p1 = term; p2 = term ->
let rec aux = function
| Appl (hd :: tl)
return_term loc (Appl (aux p1 @ [p2]))
]
];
- term: LEVEL "90" (* simple *)
- [ "90" NONA
+ term: LEVEL "90N" (* simple *)
+ [
[ id = IDENT -> return_term loc (Ident (id, None))
| id = IDENT; s = explicit_subst -> return_term loc (Ident (id, Some s))
| s = CSYMBOL -> return_term loc (Symbol (s, 0))
| blob = UNPARSED_META -> !parse_level2_meta_ref (Stream.of_string blob)
]
];
-(* }}} *)
END
+(* }}} *)
(** {2 API implementation} *)
val extend:
CicNotationPt.term ->
- ?precedence:int ->
- ?associativity:Gramext.g_assoc ->
+ precedence:int ->
+ associativity:Gramext.g_assoc ->
(CicNotationEnv.t -> CicNotationPt.location -> CicNotationPt.term) ->
rule_id
sprintf "#[%s]" (pp_term term)
| AttributedTerm (_, term) when print_attributes ->
sprintf "@[%s]" (pp_term term) *)
- | AttributedTerm (`Raw (text, None), _) -> text
- | AttributedTerm (`Raw (text, Some `Ast), _) -> sprintf "@{%s}" text
- | AttributedTerm (`Raw (text, Some `Meta), _) -> sprintf "${%s}" text
+ | AttributedTerm (`Raw text, _) -> text
| AttributedTerm (_, term) -> pp_term ~pp_parens:false term
| Appl terms ->
let (x, y) = loc_of_floc floc in
failwith (Printf.sprintf "Error at characters %d - %d: %s" x y msg)
-type blob_context = [ `Ast | `Meta ]
-
type term_attribute =
[ `Loc of location (* source file location *)
| `IdRef of string (* ACic pointer *)
| `Level of int * Gramext.g_assoc (* precedence, associativity *)
| `XmlAttrs of (string option * string * string) list
(* list of XML attributes: namespace, name, value *)
- | `Raw of string * blob_context option (* unparsed version *)
+ | `Raw of string (* unparsed version *)
]
type literal =
type interpretation_id = pattern_id
type pretty_printer_id = pattern_id
-let default_prec = 50
-let default_assoc = Gramext.NonA
-
module Ast = CicNotationPt
type term_info =
!(Hashtbl.find interpretations symbol)
with Not_found -> raise Interpretation_not_found
-let add_pretty_printer
- ?(precedence = default_prec) ?(associativity = default_assoc) l2 l1
-=
+let add_pretty_printer ~precedence ~associativity l2 l1 =
let id = fresh_id () in
let l2' = CicNotationUtil.strip_attributes l2 in
Hashtbl.add level1_patterns21 id (precedence, associativity, l1);
CicNotationPt.cic_appl_pattern) list
val add_pretty_printer:
- ?precedence:int ->
- ?associativity:Gramext.g_assoc ->
+ precedence:int ->
+ associativity:Gramext.g_assoc ->
CicNotationPt.term -> (* level 2 pattern *)
CicNotationPt.term -> (* level 1 pattern *)
pretty_printer_id
| Alias of loc * alias_spec
(** parameters, name, type, fields *)
| Obj of loc * 'obj
- | Notation of loc * CicNotationPt.term * Gramext.g_assoc option * int option *
+ | Notation of loc * CicNotationPt.term * Gramext.g_assoc * int *
CicNotationPt.term
(* level 1 pattern, associativity, precedence, level 2 pattern *)
| Interpretation of loc *
let pp_l2_pattern = CicNotationPp.pp_term
let pp_associativity = function
- | Some Gramext.LeftA -> "left associative "
- | Some Gramext.RightA -> "right associative "
- | Some Gramext.NonA -> "non associative "
- | None -> ""
+ | Gramext.LeftA -> "left associative"
+ | Gramext.RightA -> "right associative"
+ | Gramext.NonA -> "non associative"
-let pp_precedence = function
- | Some i -> sprintf "with precedence %d " i
- | None -> ""
+let pp_precedence i = sprintf "with precedence %d" i
let pp_command = function
| Include (_,path) -> "include " ^ path
(String.concat " " (List.map pp_argument_pattern arg_patterns))
(pp_cic_appl_pattern cic_appl_pattern)
| Notation (_, l1_pattern, assoc, prec, l2_pattern) ->
- sprintf "notation \"%s\" %s%sfor %s"
+ sprintf "notation \"%s\" %s %s for %s"
(pp_l1_pattern l1_pattern)
(pp_associativity assoc)
(pp_precedence prec)
let term = CicNotationParser.term
let statement = Grammar.Entry.create grammar "statement"
-let add_raw_attribute ?context ~text term =
- CicNotationPt.AttributedTerm (`Raw (text, context), term)
+let add_raw_attribute ~text t = CicNotationPt.AttributedTerm (`Raw text, t)
+
+let default_precedence = 50
+let default_associativity = Gramext.NonA
EXTEND
GLOBAL: term statement;
IDENT "for";
p2 =
[ blob = UNPARSED_AST ->
- add_raw_attribute ~context:`Ast ~text:blob
+ add_raw_attribute ~text:(sprintf "@{%s}" blob)
(CicNotationParser.parse_level2_ast (Stream.of_string blob))
| blob = UNPARSED_META ->
- add_raw_attribute ~context:`Meta ~text:blob
+ add_raw_attribute ~text:(sprintf "${%s}" blob)
(CicNotationParser.parse_level2_meta (Stream.of_string blob))
] ->
+ let assoc =
+ match assoc with
+ | None -> default_associativity
+ | Some assoc -> assoc
+ in
+ let prec =
+ match prec with
+ | None -> default_precedence
+ | Some prec -> prec
+ in
(add_raw_attribute ~text:s
(CicNotationParser.parse_level1_pattern (Stream.of_string s)),
assoc, prec, p2)
exit 2
end
+let pp_associativity = function
+ | Gramext.LeftA -> "left"
+ | Gramext.RightA -> "right"
+ | Gramext.NonA -> "non"
+
+let pp_precedence = string_of_int
+
let process_stream ?(ignore_exn = false) istream =
let char_count = ref 0 in
let module P = CicNotationPt in
char_count := y + !char_count;
match statement with
| G.Executable (_, G.Macro (_, G.Check (_, t))) ->
- prerr_endline "====";
- prerr_endline (CicNotationPp.pp_term t); flush stdout;
+ prerr_endline (sprintf "ast: %s" (CicNotationPp.pp_term t));
let t' = CicNotationRew.pp_ast t in
- prerr_endline (CicNotationPp.pp_term t'); flush stdout;
- let tbl = Hashtbl.create 0 in
- dump_xml t' tbl "out.xml"
+ prerr_endline (sprintf "rendered ast: %s"
+ (CicNotationPp.pp_term t'));
+ let tbl = Hashtbl.create 0 in
+ dump_xml t' tbl "out.xml"
| G.Executable (_, G.Command (_,
G.Notation (_, l1, associativity, precedence, l2))) ->
- prerr_endline "Extending parser ..."; flush stdout;
- prerr_endline (CicNotationPp.pp_term l1) ;
- prerr_endline (CicNotationPp.pp_term l2) ;
- prerr_endline (sprintf "Found keywords: %s"
- (String.concat " " (CicNotationUtil.keywords_of_term l1)));
- let time1 = Unix.gettimeofday () in
- ignore (CicNotationParser.extend l1 ?precedence ?associativity
- (fun env loc -> CicNotationFwd.instantiate_level2 env l2));
- let time2 = Unix.gettimeofday () in
- prerr_endline "Extending pretty printer ..."; flush stdout;
- let time3 = Unix.gettimeofday () in
- ignore (CicNotationRew.add_pretty_printer
- ?precedence ?associativity l2 l1);
- let time4 = Unix.gettimeofday () in
- printf ("done (extending parser took %f, " ^^
- "extending pretty printer took %f)\n")
- (time2 -. time1) (time4 -. time3);
- flush stdout
+ prerr_endline "notation";
+ prerr_endline (sprintf "l1: %s" (CicNotationPp.pp_term l1));
+ prerr_endline (sprintf "l2: %s" (CicNotationPp.pp_term l2));
+ prerr_endline (sprintf "prec: %s" (pp_precedence precedence));
+ prerr_endline (sprintf "assoc: %s" (pp_associativity associativity));
+ let keywords = CicNotationUtil.keywords_of_term l1 in
+ if keywords <> [] then
+ prerr_endline (sprintf "keywords: %s"
+ (String.concat " " keywords));
+ ignore (CicNotationParser.extend l1 ?precedence ?associativity
+ (fun env loc -> CicNotationFwd.instantiate_level2 env l2));
+ ignore (CicNotationRew.add_pretty_printer
+ ?precedence ?associativity l2 l1)
| G.Executable (_, G.Command (_, G.Interpretation (_, id, l2, l3))) ->
- prerr_endline "Adding interpretation ..."; flush stdout;
- let time1 = Unix.gettimeofday () in
- ignore (CicNotationRew.add_interpretation id l2 l3);
- let time2 = Unix.gettimeofday () in
- printf "done (patterns compilation took %f seconds)\n"
- (time2 -. time1);
- flush stdout
+ prerr_endline "interpretation";
+ prerr_endline (sprintf "dsc: %s" id);
+ ignore (CicNotationRew.add_interpretation id l2 l3);
+ flush stdout
| G.Executable (_, G.Command (_, G.Dump _)) ->
CicNotationParser.print_l2_pattern (); print_newline ()
| G.Executable (_, G.Command (_, G.Render (_, uri))) ->
| Cic.AVariable (_, _, _, ty, _, _) -> ty
| _ -> assert false
in
- let time1 = Unix.gettimeofday () in
let t, id_to_uri =
CicNotationRew.ast_of_acic id_to_sort annterm
in
- let time2 = Unix.gettimeofday () in
- prerr_endline (sprintf "ast creation took %f seconds\n"
- (time2 -. time1));
- prerr_endline "AST";
- prerr_endline (CicNotationPp.pp_term t);
- flush stdout;
- let time3 = Unix.gettimeofday () in
- let t' = CicNotationRew.pp_ast t in
- let time4 = Unix.gettimeofday () in
- prerr_endline (sprintf "pretty printing took %f seconds\n"
- (time4 -. time3));
- prerr_endline (CicNotationPp.pp_term t');
- dump_xml t' id_to_uri "out.xml"
- | _ ->
- prerr_endline "Unsupported statement"
+ prerr_endline "AST";
+ prerr_endline (CicNotationPp.pp_term t);
+ let t' = CicNotationRew.pp_ast t in
+ prerr_endline (CicNotationPp.pp_term t');
+ dump_xml t' id_to_uri "out.xml"
+ | _ -> prerr_endline "Unsupported statement"
with
| End_of_file -> raise End_of_file
| CicNotationParser.Parse_error (floc, msg) ->
let usage = "" in
Arg.parse arg_spec (fun _ -> raise (Arg.Bad usage)) usage;
print_endline "Loading builtin notation ...";
- let ic = open_in (Helm_registry.get "notation.core_file") in
- process_stream ~ignore_exn:true (Stream.of_channel ic);
- close_in ic;
+ CicNotation.load_notation (Helm_registry.get "notation.core_file");
print_endline "done.";
flush stdout;
process_stream ~ignore_exn:false (Stream.of_channel stdin)