Skip to content
This repository
tag: v1067
Fetching contributors…

Cannot retrieve contributors at this time

file 149 lines (112 sloc) 3.915 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
(*
Copyright © 2011 MLstate

This file is part of OPA.

OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.

OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.

You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)

(**
Console Parser for interpreters.

@author Mathieu Barbin
*)

(**
This module is a simple tool for accumulating an input of the user,
until it parse a toplevel separator [";;"].

This is used in [qmltop], [qmlcompilers].

There is a support for compilers or interpreters directives,
this is about any separated line beginning with a sharp,
as in
{[
v = 5
;;
#typer off;;
etc...
]}

Comment:

+ any thing in the same line than the semicolon separator is removed
{[
g = "toto" ;; this is a comment removed by the console parser
]}
*)

(** {6 Known bug} *)

(**
This approch has some negative points :
+ it behave very badly if a string or a comment contains a toplevel separator [";;"]

*)

(** {6 Console Parser} *)
(**
Some infos about the implementation :
+ Use an intern imperative Buffer

+ it performs a [String.rtrim] on the input.
*)

(**
The type of a console parser. Statefull
*)
type t

(**
Create a new console parser
*)
val create : unit -> t

(**
The type of a parsed entity.

In case a directive is parsed, the sharp char is keeped in the returned string.
*)
type input = Directive of string | Code of string

(** Reseting the state of the internal Buffer *)
val reset : t -> unit

(**
Accumulate a line, a return possibly something, or just accumulate the input.

The accumulate function will add a newline to the Buffer.
<!> The new line char should not be given to the string.

Typically, the correct use is :
{[
while true do
match ConsoleParser.accumulate (input_line stdin) with
| Some (ConsoleParser.Directive s) ->
| Some (ConsoleParser.Code s) ->
| None ->
done
]}
*)
val accumulate : t -> string -> input option

(** Flush the last input. It is like [accumulate ";;"] *)
val flush : t -> input option


module Directive :
sig
  (** {6 Support for directives} *)

  (**
Directives in an interpreter are a way to interact with the it,
e.g. to modify a global property or an option once the loop is already started.

The syntax for directives is defined by the [ConsoleParser], which is used
in the interpreter for parsing the input.

{[
#directives [arguments] ;;
]}

A directive can for example just modify the state of the interpreter, by modifying
some option related to its behavior (like [#typer on/off]) or enrich the environment
, as in [#load <file>].

The interface of directives is : [extra-arguments -> env -> directives arguments -> env],
so that we can handle all possible cases. (the env returned should be the same as the
input env in case of just a switch of a property.)
*)

  type arguments = string list
  type 'env action = 'env -> arguments -> 'env

  (**
For parsing directive, we use a regexpr collection.
All regexp are successively used to match the input.
Then, we apply the first matching regexp action.
*)

  type regexp = string
  type argument_number = int

  type 'env directive = regexp * argument_number * 'env action

  type 'env handler
  val empty : unit -> 'env handler
  val add : 'env handler -> 'env directive -> 'env handler
  val parse : 'env handler -> 'env -> string -> 'env option
end
Something went wrong with that request. Please try again.