camlspotter avatar camlspotter committed 2226268 Merge

Comments (0)

Files changed (8)

 
 USE_OCAMLFIND = true
 
-# OCAMLPACKS[] =
-#    pack1
-#    pack2
-#
-# if $(not $(OCAMLFIND_EXISTS))
-#    eprintln(This project requires ocamlfind, but is was not found.)
-#    eprintln(You need to install ocamlfind and run "omake --configure".)
-#    exit 1
-
 OCAMLINCLUDES +=
 
 NATIVE_ENABLED = $(OCAMLOPT_EXISTS)
    stream
    sbuffer
    planck
+   plang
 
-LIB = plancklib
+LIB = planck
 
 .DEFAULT: $(OCamlLibrary $(LIB), $(LIBFILES))
 

File contents unchanged.

File contents unchanged.

-dule Lang = struct
+include Planck.Make(Sbuffer)
+
+let rec string : string -> string t = 
+  fun str -> 
+    let len = String.length str in
+    let rec aux pos = 
+      if pos = len then return ()
+      else tokenp (fun c -> c = str.[pos]) >>= fun _ -> aux (pos+1)
+    in
+    aux 0 >>= fun () -> return str
 
 let digit_char =
-  String.charp (function
+  tokenp (function
     | '0' .. '9' -> true
     | _ -> false)
 
     | _ -> None)
 
 let oct_char =
-  String.charp (function
+  tokenp (function
     | '0' .. '7' -> true
     | _ -> false)
 
     | _ -> None)
 
 let hex_char =
-  String.charp (function
+  tokenp (function
     | '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' -> true
     | _ -> false)
 
     | _ -> None)
 
 let char = 
