]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/grafite_parser/grafiteParser.ml
initial implementation of `ncoercion name : type := body on name : pat to pat`
[helm.git] / helm / software / components / grafite_parser / grafiteParser.ml
index 214a2d10e92d81b930945461993e8fcb7c5c2d9f..dfef4d237a0ea34c8883b2b23b1e734fb46b8fcd 100644 (file)
@@ -39,20 +39,22 @@ type 'a localized_option =
 type ast_statement =
   (N.term, N.term, N.term G.reduction, N.term N.obj, string) G.statement
 
-type statement =
-  ?never_include:bool -> include_paths:string list -> LE.status ->
-    LE.status * ast_statement localized_option
+type 'status statement =
+  ?never_include:bool -> 
+    (* do not call LexiconEngine to do includes, always raise NoInclusionPerformed *) 
+  include_paths:string list -> (#LE.status as 'status) ->
+    'status * ast_statement localized_option
 
-type parser_status = {
+type 'status parser_status = {
   grammar : Grammar.g;
   term : N.term Grammar.Entry.e;
-  statement : statement Grammar.Entry.e;
+  statement : #LE.status as 'status statement Grammar.Entry.e;
 }
 
-let grafite_callback = ref (fun _ -> ())
+let grafite_callback = ref (fun _ -> ())
 let set_grafite_callback cb = grafite_callback := cb
 
-let lexicon_callback = ref (fun _ -> ())
+let lexicon_callback = ref (fun _ -> ())
 let set_lexicon_callback cb = lexicon_callback := cb
 
 let initial_parser () = 
@@ -68,7 +70,7 @@ let add_raw_attribute ~text t = N.AttributedTerm (`Raw text, t)
 
 let default_associativity = Gramext.NonA
         
-let mk_rec_corec ng ind_kind defs loc = 
+let mk_rec_corec ind_kind defs loc = 
  (* In case of mutual definitions here we produce just
     the syntax tree for the first one. The others will be
     generated from the completely specified term just before
@@ -93,12 +95,15 @@ let mk_rec_corec ng ind_kind defs loc =
    else
     `MutualDefinition
   in
-   if ng then
-    G.NObj (loc, N.Theorem(flavour, name, ty,
-     Some (N.LetRec (ind_kind, defs, body))))
-   else
-    G.Obj (loc, N.Theorem(flavour, name, ty,
-     Some (N.LetRec (ind_kind, defs, body))))
+   (loc, N.Theorem(flavour, name, ty, Some (N.LetRec (ind_kind, defs, body))))
+
+let nmk_rec_corec ind_kind defs loc = 
+ let loc,t = mk_rec_corec ind_kind defs loc in
+  G.NObj (loc,t)
+
+let mk_rec_corec ind_kind defs loc = 
+ let loc,t = mk_rec_corec ind_kind defs loc in
+  G.Obj (loc,t)
 
 let npunct_of_punct = function
   | G.Branch loc -> G.NBranch loc
@@ -257,8 +262,12 @@ EXTEND
         G.NLetIn (loc,where,t,name)
     | kind = nreduction_kind; p = pattern_spec ->
         G.NReduce (loc, kind, p)
-    | IDENT "nrewrite"; dir = direction; what = tactic_term ; where = pattern_spec ->
+    | IDENT "nrewrite"; dir = direction; what = tactic_term ; where = pattern_spec ->  
         G.NRewrite (loc, dir, what, where)
+    | IDENT "ntry"; tac = SELF -> G.NTry (loc,tac)
+    | IDENT "nrepeat"; tac = SELF -> G.NRepeat (loc,tac)
+    | LPAREN; l = LIST1 SELF; RPAREN -> G.NBlock (loc,l)
+    | IDENT "nassumption" -> G.NAssumption loc
     | SYMBOL "#"; n=IDENT -> G.NIntro (loc,n)
     | SYMBOL "#"; SYMBOL "_" -> G.NIntro (loc,"_")
     | SYMBOL "*" -> G.NCase1 (loc,"_")
@@ -773,56 +782,23 @@ EXTEND
           loc,path,true,L.WithoutPreferences
      ]];
 
