From de153bc8531334287d606ce368e5663454a18a12 Mon Sep 17 00:00:00 2001
From: Thomas Wood <thomas.wood09@imperial.ac.uk>
Date: Wed, 23 Sep 2015 16:48:07 +0100
Subject: [PATCH] Kill off custom type attribute storage

---
 generator/attributes.ml |  21 ++++----
 generator/js_of_ast.ml  | 103 +++++++---------------------------------
 2 files changed, 28 insertions(+), 96 deletions(-)

diff --git a/generator/attributes.ml b/generator/attributes.ml
index b6ab348..55ef5bc 100644
--- a/generator/attributes.ml
+++ b/generator/attributes.ml
@@ -1,23 +1,16 @@
 open Asttypes
 open Parsetree
 open Typedtree
+open Types
 open Mytools
 
-let rec extract_cstr_attrs (cstr : Typedtree.constructor_declaration)  =
-  let cstr_name   = Ident.name cstr.cd_id in
-  let cstr_params = extract_attrs cstr.cd_attributes
-  in (cstr_name, cstr_params) 
-
-and extract_vb_attrs (vb : Typedtree.value_binding) =
-  extract_attrs vb.vb_attributes
-
-and extract_attrs attrs =
+let rec extract_attrs attrs =
   attrs
     |> List.map extract_attr
     |> List.flatten
 
 and extract_attr (_, pl) = extract_payload pl
-      
+
 and extract_payload = function
   | PStr  s    -> extract_structure s
   | PTyp  _    -> error "Type found. A tuple or a single value was expected"
@@ -90,3 +83,11 @@ and extract_constant = function
   | Const_int32     _     -> error "A string or a char was expected but a int32 was found"
   | Const_int64     _     -> error "A string or a char was expected but a int64 was found"
   | Const_nativeint _     -> error "A string or a char was expected but a nativeint was found"
+
+let extract_cstr_attrs (cstr : constructor_declaration)  =
+  let cstr_name   = Ident.name cstr.cd_id in
+  let cstr_params = extract_attrs cstr.cd_attributes
+  in (cstr_name, cstr_params)
+
+let extract_vb_attrs (vb : Typedtree.value_binding) =
+  extract_attrs vb.vb_attributes
diff --git a/generator/js_of_ast.ml b/generator/js_of_ast.ml
index 91ddafd..2b672eb 100644
--- a/generator/js_of_ast.ml
+++ b/generator/js_of_ast.ml
@@ -14,13 +14,6 @@ open Typedtree
   
 let hashtbl_size = 256
 
-(* val type_tbl : (string, string list * string list) Hashtbl.t
- * Mapping constructor names to a pair of module list and constructor names list *)
-let type_tbl     = Hashtbl.create hashtbl_size
-(* Hard-code the special-syntax of the list datatype *)
-let _            = Hashtbl.add type_tbl "[]" ([], [])
-let _            = Hashtbl.add type_tbl "::" ([], ["head"; "tail"])
-
 let record_tbl   = Hashtbl.create hashtbl_size
 let module_list  = ref []
 let module_code  = ref []
@@ -30,28 +23,6 @@ module L = Logged (Token_generator) (struct let size = 256 end)
 (**
  * Debug-purpose functions
  *)
-  
-let print_type_tbl () =
-  let assemble (l, n) =
-    let rec aux = function
-      | [] -> n
-      | x :: xs -> x ^ "." ^ aux xs
-    in aux l in
-  let rec print_str_list = function
-    | [] -> ""
-    | x :: [] -> (Printf.sprintf {|"%s"|} x)
-    | x :: xs -> (Printf.sprintf {|"%s", |} x) ^ print_str_list xs
-  in Hashtbl.iter (fun cstr (mods, elems) -> Printf.printf ({|%s -> [%s]|} ^^ "\n") (assemble (mods, cstr)) (print_str_list elems)) type_tbl; ()
-
-  
-let print_candidates l =
-let rec print_str_list = function
-  | []      -> ""
-  | x :: xs -> Printf.sprintf "%s " x ^ print_str_list xs in
-let rec aux = function
-  | []         -> ""
-  | (x, y) :: xs -> "[" ^ print_str_list x ^ ", " ^ print_str_list y ^ "]" ^ " ; " ^ aux xs
-in aux l
 
 let env_diff_names env1 env2 =
   List.map Ident.unique_name (Env.diff env1 env2)
@@ -236,45 +207,6 @@ let ppf_pat_array id_list array_expr =
   Printf.sprintf "var __%s = %s;@," "array" array_expr ^
     List.fold_left2 (fun acc (name, exp_type) y -> acc ^ Printf.sprintf "@[<v 0>var %s = __%s[%d];@,@]" name "array" y)
                     "" id_list @@ range 0 (List.length id_list - 1)