-  let normal = String.charp (function
+  let normal = tokenp (function
     | '\'' | '\\' -> false
     | _ -> true)
   in
   let backslashed = 
-    String.char '\\' >>= fun _ ->
+    token '\\' >>= fun _ ->
 	filter_map (function
 	  | 'b' -> Some '\b'
 	  | 't' -> Some '\t'
 	  | _ -> None)
   in
   let hex =
-    String.string "\\x" >>= fun _ ->
+    string "\\x" >>= fun _ ->
 	hex >>= fun c1 ->
 	  hex >>= fun c2 ->
 	    return (char_of_int (c1 * 16 + c2))
   in
   let oct =
-    String.string "\\o" >>= fun _ ->
+    string "\\o" >>= fun _ ->
 	oct >>= fun c1 ->
 	  oct >>= fun c2 ->
 	    oct >>= fun c3 ->
 	      return (char_of_int (c1 * 64 + c2 * 8 + c3))
   in
   let digit = 
-    String.string "\\" >>= fun _ ->
+    string "\\" >>= fun _ ->
 	digit >>= fun c1 ->
 	  digit >>= fun c2 ->
 	    digit >>= fun c3 ->
 	      return (char_of_int (c1 * 100 + c2 * 10 + c3))
   in
-  let quote = String.char '\'' in
+  let quote = token '\'' in
   surrounded quote quote (normal <|> backslashed <|> hex <|> oct <|> digit)
 
 let string = 
-  let normal = String.charp (function
+  let normal = tokenp (function
     | '"' | '\\' -> false
     | _ -> true)
   in
   let backslashed = 
-    String.char '\\' >>= fun _ ->
+    token '\\' >>= fun _ ->
 	filter_map (function
 	  | 'b' -> Some '\b'
 	  | 't' -> Some '\t'
 	  | _ -> None)
   in
   let hex =
-    String.string "\\x" >>= fun _ ->
+    string "\\x" >>= fun _ ->
 	hex >>= fun c1 ->
 	  hex >>= fun c2 ->
 	    return (char_of_int (c1 * 16 + c2))
   in
   let oct =
-    String.string "\\o" >>= fun _ ->
+    string "\\o" >>= fun _ ->
 	oct >>= fun c1 ->
 	  oct >>= fun c2 ->
 	    oct >>= fun c3 ->
 	      return (char_of_int (c1 * 64 + c2 * 8 + c3))
   in
   let digit = 
-    String.string "\\" >>= fun _ ->
+    string "\\" >>= fun _ ->
 	digit >>= fun c1 ->
 	  digit >>= fun c2 ->
 	    digit >>= fun c3 ->
 	      return (char_of_int (c1 * 100 + c2 * 10 + c3))
   in
-  let dquote = String.char '\"' in
+  let dquote = token '\"' in
   surrounded dquote dquote (normal <|> backslashed <|> hex <|> oct <|> digit)
 
+(*
 let _ = 
   assert (test char "'x'" = Some 'x');
   assert (test char "'xx'" = None);
   assert (test char "'\\x41'" = Some 'A');
   assert (test char "'\\o101'" = Some 'A');
   assert (test char "'\\065'" = Some 'A');
-
-
+*)
+module type S : sig
+  type t
+  val format : Format.formatter -> t -> unit
+  val top : t
+end
 open Utils
 
-module P = Plank.Make(Stream.Char)
+module P = Plank.Make(Sbuffer)
 
 include P
 
 open Utils
 open Stream
 
+module Position = struct
+  type t = {
+    byte : int; (* in bytes from 0 *)
+    line : int; (* from 1 *)
+    column : int; (* in bytes from 0 *)
+  }
+
+  let top = { byte = 0; line = 1; column = 0; } 
+  let add_newlines t n = { byte = t.byte + n; line = t.line + n; column = 0; }
+  let add_columns t n = { t with byte = t.byte + n; column = t.column + n; }
+  let format ppf t = Format.fprintf ppf "line %d, character %d" t.line t.column
+end
+
+module type S = sig
+  include Stream.S with type elem = char
+                   and  type gen  = string Stream.simple_gen
+  val pos : t -> Position.t
+  val substr : t -> int -> int -> string
+end
+
 module Simple_string = Simple(struct type t = string end)
 
 module M = struct
   type elem = char
   type t = { 
     buf : Simple_string.t;
-    rel_pos : int; (* from the buf head *)
-    abs_pos : int; (* from the first *)
+    rel_pos : int; (* from the buf head in bytes from 0 *)
+    abs_pos : Position.t; (* from the first *)
   }
 
   let empty = 
     { buf = Simple_string.empty;
       rel_pos = 0;
-      abs_pos = 0; }
+      abs_pos = Position.top; }
 
   let rec take : t -> (elem * t) option = fun t -> 
     Option.bind (Simple_string.take t.buf)
 	  take { buf = buf'; 
 		 rel_pos = t.rel_pos - String.length elem;
 		 abs_pos = t.abs_pos }
-	else Some (elem.[t.rel_pos],
-		  { t with rel_pos = t.rel_pos + 1;
-		           abs_pos = t.abs_pos + 1 }))
+	else 
+	  let char = elem.[t.rel_pos] in
+	  let abs_pos = match char with
+	    | '\n' -> Position.add_newlines t.abs_pos 1
+	    | _ -> Position.add_columns t.abs_pos 1
+	  in 
+	  Some (char, { t with rel_pos = t.rel_pos + 1; abs_pos}))
 
   type gen = Simple_string.gen
   let create gen = { buf = Simple_string.create gen;
 		     rel_pos = 0;
-		     abs_pos = 0; }
+		     abs_pos = Position.top; }
 
   let substr t start_abs_pos len =
-    if t.abs_pos > start_abs_pos then failwith "Sbuffer.substr: start_abs_pos is over";
+    if t.abs_pos.Position.byte > start_abs_pos then failwith "Sbuffer.substr: start_abs_pos is over";
     let buffer = Buffer.create len in
     let rec substr buf buf_pos pos len =
       if len = 0 then ()
-include Stream.S with type elem = char
-                 and  type gen  = string Stream.simple_gen
-val pos : t -> int
-val substr : t -> int -> int -> string
+module Position : sig
+  type t = {
+    byte : int; (* in bytes from 0 *)
+    line : int; (* from 1 *)
+    column : int; (* in bytes from 0 *)
+  }
 
+  val top : t
+  val add_newlines : t -> int -> t
+  val add_columns : t -> int -> t
+  val format : Format.formatter -> t -> unit
+end
 
+module type S = sig
+  include Stream.S with type elem = char
+                   and  type gen  = string Stream.simple_gen
+  val pos : t -> Position.t
+  val substr : t -> int -> int -> string
+end
+
+include S
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.