[SVN] r5122 (OCaml)

William D. Neumann wneumann at cs.unm.edu
Fri Sep 8 18:15:17 UTC 2006


OK.  This time I blew away my old bundle repository and downloaded a fresh one
before making changes.  Let's hope it works this time.

Changelog:

* Added `let` to the `type` option to end the meta.type scope so code like:
    module AMap = Map.Make (struct type t = int let compare = (-) end)
  highlights properly and so the type scope doesn't propogate too far in cases like:
    type t = int
    let x = 10
  There are still, however some big issues with meta.type.  See note [1] below.

* In meta.match.ocaml, added a rule so that polymorphic variant abbreviations,
  such as #pmv_abbr are given the entity.name.class.variant.polymorphic.ocaml
  scope, rather than the scopes keyword.operator.symbol for the `#` and
  variable.parameter.ocaml for the typename part.  Perhaps the name should be
  something like 'entity.name.class.variant.polymorphic.abbreviation.ocaml', but
  that might be silly.

* In meta.object.ocaml, added a rudimentary meta.object.type-constraint.ocaml
  scope.  This may need bettering eventually, but it serves as a placeholder and
  as a quick hack it seems to work.

* Added rudimentary scopes meta.module.signature.ocaml and
  meta.module.structure.ocaml, moved the previous meta.module.ocaml to
  meta.module.use.ocaml, and added a new meta.module.ocaml for matching module
  definitions, much like meta.class.ocaml.

* Added an invalid.illegal section that only matches curly quotes, single and
  double.  These are occasionally a problem when cutting and pasting code from
  pdfs or web pages -- it's nice to flag them early.

* Tweaked the meta.class and meta.class.type sections to scope the type parameter
  of prarmeterized classes as storage.type.user-defined.  While this satisfies me,
  I'm not sure if this is good or not.

NOTES:

[1] meta.type.ocaml is a bit odd:
    • It does not recognize abstract type definitions (E.g. in the line `type t`
    in the example above, the scope is not meta.type)
    • It does not admit comments in either abstract or concrete type
    declarations.  E.g.
      type hoo (* = Hoo | Hah of int *)
      type (* 'a *) feh = (* 'a *) Thing.t
    (though things are fine with comments after the `=` that ends the scope)
    • It hijacks the and keyword for both point-free function declarations and
    value bindings (See print and base in the sample code below).  While this is
    really nice for recursive types, it's pretty lousy for regular `let ... and
    ...` in constructs.  See e.g. func1 below.

[2] The meta.object.ocaml scope is a bit fragile in its end match.  The `end`
    can be at the same indentation as the opening `object`, but if it's not
    composed of the same whitespace sequence (e.g. one is tabs, the other is
    spaces), then the meta.object scope doesn't end.  This problem now exists in
    the meta.module.signature.ocaml and meta.module.structure.ocaml scopes as
    well, as I borrowed the structure for them from meta.object.ocaml.

[3] I'm wondering if the object section of a class definition shouldn't
    somehow be assigned the scope meta.class.ocaml as well.  It's good for it to
    have the meta.object.ocaml scope, as ocaml has immediate objects which can
    make good use of it, but I'm just wondering if it's possible to extend the
    meta.class scope when feasible.  This is a very minor concern.

[4] Note that something similar to the above could be added to the
    meta.object.ocaml scope for class type abbreviations.  This should be added to
    type annotations too, if we ever work that out, but that's a bit trickier, as
    in (x : #t), #t could be either a PMV or a class type...

[5] Type annotations are still being scoped as tuples.  But this may be a
    tricky problem to fix.

SAMPLE CODE:
module Feh :
  sig
    type t
     
    val compare : t -> t -> int
    val print : t -> unit
  end =
  struct
    type t = string
    let x = 10

    type pt = [`Alpha | `Beta | `Gamma]

    let compare = Pervasives.compare
    and print = print_string
    and base = 10

    let func1 a (b : int) c d =
      let e = b + c
      and f = a + d
      in      
      print_endline "e,f:";
      Printf.printf "%d %d" e f

      let pf = function
      | #pt -> "PT"
      | `Eta -> "ETA"

      class c x =
        object
          val x = x
          method id = x
          method clone = {< x = succ x >}
        end

      class point x_init =
        object
          val mutable x = x_init
          method get_x = x
          method get_offset = x - x_init
          method move d = x <- x + d
        end

      class ['a,'printable] circle (c : ’a) (name : 'printable) =
        object
          constraint 'a = #point
          constraint 'printable = string
          val mutable center = c
          val name = name
          method center = center
          method set_center c = center <- c
          method move = center#move
          method who = name
        end

  end
 
module type THING_TYPE =
  sig
    type t

    val pr : t -> string
  end;;

module type BLAH_TYPE =
  functor (Thing : THING_TYPE) ->
    sig
      type tang
      type hoo (* = Hoo | Hah of int *)
      type (* 'a *) feh = (* 'a *) Thing.t

      val add : feh -> hoo -> unit
      val clear : unit -> unit
      val contents : unit -> unit
    end;;


module Blah : BLAH_TYPE =
  functor (Thing : THING_TYPE) ->
    struct
      type hoo = Hoo | Hah of int
      type feh = Thing.t
 
      let data = ref []
      let add (f : feh) = function
      | Hoo -> data := (f,None)::!data
      | Hah i -> data := (f,Some i)::!data
      
      let clear () = data :=[]
      let contents () =
        List.iter
          (fun (f,i) -> Printf.printf "feh(%d): %s\n"
                        ((function Some x -> x | _ -> 0) i) (Thing.pr f))
          !data
    end;;

module B = Blah(struct type t = int let pr = string_of_int end)

William D. Neumann

Changed:
U   trunk/Bundles/OCaml.tmbundle/Syntaxes/OCaml.plist



More information about the textmate-dev mailing list