Skip to content

Commit

Permalink
v0.12-preview.120.18+252
Browse files Browse the repository at this point in the history
  • Loading branch information
xclerc committed Jan 16, 2019
1 parent 6b33250 commit de8312e
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 109 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License

Copyright (c) 2015--2018 Jane Street Group, LLC <opensource@janestreet.com>
Copyright (c) 2015--2019 Jane Street Group, LLC <opensource@janestreet.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
INSTALL_ARGS := $(if $(PREFIX),--prefix $(PREFIX),)

# Default rule
default:
jbuilder build @install
dune build

install:
jbuilder install $(INSTALL_ARGS)
dune install $(INSTALL_ARGS)

uninstall:
jbuilder uninstall $(INSTALL_ARGS)
dune uninstall $(INSTALL_ARGS)

reinstall: uninstall install

clean:
rm -rf _build
dune clean

.PHONY: default install uninstall reinstall clean
Empty file added dune
Empty file.
1 change: 1 addition & 0 deletions dune-project
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(lang dune 1.5)
2 changes: 2 additions & 0 deletions expander/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(library (name ppx_let_expander) (public_name ppx_let.expander)
(libraries base ppxlib) (preprocess no_preprocessing))
7 changes: 0 additions & 7 deletions expander/jbuild

This file was deleted.

79 changes: 52 additions & 27 deletions expander/ppx_let_expander.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module List = struct
match l with
| [] -> invalid_arg "List.reduce_exn"
| hd :: tl -> fold_left tl ~init:hd ~f
;;
end

module Extension_name = struct
Expand All @@ -20,22 +21,26 @@ module Extension_name = struct

let operator_name = function
| Bind | Bind_open -> "bind"
| Map | Map_open -> "map"
| Map | Map_open -> "map"
;;

let to_string = function
| Bind -> "bind"
let to_string = function
| Bind -> "bind"
| Bind_open -> "bind_open"
| Map -> "map"
| Map_open -> "map_open"
| Map -> "map"
| Map_open -> "map_open"
;;
end

let let_syntax ~modul : Longident.t =
match modul with
| None -> Lident "Let_syntax"
| Some id -> Ldot (id.txt, "Let_syntax")
;;

let open_on_rhs ~loc ~modul =
Located.mk ~loc (Longident.Ldot (let_syntax ~modul, "Open_on_rhs" ))
Located.mk ~loc (Longident.Ldot (let_syntax ~modul, "Open_on_rhs"))
;;

let eoperator ~loc ~modul func =
let lid : Longident.t = Ldot (let_syntax ~modul, func) in
Expand All @@ -44,30 +49,33 @@ let eoperator ~loc ~modul func =

let expand_with_tmp_vars ~loc bindings expr ~f =
match bindings with
| [_] -> f ~loc bindings expr
| [ _ ] -> f ~loc bindings expr
| _ ->
let tmp_vars = List.map bindings ~f:(fun _ -> gen_symbol ~prefix:"__let_syntax" ()) in
let tmp_vars =
List.map bindings ~f:(fun _ -> gen_symbol ~prefix:"__let_syntax" ())
in
let s_rhs_tmp_var (* s/rhs/tmp_var *) =
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
{ vb with pvb_expr = evar ~loc:vb.pvb_expr.pexp_loc var })
in
let s_lhs_tmp_var (* s/lhs/tmp_var *) =
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
List.map2_exn bindings tmp_vars ~f:(fun vb var ->
{ vb with pvb_pat = pvar ~loc:vb.pvb_pat.ppat_loc var })
in
pexp_let ~loc Nonrecursive s_lhs_tmp_var (f ~loc s_rhs_tmp_var expr)
;;

let bind_apply ~loc ~modul extension_name ~arg ~fn =
pexp_apply ~loc
pexp_apply
~loc
(eoperator ~loc ~modul (Extension_name.operator_name extension_name))
[(Nolabel, arg); (Labelled "f", fn)]
[ Nolabel, arg; Labelled "f", fn ]
;;

let maybe_open extension_name ~to_open:module_to_open expr =
let loc = expr.pexp_loc in
match (extension_name : Extension_name.t) with
| Bind | Map -> expr
| Bind | Map -> expr
| Bind_open | Map_open -> pexp_open ~loc Override (module_to_open ~loc) expr
;;

Expand All @@ -79,30 +87,41 @@ let expand_let extension_name ~loc ~modul bindings body =
let rev_boths = List.rev_map bindings ~f:(fun vb -> vb.pvb_expr) in
List.reduce_exn rev_boths ~f:(fun acc e ->
let loc = e.pexp_loc in
eapply ~loc (eoperator ~loc ~modul "both") [e; acc])
eapply ~loc (eoperator ~loc ~modul "both") [ e; acc ])
in
(* Build pattern [(P1, (P2, ...))] *)
let nested_patterns =
let rev_patts = List.rev_map bindings ~f:(fun vb -> vb.pvb_pat) in
List.reduce_exn rev_patts ~f:(fun acc p ->
let loc = p.ppat_loc in
ppat_tuple ~loc [p; acc])
ppat_tuple ~loc [ p; acc ])
in
bind_apply ~loc ~modul extension_name ~arg:nested_boths
bind_apply
~loc
~modul
extension_name
~arg:nested_boths
~fn:(pexp_fun ~loc Nolabel None nested_patterns body)
;;

let expand_match extension_name ~loc ~modul expr cases =
bind_apply ~loc ~modul extension_name
bind_apply
~loc
~modul
extension_name
~arg:(maybe_open extension_name ~to_open:(open_on_rhs ~modul) expr)
~fn:(pexp_function ~loc cases)
;;

