Blame compiler/printer.ml

Packit bd2e5d
(***********************************************************************)
Packit bd2e5d
(*                                                                     *)
Packit bd2e5d
(*                 MLTk, Tcl/Tk interface of OCaml                     *)
Packit bd2e5d
(*                                                                     *)
Packit bd2e5d
(*    Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis    *)
Packit bd2e5d
(*               projet Cristal, INRIA Rocquencourt                    *)
Packit bd2e5d
(*            Jacques Garrigue, Kyoto University RIMS                  *)
Packit bd2e5d
(*                                                                     *)
Packit bd2e5d
(*  Copyright 2002 Institut National de Recherche en Informatique et   *)
Packit bd2e5d
(*  en Automatique and Kyoto University.  All rights reserved.         *)
Packit bd2e5d
(*  This file is distributed under the terms of the GNU Library        *)
Packit bd2e5d
(*  General Public License, with the special exception on linking      *)
Packit bd2e5d
(*  described in file LICENSE found in the OCaml source tree.          *)
Packit bd2e5d
(*                                                                     *)
Packit bd2e5d
(***********************************************************************)
Packit bd2e5d
Packit bd2e5d
open Tables;;
Packit bd2e5d
Packit bd2e5d
open Format;;
Packit bd2e5d
Packit bd2e5d
let (.![]<-) = Bytes.set ;;
Packit bd2e5d
Packit bd2e5d
let escape_string s =
Packit bd2e5d
  let more = ref 0 in
Packit bd2e5d
  for i = 0 to String.length s - 1 do
Packit bd2e5d
   match s.[i] with
Packit bd2e5d
   | '\\' | '\"' | '\'' -> incr more
Packit bd2e5d
   |  _ -> ()
Packit bd2e5d
  done;
Packit bd2e5d
  if !more = 0 then s else
Packit bd2e5d
  let res = Bytes.create (String.length s + !more) in
Packit bd2e5d
  let j = ref 0 in
Packit bd2e5d
  for i = 0 to String.length s - 1 do
Packit bd2e5d
   let c = s.[i] in
Packit bd2e5d
   match c with
Packit bd2e5d
   | '\\' | '\"' |'\'' -> res.![!j] <- '\\'; incr j; res.![!j] <- c; incr j
Packit bd2e5d
   | _ -> res.![!j] <- c; incr j
Packit bd2e5d
  done;
Packit bd2e5d
  Bytes.to_string res
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let escape_char c = if c = '\'' then "\\\'" else String.make 1 c;;
Packit bd2e5d
Packit bd2e5d
let print_quoted_string s = printf "\"%s\"" (escape_string s);;
Packit bd2e5d
let print_quoted_char c = printf "\'%s\'" (escape_char c);;
Packit bd2e5d
let print_quoted_int i =
Packit bd2e5d
  if i < 0 then printf "(%d)" i else printf "%d" i
Packit bd2e5d
;;
Packit bd2e5d
let print_quoted_float f =
Packit bd2e5d
  if f <= 0.0 then printf "(%f)" f else printf "%f" f
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
(* Iterators *)
Packit bd2e5d
let print_list f l =
Packit bd2e5d
  printf "@[<1>[";
Packit bd2e5d
  let rec pl = function
Packit bd2e5d
  | [] -> printf "@;<0 -1>]@]"
Packit bd2e5d
  | [x] -> f x; pl []
Packit bd2e5d
  | x :: xs -> f x; printf ";@ "; pl xs in
Packit bd2e5d
  pl l
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let print_array f v =
Packit bd2e5d
  printf "@[<2>[|";
Packit bd2e5d
  let l = Array.length v in
Packit bd2e5d
  if l >= 1 then f v.(0);
Packit bd2e5d
  if l >= 2 then
Packit bd2e5d
   for i = 1 to l - 1 do
Packit bd2e5d
    printf ";@ "; f v.(i)
Packit bd2e5d
   done;
Packit bd2e5d
  printf "@;<0 -1>|]@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let print_option f = function
Packit bd2e5d
  | None -> print_string "None"
Packit bd2e5d
  | Some x -> printf "@[<1>Some@ "; f x; printf "@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let print_bool = function
Packit bd2e5d
  | true -> print_string "true" | _ -> print_string "false"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let print_poly x = print_string "<poly>";;
Packit bd2e5d
Packit bd2e5d
(* Types of the description language *)
Packit bd2e5d
let rec print_mltype = function
Packit bd2e5d
  | Unit -> printf "Unit" | Int -> printf "Int" | Float -> printf "Float"
Packit bd2e5d
  | Bool -> printf "Bool" | Char -> printf "Char" | String -> printf "String"
Packit bd2e5d
  | List m -> printf "@[<1>(%s@ " "List"; print_mltype m; printf ")@]"
Packit bd2e5d
  | Product l_m ->
Packit bd2e5d
     printf "@[<1>(%s@ " "Product"; print_list print_mltype l_m; printf ")@]"
Packit bd2e5d
  | Record l_t_s_m ->
Packit bd2e5d
     printf "@[<1>(%s@ " "Record";
Packit bd2e5d
     print_list
Packit bd2e5d
      (function (s, m) ->
Packit bd2e5d
        printf "@[<1>("; print_quoted_string s; printf ",@ "; print_mltype m;
Packit bd2e5d
        printf ")@]")
Packit bd2e5d
      l_t_s_m;
Packit bd2e5d
     printf ")@]"
Packit bd2e5d
  | UserDefined s ->
Packit bd2e5d
     printf "@[<1>(%s@ " "UserDefined"; print_quoted_string s; printf ")@]"