-                 
-   
-(**
- * Type managment part
- *)
-
-let short_type_name name =
-  let len = String.length name - 1 in
-  let rec find_last_point i =
-    if i < 0 then 0
-    else if name.[i] = '.' then (succ i)
-    else find_last_point (pred i) in
-  let last_point_pos = find_last_point len in
-  String.sub name last_point_pos (len - last_point_pos + 1)
-
-let add_type mod_gen name cstrs_name =
-  Hashtbl.add type_tbl (short_type_name name) (mod_gen, cstrs_name)
-
-(* string -> string list
- * Appears to return the name annotations of a type definition *)
-let find_type name =
-  let short_name = short_type_name name in
-  let find_points name = 
-    let len = String.length name in
-    string_fold_righti (fun i x acc -> if x = '.' then i :: acc else 
-                                       if i = len - 1 then i + 1 :: acc else acc) name [] in
-  let split_on_rev pos = snd @@ List.fold_left (fun (deb, acc) x -> x + 1, String.sub name deb (x - deb) :: acc) (0, []) pos in
-  let prefixes = split_on_rev @@ find_points @@ name in 
-  let rec filter_on_prefixes l prefixes = match l, prefixes with
-    | _, [] -> true
-    | [], _ -> false
-    | x :: xs, y :: ys -> if x = y then filter_on_prefixes xs ys else false in
-  let tmp = Hashtbl.find_all type_tbl short_name in
-  let candidates = if List.length tmp = 1 then tmp else List.filter (fun (x, _) -> filter_on_prefixes prefixes (short_name :: x)) tmp in
-    (* print_string @@ print_candidates @@ (Hashtbl.find_all type_tbl short_name); print_newline (); *)
-  match candidates with
-  | [] -> print_type_tbl (); failwith ("no options for constructor " ^ name)
-  | c :: [] -> snd c
-  | _ -> print_type_tbl (); failwith ("ambiguity when applying constructor " ^ name)
 
 (**
  * Module managment part
@@ -326,10 +258,7 @@ and js_of_structure_item ?(mod_gen=[]) old_env s =
   | Tstr_type tl ->
    let create_type x =
       (match x.typ_kind with
-        | Ttype_variant cdl ->
-          let cl = List.map (fun cstr -> extract_cstr_attrs cstr) cdl in
-          List.iter (fun (name, cstrs_name) -> add_type mod_gen name cstrs_name) cl;
-          (* print_type_tbl () *)
+        | Ttype_variant cdl -> () (* Do nothing, now using typedtree defs *)
         | Ttype_record ldl ->
           (* Beware silent shadowing for record labels *)
           List.iter (fun lbl -> Hashtbl.replace record_tbl (Ident.name lbl.ld_id) (Ident.name x.typ_id)) ldl
@@ -402,24 +331,26 @@ and js_of_expression ?(mod_gen=[]) old_env e =
     if is_infix f sl' && List.length exp_l = 2
     then ppf_apply_infix se (List.hd sl) (List.hd (List.tl sl))
     else ppf_apply se (String.concat ", " sl)
+
   | Texp_match (exp, l, [], Total) ->
      let se = js_of_expression ~mod_gen new_env exp in
      let sb = String.concat "@," (List.map (fun x -> js_of_branch ~mod_gen old_env x se) l) in
      ppf_match se sb
-  | Texp_tuple (tl)               -> ppf_tuple @@ show_list_f (fun exp -> js_of_expression ~mod_gen new_env exp) ", " tl
+
+  | Texp_tuple (tl) -> ppf_tuple @@ show_list_f (fun exp -> js_of_expression ~mod_gen new_env exp) ", " tl
+
   | Texp_construct (loc, cd, el) ->
-        let value = js_of_longident loc in
-        if el = [] then
-          if is_sbool value
-          then value
-          else ppf_single_cstrs value
-        else
-          let rec expand_constructor_list fields exprs = match fields, exprs with
-            | [], [] -> []
-            | [], x :: xs | x :: xs , [] -> error ~loc:locn "argument lists should have the same length."
-            | x :: xs, y :: ys -> (if y = "" then ppf_single_cstrs x else ppf_cstr x y) :: expand_constructor_list xs ys in
-          let names = find_type value
-             in ppf_multiple_cstrs value (show_list ", " (expand_constructor_list names (List.map (fun exp -> js_of_expression ~mod_gen new_env exp) el)))
+    let name = js_of_longident loc in
+    if el = [] then (* Constructor has no parameters *)
+      if is_sbool name then name (* Special case true/false to their JS natives *)
+      else ppf_single_cstrs name
+    else (* Constructor has parameters *)
+      let fields = extract_attrs cd.cstr_attributes in
+      let expr_strs = List.map (fun exp -> js_of_expression ~mod_gen new_env exp) el in
+      let expand_constructor_list = List.map2 ppf_cstr in
+      let expanded_constructors = expand_constructor_list fields expr_strs in
+      ppf_multiple_cstrs name (show_list ", " expanded_constructors)
+
   | Texp_array      (exp_l)           -> ppf_array @@ show_list_f (fun exp -> js_of_expression ~mod_gen new_env exp) ", " exp_l
   | Texp_ifthenelse (e1, e2, None)    -> ppf_ifthen (js_of_expression ~mod_gen new_env e1) (js_of_expression ~mod_gen new_env e2)
   | Texp_ifthenelse (e1, e2, Some e3) -> ppf_ifthenelse (js_of_expression ~mod_gen new_env e1) (js_of_expression ~mod_gen new_env e2) (js_of_expression ~mod_gen new_env e3)
@@ -487,7 +418,7 @@ and js_of_pattern ?(mod_gen=[]) pat obj =
   | Tpat_construct (loc, cd, el) ->
      let c = js_of_longident loc in
      let spat = Printf.sprintf "%s" ("case \"" ^ c ^ "\"") in
-     let params = find_type c in
+     let params = extract_attrs cd.cstr_attributes in
      let binders =
        if List.length el = 0 then ""
        else Printf.sprintf "@[<v 0>%s@]"
-- 
GitLab