2010-10-31 2 views
4

название может быть несколько обманчивым, поэтому позвольте мне объяснить, чего я пытаюсь достичь.Аннотации в OCaml

Я пишу язык программирования, который имеет множество операторов, которые могут работать на нескольких типах с различным поведением. Реализация эволюционирует, и операторы меняются/адаптируются к тому, что я нахожу более полезным при его попытке.

Проблема заключается в том, как сохранить согласованность между языковой документацией, реализацией и встроенной помощью языка (который имеет своего рода REPL).

Поскольку большая часть поведения определяется внутри больших блоков, сопоставленных шаблону, мне было интересно, возможно ли как-нибудь (возможно, с Camlp4) аннотировать код так, чтобы запуск препроцесса мог извлечь файл txt (или что-то подобное csv, html, что угодно), в котором перечислены все выполняемые операторы.

Я имею в виду, если у меня есть что-то вроде

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

Я хотел бы иметь что-то вроде

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

, в котором информация в комментариях (я использовал комментарии синтаксис просто использовать что-то, я действительно никогда не использовали препроцессор OCaml, поэтому я не знаю, как это работает) извлекаются и сохраняются где-то, когда я скомпилирую свой проект.

Возможно, что спросить невозможно, и я должен обрабатывать источник отдельно с чем-то отличным от препроцессора/компилятора ocaml.

Любые подсказки?

EDIT: Я дам конкретный пример, чтобы показать, что я хотел бы сделать ...

Инструкция плюс, например, компилирует программу, написанную на моем языке, таким образом:

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

Я хотел бы, чтобы иметь возможность комментировать каждый пункт этой картины матча с чем-то вроде

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

таким образом, что я в состоянии предобработки свой исходный код и построить ша f список всех реализованных операций с их типами и описанием, только что взятый из аннотации. Мне не нужно ничего менять в моем коде. Это просто сохранить согласованность только в одном месте без необходимости отслеживать все доступные инструкции отдельным способом (так как мне нужно индексировать их для документации и для встроенной справки).

Я бы хотел сделать это без использования внешнего инструмента обработки, поэтому я спросил, есть ли что-то, что может обрабатывать комментарии или что-то подобное на этапе компиляции.

Заранее спасибо

+0

Вы могли бы привести более подробный пример того, что мы могли бы скомпилировать и запустить, и это будет воспроизводить вашу проблему? – gasche

+0

Что такое статус «+» и «-» в вашем примере? Предназначен ли вам этот комментарий, чтобы как-то неявно объявить инфиксные операторы '(+)' и '(-)' в остальной части предложения шаблона? – gasche

ответ

1

То, что вы пытаетесь сделать много походит грамотного программирования, так что я собираюсь предложить ocamlweb, даже если это внешний инструмент.

В стандартном дистрибутиве есть ocamldoc, так как Pascal suggested, но у вас нет большого контроля над исходным синтаксисом или как выглядит вывод.

С CamlP4 (стандартный препроцессор Ocaml) вы можете изменить lexer, чтобы получить доступ к комментариям, но я не думаю, что это очень просто. Гораздо проще добавить запись в синтаксис шаблона, содержащий либо строку, либо цитату с расширителем строки, поэтому вы должны написать что-то вроде | <:casedoc<Plus, +, int -> int -> int, computes the sum>> Plus -> ....

3

Принимали ли вы посмотрите на ocamldoc?

Обычно это файл .mli, который получает аннотации. В вашем случае, не могли бы вы написать документацию по определению типа instruction?Как:

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

Проблема в том, что операторы являются полиморфными, поэтому каждая возможная инструкция будет иметь 5-10-15 различных случаев, которые должны быть документированы отдельно. Я мог бы сделать это просто путем аннотирования исходного кода в .ml :( – Jack