2010-10-31 9 views
4

le titre pourrait être quelque peu trompeur, alors laissez-moi vous expliquer ce que je suis en train de réaliser.annotations en OCaml

J'écris un langage de programmation qui a une pléthore d'opérateurs qui peuvent travailler sur plusieurs types avec des comportements différents. La mise en œuvre évolue et les opérateurs changent/s'adaptent à ce que je trouve plus utile en l'essayant.

Le problème est de savoir comment maintenir la cohérence entre la documentation linguistique, la mise en œuvre et l'aide en ligne de la langue (qui a une sorte de REPL). Puisque la plupart du comportement est défini à l'intérieur de gros blocs appariés, je me demandais s'il était possible d'annoter le code (peut-être avec Camlp4) afin qu'un prétraitement puisse extraire un fichier txt (ou quelque chose comme csv, html, quel que soit) qui répertorie tous les opérateurs mis en œuvre.

Je veux dire, si j'ai quelque chose comme

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

Je voudrais avoir quelque chose comme

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

dans lequel les informations dans les commentaires (j'ai utilisé les commentaires syntaxe juste utiliser quelque chose, je n'ont pas vraiment utilisé le préprocesseur OCaml donc je ne sais pas encore comment ça marche) sont extraits et sauvegardés quelque part quand je compile mon projet.

Peut-être ce qui est pas possible de demander et je dois traiter la source séparément avec quelque chose de différent qu'OCaml préprocesseur/compilateur par lui-même.

Des indices?

EDIT: Je vais vous donner un exemple concret pour montrer ce que je voudrais faire ...

L'instruction ainsi que par exemple le programme écrit compile dans ma langue de cette façon:

| 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 
    ) 

Je voudrais pouvoir annoter toutes les clauses de cette correspondance de motif avec quelque chose comme

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

d'une manière que je suis capable de prétraiter mon code source et construire un o de tri f liste de toutes les opérations implémentées avec leurs types et descriptions, issues de l'annotation. Je n'ai pas besoin de modifier quoi que ce soit dans mon code. C'est juste pour garder la cohérence dans un endroit sans avoir à suivre toutes les instructions disponibles de manière séparée (puisque j'ai besoin de les indexer pour la documentation et pour l'aide en ligne aussi).

Je voudrais le faire sans utiliser aucun outil de traitement externe, c'est pourquoi j'ai demandé s'il y a quelque chose qui est capable de traiter les commentaires ou quelque chose de similaire dans la phase de compilation.

Merci à l'avance

+0

pourriez-vous donner un exemple plus détaillé que nous pourrions compiler et exécuter, et qui reproduirait votre problème? – gasche

+0

Quel est le statut de "+" et "-" dans votre exemple? Avez-vous l'intention de faire ce commentaire à quelqu'un quand vous déclarez implicitement les opérateurs infixes '(+)' et '(-)' dans le reste de la clause pattern? – gasche

Répondre

1

Qu'est-ce que vous essayez de faire ressemble beaucoup à la programmation littéraire, donc je vais suggérer ocamlweb, même si elle est un outil externe.

Dans la distribution standard, il y a ocamldoc, comme Pascal suggested, mais vous n'avez pas beaucoup de contrôle sur la syntaxe de la source ou à quoi ressemble la sortie. Avec CamlP4 (le préprocesseur Ocaml standard), vous pouvez changer le lexeur pour avoir accès aux commentaires, mais je ne pense pas que ce soit très facile. Il est beaucoup plus facile d'ajouter une entrée à la syntaxe du modèle contenant une chaîne ou une citation avec une extension de chaîne, de sorte que vous écrivez quelque chose comme | <:casedoc<Plus, +, int -> int -> int, computes the sum>> Plus -> ....

3

Avez-vous jeter un oeil à ocamldoc?

En général, il est plus le fichier .mli qui reçoit les annotations, cependant. Dans votre cas, cela vous dérangerait-il d'écrire la documentation à la définition du type instruction?Comme:

(** Comment for type weather *) 
type weather = 
| Rain of int (** The comment for construtor Rain *) 
| Sun (** The comment for constructor Sun *) 
+0

Le problème est que les opérateurs sont polimorphes donc chaque instruction possible aura 5-10-15 cas différents qui devraient être documentés séparément. Je pourrais le faire juste en annotant le code source en .ml lui-même :( – Jack