Grammar.Entry.create level1_pattern_grammar "level1_pattern"
let level2_ast = Grammar.Entry.create level2_ast_grammar "level2_ast"
let term = Grammar.Entry.create level2_ast_grammar "term"
+let let_defs = Grammar.Entry.create level2_ast_grammar "let_defs"
let level2_meta = Grammar.Entry.create level2_meta_grammar "level2_meta"
-let level3_term = Grammar.Entry.create level2_ast_grammar "level3_term"
-let notation = (* level1 <-> level 2 *)
- Grammar.Entry.create level2_ast_grammar "notation"
-let interpretation = (* level2 <-> level 3 *)
- Grammar.Entry.create level2_ast_grammar "interpretation"
-let phrase = Grammar.Entry.create level2_ast_grammar "phrase"
-
let return_term loc term = ()
let fail floc msg =
let parse_level2_ast_ref = ref (fun _ -> assert false)
let parse_level2_meta_ref = ref (fun _ -> assert false)
+let fold_cluster binder terms ty body =
+ List.fold_right
+ (fun term body -> Binder (binder, (term, ty), body))
+ terms body (* terms are names: either Ident or FreshVar *)
+
let fold_binder binder pt_names body =
- let fold_cluster binder terms ty body =
- List.fold_right
- (fun term body -> Binder (binder, (term, ty), body))
- terms body (* terms are names: either Ident or FreshVar *)
- in
List.fold_right
(fun (names, ty) body -> fold_cluster binder names ty body)
pt_names body
END
EXTEND
- GLOBAL: level2_ast term
- level3_term
- notation interpretation
- phrase;
+ GLOBAL: level2_ast term let_defs;
(* {{{ Grammar for ast patterns, notation level 2 *)
level2_ast: [ [ p = term -> p ] ];
sort: [
[ SYMBOL "["; substs = LIST0 meta_subst; SYMBOL "]" -> substs ]
];
possibly_typed_name: [
- [ LPAREN; id = bound_name; SYMBOL ":"; typ = term; RPAREN ->
+ [ LPAREN; id = single_arg; SYMBOL ":"; typ = term; RPAREN ->
id, Some typ
- | id = bound_name -> id, None
+ | arg = single_arg -> arg, None
]
];
match_pattern: [
| SYMBOL <:unicode<lambda>> (* λ *) -> `Lambda
]
];
- bound_name: [
- [ i = IDENT -> Ident (i, None)
- | SYMBOL "\\FRESH"; i = IDENT -> Variable (FreshVar i)
- ]
+ arg: [
+ [ LPAREN; names = LIST1 IDENT SEP SYMBOL ",";
+ SYMBOL ":"; ty = term; RPAREN ->
+ List.map (fun n -> Ident (n, None)) names, Some ty
+ | name = IDENT -> [Ident (name, None)], None
+ | blob = UNPARSED_META ->
+ let meta = !parse_level2_meta_ref (Stream.of_string blob) in
+ match meta with
+ | Variable (FreshVar _) -> [meta], None
+ | Variable (TermVar "_") -> [Ident ("_", None)], None
+ | _ -> failwith "Invalid bound name."
+ ]
];
- bound_names: [
- [ vars = LIST1 bound_name SEP SYMBOL ",";
- ty = OPT [ SYMBOL ":"; p = term -> p ] ->
- [ vars, ty ]
- | clusters = LIST1 [
- LPAREN;
- vars = LIST1 bound_name SEP SYMBOL ",";
- ty = OPT [ SYMBOL ":"; p = term -> p ];
- RPAREN ->
- vars, ty
- ] ->
- clusters
+ single_arg: [
+ [ name = IDENT -> Ident (name, None)
+ | blob = UNPARSED_META ->
+ let meta = !parse_level2_meta_ref (Stream.of_string blob) in
+ match meta with
+ | Variable (FreshVar _) -> meta
+ | Variable (TermVar "_") -> Ident ("_", None)
+ | _ -> failwith "Invalid index name."
]
];
induction_kind: [
];
let_defs: [
[ defs = LIST1 [
- name = bound_name; args = bound_names;
- index_name = OPT [ "on"; id = bound_name -> id ];
+ name = single_arg;
+ args = LIST1 arg;
+ index_name = OPT [ "on"; id = single_arg -> id ];
ty = OPT [ SYMBOL ":" ; p = term -> p ];
SYMBOL <:unicode<def>> (* ≝ *); body = term ->
let body = fold_binder `Lambda args body in
let index =
match index_name with
| None -> 0
- | Some name -> find_arg name 0 args
+ | Some index_name -> find_arg index_name 0 args
in
(name, ty), body, index
] SEP "and" ->
defs
]
];
+ binder_vars: [
+ [ vars = [
+ l = LIST1 single_arg SEP SYMBOL "," -> l
+ | SYMBOL "_" -> [Ident ("_", None)] ];
+ typ = OPT [ SYMBOL ":"; t = term -> t ] -> (vars, typ)
+ | LPAREN;
+ vars = [
+ l = LIST1 single_arg SEP SYMBOL "," -> l
+ | SYMBOL "_" -> [Ident ("_", None)] ];
+ typ = OPT [ SYMBOL ":"; t = term -> t ];
+ RPAREN -> (vars, typ)
+ ]
+ ];
term: LEVEL "10" (* let in *)
[ "10" NONA
[ "let"; var = possibly_typed_name; SYMBOL <:unicode<def>> (* ≝ *);
];
term: LEVEL "20" (* binder *)
[ "20" RIGHTA
- [ b = binder; names = bound_names; SYMBOL "."; body = term ->
- return_term loc (fold_binder b names body)
+ [ b = binder; (vars, typ) = binder_vars; SYMBOL "."; body = term ->
+ return_term loc (fold_cluster b vars typ body)
]
];
term: LEVEL "70" (* apply *)
| u = URI -> return_term loc (Uri (u, None))
| n = NUMBER -> return_term loc (Num (n, 0))
| IMPLICIT -> return_term loc (Implicit)
+ | PLACEHOLDER -> return_term loc UserInput
| m = META -> return_term loc (Meta (int_of_string m, []))
| m = META; s = meta_substs -> return_term loc (Meta (int_of_string m, s))
| s = sort -> return_term loc (Sort s)
| outtyp = OPT [ SYMBOL "["; ty = term; SYMBOL "]" -> ty ];
"match"; t = term;
- indty_ident = OPT [ SYMBOL ":"; id = IDENT -> id ];
+ indty_ident = OPT [ "in"; id = IDENT -> id ];
"with"; SYMBOL "[";
patterns = LIST0 [
lhs = match_pattern; SYMBOL <:unicode<Rightarrow>> (* ⇒ *);
]
];
(* }}} *)
-(* {{{ Grammar for interpretation, notation level 3 *)
- argument: [
- [ id = IDENT -> IdentArg (0, id)
- | l = LIST1 [ SYMBOL <:unicode<eta>> (* η *) -> () ] SEP SYMBOL ".";
- SYMBOL "."; id = IDENT ->
- IdentArg (List.length l, id)
- ]
- ];
- level3_term: [
- [ u = URI -> UriPattern (UriManager.uri_of_string u)
- | id = IDENT -> VarPattern id
- | LPAREN; terms = LIST1 SELF; RPAREN ->
- (match terms with
- | [] -> assert false
- | [term] -> term
- | terms -> ApplPattern terms)
- ]
- ];
-(* }}} *)
-(* {{{ Notation glues *)
- associativity: [
- [ IDENT "left"; IDENT "associative" -> Gramext.LeftA
- | IDENT "right"; IDENT "associative" -> Gramext.RightA
- | IDENT "non"; IDENT "associative" -> Gramext.NonA
- ]
- ];
- precedence: [
- [ "with"; IDENT "precedence"; n = NUMBER -> int_of_string n ]
- ];
- notation: [
- [ s = QSTRING;
- assoc = OPT associativity; prec = OPT precedence;
- IDENT "for";
- p2 =
- [ blob = UNPARSED_AST -> !parse_level2_ast_ref (Stream.of_string blob)
- | blob = UNPARSED_META ->
- !parse_level2_meta_ref (Stream.of_string blob) ]
- ->
- (!parse_level1_pattern_ref (Stream.of_string s), assoc, prec, p2)
- ]
- ];
- interpretation: [
- [ s = CSYMBOL; args = LIST1 argument; SYMBOL "="; t = level3_term ->
- (s, args, t)
- ]
- ];
-(* }}} *)
-(* {{{ Top-level phrases *)
- phrase: [
- [ IDENT "print"; t = term; SYMBOL "." -> Print t
- | IDENT "notation"; (l1, assoc, prec, l2) = notation; SYMBOL "." ->
- Notation (l1, assoc, prec, l2)
- | IDENT "interpretation"; (symbol, args, l3) = interpretation; SYMBOL "." ->
- Interpretation ((symbol, args), l3)
- | IDENT "render"; u = URI; SYMBOL "." -> Render (UriManager.uri_of_string u)
- | IDENT "dump"; SYMBOL "." -> Dump
- ]
- ];
-(* }}} *)
END
(** {2 API implementation} *)
exc_located_wrapper (fun () -> Grammar.Entry.parse level2_ast stream)
let parse_level2_meta stream =
exc_located_wrapper (fun () -> Grammar.Entry.parse level2_meta stream)
-let parse_interpretation stream =
- exc_located_wrapper (fun () -> Grammar.Entry.parse level3_term stream)
-let parse_phrase stream =
- exc_located_wrapper (fun () -> Grammar.Entry.parse phrase stream)
let _ =
parse_level1_pattern_ref := parse_level1_pattern;