4

the title could be somewhat misleading so let me explain what I'm trying to achieve.

I'm writing a programming language that has a plethora of operators which can work on multiple types with different behaviour. The implementation is evolving and operators are changing/adapting to what I find more useful while trying it.

The problem is how to keep consistency between the language documentation, the implementation and the inline help of the language (which has a sort of REPL).

Since most of the behaviour is defined inside big pattern matched blocks I was wondering if it's possible somehow (maybe with Camlp4) to annotate the code so that a preprocess run could extract a txt file (or anything similar csv, html, whatever) that lists all the operators implemented.

I mean, if I have something like

match instruction with
  Plus -> ...
  | Minus -> ...

I would like to have something like

match instruction with
  (* Plus, +, int -> int -> int, computes the sum *)
  Plus -> ...
  (* Minus, -, int -> int -> int, computes the difference *)
  | Minus -> ...

in which the informations in comments (I used comments syntax just to use something, I really haven't never used OCaml preprocessor so I don't know how it works yet) are extracted and saved somewhere when I compile my project.

Maybe what's asking is not possible and I have to process the source separately with something different than ocaml preprocessor/compiler by itself.

Any clues?

EDIT: I'll give a concrete example to show what I would like to do...

The plus instruction for example compiles the program written in my language in this way:

| Plus -> (fun s ->
        let o2 = vm_pop s and o1 = vm_pop s in
          (match o1, o2 with
              Float f1, Float f2 -> vm_push s (Float (f1 +. f2))
            | Float f, Int i -> vm_push s (Float (f +. float i))
            | Int i, Float f -> vm_push s (Float (float i +. f))
            | Int i1, Int i2 -> vm_push s (Int (i1 + i2))
            | Complex c1, Complex c2 -> vm_push s (Complex (Complex.add c1 c2))
            | String str, v -> vm_push s (String (Printf.sprintf "%s%s" str (string_value_short v)))
            | List l, a -> l := a :: !l; vm_push s (Types.I.List l)
            | (Set c as set), a -> c := Types.ValueSet.add a !c; vm_push s set;
            | w, w2 -> throw_exc2 "+" w w2
          ); s
      )

I would like to be able to annotate every clause of this pattern match with something like

(* Plus, +, float -> float -> float, sum, computes the sum between two floats *)
(* Plus, +, string -> any -> string, append, appends the string representation of the value *)
(* etc *)

in a way that I'm able to preprocess my source code and build a sort of list of all implemented operations with their types and description, just taken from the annotation. I don't need to modify anything in my code. It's just to keep consistency in just a place without having to keep track all the available instructions in a separate way (since I need to index them for the documentation and for the inline help too).

I would like to do it without using any external processing tool, that's why I asked if there's something that is able to process comments or something similar in the compile phase.

Thanks in advance

Jack
  • 131,802
  • 30
  • 241
  • 343
  • could you give a more detailed example that we could compile and run, and that would reproduce your problem ? – gasche Oct 31 '10 at 15:27
  • What is the status of "+" and "-" in your example ? Do you intended that comment to somewhow implicitly declare the infix operators `(+)` and `(-)` in the rest of the pattern clause ? – gasche Oct 31 '10 at 15:27

2 Answers2

3

Did you take a look at ocamldoc ?

Typically it's more the .mli file that receives the annotations, though. In your case, would you mind writing the documentation at the definition of type instruction ? Like:

(** Comment for type weather  *)
type weather =
| Rain of int (** The comment for construtor Rain *)
| Sun (** The comment for constructor Sun *)
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • The problem is that the operators are polimorphic so every possible instruction will have 5-10-15 different cases that should be documented separately. I could do it just by annotating the source code in .ml itself :( – Jack Oct 31 '10 at 12:22
1

What you're trying to do sounds a lot like literate programming, so I'm going to suggest ocamlweb, even if it's an external tool.

In the standard distribution, there is ocamldoc, as Pascal suggested, but you don't have much control over the source syntax or what the output looks like.

With CamlP4 (the standard Ocaml preprocessor), you could change the lexer to get access to comments, but I don't think this is very easy. It's a lot easier to add an entry to the pattern syntax containing either a string or a quotation with a string expander, so you'd write something like | <:casedoc<Plus, +, int -> int -> int, computes the sum>> Plus -> ....

Community
  • 1
  • 1
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254