let expand_if extension_name ~loc expr then_ else_ =
expand_match extension_name ~loc expr
[ case ~lhs:(pbool ~loc true) ~guard:None ~rhs:then_
expand_match
extension_name
~loc
expr
[ case ~lhs:(pbool ~loc true) ~guard:None ~rhs:then_
; case ~lhs:(pbool ~loc false) ~guard:None ~rhs:else_
]
;;

let expand ~modul extension_name expr =
let loc = expr.pexp_loc in
Expand All @@ -118,32 +137,38 @@ let expand ~modul extension_name expr =
For reference, here is the relevant part of the parser:
https://github.com/ocaml/ocaml/blob/4.07/parsing/parser.mly#L1628 *)
match vb.pvb_pat.ppat_desc, vb.pvb_expr.pexp_desc with
| Ppat_constraint (p, { ptyp_desc = Ptyp_poly ([], t1); _ }),
Pexp_constraint (_, t2) when phys_equal t1 t2 -> p
| ( Ppat_constraint (p, { ptyp_desc = Ptyp_poly ([], t1); _ })
, Pexp_constraint (_, t2) )
when phys_equal t1 t2 -> p
| _ -> vb.pvb_pat
in
{ vb with
pvb_pat;
pvb_expr = maybe_open extension_name ~to_open:(open_on_rhs ~modul) vb.pvb_expr;
pvb_pat
; pvb_expr =
maybe_open extension_name ~to_open:(open_on_rhs ~modul) vb.pvb_expr
})
in
expand_with_tmp_vars ~loc bindings expr ~f:(expand_let extension_name ~modul)
| Pexp_let (Recursive, _, _) ->
Location.raise_errorf ~loc "'let%%%s' may not be recursive"
Location.raise_errorf
~loc
"'let%%%s' may not be recursive"
(Extension_name.to_string extension_name)
| Pexp_match (expr, cases) ->
expand_match extension_name ~loc ~modul expr cases
| Pexp_match (expr, cases) -> expand_match extension_name ~loc ~modul expr cases
| Pexp_ifthenelse (expr, then_, else_) ->
let else_ =
match else_ with
| Some else_ -> else_
| None ->
Location.raise_errorf ~loc "'if%%%s' must include an else branch"
Location.raise_errorf
~loc
"'if%%%s' must include an else branch"
(Extension_name.to_string extension_name)
in
expand_if extension_name ~loc ~modul expr then_ else_
| _ ->
Location.raise_errorf ~loc
Location.raise_errorf
~loc
"'%%%s' can only be used with 'let', 'match', and 'if'"
(Extension_name.to_string extension_name)
in
Expand Down
8 changes: 2 additions & 6 deletions expander/ppx_let_expander.mli
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ module Extension_name : sig
| Bind_open
| Map
| Map_open

val to_string : t -> string
end

val expand
: modul:longident loc option
-> Extension_name.t
-> expression
-> expression

val expand : modul:longident loc option -> Extension_name.t -> expression -> expression
2 changes: 0 additions & 2 deletions jbuild

This file was deleted.

16 changes: 8 additions & 8 deletions ppx_let.opam
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
opam-version: "1.2"
opam-version: "2.0"
maintainer: "opensource@janestreet.com"
authors: ["Jane Street Group, LLC <opensource@janestreet.com>"]
homepage: "https://github.com/janestreet/ppx_let"
bug-reports: "https://github.com/janestreet/ppx_let/issues"
dev-repo: "git+https://github.com/janestreet/ppx_let.git"
doc: "https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_let/index.html"
license: "MIT"
build: [
["jbuilder" "build" "-p" name "-j" jobs]
["dune" "build" "-p" name "-j" jobs]
]
depends: [
"ocaml" {>= "4.04.2"}
"base"
"jbuilder" {build & >= "1.0+beta18.1"}
"ppxlib" {>= "0.1.0"}
"dune" {build & >= "1.5.1"}
"ppxlib" {>= "0.4.0"}
]
available: [ ocaml-version >= "4.04.2" ]
descr: "
Monadic let-bindings

synopsis: "Monadic let-bindings"
description: "
Part of the Jane Street's PPX rewriters collection.
"
2 changes: 2 additions & 0 deletions src/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(library (name ppx_let) (public_name ppx_let) (kind ppx_rewriter)
(libraries base ppxlib ppx_let_expander) (preprocess no_preprocessing))
8 changes: 0 additions & 8 deletions src/jbuild

This file was deleted.

10 changes: 3 additions & 7 deletions src/ppx_let.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ let ext extension_name =
;;

let () =
Driver.register_transformation "let"
~extensions:[
ext Bind;
ext Bind_open;
ext Map;
ext Map_open;
]
Driver.register_transformation
"let"
~extensions:[ ext Bind; ext Bind_open; ext Map; ext Map_open ]
;;
1 change: 1 addition & 0 deletions src/ppx_let.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions test/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(executables (names test) (preprocess (pps ppx_let)))
6 changes: 0 additions & 6 deletions test/jbuild

This file was deleted.

17 changes: 13 additions & 4 deletions test/test-locations.mlt
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@

module Let_syntax = struct
type 'a t = T of 'a

let map (T x) ~f = T (f x)
let both (T x) (T y) = T (x, y)

module Open_on_rhs = struct
let return x = T x
let f x ~(doc:string) = T (x, doc)
let f x ~(doc : string) = T (x, doc)
end
end

let _ = [%map_open let x = return 42 and y = f 42 in ()]
[%%expect{|
Line _, characters 45-49:
let _ =
[%map_open
let x = return 42
and y = f 42 in
()]
;;

[%%expect
{|
Line _, characters 12-16:
Error: This expression has type doc:string -> (int * string) Let_syntax.t
but an expression was expected of type 'a Let_syntax.t
|}]
Loading

0 comments on commit de8312e

Please sign in to comment.