-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
648 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# ppx_easy_deriving | ||
|
||
Goblint vendors a subset of the unreleased [ppx_easy_deriving](https://github.com/sim642/ppx_easy_deriving) library. | ||
It only includes products, excluding simples and variants. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
open Ppxlib | ||
open Ast_builder.Default | ||
|
||
include Deriver_intf | ||
|
||
module Make (Arg: Intf.S): S = | ||
struct | ||
let attr = Attribute.declare (Printf.sprintf "deriving.%s.%s" Arg.name Arg.name) Attribute.Context.core_type Ast_pattern.(single_expr_payload __) (fun expr -> expr) | ||
|
||
let unit ~loc = Arg.tuple ~loc [] | ||
|
||
let rec expr ~loc ~quoter ct = | ||
match Attribute.get attr ct with | ||
| Some expr -> | ||
Expansion_helpers.Quoter.quote quoter expr | ||
| None -> | ||
match ct with | ||
| [%type: unit] -> | ||
unit ~loc | ||
| {ptyp_desc = Ptyp_constr ({txt = lid; loc}, args); _} -> | ||
let ident = pexp_ident ~loc {loc; txt = Expansion_helpers.mangle_lid (Prefix Arg.name) lid} in | ||
let ident = Expansion_helpers.Quoter.quote quoter ident in | ||
let apply_args = List.map (fun ct -> | ||
(Nolabel, expr ~loc ~quoter ct) | ||
) args | ||
in | ||
pexp_apply ~loc ident apply_args | ||
| {ptyp_desc = Ptyp_tuple elems; _} -> | ||
expr_tuple ~loc ~quoter elems | ||
| {ptyp_desc = Ptyp_var name; _} -> | ||
evar ~loc ("poly_" ^ name) | ||
| _ -> | ||
pexp_extension ~loc (Location.error_extensionf ~loc "unsupported core type") | ||
|
||
and expr_record ~loc ~quoter (lds: label_declaration list) = | ||
let les = List.map (fun {pld_name = {txt = label; _}; pld_type; _} -> | ||
(Lident label, expr ~loc ~quoter pld_type) | ||
) lds | ||
in | ||
Arg.record ~loc les | ||
|
||
and expr_tuple ~loc ~quoter elems = | ||
let es = List.map (expr ~loc ~quoter) elems in | ||
Arg.tuple ~loc es | ||
|
||
let expr_declaration ~loc ~quoter = function | ||
| {ptype_kind = Ptype_abstract; ptype_manifest = Some ct; _} -> | ||
expr ~loc ~quoter ct | ||
| {ptype_kind = Ptype_abstract; _} -> | ||
pexp_extension ~loc (Location.error_extensionf ~loc "unsupported abstract type") | ||
| {ptype_kind = Ptype_variant constrs; _} -> | ||
pexp_extension ~loc (Location.error_extensionf ~loc "unsupported variant type") | ||
| {ptype_kind = Ptype_open; _} -> | ||
pexp_extension ~loc (Location.error_extensionf ~loc "unsupported open type") | ||
| {ptype_kind = Ptype_record fields; _} -> | ||
expr_record ~loc ~quoter fields | ||
|
||
let typ ~loc td = | ||
let ct = Ppx_deriving.core_type_of_type_decl td in | ||
Ppx_deriving.poly_arrow_of_type_decl | ||
(Arg.typ ~loc) | ||
td | ||
(Arg.typ ~loc ct) | ||
|
||
let generate_impl ~ctxt (_rec_flag, type_declarations) = | ||
let loc = Expansion_context.Deriver.derived_item_loc ctxt in | ||
let vbs = List.map (fun td -> | ||
let quoter = Expansion_helpers.Quoter.create () in | ||
let expr = expr_declaration ~loc ~quoter td in | ||
let expr = Expansion_helpers.Quoter.sanitize quoter expr in | ||
let expr = Ppx_deriving.poly_fun_of_type_decl td expr in | ||
let ct = typ ~loc td in | ||
let pat = ppat_var ~loc {loc; txt = Expansion_helpers.mangle_type_decl (Prefix Arg.name) td} in | ||
let pat = ppat_constraint ~loc pat ct in | ||
Ast_helper.Vb.mk ~loc ~attrs:[Ppx_deriving.attr_warning [%expr "-39"]] pat expr | ||
) type_declarations | ||
in | ||
[Ast_helper.Str.value ~loc Recursive vbs] | ||
|
||
let generate_intf ~ctxt (_rec_flag, type_declarations) = | ||
let loc = Expansion_context.Deriver.derived_item_loc ctxt in | ||
List.map (fun td -> | ||
let ct = typ ~loc td in | ||
let val_ = Ast_helper.Val.mk ~loc {loc; txt = Expansion_helpers.mangle_type_decl (Prefix Arg.name) td} ct in | ||
Ast_helper.Sig.value ~loc val_ | ||
) type_declarations | ||
|
||
let impl_generator = Deriving.Generator.V2.make_noarg generate_impl | ||
let intf_generator = Deriving.Generator.V2.make_noarg generate_intf | ||
let extension ~loc ~path:_ ct = | ||
let quoter = Expansion_helpers.Quoter.create () in | ||
let expr = expr ~loc ~quoter ct in | ||
Expansion_helpers.Quoter.sanitize quoter expr | ||
|
||
let register () = | ||
Deriving.add Arg.name | ||
~sig_type_decl:intf_generator | ||
~str_type_decl:impl_generator | ||
~extension | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(** Registerable deriver. *) | ||
|
||
include Deriver_intf.Deriver (** @inline *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module type S = | ||
sig | ||
val register: unit -> Ppxlib.Deriving.t | ||
(** Register deriver with ppxlb. *) | ||
end | ||
|
||
module type Deriver = | ||
sig | ||
module type S = S | ||
|
||
module Make (_: Intf.S): S | ||
(** Make registerable deriver. *) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(library | ||
(name ppx_easy_deriving) | ||
(libraries ppxlib ppx_deriving.api) | ||
(preprocess (pps ppxlib.metaquot))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
(** Main interfaces. *) | ||
|
||
open Ppxlib | ||
|
||
(** Deriver name interface. *) | ||
module type Name = | ||
sig | ||
val name: string | ||
(** Deriver name. | ||
For example, with the name "equal": | ||
+ Use [[@@deriving equal]] after a type definition. | ||
+ The derived value/function is [val equal: ...] (if the type is named [t]) or [val equal_ty: ...] (otherwise if the type is named [ty]). | ||
+ Use [[@equal ...]] after a type expression to override the underlying value/function used for it. | ||
+ Use [[%equal: ty]] as an expression for the value/function of type [ty]. *) | ||
end | ||
|
||
(** Deriver base interface. *) | ||
module type Base = | ||
sig | ||
include Name | ||
val typ: loc:location -> core_type -> core_type | ||
(** Derived value/function type for a given type. | ||
For example, "equal" deriver would map [t] to [t -> t -> bool]. *) | ||
end | ||
|
||
module Tuple = | ||
struct | ||
|
||
(** Tuple deriver interface. *) | ||
module type S = | ||
sig | ||
include Base | ||
val tuple: loc:location -> expression list -> expression | ||
(** Compose derived values/functions for tuple elements into derived value/function for the tuple. *) | ||
end | ||
end | ||
|
||
module Record = | ||
struct | ||
|
||
(** Record deriver interface. *) | ||
module type S = | ||
sig | ||
include Base | ||
val record: loc:location -> (longident * expression) list -> expression | ||
(** Compose derived values/functions for record fields into derived value/function for the record. *) | ||
end | ||
end | ||
|
||
module Full = | ||
struct | ||
|
||
(** Full deriver interface. *) | ||
module type S = | ||
sig | ||
include Tuple.S | ||
include Record.S | ||
end | ||
end | ||
|
||
module type S = Full.S | ||
(** Deriver interface. *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
open Ppxlib | ||
open Ast_builder.Default | ||
|
||
type t = | ||
| Record of (longident * t) list | ||
| Tuple of t list | ||
| Unit | ||
| Base of string | ||
let create_record ~prefix ls = | ||
Record (List.mapi (fun i l -> (l, Base (prefix ^ string_of_int (i + 1)))) ls) | ||
let create_tuple ~prefix n = | ||
match n with | ||
| 0 -> Unit | ||
| 1 -> Base (prefix ^ "1") | ||
| n -> Tuple (List.init n (fun i -> Base (prefix ^ string_of_int (i + 1)))) | ||
let rec to_pat ~loc = function | ||
| Record xs -> | ||
ppat_record ~loc (List.map (fun (l, x) -> | ||
(Located.mk ~loc l, to_pat ~loc x) | ||
) xs) Closed | ||
| Tuple xs -> | ||
ppat_tuple ~loc (List.map (to_pat ~loc) xs) | ||
| Unit -> | ||
[%pat? ()] | ||
| Base s -> | ||
ppat_var ~loc (Located.mk ~loc s) | ||
let rec to_exps ~loc = function | ||
| Record xs -> | ||
List.flatten (List.map (fun (_, x) -> to_exps ~loc x) xs) | ||
| Tuple xs -> | ||
List.flatten (List.map (to_exps ~loc) xs) | ||
| Unit -> | ||
[] | ||
| Base s -> | ||
[pexp_ident ~loc {loc; txt = Lident s}] | ||
let rec to_exp ~loc = function | ||
| Record xs -> | ||
pexp_record ~loc (List.map (fun (l, x) -> | ||
(Located.mk ~loc l, to_exp ~loc x) | ||
) xs) None | ||
| Tuple xs -> | ||
pexp_tuple ~loc (List.map (to_exp ~loc) xs) | ||
| Unit -> | ||
[%expr ()] | ||
| Base s -> | ||
pexp_ident ~loc {loc; txt = Lident s} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
(** Common representation of patterns and expressions. *) | ||
|
||
open Ppxlib | ||
|
||
type t = | ||
| Record of (longident * t) list | ||
| Tuple of t list | ||
| Unit | ||
| Base of string | ||
|
||
val create_record: prefix:string -> longident list -> t | ||
val create_tuple: prefix:string -> int -> t | ||
|
||
val to_pat: loc:location -> t -> pattern | ||
val to_exps: loc:location -> t -> expression list | ||
val to_exp: loc:location -> t -> expression |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
(** Library for easily defining PPX derivers without boilerplate and runtime overhead. *) | ||
|
||
(** {1 Interfaces} *) | ||
|
||
include Intf (** @inline *) | ||
|
||
|
||
(** {1 Deriver} *) | ||
|
||
module Deriver = Deriver | ||
|
||
|
||
(** {1 Easier constructs} *) | ||
|
||
module Product = Product |
Oops, something went wrong.