From 6570e52bf969a8f8f9cc484cc901907b06eadc49 Mon Sep 17 00:00:00 2001
From: charguer <arthur@chargueraud.org>
Date: Tue, 5 Apr 2016 20:35:22 +0200
Subject: [PATCH] ppx

---
 generator/Makefile                     | 19 ++++++--
 generator/_tags                        |  1 +
 generator/js_of_ast.ml                 |  2 +-
 generator/main.ml                      | 10 ++++
 generator/monad_ppx.ml                 | 65 ++++++++++++++++++++++++++
 generator/parse_type.ml                |  6 ++-
 generator/tests/jsref/JsInterpreter.ml |  3 +-
 7 files changed, 100 insertions(+), 6 deletions(-)
 create mode 100644 generator/monad_ppx.ml

diff --git a/generator/Makefile b/generator/Makefile
index 241fabe..c50ea4b 100644
--- a/generator/Makefile
+++ b/generator/Makefile
@@ -88,7 +88,10 @@ OCAMLBUILD := ocamlbuild -j 4 -classic-display -use-ocamlfind -X tests -X $(STDL
 OCAMLPAR := OCAMLRUNPARAM="l=200M"
 
 LINEOF := $(OCAMLPAR) ./lineof.byte
-MLTOJS := $(OCAMLPAR) ./main.byte
+MLTOJS := $(OCAMLPAR) ./main.byte -ppx ./monad_ppx.native
+# -dsource is automatically considered by main.byte
+
+
 DISPLAYGEN := $(OCAMLPAR) ./displayed_sources.byte
 
 ###############################################################
@@ -103,14 +106,24 @@ endif
 ###############################################################
 # Rules
 
+
+
 ##### Compilation of STDLIB
 
 $(STDLIB_DIR)/stdlib.cmi: $(STDLIB_DIR)/stdlib.mli
 	$(CC) $<
 
+##### Rule for parser extension
+
+monad_ppx.native: monad_ppx.ml
+	$(OCAMLBUILD) $@
+	
+#ocamlfind ocamlc -linkpkg -o $@ $<
+# -package compiler-libs.common
+
 ##### Rule for binaries
 
-%.byte: *.ml _tags
+%.byte: *.ml _tags monad_ppx.native
 	$(OCAMLBUILD) $@
 
 ##### Rule for dependencies
@@ -121,7 +134,7 @@ $(JSREF_PATH)/.depends: $(JSREF_ML)
 ##### Rule for cmi
 
 tests/%.cmi: tests/%.ml main.byte stdlib
-	./main.byte -mode cmi -I $(<D) $<
+	$(MLTOJS) -mode cmi -I $(<D) $<
 
 tests/%.cmi: tests/%.mli stdlib
 	ocamlc -I $(JSREF_PATH) -I stdlib_ml -open Stdlib $<
diff --git a/generator/_tags b/generator/_tags
index 1b53152..ea720ef 100644
--- a/generator/_tags
+++ b/generator/_tags
@@ -6,6 +6,7 @@ true: bin_annot
 <parsing>: include
 <typing>: include
 <utils>: include
+<driver>: include
 
 # <tests>: precious
 # <stdlib_ml>: precious
diff --git a/generator/js_of_ast.ml b/generator/js_of_ast.ml
index e5de477..3e016d0 100644
--- a/generator/js_of_ast.ml
+++ b/generator/js_of_ast.ml
@@ -881,7 +881,7 @@ and js_of_path_longident path ident =
   (* for string *)
   | "^"   -> "+" (* !!TODO: we want to claim ability to type our sublanguage, so we should not use this *)
   | res   -> 
-      let res = if !generate_qualified_names && (Path.head path).name <> "Stdlib" 
+      let res = if !generate_qualified_names && (Path.head path).Ident.name <> "Stdlib" 
                    then ppf_path path else res in
       ppf_ident_name res
 
diff --git a/generator/main.ml b/generator/main.ml
index df98a07..d60b1a7 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -20,6 +20,10 @@ let outputfile = ref None
 
 (*#########################################################################*)
 
+let add_to_list li s =
+  li := s :: !li
+
+
 let _ =
    (*---------------------------------------------------*)
    (* parsing of command line *)
@@ -30,10 +34,16 @@ let _ =
                       "includes a directory where to look for interface files");
        ("-o", Arg.String (fun s -> outputfile := Some s), "set the output file name");
        ("-debug", Arg.Set debug, "trace the various steps");
+       ("-ppx", Arg.String (add_to_list Clflags.all_ppx (* TODO Compenv.first_ppx *) ), "load ppx");
        ("-mode", Arg.String (fun s -> set_current_mode s), "current mode: unlog, log, or token")
      ]
      (fun f -> files := f :: !files)
      ("usage: [-I dir] [..other options..] file.ml");
