nonterminalType.ml 1.38 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
open UnparameterizedSyntax
open IL

(* This is the conventional name of the nonterminal GADT, which describes the
   nonterminal symbols. *)

let tcnonterminalgadt =
  "nonterminal"

let tnonterminalgadt a =
  TypApp (tcnonterminalgadt, [ a ])

(* This is the conventional name of the data constructors of the nonterminal
   GADT. *)

let tnonterminalgadtdata nt =
  "N_" ^ Misc.normalize nt

(* This is the definition of the nonterminal GADT. Here, the data
   constructors have no value argument, but have a type index. *)

exception MissingOCamlType

let nonterminalgadtdef grammar =
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
  assert Settings.table;
  try
    let datadefs =
      List.fold_left (fun defs nt ->
        let index =
          match ocamltype_of_symbol grammar nt with
          | Some t ->
              TypTextual t
          | None ->
              raise MissingOCamlType
        in
        {
          dataname = tnonterminalgadtdata nt;
          datavalparams = [];
          datatypeparams = Some [ index ]
        } :: defs
      ) [] (nonterminals grammar)
    in
    [
      IIComment "The indexed type of nonterminal symbols.";
      IITypeDecls [{
        typename = tcnonterminalgadt;
        typeparams = [ "_" ];
        typerhs = TDefSum datadefs;
        typeconstraint = None
      }]
    ]
  with MissingOCamlType ->
    (* If the type of some nonterminal symbol is unknown, give up
       on the whole thing. *)
55
    []