]> matita.cs.unibo.it Git - helm.git/commitdiff
snapshot (notably: first working version of the console)
authorStefano Zacchiroli <zack@upsilon.cc>
Tue, 4 May 2004 10:47:10 +0000 (10:47 +0000)
committerStefano Zacchiroli <zack@upsilon.cc>
Tue, 4 May 2004 10:47:10 +0000 (10:47 +0000)
helm/matita/.depend
helm/matita/matita.ml
helm/matita/matitaConsole.ml
helm/matita/matitaConsole.mli
helm/matita/matitaDisambiguator.ml
helm/matita/matitaGui.ml
helm/matita/matitaInterpreter.ml
helm/matita/matitaInterpreter.mli
helm/matita/matitaTypes.ml

index 4576d80bac36fa4cf24652e71cd9fcff75d5ba08..8d7e4e7b977dd3c33d27dd69a35e74ae770553f3 100644 (file)
@@ -10,8 +10,10 @@ matitaGui.cmo: matitaConsole.cmi matitaGeneratedGui.cmi matitaGtkMisc.cmi \
     matitaGui.cmi 
 matitaGui.cmx: matitaConsole.cmx matitaGeneratedGui.cmx matitaGtkMisc.cmx \
     matitaGui.cmi 
-matitaInterpreter.cmo: matitaProof.cmi matitaTypes.cmo matitaInterpreter.cmi 
-matitaInterpreter.cmx: matitaProof.cmx matitaTypes.cmx matitaInterpreter.cmi 
+matitaInterpreter.cmo: matitaConsole.cmi matitaProof.cmi matitaTypes.cmo \
+    matitaInterpreter.cmi 
+matitaInterpreter.cmx: matitaConsole.cmx matitaProof.cmx matitaTypes.cmx \
+    matitaInterpreter.cmi 
 matita.cmo: buildTimeConf.cmo matitaDisambiguator.cmi matitaGtkMisc.cmi \
     matitaGui.cmi matitaInterpreter.cmi matitaProof.cmi matitaTypes.cmo 
 matita.cmx: buildTimeConf.cmx matitaDisambiguator.cmx matitaGtkMisc.cmx \
@@ -22,6 +24,6 @@ matitaTypes.cmo: buildTimeConf.cmo
 matitaTypes.cmx: buildTimeConf.cmx 
 matitaDisambiguator.cmi: matitaTypes.cmo 
 matitaGtkMisc.cmi: matitaGeneratedGui.cmi matitaTypes.cmo 
-matitaGui.cmi: matitaGeneratedGui.cmi 
-matitaInterpreter.cmi: matitaTypes.cmo 
+matitaGui.cmi: matitaConsole.cmi matitaGeneratedGui.cmi 
+matitaInterpreter.cmi: matitaConsole.cmi matitaTypes.cmo 
 matitaProof.cmi: matitaTypes.cmo 
index 8f34f5bf728c141b88fe12cc8f97c3303cc45756..8954ec704af26b49dde3d8adcad6116fcee144ad 100644 (file)
@@ -33,7 +33,9 @@ let (get_proof, set_proof, has_proof) =
     match !current_proof with
     | Some proof -> proof
     | None -> failwith "No current proof"),
-   (fun proof -> current_proof := proof),
+   (fun proof ->  (* TODO Zack: this function should probably be smarter taking
+               care also of unregistering notifications subscriber and so on *)
+     current_proof := proof),
    (fun () -> !current_proof <> None))
 
 (** {2 Settings} *)
index a2c0515bd05cc26efeed58bffbc955423e7b3df6..9c3c5a9b5aa7fb702ffa64f0d1e2e9695a91f7cf 100644 (file)
@@ -33,12 +33,13 @@ let message_props = [ `STYLE `ITALIC ]
 let error_props = [ `WEIGHT `BOLD ]
 let prompt_props = [ ]
 
+let trailing_NL_RE = Pcre.regexp "\n\\s*$"
+
 class console
   ?(prompt = default_prompt) ?(phrase_sep = default_phrase_sep)
   ?(callback = default_callback)
   obj
 =
