[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