Аннотации в OCaml - PullRequest
       31

Аннотации в OCaml

4 голосов
/ 31 октября 2010

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

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

Проблема состоит в том, как сохранить согласованность между языковой документацией, реализацией и встроенной справкой языка (которая имеетсвоего рода 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.

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

РЕДАКТИРОВАТЬ: Я приведу конкретный пример, чтобы показать, что я хотел бы сделать ...

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 31 октября 2010

Вы смотрели на ocamldoc ?

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

(** Comment for type weather  *)
type weather =
| Rain of int (** The comment for construtor Rain *)
| Sun (** The comment for constructor Sun *)
1 голос
/ 01 ноября 2010

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

В стандартном дистрибутивеесть ocamldoc, как предложил Паскаль , но вы не имеете большого контроля над синтаксисом источника или как выглядит вывод.

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

...