Add a user context to Of_sexp.t
Signed-off-by: Jeremie Dimino <jeremie@dimino.org>
This commit is contained in:
parent
4922faf18a
commit
0c6edde131
|
@ -626,7 +626,8 @@ module Promotion = struct
|
||||||
let load_db () =
|
let load_db () =
|
||||||
if Path.exists db_file then
|
if Path.exists db_file then
|
||||||
Sexp.Of_sexp.(
|
Sexp.Of_sexp.(
|
||||||
parse (list File.t) (Io.Sexp.load db_file ~mode:Many_as_one))
|
parse (list File.t) Univ_map.empty
|
||||||
|
(Io.Sexp.load db_file ~mode:Many_as_one))
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ module Promoted_to_delete = struct
|
||||||
let load () =
|
let load () =
|
||||||
if Path.exists fn then
|
if Path.exists fn then
|
||||||
Io.Sexp.load fn ~mode:Many
|
Io.Sexp.load fn ~mode:Many
|
||||||
|> List.map ~f:(Sexp.Of_sexp.parse Path.t)
|
|> List.map ~f:(Sexp.Of_sexp.parse Path.t Univ_map.empty)
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -1220,7 +1220,8 @@ let update_universe t =
|
||||||
Utils.Cached_digest.remove universe_file;
|
Utils.Cached_digest.remove universe_file;
|
||||||
let n =
|
let n =
|
||||||
if Path.exists universe_file then
|
if Path.exists universe_file then
|
||||||
Sexp.Of_sexp.(parse int) (Io.Sexp.load ~mode:Single universe_file) + 1
|
Sexp.Of_sexp.(parse int) Univ_map.empty
|
||||||
|
(Io.Sexp.load ~mode:Single universe_file) + 1
|
||||||
else
|
else
|
||||||
0
|
0
|
||||||
in
|
in
|
||||||
|
|
|
@ -115,7 +115,7 @@ let user_config_file =
|
||||||
"dune/config"
|
"dune/config"
|
||||||
|
|
||||||
let load_config_file p =
|
let load_config_file p =
|
||||||
(Sexp.Of_sexp.parse t) (Io.Sexp.load p ~mode:Many_as_one)
|
(Sexp.Of_sexp.parse t Univ_map.empty) (Io.Sexp.load p ~mode:Many_as_one)
|
||||||
|
|
||||||
let load_user_config_file () =
|
let load_user_config_file () =
|
||||||
if Path.exists user_config_file then
|
if Path.exists user_config_file then
|
||||||
|
|
|
@ -425,7 +425,7 @@ let create_for_opam ?root ~env ~targets ~profile ~switch ~name
|
||||||
>>= fun s ->
|
>>= fun s ->
|
||||||
let vars =
|
let vars =
|
||||||
Usexp.parse_string ~fname:"<opam output>" ~mode:Single s
|
Usexp.parse_string ~fname:"<opam output>" ~mode:Single s
|
||||||
|> Sexp.Of_sexp.(parse (list (pair string string)))
|
|> Sexp.Of_sexp.(parse (list (pair string string)) Univ_map.empty)
|
||||||
|> Env.Map.of_list_multi
|
|> Env.Map.of_list_multi
|
||||||
|> Env.Map.mapi ~f:(fun var values ->
|
|> Env.Map.mapi ~f:(fun var values ->
|
||||||
match List.rev values with
|
match List.rev values with
|
||||||
|
|
|
@ -143,7 +143,7 @@ module Lang = struct
|
||||||
} = first_line
|
} = first_line
|
||||||
in
|
in
|
||||||
let ver =
|
let ver =
|
||||||
Sexp.Of_sexp.parse Syntax.Version.t
|
Sexp.Of_sexp.parse Syntax.Version.t Univ_map.empty
|
||||||
(Atom (ver_loc, Sexp.Atom.of_string ver)) in
|
(Atom (ver_loc, Sexp.Atom.of_string ver)) in
|
||||||
match Hashtbl.find langs name with
|
match Hashtbl.find langs name with
|
||||||
| None ->
|
| None ->
|
||||||
|
@ -269,7 +269,8 @@ let load_dune_project ~dir packages =
|
||||||
Io.with_lexbuf_from_file fname ~f:(fun lb ->
|
Io.with_lexbuf_from_file fname ~f:(fun lb ->
|
||||||
let lang_stanzas = Lang.parse (Dune_lexer.first_line lb) in
|
let lang_stanzas = Lang.parse (Dune_lexer.first_line lb) in
|
||||||
let sexp = Sexp.Parser.parse lb ~mode:Many_as_one in
|
let sexp = Sexp.Parser.parse lb ~mode:Many_as_one in
|
||||||
Sexp.Of_sexp.parse (parse ~dir ~lang_stanzas ~packages ~file:fname) sexp)
|
Sexp.Of_sexp.parse (parse ~dir ~lang_stanzas ~packages ~file:fname)
|
||||||
|
Univ_map.empty sexp)
|
||||||
|
|
||||||
let make_jbuilder_project ~dir packages =
|
let make_jbuilder_project ~dir packages =
|
||||||
let t =
|
let t =
|
||||||
|
|
|
@ -60,7 +60,7 @@ module Dune_file = struct
|
||||||
List.partition_map sexps ~f:(fun sexp ->
|
List.partition_map sexps ~f:(fun sexp ->
|
||||||
match (sexp : Sexp.Ast.t) with
|
match (sexp : Sexp.Ast.t) with
|
||||||
| List (_, (Atom (_, A "ignored_subdirs") :: _)) ->
|
| List (_, (Atom (_, A "ignored_subdirs") :: _)) ->
|
||||||
Left (Sexp.Of_sexp.parse stanza sexp)
|
Left (Sexp.Of_sexp.parse stanza Univ_map.empty sexp)
|
||||||
| _ -> Right sexp)
|
| _ -> Right sexp)
|
||||||
in
|
in
|
||||||
let ignored_subdirs =
|
let ignored_subdirs =
|
||||||
|
|
|
@ -3,7 +3,8 @@ open Import
|
||||||
let parse_sub_systems sexps =
|
let parse_sub_systems sexps =
|
||||||
List.filter_map sexps ~f:(fun sexp ->
|
List.filter_map sexps ~f:(fun sexp ->
|
||||||
let name, ver, data =
|
let name, ver, data =
|
||||||
Sexp.Of_sexp.(parse (triple string (located Syntax.Version.t) raw)) sexp
|
Sexp.Of_sexp.(parse (triple string (located Syntax.Version.t) raw)
|
||||||
|
Univ_map.empty) sexp
|
||||||
in
|
in
|
||||||
match Sub_system_name.get name with
|
match Sub_system_name.get name with
|
||||||
| None ->
|
| None ->
|
||||||
|
@ -24,7 +25,7 @@ let parse_sub_systems sexps =
|
||||||
Syntax.Versioned_parser.find_exn M.parsers ~loc:vloc
|
Syntax.Versioned_parser.find_exn M.parsers ~loc:vloc
|
||||||
~data_version:ver
|
~data_version:ver
|
||||||
in
|
in
|
||||||
M.T (Sexp.Of_sexp.parse parser data))
|
M.T (Sexp.Of_sexp.parse parser Univ_map.empty data))
|
||||||
|
|
||||||
let of_sexp =
|
let of_sexp =
|
||||||
let open Sexp.Of_sexp in
|
let open Sexp.Of_sexp in
|
||||||
|
@ -42,7 +43,8 @@ let of_sexp =
|
||||||
parse_sub_systems l)
|
parse_sub_systems l)
|
||||||
]
|
]
|
||||||
|
|
||||||
let load fname = Sexp.Of_sexp.parse of_sexp (Io.Sexp.load ~mode:Single fname)
|
let load fname =
|
||||||
|
Sexp.Of_sexp.parse of_sexp Univ_map.empty (Io.Sexp.load ~mode:Single fname)
|
||||||
|
|
||||||
let gen confs =
|
let gen confs =
|
||||||
let sexps =
|
let sexps =
|
||||||
|
|
|
@ -1354,7 +1354,7 @@ module Stanzas = struct
|
||||||
exception Include_loop of Path.t * (Loc.t * Path.t) list
|
exception Include_loop of Path.t * (Loc.t * Path.t) list
|
||||||
|
|
||||||
let rec parse stanza_parser ~current_file ~include_stack sexps =
|
let rec parse stanza_parser ~current_file ~include_stack sexps =
|
||||||
List.concat_map sexps ~f:(Sexp.Of_sexp.parse stanza_parser)
|
List.concat_map sexps ~f:(Sexp.Of_sexp.parse stanza_parser Univ_map.empty)
|
||||||
|> List.concat_map ~f:(function
|
|> List.concat_map ~f:(function
|
||||||
| Include (loc, fn) ->
|
| Include (loc, fn) ->
|
||||||
let include_stack = (loc, current_file) :: include_stack in
|
let include_stack = (loc, current_file) :: include_stack in
|
||||||
|
|
|
@ -181,7 +181,7 @@ module Unexpanded = struct
|
||||||
match t with
|
match t with
|
||||||
| Element x -> Element x
|
| Element x -> Element x
|
||||||
| Union [Special (_, "include"); Element fn] ->
|
| Union [Special (_, "include"); Element fn] ->
|
||||||
Include (Sexp.Of_sexp.parse String_with_vars.t fn)
|
Include (Sexp.Of_sexp.parse String_with_vars.t Univ_map.empty fn)
|
||||||
| Union [Special (loc, "include"); _]
|
| Union [Special (loc, "include"); _]
|
||||||
| Special (loc, "include") ->
|
| Special (loc, "include") ->
|
||||||
Loc.fail loc "(:include expects a single element (do you need to quote the filename?)"
|
Loc.fail loc "(:include expects a single element (do you need to quote the filename?)"
|
||||||
|
@ -246,7 +246,8 @@ module Unexpanded = struct
|
||||||
let open Ast in
|
let open Ast in
|
||||||
match t with
|
match t with
|
||||||
| Element s ->
|
| Element s ->
|
||||||
Element (Sexp.Ast.loc s, f (Sexp.Of_sexp.parse String_with_vars.t s))
|
Element (Sexp.Ast.loc s,
|
||||||
|
f (Sexp.Of_sexp.parse String_with_vars.t Univ_map.empty s))
|
||||||
| Special (l, s) -> Special (l, s)
|
| Special (l, s) -> Special (l, s)
|
||||||
| Include fn ->
|
| Include fn ->
|
||||||
let sexp =
|
let sexp =
|
||||||
|
@ -262,7 +263,8 @@ module Unexpanded = struct
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
parse_general sexp ~f:(fun sexp ->
|
parse_general sexp ~f:(fun sexp ->
|
||||||
(Sexp.Ast.loc sexp, f (Sexp.Of_sexp.parse String_with_vars.t sexp)))
|
(Sexp.Ast.loc sexp,
|
||||||
|
f (Sexp.Of_sexp.parse String_with_vars.t Univ_map.empty sexp)))
|
||||||
| Union l -> Union (List.map l ~f:expand)
|
| Union l -> Union (List.map l ~f:expand)
|
||||||
| Diff (l, r) ->
|
| Diff (l, r) ->
|
||||||
Diff (expand l, expand r)
|
Diff (expand l, expand r)
|
||||||
|
|
|
@ -182,7 +182,7 @@ module Jbuild_driver = struct
|
||||||
let make name info : (Pp.t * Driver.t) Lazy.t = lazy (
|
let make name info : (Pp.t * Driver.t) Lazy.t = lazy (
|
||||||
let info =
|
let info =
|
||||||
Sexp.parse_string ~mode:Single ~fname:"<internal>" info
|
Sexp.parse_string ~mode:Single ~fname:"<internal>" info
|
||||||
|> Sexp.Of_sexp.parse Driver.Info.parse
|
|> Sexp.Of_sexp.parse Driver.Info.parse Univ_map.empty
|
||||||
in
|
in
|
||||||
(Pp.of_string name,
|
(Pp.of_string name,
|
||||||
{ info
|
{ info
|
||||||
|
|
|
@ -100,11 +100,15 @@ module Of_sexp = struct
|
||||||
; known : string list
|
; known : string list
|
||||||
}
|
}
|
||||||
|
|
||||||
(* The two arguments are the location of the whole list as well as
|
(* Arguments are:
|
||||||
the first atom when either parsing a constructor or a field. *)
|
|
||||||
|
- the location of the whole list
|
||||||
|
- the first atom when parsing a constructor or a field
|
||||||
|
- the universal map holding the user context
|
||||||
|
*)
|
||||||
type 'kind context =
|
type 'kind context =
|
||||||
| Values : Loc.t * string option -> values context
|
| Values : Loc.t * string option * Univ_map.t -> values context
|
||||||
| Fields : Loc.t * string option -> fields context
|
| Fields : Loc.t * string option * Univ_map.t -> fields context
|
||||||
|
|
||||||
type ('a, 'kind) parser = 'kind context -> 'kind -> 'a * 'kind
|
type ('a, 'kind) parser = 'kind context -> 'kind -> 'a * 'kind
|
||||||
|
|
||||||
|
@ -123,10 +127,24 @@ module Of_sexp = struct
|
||||||
b ctx state
|
b ctx state
|
||||||
let map t ~f = t >>| f
|
let map t ~f = t >>| f
|
||||||
|
|
||||||
|
let get_user_context : type k. k context -> Univ_map.t = function
|
||||||
|
| Values (_, _, uc) -> uc
|
||||||
|
| Fields (_, _, uc) -> uc
|
||||||
|
|
||||||
|
let get key ctx state = (Univ_map.find (get_user_context ctx) key, state)
|
||||||
|
|
||||||
|
let set : type a b k. a Univ_map.Key.t -> a -> (b, k) parser -> (b, k) parser
|
||||||
|
= fun key v t ctx state ->
|
||||||
|
match ctx with
|
||||||
|
| Values (loc, cstr, uc) ->
|
||||||
|
t (Values (loc, cstr, Univ_map.add uc key v)) state
|
||||||
|
| Fields (loc, cstr, uc) ->
|
||||||
|
t (Fields (loc, cstr, Univ_map.add uc key v)) state
|
||||||
|
|
||||||
let loc : type k. k context -> k -> Loc.t * k = fun ctx state ->
|
let loc : type k. k context -> k -> Loc.t * k = fun ctx state ->
|
||||||
match ctx with
|
match ctx with
|
||||||
| Values (loc, _) -> (loc, state)
|
| Values (loc, _, _) -> (loc, state)
|
||||||
| Fields (loc, _) -> (loc, state)
|
| Fields (loc, _, _) -> (loc, state)
|
||||||
|
|
||||||
let eos : type k. k context -> k -> bool * k = fun ctx state ->
|
let eos : type k. k context -> k -> bool * k = fun ctx state ->
|
||||||
match ctx with
|
match ctx with
|
||||||
|
@ -146,7 +164,7 @@ module Of_sexp = struct
|
||||||
let result : type a k. k context -> a * k -> a =
|
let result : type a k. k context -> a * k -> a =
|
||||||
fun ctx (v, state) ->
|
fun ctx (v, state) ->
|
||||||
match ctx with
|
match ctx with
|
||||||
| Values (_, cstr) -> begin
|
| Values (_, cstr, _) -> begin
|
||||||
match state with
|
match state with
|
||||||
| [] -> v
|
| [] -> v
|
||||||
| sexp :: _ ->
|
| sexp :: _ ->
|
||||||
|
@ -169,11 +187,11 @@ module Of_sexp = struct
|
||||||
name_loc "Unknown field %s" name
|
name_loc "Unknown field %s" name
|
||||||
end
|
end
|
||||||
|
|
||||||
let parse t sexp =
|
let parse t context sexp =
|
||||||
let ctx = Values (Ast.loc sexp, None) in
|
let ctx = Values (Ast.loc sexp, None, context) in
|
||||||
result ctx (t ctx [sexp])
|
result ctx (t ctx [sexp])
|
||||||
|
|
||||||
let end_of_list (Values (loc, cstr)) =
|
let end_of_list (Values (loc, cstr, _)) =
|
||||||
match cstr with
|
match cstr with
|
||||||
| None ->
|
| None ->
|
||||||
let loc = { loc with start = loc.stop } in
|
let loc = { loc with start = loc.stop } in
|
||||||
|
@ -188,6 +206,12 @@ module Of_sexp = struct
|
||||||
| sexp :: sexps -> (f sexp, sexps)
|
| sexp :: sexps -> (f sexp, sexps)
|
||||||
[@@inline always]
|
[@@inline always]
|
||||||
|
|
||||||
|
let next_with_user_context f ctx sexps =
|
||||||
|
match sexps with
|
||||||
|
| [] -> end_of_list ctx
|
||||||
|
| sexp :: sexps -> (f (get_user_context ctx) sexp, sexps)
|
||||||
|
[@@inline always]
|
||||||
|
|
||||||
let peek t ctx sexps =
|
let peek t ctx sexps =
|
||||||
let x, _ = t ctx sexps in
|
let x, _ = t ctx sexps in
|
||||||
(x, sexps)
|
(x, sexps)
|
||||||
|
@ -201,9 +225,10 @@ module Of_sexp = struct
|
||||||
| List (loc, _) -> of_sexp_error loc "Atom or quoted string expected")
|
| List (loc, _) -> of_sexp_error loc "Atom or quoted string expected")
|
||||||
|
|
||||||
let enter t =
|
let enter t =
|
||||||
next (function
|
next_with_user_context (fun uc sexp ->
|
||||||
|
match sexp with
|
||||||
| List (loc, l) ->
|
| List (loc, l) ->
|
||||||
let ctx = Values (loc, None) in
|
let ctx = Values (loc, None, uc) in
|
||||||
result ctx (t ctx l)
|
result ctx (t ctx l)
|
||||||
| sexp ->
|
| sexp ->
|
||||||
of_sexp_error (Ast.loc sexp) "List expected")
|
of_sexp_error (Ast.loc sexp) "List expected")
|
||||||
|
@ -219,7 +244,7 @@ module Of_sexp = struct
|
||||||
| sexp :: rest when rest == state2 -> (* common case *)
|
| sexp :: rest when rest == state2 -> (* common case *)
|
||||||
((Ast.loc sexp, x), state2)
|
((Ast.loc sexp, x), state2)
|
||||||
| [] ->
|
| [] ->
|
||||||
let (Values (loc, _)) = ctx in
|
let (Values (loc, _, _)) = ctx in
|
||||||
(({ loc with start = loc.stop }, x), state2)
|
(({ loc with start = loc.stop }, x), state2)
|
||||||
| sexp :: rest ->
|
| sexp :: rest ->
|
||||||
let loc = Ast.loc sexp in
|
let loc = Ast.loc sexp in
|
||||||
|
@ -229,7 +254,7 @@ module Of_sexp = struct
|
||||||
else
|
else
|
||||||
match l with
|
match l with
|
||||||
| [] ->
|
| [] ->
|
||||||
let (Values (loc, _)) = ctx in
|
let (Values (loc, _, _)) = ctx in
|
||||||
(({ (Ast.loc sexp) with stop = loc.stop }, x), state2)
|
(({ (Ast.loc sexp) with stop = loc.stop }, x), state2)
|
||||||
| sexp :: rest ->
|
| sexp :: rest ->
|
||||||
search sexp rest
|
search sexp rest
|
||||||
|
@ -318,10 +343,10 @@ module Of_sexp = struct
|
||||||
"Unknown constructor %s" name
|
"Unknown constructor %s" name
|
||||||
|
|
||||||
let sum cstrs =
|
let sum cstrs =
|
||||||
next (fun sexp ->
|
next_with_user_context (fun uc sexp ->
|
||||||
match sexp with
|
match sexp with
|
||||||
| Atom (loc, A s) ->
|
| Atom (loc, A s) ->
|
||||||
find_cstr cstrs loc s (Values (loc, Some s)) []
|
find_cstr cstrs loc s (Values (loc, Some s, uc)) []
|
||||||
| Quoted_string (loc, _) ->
|
| Quoted_string (loc, _) ->
|
||||||
of_sexp_error loc "Atom expected"
|
of_sexp_error loc "Atom expected"
|
||||||
| List (loc, []) ->
|
| List (loc, []) ->
|
||||||
|
@ -331,7 +356,7 @@ module Of_sexp = struct
|
||||||
| Quoted_string (loc, _) | List (loc, _) ->
|
| Quoted_string (loc, _) | List (loc, _) ->
|
||||||
of_sexp_error loc "Atom expected"
|
of_sexp_error loc "Atom expected"
|
||||||
| Atom (s_loc, A s) ->
|
| Atom (s_loc, A s) ->
|
||||||
find_cstr cstrs s_loc s (Values (loc, Some s)) args)
|
find_cstr cstrs s_loc s (Values (loc, Some s, uc)) args)
|
||||||
|
|
||||||
let enum cstrs =
|
let enum cstrs =
|
||||||
next (function
|
next (function
|
||||||
|
@ -377,7 +402,7 @@ module Of_sexp = struct
|
||||||
Int.compare a.Loc.start.pos_cnum b.start.pos_cnum)
|
Int.compare a.Loc.start.pos_cnum b.start.pos_cnum)
|
||||||
with
|
with
|
||||||
| [] ->
|
| [] ->
|
||||||
let (Fields (loc, _)) = ctx in
|
let (Fields (loc, _, _)) = ctx in
|
||||||
loc
|
loc
|
||||||
| first :: l ->
|
| first :: l ->
|
||||||
let last = List.fold_left l ~init:first ~f:(fun _ x -> x) in
|
let last = List.fold_left l ~init:first ~f:(fun _ x -> x) in
|
||||||
|
@ -385,7 +410,7 @@ module Of_sexp = struct
|
||||||
in
|
in
|
||||||
of_sexp_errorf loc "%s" msg
|
of_sexp_errorf loc "%s" msg
|
||||||
|
|
||||||
let field_missing (Fields (loc, _)) name =
|
let field_missing loc name =
|
||||||
of_sexp_errorf loc "field %s missing" name
|
of_sexp_errorf loc "field %s missing" name
|
||||||
[@@inline never]
|
[@@inline never]
|
||||||
|
|
||||||
|
@ -407,21 +432,21 @@ module Of_sexp = struct
|
||||||
| _ -> ());
|
| _ -> ());
|
||||||
res
|
res
|
||||||
|
|
||||||
let field name ?default t ctx state =
|
let field name ?default t (Fields (loc, _, uc)) state =
|
||||||
match find_single state name with
|
match find_single state name with
|
||||||
| Some { values; entry; _ } ->
|
| Some { values; entry; _ } ->
|
||||||
let ctx = Values (Ast.loc entry, Some name) in
|
let ctx = Values (Ast.loc entry, Some name, uc) in
|
||||||
let x = result ctx (t ctx values) in
|
let x = result ctx (t ctx values) in
|
||||||
(x, consume name state)
|
(x, consume name state)
|
||||||
| None ->
|
| None ->
|
||||||
match default with
|
match default with
|
||||||
| Some v -> (v, add_known name state)
|
| Some v -> (v, add_known name state)
|
||||||
| None -> field_missing ctx name
|
| None -> field_missing loc name
|
||||||
|
|
||||||
let field_o name t _ctx state =
|
let field_o name t (Fields (_, _, uc)) state =
|
||||||
match find_single state name with
|
match find_single state name with
|
||||||
| Some { values; entry; _ } ->
|
| Some { values; entry; _ } ->
|
||||||
let ctx = Values (Ast.loc entry, Some name) in
|
let ctx = Values (Ast.loc entry, Some name, uc) in
|
||||||
let x = result ctx (t ctx values) in
|
let x = result ctx (t ctx values) in
|
||||||
(Some x, consume name state)
|
(Some x, consume name state)
|
||||||
| None ->
|
| None ->
|
||||||
|
@ -433,19 +458,19 @@ module Of_sexp = struct
|
||||||
| true -> return true
|
| true -> return true
|
||||||
| _ -> bool)
|
| _ -> bool)
|
||||||
|
|
||||||
let multi_field name t _ctx state =
|
let multi_field name t (Fields (_, _, uc)) state =
|
||||||
let rec loop acc field =
|
let rec loop acc field =
|
||||||
match field with
|
match field with
|
||||||
| None -> acc
|
| None -> acc
|
||||||
| Some { values; prev; entry } ->
|
| Some { values; prev; entry } ->
|
||||||
let ctx = Values (Ast.loc entry, Some name) in
|
let ctx = Values (Ast.loc entry, Some name, uc) in
|
||||||
let x = result ctx (t ctx values) in
|
let x = result ctx (t ctx values) in
|
||||||
loop (x :: acc) prev
|
loop (x :: acc) prev
|
||||||
in
|
in
|
||||||
let res = loop [] (Name_map.find state.unparsed name) in
|
let res = loop [] (Name_map.find state.unparsed name) in
|
||||||
(res, consume name state)
|
(res, consume name state)
|
||||||
|
|
||||||
let fields t (Values (loc, cstr)) sexps =
|
let fields t (Values (loc, cstr, uc)) sexps =
|
||||||
let unparsed =
|
let unparsed =
|
||||||
List.fold_left sexps ~init:Name_map.empty ~f:(fun acc sexp ->
|
List.fold_left sexps ~init:Name_map.empty ~f:(fun acc sexp ->
|
||||||
match sexp with
|
match sexp with
|
||||||
|
@ -464,7 +489,7 @@ module Of_sexp = struct
|
||||||
of_sexp_error (Ast.loc sexp)
|
of_sexp_error (Ast.loc sexp)
|
||||||
"S-expression of the form (<name> <values>...) expected")
|
"S-expression of the form (<name> <values>...) expected")
|
||||||
in
|
in
|
||||||
let ctx = Fields (loc, cstr) in
|
let ctx = Fields (loc, cstr, uc) in
|
||||||
let x = result ctx (t ctx { unparsed; known = [] }) in
|
let x = result ctx (t ctx { unparsed; known = [] }) in
|
||||||
(x, [])
|
(x, [])
|
||||||
|
|
||||||
|
|
|
@ -94,8 +94,11 @@ module Of_sexp : sig
|
||||||
type 'a t = ('a, values) parser
|
type 'a t = ('a, values) parser
|
||||||
type 'a fields_parser = ('a, fields) parser
|
type 'a fields_parser = ('a, fields) parser
|
||||||
|
|
||||||
(** Parse a S-expression using the following parser *)
|
(** [parse parser context sexp] parse a S-expression using the
|
||||||
val parse : 'a t -> ast -> 'a
|
following parser. The input consist of a single
|
||||||
|
S-expression. [context] allows to pass extra informations such as
|
||||||
|
versions to individual parsers. *)
|
||||||
|
val parse : 'a t -> Univ_map.t -> ast -> 'a
|
||||||
|
|
||||||
val return : 'a -> ('a, _) parser
|
val return : 'a -> ('a, _) parser
|
||||||
val (>>=) : ('a, 'k) parser -> ('a -> ('b, 'k) parser) -> ('b, 'k) parser
|
val (>>=) : ('a, 'k) parser -> ('a -> ('b, 'k) parser) -> ('b, 'k) parser
|
||||||
|
@ -103,6 +106,10 @@ module Of_sexp : sig
|
||||||
val (>>>) : (unit, 'k) parser -> ('a, 'k) parser -> ('a, 'k) parser
|
val (>>>) : (unit, 'k) parser -> ('a, 'k) parser -> ('a, 'k) parser
|
||||||
val map : ('a, 'k) parser -> f:('a -> 'b) -> ('b, 'k) parser
|
val map : ('a, 'k) parser -> f:('a -> 'b) -> ('b, 'k) parser
|
||||||
|
|
||||||
|
(** Access to the context *)
|
||||||
|
val get : 'a Univ_map.Key.t -> ('a option, _) parser
|
||||||
|
val set : 'a Univ_map.Key.t -> 'a -> ('b, 'k) parser -> ('b, 'k) parser
|
||||||
|
|
||||||
(** Return the location of the list currently being parsed. *)
|
(** Return the location of the list currently being parsed. *)
|
||||||
val loc : (Loc.t, _) parser
|
val loc : (Loc.t, _) parser
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ module Make
|
||||||
struct
|
struct
|
||||||
module Of_sexp = struct
|
module Of_sexp = struct
|
||||||
include F(Sexp.Of_sexp)
|
include F(Sexp.Of_sexp)
|
||||||
let t _ sexp = Sexp.Of_sexp.parse t sexp
|
let t _ sexp = Sexp.Of_sexp.parse t Univ_map.empty sexp
|
||||||
end
|
end
|
||||||
module To_sexp = struct
|
module To_sexp = struct
|
||||||
include F(Sexp.To_sexp)
|
include F(Sexp.To_sexp)
|
||||||
|
|
|
@ -111,7 +111,7 @@ let t ?x ?profile:cmdline_profile sexps =
|
||||||
let defined_names = ref String.Set.empty in
|
let defined_names = ref String.Set.empty in
|
||||||
let profiles, contexts =
|
let profiles, contexts =
|
||||||
List.partition_map sexps ~f:(fun sexp ->
|
List.partition_map sexps ~f:(fun sexp ->
|
||||||
match Sexp.Of_sexp.parse item_of_sexp sexp with
|
match Sexp.Of_sexp.parse item_of_sexp Univ_map.empty sexp with
|
||||||
| Profile (loc, p) -> Left (loc, p)
|
| Profile (loc, p) -> Left (loc, p)
|
||||||
| Context c -> Right c)
|
| Context c -> Right c)
|
||||||
in
|
in
|
||||||
|
@ -130,7 +130,7 @@ let t ?x ?profile:cmdline_profile sexps =
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
List.fold_left contexts ~init ~f:(fun t sexp ->
|
List.fold_left contexts ~init ~f:(fun t sexp ->
|
||||||
let ctx = Sexp.Of_sexp.parse (Context.t ~profile) sexp in
|
let ctx = Sexp.Of_sexp.parse (Context.t ~profile) Univ_map.empty sexp in
|
||||||
let ctx =
|
let ctx =
|
||||||
match x with
|
match x with
|
||||||
| None -> ctx
|
| None -> ctx
|
||||||
|
|
|
@ -8,7 +8,7 @@ open Stdune;;
|
||||||
|
|
||||||
(* Jbuild.Executables.Link_mode.t *)
|
(* Jbuild.Executables.Link_mode.t *)
|
||||||
let test s =
|
let test s =
|
||||||
Sexp.Of_sexp.parse Jbuild.Executables.Link_mode.t
|
Sexp.Of_sexp.parse Jbuild.Executables.Link_mode.t Univ_map.empty
|
||||||
(Sexp.parse_string ~fname:"" ~mode:Sexp.Parser.Mode.Single s)
|
(Sexp.parse_string ~fname:"" ~mode:Sexp.Parser.Mode.Single s)
|
||||||
[%%expect{|
|
[%%expect{|
|
||||||
val test : string -> Dune.Jbuild.Executables.Link_mode.t = <fun>
|
val test : string -> Dune.Jbuild.Executables.Link_mode.t = <fun>
|
||||||
|
|
|
@ -24,7 +24,7 @@ val sexp : Usexp.Ast.t = ((foo 1) (foo 2))
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
let of_sexp = record (field "foo" int)
|
let of_sexp = record (field "foo" int)
|
||||||
let x = parse of_sexp sexp
|
let x = parse of_sexp Univ_map.empty sexp
|
||||||
[%%expect{|
|
[%%expect{|
|
||||||
val of_sexp : int Stdune.Sexp.Of_sexp.t = <abstr>
|
val of_sexp : int Stdune.Sexp.Of_sexp.t = <abstr>
|
||||||
Exception:
|
Exception:
|
||||||
|
@ -33,7 +33,7 @@ Stdune__Sexp.Of_sexp.Of_sexp (<abstr>,
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
let of_sexp = record (multi_field "foo" int)
|
let of_sexp = record (multi_field "foo" int)
|
||||||
let x = parse of_sexp sexp
|
let x = parse of_sexp Univ_map.empty sexp
|
||||||
[%%expect{|
|
[%%expect{|
|
||||||
val of_sexp : int list Stdune.Sexp.Of_sexp.t = <abstr>
|
val of_sexp : int list Stdune.Sexp.Of_sexp.t = <abstr>
|
||||||
val x : int list = [1; 2]
|
val x : int list = [1; 2]
|
||||||
|
|
Loading…
Reference in New Issue