Packit bd2e5d
  | Subtype (s, s0) ->
Packit bd2e5d
     printf "@[<1>(%s@ " "Subtype"; printf "@[<1>("; print_quoted_string s;
Packit bd2e5d
     printf ",@ "; print_quoted_string s0; printf ")@]"; printf ")@]"
Packit bd2e5d
  | Function m ->
Packit bd2e5d
     printf "@[<1>(%s@ " "Function"; print_mltype m; printf ")@]"
Packit bd2e5d
  | As (m, s) ->
Packit bd2e5d
     printf "@[<1>(%s@ " "As"; printf "@[<1>("; print_mltype m; printf ",@ ";
Packit bd2e5d
     print_quoted_string s; printf ")@]"; printf ")@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let rec print_template = function
Packit bd2e5d
  | StringArg s ->
Packit bd2e5d
     printf "@[<1>(%s@ " "StringArg"; print_quoted_string s; printf ")@]"
Packit bd2e5d
  | TypeArg (s, m) ->
Packit bd2e5d
     printf "@[<1>(%s@ " "TypeArg"; printf "@[<1>("; print_quoted_string s;
Packit bd2e5d
     printf ",@ "; print_mltype m; printf ")@]"; printf ")@]"
Packit bd2e5d
  | ListArg l_t ->
Packit bd2e5d
     printf "@[<1>(%s@ " "ListArg"; print_list print_template l_t;
Packit bd2e5d
     printf ")@]"
Packit bd2e5d
  | OptionalArgs (s, l_t, l_t0) ->
Packit bd2e5d
     printf "@[<1>(%s@ " "OptionalArgs"; printf "@[<1>(";
Packit bd2e5d
     print_quoted_string s; printf ",@ "; print_list print_template l_t;
Packit bd2e5d
     printf ",@ "; print_list print_template l_t0; printf ")@]"; printf ")@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
(* Sorts of components *)
Packit bd2e5d
let rec print_component_type = function
Packit bd2e5d
  | Constructor -> printf "Constructor" | Command -> printf "Command"
Packit bd2e5d
  | External -> printf "External"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
(* Full definition of a component *)
Packit bd2e5d
let rec print_fullcomponent = function
Packit bd2e5d
  {component = c; ml_name = s; var_name = s0; template = t; result = m;
Packit bd2e5d
   safe = b;
Packit bd2e5d
  } ->
Packit bd2e5d
    printf "@[<1>{"; printf "@[<1>component =@ "; print_component_type c;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>ml_name =@ "; print_quoted_string s;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>var_name =@ "; print_quoted_string s0;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>template =@ "; print_template t;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>result =@ "; print_mltype m; printf ";@]@ ";
Packit bd2e5d
    printf "@[<1>safe =@ "; print_bool b; printf ";@]@ "; printf "@,}@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
(* components are given either in full or abbreviated *)
Packit bd2e5d
let rec print_component = function
Packit bd2e5d
  | Full f -> printf "@[<1>(%s@ " "Full"; print_fullcomponent f; printf ")@]"
Packit bd2e5d
  | Abbrev s ->
Packit bd2e5d
     printf "@[<1>(%s@ " "Abbrev"; print_quoted_string s; printf ")@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
(* A type definition *)
Packit bd2e5d
(*
Packit bd2e5d
 requires_widget_context: the converter of the type MUST be passed
Packit bd2e5d
   an additional argument of type Widget.
Packit bd2e5d
*)
Packit bd2e5d
let rec print_parser_arity = function
Packit bd2e5d
  | OneToken -> printf "OneToken" | MultipleToken -> printf "MultipleToken"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let rec print_type_def = function
Packit bd2e5d
  {parser_arity = p; constructors = l_f; subtypes = l_t_s_l_f;
Packit bd2e5d
   requires_widget_context = b; variant = b0;
Packit bd2e5d
  } ->
Packit bd2e5d
    printf "@[<1>{"; printf "@[<1>parser_arity =@ "; print_parser_arity p;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>constructors =@ ";
Packit bd2e5d
    print_list print_fullcomponent l_f; printf ";@]@ ";
Packit bd2e5d
    printf "@[<1>subtypes =@ ";
Packit bd2e5d
    print_list
Packit bd2e5d
     (function (s, l_f0) ->
Packit bd2e5d
       printf "@[<1>("; print_quoted_string s; printf ",@ ";
Packit bd2e5d
       print_list print_fullcomponent l_f0; printf ")@]")
Packit bd2e5d
     l_t_s_l_f;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>requires_widget_context =@ "; print_bool b;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>variant =@ "; print_bool b0; printf ";@]@ ";
Packit bd2e5d
    printf "@,}@]"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let rec print_module_type = function
Packit bd2e5d
  | Widget -> printf "Widget" | Family -> printf "Family"
Packit bd2e5d
;;
Packit bd2e5d
Packit bd2e5d
let rec print_module_def = function
Packit bd2e5d
  {module_type = m; commands = l_f; externals = l_f0; } ->
Packit bd2e5d
    printf "@[<1>{"; printf "@[<1>module_type =@ "; print_module_type m;
Packit bd2e5d
    printf ";@]@ "; printf "@[<1>commands =@ ";
Packit bd2e5d
    print_list print_fullcomponent l_f; printf ";@]@ ";
Packit bd2e5d
    printf "@[<1>externals =@ "; print_list print_fullcomponent l_f0;
Packit bd2e5d
    printf ";@]@ "; printf "@,}@]"
Packit bd2e5d
;;