-  let ui_mark = `NAME "USER_INPUT_START" in
   object (self)
     inherit GText.view obj
 
@@ -49,6 +50,10 @@ class console
     val mutable _callback = callback
     method set_callback f = _callback <- f
 
+    val mutable _ignore_insert_text_signal = false
+    method ignore_insert_text_signal ignore =
+      _ignore_insert_text_signal <- ignore
+
 (*
     (* TODO Zack: implement history.
        IDEA: use CTRL-P/N a la emacs.
@@ -60,49 +65,56 @@ class console
 
     initializer
       let buf = self#buffer in
+      self#set_wrap_mode `CHAR;
         (* create "USER_INPUT_START" mark. This mark will always point to the
         * beginning of user input not yet processed *)
       ignore (buf#create_mark ~name:"USER_INPUT_START"
         ~left_gravity:true buf#start_iter);
-      ignore (self#event#connect#key_press (fun key ->  (* handle return ev. *)
-        if GdkEvent.Key.keyval key = GdkKeysyms._Return then begin
-          let insert_point = buf#get_iter_at_mark `INSERT in
-          if insert_point#compare buf#end_iter = 0 then (* insert pt. at end *)
-            let inserted_text =
-              buf#get_text ~start:(buf#get_iter_at_mark ui_mark)
-                ~stop:buf#end_iter ()
-            in
-            let pat = (Pcre.quote _phrase_sep) ^ "\\s*$" in
-            if Pcre.pmatch ~pat inserted_text then begin (* complete phrase *)
-              self#lock;
-              _callback inserted_text
-            end
-        end;
-        false (* continue event processing *)))
+      ignore (buf#connect#after#insert_text (fun iter text ->
+        if (not _ignore_insert_text_signal) &&
+          (iter#compare buf#end_iter = 0) &&  (* insertion at end *)
+          (Pcre.pmatch ~rex:trailing_NL_RE text)
+        then
+          let inserted_text =
+            buf#get_text
+              ~start:(buf#get_iter_at_mark (`NAME "USER_INPUT_START"))
+              ~stop:buf#end_iter ()
+          in
+          let pat = (Pcre.quote _phrase_sep) ^ "\\s*$" in
+          if Pcre.pmatch ~pat inserted_text then begin (* complete phrase *)
+            self#lock;
+            _callback inserted_text;
+            self#echo_prompt ()
+          end))
 
       (* lock old text and bump USER_INPUT_START mark *)
     method private lock =
       let buf = self#buffer in
       let read_only = buf#create_tag [`EDITABLE false] in
-      let stop = buf#end_iter in
-      buf#apply_tag read_only ~start:buf#start_iter ~stop;
-      buf#move_mark ui_mark stop
+      buf#apply_tag read_only ~start:buf#start_iter ~stop:buf#end_iter;
+      buf#move_mark (`NAME "USER_INPUT_START") buf#end_iter
 
     method echo_prompt () =
       let buf = self#buffer in
+      self#ignore_insert_text_signal true;
       buf#insert ~iter:buf#end_iter ~tags:[buf#create_tag prompt_props] prompt;
+      self#ignore_insert_text_signal false;
       self#lock
 
     method echo_message msg =
       let buf = self#buffer in
+      self#ignore_insert_text_signal true;
       buf#insert ~iter:buf#end_iter ~tags:[buf#create_tag message_props]
         (msg ^ "\n");
+      self#ignore_insert_text_signal false;
       self#lock
 
     method echo_error msg =
       let buf = self#buffer in
+      self#ignore_insert_text_signal true;
       buf#insert ~iter:buf#end_iter ~tags:[buf#create_tag error_props]
         (msg ^ "\n");
+      self#ignore_insert_text_signal false;
       self#lock
   end
 
index ee7b8d4fb351445e7552073271e0ccef006f0c5e..2cbd1ffe33d33c5c6f97afbe20ed7a7b815721fe 100644 (file)
@@ -38,6 +38,8 @@ class console:
 
       (** override previous callback definition *)
     method set_callback   : (string -> unit) -> unit
+
+    method ignore_insert_text_signal: bool -> unit
   end
 
   (** @param prompt user prompt (default "# ")
index 87215fba177db6ea4cc9ed50e6b7ab8249b499c5..daf64884ca6b89c0e67e966c64ba0c27900e2724 100644 (file)
 
 class parserr () =
   object
-    method parseTerm (stream: char Stream.t) =
-      CicTextualParser2.parse_term stream
-
-      (* TODO Zack: implements methods below *)
-    method parseTactic (_: char Stream.t) : DisambiguateTypes.tactic =
-      MatitaTypes.not_implemented "parserr.parseTactic"
-    method parseTactical (_: char Stream.t) : DisambiguateTypes.tactical =
-      MatitaTypes.not_implemented "parserr.parseTactical"
-    method parseCommand (_: char Stream.t) : DisambiguateTypes.command =
-      MatitaTypes.not_implemented "parserr.parseCommand"
-    method parseScript (_: char Stream.t) : DisambiguateTypes.script =
-      MatitaTypes.not_implemented "parserr.parseScript"
+    method parseTerm = CicTextualParser2.parse_term
+    method parseTactical = CicTextualParser2.parse_tactical
   end
 
 class disambiguator
index 95882a0f1f4fd57ab558d93ef525efe575ccdca4..2018d7176210f8b4cbc9b2bfbf40aa903436610b 100644 (file)
@@ -80,8 +80,7 @@ class gui file =
         [ main#saveMenuItem; main#saveAsMenuItem ];
       main#helpMenu#set_right_justified true;
         (* console *)
-      console#echo_message "message";
-      console#echo_error "error";
+      console#echo_message "\tMatita version 0.0.1\n";
       console#echo_prompt ();
       console#misc#grab_focus ()
 
index 4b87ec8f808012fcac907889e7484b4089dd18d5..f5dd123f53ef6a18c6e29a43c7a9587621d7888e 100644 (file)
  * http://helm.cs.unibo.it/
  *)
 
+open Printf
+
 type state_tag = [ `Command | `Proof ]
 
-class type interpreterState =
-  object
+exception Command_not_found of string
+
+class virtual interpreterState ~(console: MatitaConsole.console) =
+  object (self)
       (** eval a toplevel phrase in the current state and return the new state
       *)
-    method evalPhrase: string -> state_tag
+    method parsePhrase s = CicTextualParser2.parse_tactical (Stream.of_string s)
+
+    method virtual evalTactical:
+      (CicAst.term, string) TacticAst.tactical -> state_tag
+
+    method evalPhrase s = self#evalTactical (self#parsePhrase s)
   end
 
 class commandState
@@ -38,45 +47,58 @@ class commandState
   ~(console: MatitaConsole.console)
   ()
 =
-  object
-    method evalPhrase s: state_tag =
-      let command = CicTextualParser2.parse_command (Stream.of_string s) in
-      match command with
-      | CommandAst.Theorem (_, _, Some name, ast, None) ->
+  object (self)
+    inherit interpreterState ~console
+
+    method evalTactical = function
+(*
+      | TacticAst.Command _ -> failwith "1"
+      | TacticAst.Tactic _ -> failwith "2"
+      | TacticAst.LocatedTactical _ -> failwith "3"
+      | TacticAst.Fail -> failwith "4"
+      | TacticAst.Do (_, _) -> failwith "5"
+      | TacticAst.IdTac -> failwith "6"
+      | TacticAst.Repeat _ -> failwith "7"
+      | TacticAst.Seq _ -> failwith "8"
+      | TacticAst.Then (_, _) -> failwith "9"
+      | TacticAst.Tries _ -> failwith "10"
+      | TacticAst.Try _ -> failwith "11"
+*)
+      | TacticAst.LocatedTactical (_, tactical) -> self#evalTactical tactical
+      | TacticAst.Command (TacticAst.Theorem (_, Some name, ast, None)) ->
           let (_, metasenv, expr) = disambiguator#disambiguateTermAst ast in
           let _  = CicTypeChecker.type_of_aux' metasenv [] expr in
           let proof = MatitaProof.proof ~typ:expr ~metasenv () in
           proof_handler.MatitaTypes.new_proof proof;
           `Proof
-      | CommandAst.Quit _ ->
+      | TacticAst.Command TacticAst.Quit ->
           proof_handler.MatitaTypes.quit ();
-          `Command (* dummy answer *)
-      | _ ->
-          MatitaTypes.not_implemented (* TODO Zack *)
-            "MatitaInterpreter.commandState#evalPhrase: commands other than full theorem ones";
-          `Proof
+          `Command (* dummy answer, useless *)
+      | TacticAst.Command TacticAst.Proof ->
+            (* do nothing, just for compatibility with coq syntax *)
+          `Command
+      | tactical ->
+          raise (Command_not_found (TacticAstPp.pp_tactical tactical))
   end
 
-  (* TODO Zack FINQUI
-  * bisogna rivedere la grammatica di tatticali/comandi
-  * molti comandi (o addirittura tutti tranne Theorem) hanno senso anche nello
-  * stato proof, e' quindi un casino parsare la phrase. Un'idea potrebbe essere
-  * quella di tentare di parsare una tattica e se il parsing fallisce provare a
-  * parsare un comando (BLEAARGH). Oppure si puo' aggiungere una possibile entry
-  * nella grammatica delle tattiche che punti ad un comando (RI-BLEAARGH).
-  * Oppure boh ...
-  *)
 class proofState
   ~(disambiguator: MatitaTypes.disambiguator)
   ~(proof_handler: MatitaTypes.proof_handler)
   ~(console: MatitaConsole.console)
   ()
 =
+  let commandState =
+    new commandState ~disambiguator ~proof_handler ~console ()
+  in
   object
-    method evalPhrase (s: string): state_tag =
-      (* TODO Zack *)
-      MatitaTypes.not_implemented "MatitaInterpreter.proofState#evalPhrase";
-      `Command
+    inherit interpreterState ~console
+
+    method evalTactical = function
+      | TacticAst.Command TacticAst.Abort ->
+          proof_handler.MatitaTypes.set_proof None;
+          `Command
+      | tactical -> (* fallback on command state *)
+          commandState#evalTactical tactical
   end
 
 class interpreter
@@ -86,17 +108,19 @@ class interpreter
   ()
 =
   let commandState =
-    lazy (new commandState ~disambiguator ~proof_handler ~console ())
-  in
-  let proofState =
-    lazy (new proofState ~disambiguator ~proof_handler ~console ())
+    new commandState ~disambiguator ~proof_handler ~console ()
   in
+  let proofState = new proofState ~disambiguator ~proof_handler ~console () in
   object
-    val mutable state = Lazy.force commandState
+    val mutable state = commandState
 
     method evalPhrase s =
-      match state#evalPhrase s with
-      | `Command -> state <- Lazy.force commandState
-      | `Proof -> state <- Lazy.force proofState
+      try
+        (match state#evalPhrase s with
+        | `Command -> state <- commandState
+        | `Proof -> state <- proofState)
+      with exn ->
+        console#echo_error (sprintf "Uncaught exception: %s"
+          (Printexc.to_string exn))
   end
 
index 1407f9c0ef976c9ec56799be367b2f256b29a1bc..a19c1c921f0046e113b48db30364aab81cef076b 100644 (file)
@@ -23,6 +23,8 @@
  * http://helm.cs.unibo.it/
  *)
 
+exception Command_not_found of string
+
 class interpreter:
   disambiguator:MatitaTypes.disambiguator ->
   proof_handler:MatitaTypes.proof_handler ->
index 92fc79b7c288fb979f65d136eb510c148c04fee4..864e9604c3d9d853aeaea9c566813b77bc5fdd18 100644 (file)
@@ -64,10 +64,7 @@ class type command =
 class type parserr =  (* "parser" is a keyword :-( *)
   object
     method parseTerm:     char Stream.t -> DisambiguateTypes.term
-    method parseTactic:   char Stream.t -> DisambiguateTypes.tactic
     method parseTactical: char Stream.t -> DisambiguateTypes.tactical
-    method parseCommand:  char Stream.t -> DisambiguateTypes.command
-    method parseScript:   char Stream.t -> DisambiguateTypes.script
   end
 
 class type disambiguator =