nonterminalType.ml 1.46 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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
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 =
  if Settings.table then
    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
43 44 45 46 47 48 49 50 51
      [
        IIComment "The indexed type of nonterminal symbols.";
        IITypeDecls [{
          typename = tcnonterminalgadt;
          typeparams = [ "_" ];
          typerhs = TDefSum datadefs;
          typeconstraint = None
        }]
      ]
52 53 54 55 56 57 58
    with MissingOCamlType ->
      (* If the type of some nonterminal symbol is unknown, give up
         on the whole thing. *)
      []
  else
    []