-  grafite_command: [ [
-      IDENT "set"; n = QSTRING; v = QSTRING ->
-        G.Set (loc, n, v)
-    | IDENT "drop" -> G.Drop loc
-    | IDENT "print"; s = IDENT -> G.Print (loc,s)
-    | IDENT "qed" -> G.Qed loc
-    | IDENT "nqed" -> G.NQed loc
-    | IDENT "variant" ; name = IDENT; SYMBOL ":"; 
-      typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
-        G.Obj (loc, 
-          N.Theorem 
-            (`Variant,name,typ,Some (N.Ident (newname, None))))
+  grafite_ncommand: [ [
+      IDENT "nqed" -> G.NQed loc
     | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
       body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
         G.NObj (loc, N.Theorem (nflavour, name, typ, body))
     | nflavour = ntheorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
       body = term ->
         G.NObj (loc, N.Theorem (nflavour, name, N.Implicit, Some body))
-    | flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
-      body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
-        G.Obj (loc, N.Theorem (flavour, name, typ, body))
-    | flavour = theorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
-      body = term ->
-        G.Obj (loc,
-          N.Theorem (flavour, name, N.Implicit, Some body))
-    | IDENT "axiom"; name = IDENT; SYMBOL ":"; typ = term ->
-        G.Obj (loc, N.Theorem (`Axiom, name, typ, None))
     | IDENT "naxiom"; name = IDENT; SYMBOL ":"; typ = term ->
         G.NObj (loc, N.Theorem (`Axiom, name, typ, None))
-    | LETCOREC ; defs = let_defs -> 
-        mk_rec_corec false `CoInductive defs loc
-    | LETREC ; defs = let_defs -> 
-        mk_rec_corec false `Inductive defs loc
     | NLETCOREC ; defs = let_defs -> 
-        mk_rec_corec true `CoInductive defs loc
+        nmk_rec_corec `CoInductive defs loc
     | NLETREC ; defs = let_defs -> 
-        mk_rec_corec true `Inductive defs loc
-    | IDENT "inductive"; spec = inductive_spec ->
-        let (params, ind_types) = spec in
-        G.Obj (loc, N.Inductive (params, ind_types))
+        nmk_rec_corec `Inductive defs loc
     | IDENT "ninductive"; spec = inductive_spec ->
         let (params, ind_types) = spec in
         G.NObj (loc, N.Inductive (params, ind_types))
-    | IDENT "coinductive"; spec = inductive_spec ->
-        let (params, ind_types) = spec in
-        let ind_types = (* set inductive flags to false (coinductive) *)
-          List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
-            ind_types
-        in
-        G.Obj (loc, N.Inductive (params, ind_types))
     | IDENT "ncoinductive"; spec = inductive_spec ->
         let (params, ind_types) = spec in
         let ind_types = (* set inductive flags to false (coinductive) *)
@@ -851,6 +827,51 @@ EXTEND
           | _ -> raise (Failure "only a sort can be constrained")
         in
          G.NUnivConstraint (loc, strict,u1,u2)
+    | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
+        G.UnificationHint (loc, t, n)
+    | IDENT "ncoercion"; name = IDENT; SYMBOL ":"; ty = term; 
+        SYMBOL <:unicode<def>>; t = term; "on"; 
+        id = [ IDENT | PIDENT ]; SYMBOL ":"; source = term;
+        "to"; target = term ->
+          G.NCoercion(loc,name,t,ty,(id,source),target)     
+    | IDENT "nrecord" ; (params,name,ty,fields) = record_spec ->
+        G.NObj (loc, N.Record (params,name,ty,fields))
+  ]];
+
+  grafite_command: [ [
+      IDENT "set"; n = QSTRING; v = QSTRING ->
+        G.Set (loc, n, v)
+    | IDENT "drop" -> G.Drop loc
+    | IDENT "print"; s = IDENT -> G.Print (loc,s)
+    | IDENT "qed" -> G.Qed loc
+    | IDENT "variant" ; name = IDENT; SYMBOL ":"; 
+      typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
+        G.Obj (loc, 
+          N.Theorem 
+            (`Variant,name,typ,Some (N.Ident (newname, None))))
+    | flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
+      body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
+        G.Obj (loc, N.Theorem (flavour, name, typ, body))
+    | flavour = theorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
+      body = term ->
+        G.Obj (loc,
+          N.Theorem (flavour, name, N.Implicit, Some body))
+    | IDENT "axiom"; name = IDENT; SYMBOL ":"; typ = term ->
+        G.Obj (loc, N.Theorem (`Axiom, name, typ, None))
+    | LETCOREC ; defs = let_defs -> 
+        mk_rec_corec `CoInductive defs loc
+    | LETREC ; defs = let_defs -> 
+        mk_rec_corec `Inductive defs loc
+    | IDENT "inductive"; spec = inductive_spec ->
+        let (params, ind_types) = spec in
+        G.Obj (loc, N.Inductive (params, ind_types))
+    | IDENT "coinductive"; spec = inductive_spec ->
+        let (params, ind_types) = spec in
+        let ind_types = (* set inductive flags to false (coinductive) *)
+          List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
+            ind_types
+        in
+        G.Obj (loc, N.Inductive (params, ind_types))
     | IDENT "coercion" ; 
       t = [ u = URI -> N.Uri (u,None) | t = tactic_term ; OPT "with" -> t ] ;
       arity = OPT int ; saturations = OPT int; 
@@ -864,16 +885,12 @@ EXTEND
         G.PreferCoercion (loc, t)
     | IDENT "pump" ; steps = int ->
         G.Pump(loc,steps)
-    | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
-        G.UnificationHint (loc, t, n)
     | IDENT "inverter"; name = IDENT; IDENT "for";
         indty = tactic_term; paramspec = inverter_param_list ->
           G.Inverter
             (loc, name, indty, paramspec)
     | IDENT "record" ; (params,name,ty,fields) = record_spec ->
         G.Obj (loc, N.Record (params,name,ty,fields))
-    | IDENT "nrecord" ; (params,name,ty,fields) = record_spec ->
-        G.NObj (loc, N.Record (params,name,ty,fields))
     | IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
        let uris = List.map UriManager.uri_of_string uris in
         G.Default (loc,what,uris)
@@ -898,6 +915,7 @@ EXTEND
   ]];
   executable: [
     [ cmd = grafite_command; SYMBOL "." -> G.Command (loc, cmd)
+    | ncmd = grafite_ncommand; SYMBOL "." -> G.NCommand (loc, ncmd)
     | tac = atomic_tactical LEVEL "loops"; punct = punctuation_tactical ->
         G.Tactic (loc, Some tac, punct)
     | punct = punctuation_tactical -> G.Tactic (loc, None, punct)
@@ -929,33 +947,35 @@ EXTEND
     [ ex = executable ->
        fun ?(never_include=false) ~include_paths status ->
           let stm = G.Executable (loc, ex) in
-          !grafite_callback status stm;
+          !grafite_callback stm;
          status, LSome stm
     | com = comment ->
        fun ?(never_include=false) ~include_paths status -> 
           let stm = G.Comment (loc, com) in
-          !grafite_callback status stm;
+          !grafite_callback stm;
          status, LSome stm
     | (iloc,fname,normal,mode) = include_command ; SYMBOL "."  ->
        fun ?(never_include=false) ~include_paths status ->
+       let _root, buri, fullpath, _rrelpath = 
+          Librarian.baseuri_of_script ~include_paths fname in
+        if never_include then raise (NoInclusionPerformed fullpath)
+        else
+         begin
          let stm =
-            G.Executable (loc, G.Command (loc, G.Include (iloc, normal, fname)))
-         in
-          !grafite_callback status stm;
-         let _root, buri, fullpath, _rrelpath = 
-            Librarian.baseuri_of_script ~include_paths fname 
-          in
+          G.Executable
+            (loc, G.Command (loc, G.Include (iloc,normal,`OldAndNew,fname))) in
+          !grafite_callback stm;
          let status =
-            if never_include then raise (NoInclusionPerformed fullpath)
-            else LE.eval_command status (L.Include (iloc,buri,mode,fullpath))
-          in
+           LE.eval_command status (L.Include (iloc,buri,mode,fullpath)) in
           let stm =
-            G.Executable (loc, G.Command (loc, G.Include (iloc, normal, buri)))
+          G.Executable
+            (loc,G.Command (loc,G.Include (iloc,normal,`OldAndNew,buri)))
          in
-         status, LSome stm
+          status, LSome stm
+         end
     | scom = lexicon_command ; SYMBOL "." ->
        fun ?(never_include=false) ~include_paths status ->
-          !lexicon_callback status scom;         
+          !lexicon_callback scom;        
          let status = LE.eval_command status scom in
           status, LNone loc
     | EOI -> raise End_of_file
@@ -983,9 +1003,9 @@ let exc_located_wrapper f =
 
 let parse_statement lexbuf =
   exc_located_wrapper
-    (fun () -> (Grammar.Entry.parse !grafite_parser.statement (Obj.magic lexbuf)))
+    (fun () -> (Grammar.Entry.parse (Obj.magic !grafite_parser.statement) (Obj.magic lexbuf)))
 
-let statement () = !grafite_parser.statement
+let statement () = Obj.magic !grafite_parser.statement
 
 let history = ref [] ;;