+
+   (* force: -dsource *)
+   Clflags.dump_source := true;
+
+
    files := List.rev !files;
    if List.length !files <> 1 then
       failwith "Expects one argument: the filename of the ML source file";
diff --git a/generator/monad_ppx.ml b/generator/monad_ppx.ml
new file mode 100644
index 0000000..4795795
--- /dev/null
+++ b/generator/monad_ppx.ml
@@ -0,0 +1,65 @@
+open Ast_mapper
+open Ast_helper
+open Asttypes
+open Parsetree
+open Longident
+
+let monad_mapping =
+   [("spec", "if_spec");
+    (*("success", "ifsuccess")*)
+   ]
+
+(* e.g. 
+
+  let%some x = expr in cont
+becomes
+   if_some expr (fun x -> cont)
+
+  let%if_spec (s,x) = expr in cont
+becomes
+   if_spec expr (fun s x -> cont) 
+
+ *)
+
+
+
+let generate_mapper namesid = function argv ->
+  { default_mapper with
+    expr = fun mapper expr ->
+      match expr with
+      (* Is this an extension node? *)
+      | { pexp_desc =
+            (* Should have name "getenv". *)
+            Pexp_extension ({ txt = name; loc }, pstr)} ->
+        begin
+        try
+          let ident = List.assoc name namesid in
+          match pstr with
+          | PStr [{ pstr_desc =
+                      Pstr_eval ({ pexp_loc  = loc;
+                                   pexp_desc = Pexp_let
+                                       (rf,
+                                        [{pvb_pat =
+                                            {ppat_desc =
+                                               Ppat_tuple [p1;p2]};
+                                          pvb_expr = e}],
+                                        cont)
+                                 }, _)}] ->
+            Exp.apply ~loc (Exp.ident
+                              (Location.mkloc
+                                 (Longident.Lident ident) Location.none))
+              [("", e);
+               ("", Exp.fun_ "" None p1 (Exp.fun_ "" None p2 cont))]
+          | _ ->
+            raise (Location.Error (
+                Location.error ~loc ("error with let%"^name)))
+        with
+        | Not_found ->
+          raise (Location.Error (
+              Location.error ~loc ("no let%"^name)))
+        end
+        (* Delegate to the default mapper. *)
+        | x -> default_mapper.expr mapper x;
+  }
+
+let () = register "my_monads" (generate_mapper monad_mapping)
diff --git a/generator/parse_type.ml b/generator/parse_type.ml
index fb16208..71a81c9 100644
--- a/generator/parse_type.ml
+++ b/generator/parse_type.ml
@@ -88,7 +88,9 @@ let parse_file inputfile parse_fun ast_magic =
     with x -> close_in ic; raise x
   in
   close_in ic;
-  ast
+  (* was: ast *)
+  Pparse.apply_rewriters ~restore:false ~tool_name:"ok" ast_magic ast
+
 
 
 (** Analysis of an implementation file. Returns (Some typedtree) if
@@ -103,6 +105,8 @@ let process_implementation_file ppf sourcefile =
   try
     let env = initial_env () in
     let parsetree = parse_file inputfile Parse.implementation ast_impl_magic_number in
+
+
     let typedtree = Typemod.type_implementation sourcefile prefixname modulename env parsetree in
     (Some (parsetree, typedtree), inputfile, modulename)
   with
diff --git a/generator/tests/jsref/JsInterpreter.ml b/generator/tests/jsref/JsInterpreter.ml
index fc2f6f0..153775e 100644
--- a/generator/tests/jsref/JsInterpreter.ml
+++ b/generator/tests/jsref/JsInterpreter.ml
@@ -2791,7 +2791,8 @@ match _foo_ with
 
 and run_binary_op s c op v1 v2 =
   if binary_op_comparable op Coq_binary_op_add
-  then if_spec (convert_twice_primitive s c v1 v2) (fun s1 ww ->
+  then (* if_spec (convert_twice_primitive s c v1 v2) (fun s1 ww ->*)
+        (let%spec (s1,ww) = convert_twice_primitive s c v1 v2 in 
          let (w1, w2) = ww in
          if or_decidable
               (type_comparable (type_of (Coq_value_prim w1)) Coq_type_string)
-- 
GitLab