From d01f494c040937a61b7d586aa8fd9b281b659fdc Mon Sep 17 00:00:00 2001 From: Torben Ewert Date: Fri, 12 Apr 2024 16:13:34 +0200 Subject: [PATCH] split meta and data providers to be able to request array template meta data --- benchmark/benchmark.ml | 2 +- bin/print.ml | 2 +- bin/print_debug.ml | 2 +- lib/02_parsing/Ast.ml | 2 +- lib/02_parsing/Pinc_Parser.ml | 9 +- lib/pinc_backend/Helpers.ml | 23 +++++ lib/pinc_backend/Interpreter.ml | 94 +++++++++++------ lib/pinc_backend/Interpreter.mli | 8 +- lib/pinc_backend/State.ml | 4 + lib/pinc_backend/Tag.ml | 172 +++++++++++++++++++------------ lib/pinc_backend/Types.ml | 14 ++- 11 files changed, 224 insertions(+), 108 deletions(-) diff --git a/benchmark/benchmark.ml b/benchmark/benchmark.ml index cc4b41f..69f7558 100644 --- a/benchmark/benchmark.ml +++ b/benchmark/benchmark.ml @@ -177,7 +177,7 @@ end = struct let _ = Sys.opaque_identity (Pinc.Interpreter.eval_sources - ~tag_data_provider:Pinc.Interpreter.noop_data_provider + ~tag_data_provider:Pinc.Helpers.noop_data_provider ~root [ src ]) in diff --git a/bin/print.ml b/bin/print.ml index ddf4fe7..b1c5634 100644 --- a/bin/print.ml +++ b/bin/print.ml @@ -26,7 +26,7 @@ let main = let root = Sys.argv.(2) in let declarations = get_declarations_from ~directory () in declarations - |> Interpreter.eval_sources ~root ~tag_data_provider:Interpreter.noop_data_provider + |> Interpreter.eval_sources ~root ~tag_data_provider:Helpers.noop_data_provider |> fst |> print_endline ;; diff --git a/bin/print_debug.ml b/bin/print_debug.ml index 6749455..e6a8b38 100644 --- a/bin/print_debug.ml +++ b/bin/print_debug.ml @@ -8,7 +8,7 @@ let main = let end_time_parser = Unix.gettimeofday () in let result = [ src ] - |> Interpreter.eval_sources ~tag_data_provider:Interpreter.noop_data_provider ~root + |> Interpreter.eval_sources ~tag_data_provider:Helpers.noop_data_provider ~root in let end_time = Unix.gettimeofday () in Printf.printf "Lexer & Parser: %fms\n" ((end_time_parser -. start_time) *. 1000.); diff --git a/lib/02_parsing/Ast.ml b/lib/02_parsing/Ast.ml index 3f2517c..a5bf27e 100644 --- a/lib/02_parsing/Ast.ml +++ b/lib/02_parsing/Ast.ml @@ -71,7 +71,7 @@ and expression_desc = | Float of float | Bool of bool | Array of expression array - | Record of (bool * expression) StringMap.t (** nullable, value *) + | Record of ([ `Required | `Optional ] * expression) StringMap.t | Function of { parameters : string list; body : expression; diff --git a/lib/02_parsing/Pinc_Parser.ml b/lib/02_parsing/Pinc_Parser.ml index ebdd700..f95495b 100644 --- a/lib/02_parsing/Pinc_Parser.ml +++ b/lib/02_parsing/Pinc_Parser.ml @@ -183,10 +183,15 @@ module Rules = struct match t.token.typ with | Token.IDENT_LOWER key -> next t; - let nullable = optional Token.QUESTIONMARK t in + let requirement = + if optional Token.QUESTIONMARK t then + `Optional + else + `Required + in expect Token.COLON t; let value = parse_expression t in - value |> Option.map (fun value -> (key, (nullable, value))) + value |> Option.map (fun value -> (key, (requirement, value))) | _ -> None and parse_block t = diff --git a/lib/pinc_backend/Helpers.ml b/lib/pinc_backend/Helpers.ml index 698b168..d623ada 100644 --- a/lib/pinc_backend/Helpers.ml +++ b/lib/pinc_backend/Helpers.ml @@ -276,6 +276,7 @@ module TagMeta = struct let array a : meta = `Array a let record r : meta = `Record r let children () : meta = `SubTagPlaceholder + let template () : meta = `TemplatePlaceholder let rec merge (a : meta) (b : meta) = match (a, b) with @@ -299,4 +300,26 @@ module TagMeta = struct | `Array a -> `Array (a |> List.map (map fn)) | value -> fn value ;; + + let rec filter_map : (meta -> 'a option) -> meta -> 'a option = + fun fn (meta : meta) -> + match meta with + | `Record a -> ( + let result = + a + |> List.filter_map @@ fun (key, v) -> + filter_map fn v |> Option.map (fun v -> (key, v)) + in + match result with + | [] -> None + | l -> Some (`Record l)) + | `Array a -> ( + match a |> List.filter_map (filter_map fn) with + | [] -> None + | l -> Some (`Array l)) + | value -> fn value + ;; end + +let noop_data_provider ~tag:_ ~attributes:_ ~required:_ ~key:_ = None +let noop_meta_provider ~tag:_ ~attributes:_ ~required:_ ~key:_ = None diff --git a/lib/pinc_backend/Interpreter.ml b/lib/pinc_backend/Interpreter.ml index 6ac9ac7..c4ebbe5 100644 --- a/lib/pinc_backend/Interpreter.ml +++ b/lib/pinc_backend/Interpreter.ml @@ -39,6 +39,8 @@ let rec get_uppercase_identifier_typ ~state ident = (State.make ~root_tag_data_provider:state.root_tag_data_provider ~tag_data_provider:state.tag_data_provider + ~root_tag_meta_provider:state.root_tag_meta_provider + ~tag_meta_provider:state.tag_meta_provider ~tag_meta:state.tag_meta ~mode:state.mode state.declarations) @@ -117,16 +119,16 @@ and eval_expression ~state expression = map |> StringMap.to_seq |> Seq.fold_left - (fun (state, seq) (ident, (optional, expression)) -> + (fun (state, seq) (ident, (requirement, expression)) -> let state = expression |> eval_expression - ~state:{ state with binding_identifier = Some (optional, ident) } + ~state:{ state with binding_identifier = Some (requirement, ident) } in let output = state |> State.get_output in let () = match output with - | { value_desc = Null; value_loc } when not optional -> + | { value_desc = Null; value_loc } when requirement = `Required -> Pinc_Diagnostics.error value_loc (Printf.sprintf @@ -962,10 +964,16 @@ and eval_lowercase_identifier ~state ~loc ident = and eval_let ~state ~ident ~is_mutable ~is_optional expression = let ident, ident_location = ident in + let requirement = + if is_optional then + `Optional + else + `Required + in let state = expression |> eval_expression - ~state:{ state with binding_identifier = Some (is_optional, ident) } + ~state:{ state with binding_identifier = Some (requirement, ident) } in let value = State.get_output state in match value with @@ -1015,10 +1023,16 @@ and eval_mutation ~state ~ident expression = | Some { is_mutable = false; _ } -> Pinc_Diagnostics.error ident_location "Trying to update a non mutable variable." | Some { value = _; is_mutable = true; is_optional } -> + let requirement = + if is_optional then + `Optional + else + `Required + in let output = expression |> eval_expression - ~state:{ state with binding_identifier = Some (is_optional, ident) } + ~state:{ state with binding_identifier = Some (requirement, ident) } in let () = output |> State.get_output |> function @@ -1259,29 +1273,37 @@ and eval_template ~state template = |> Fun.flip Option.bind (Tag.find_path (key |> List.tl)) |> function | None -> state.root_tag_data_provider ~tag ~attributes ~required ~key - | value -> (value, None)) + | value -> value) | Type_Tag.Tag_Slot _ -> let key = key |> List.rev |> List.hd in - ( component_tag_children - |> List.fold_left (Tag.Tag_Slot.keep_slotted ~key) [] - |> List.rev - |> Helpers.Value.list - |> Option.some, - None ) + component_tag_children + |> List.fold_left (Tag.Tag_Slot.keep_slotted ~key) [] + |> List.rev + |> Helpers.Value.list + |> Option.some | Type_Tag.Tag_Array -> let key = key |> List.rev |> List.hd in - ( component_tag_attributes - |> StringMap.find_opt key - |> Fun.flip Option.bind (function - | { value_desc = Array a; _ } -> - a |> Array.length |> Helpers.Value.int |> Option.some - | _ -> None), - None ) + component_tag_attributes + |> StringMap.find_opt key + |> Fun.flip Option.bind (function + | { value_desc = Array a; _ } -> + a |> Array.length |> Helpers.Value.int |> Option.some + | _ -> None) | _ -> - ( component_tag_attributes - |> StringMap.find_opt (key |> List.hd) - |> Fun.flip Option.bind (Tag.find_path (key |> List.tl)), - None ) + component_tag_attributes + |> StringMap.find_opt (key |> List.hd) + |> Fun.flip Option.bind (Tag.find_path (key |> List.tl)) + in + let tag_meta_provider ~tag ~attributes ~required ~key = + match tag with + | Type_Tag.Tag_Store _ -> ( + component_tag_attributes + |> StringMap.find_opt (key |> List.hd) + |> Fun.flip Option.bind (Tag.find_path (key |> List.tl)) + |> function + | None -> state.root_tag_meta_provider ~tag ~attributes ~required ~key + | _ -> None) + | _ -> None in let state = @@ -1289,8 +1311,10 @@ and eval_template ~state template = ~context:state.context ~mode:state.mode ~tag_meta:state.tag_meta - ~root_tag_data_provider:state.root_tag_data_provider ~tag_data_provider + ~root_tag_data_provider:state.root_tag_data_provider + ~tag_meta_provider + ~root_tag_meta_provider:state.root_tag_meta_provider state.declarations in DeclarationEvaluator.eval ~eval_expression ~state component_tag_identifier @@ -1308,8 +1332,6 @@ and eval_template ~state template = } ;; -let noop_data_provider ~tag:_ ~attributes:_ ~required:_ ~key:_ = (None, None) - let declarations_of_sources = ListLabels.fold_left ~init:[] ~f:(fun acc source -> let decls = Parser.parse source in @@ -1342,8 +1364,10 @@ let eval_meta sources = State.make ~mode:`Portal_Collection ~tag_meta:[] - ~root_tag_data_provider:noop_data_provider - ~tag_data_provider:noop_data_provider + ~root_tag_data_provider:Helpers.noop_data_provider + ~tag_data_provider:Helpers.noop_data_provider + ~root_tag_meta_provider:Helpers.noop_meta_provider + ~tag_meta_provider:Helpers.noop_data_provider declarations in let eval attrs = @@ -1380,7 +1404,11 @@ let get_stdlib () = StringMap.empty ;; -let eval_declarations ~tag_data_provider ~root declarations = +let eval_declarations + ?(tag_meta_provider = Helpers.noop_meta_provider) + ~tag_data_provider + ~root + declarations = Hashtbl.reset Tag.Tag_Portal.portals; let declarations = @@ -1399,6 +1427,8 @@ let eval_declarations ~tag_data_provider ~root declarations = State.make ~root_tag_data_provider:tag_data_provider ~tag_data_provider + ~root_tag_meta_provider:tag_meta_provider + ~tag_meta_provider ~tag_meta:[] ~mode:`Portal_Collection declarations @@ -1421,6 +1451,8 @@ let eval_declarations ~tag_data_provider ~root declarations = (html, meta_tree) ;; -let eval_sources ~tag_data_provider ~root sources = - sources |> declarations_of_sources |> eval_declarations ~tag_data_provider ~root +let eval_sources ?tag_meta_provider ~tag_data_provider ~root sources = + sources + |> declarations_of_sources + |> eval_declarations ?tag_meta_provider ~tag_data_provider ~root ;; diff --git a/lib/pinc_backend/Interpreter.mli b/lib/pinc_backend/Interpreter.mli index f2cf1d1..cfb6f41 100644 --- a/lib/pinc_backend/Interpreter.mli +++ b/lib/pinc_backend/Interpreter.mli @@ -2,8 +2,6 @@ module Types = Types module Ast = Pinc_Parser.Ast open Types -val noop_data_provider : Type_Tag.data_provider - val eval_meta : Pinc_Source.t list -> [> `Component of value StringMap.t @@ -13,17 +11,19 @@ val eval_meta : ] StringMap.t -(** [eval_sources ~tag_data_provider ~root sources] evaluates definition {!root} found in {!sources}, getting its data from the {!tag_data_provider}. +(** [eval_sources ?tag_meta_provider ~tag_data_provider ~root sources] evaluates definition {!root} found in {!sources}, getting its data from the {!tag_data_provider}. @raise Invalid_argument if the given root can't be evaluated (store, library). *) val eval_sources : + ?tag_meta_provider:Types.Type_Tag.meta_provider -> tag_data_provider:Types.Type_Tag.data_provider -> root:string -> Pinc_Source.t list -> string * (string * Types.Type_Tag.meta) list -(** [eval ~tag_data_provider ~root sources] evaluates definition {!root} found in {!sources}, getting its data from the {!tag_data_provider}. +(** [eval ?tag_meta_provider ~tag_data_provider ~root sources] evaluates definition {!root} found in {!sources}, getting its data from the {!tag_data_provider}. @raise Invalid_argument if the given root can't be evaluated (store, library). *) val eval_declarations : + ?tag_meta_provider:Types.Type_Tag.meta_provider -> tag_data_provider:Types.Type_Tag.data_provider -> root:string -> (string * Pinc_Parser.Ast.declaration) list -> diff --git a/lib/pinc_backend/State.ml b/lib/pinc_backend/State.ml index 8e5b367..f92b5ce 100644 --- a/lib/pinc_backend/State.ml +++ b/lib/pinc_backend/State.ml @@ -7,6 +7,8 @@ let make ~tag_meta ~tag_data_provider ~root_tag_data_provider + ~tag_meta_provider + ~root_tag_meta_provider ~mode declarations = { @@ -16,6 +18,8 @@ let make environment = { scope = []; use_scope = StringMap.empty }; tag_data_provider; root_tag_data_provider; + tag_meta_provider; + root_tag_meta_provider; tag_meta; tag_path; context; diff --git a/lib/pinc_backend/Tag.ml b/lib/pinc_backend/Tag.ml index 08c79ef..ebe1813 100644 --- a/lib/pinc_backend/Tag.ml +++ b/lib/pinc_backend/Tag.ml @@ -69,13 +69,14 @@ end module Tag_String = struct let eval ~state ~attributes t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true - in - let value, meta = - state.State.tag_data_provider ~tag:Tag_String ~key ~attributes ~required + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in + let meta = state.State.tag_meta_provider ~tag:Tag_String ~key ~attributes ~required in + let data = state.State.tag_data_provider ~tag:Tag_String ~key ~attributes ~required in let output = - value + data |> Option.map (function | { value_desc = String _; _ } as value -> value | { value_desc = _; value_loc } -> @@ -96,13 +97,14 @@ end module Tag_Int = struct let eval ~state ~attributes t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true - in - let value, meta = - state.State.tag_data_provider ~tag:Tag_Int ~key ~attributes ~required + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in + let meta = state.State.tag_meta_provider ~tag:Tag_Int ~key ~attributes ~required in + let data = state.State.tag_data_provider ~tag:Tag_Int ~key ~attributes ~required in let output = - value + data |> Option.map (function | { value_desc = Int _; _ } as value -> value | { value_desc = _; value_loc } -> @@ -123,13 +125,14 @@ end module Tag_Float = struct let eval ~state ~attributes t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true - in - let value, meta = - state.State.tag_data_provider ~tag:Tag_Float ~key ~attributes ~required + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in + let meta = state.State.tag_meta_provider ~tag:Tag_Float ~key ~attributes ~required in + let data = state.State.tag_data_provider ~tag:Tag_Float ~key ~attributes ~required in let output = - value + data |> Option.map (function | { value_desc = Float _; _ } as value -> value | { value_desc = _; value_loc } -> @@ -150,13 +153,14 @@ end module Tag_Boolean = struct let eval ~(state : State.state) ~attributes t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true - in - let value, meta = - state.tag_data_provider ~tag:Tag_Boolean ~key ~attributes ~required + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in + let meta = state.tag_meta_provider ~tag:Tag_Boolean ~key ~attributes ~required in + let data = state.tag_data_provider ~tag:Tag_Boolean ~key ~attributes ~required in let output = - value + data |> Option.map (function | { value_desc = Bool _; _ } as value -> value | { value_desc = _; value_loc } -> @@ -177,12 +181,17 @@ end module Tag_Custom = struct let eval ~state ~attributes ~name t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in - let value, meta = + let meta = + state.tag_meta_provider ~tag:(Tag_Custom name) ~key ~attributes ~required + in + let data = state.tag_data_provider ~tag:(Tag_Custom name) ~key ~attributes ~required in - let output = value |> Option.value ~default:(Helpers.Value.null ~loc:t.tag_loc ()) in + let output = data |> Option.value ~default:(Helpers.Value.null ~loc:t.tag_loc ()) in state |> State.add_output ~output @@ -256,31 +265,40 @@ module Tag_Store = struct |> StringMap.find_opt (key |> List.hd) |> Fun.flip Option.bind (find_path (key |> List.tl)) |> function - | None -> - let value, meta = state.tag_data_provider ~tag ~attributes ~key ~required in - (value, meta) - | value -> (value, None)) + | None -> state.tag_data_provider ~tag ~attributes ~key ~required + | value -> value) | Types.Type_Tag.Tag_Array -> - ( value - |> StringMap.find_opt (key |> List.rev |> List.hd) - |> Fun.flip Option.bind (function - | { value_desc = Array a; _ } -> - a |> Array.length |> Helpers.Value.int |> Option.some - | _ -> None), - None ) + value + |> StringMap.find_opt (key |> List.rev |> List.hd) + |> Fun.flip Option.bind (function + | { value_desc = Array a; _ } -> + a |> Array.length |> Helpers.Value.int |> Option.some + | _ -> None) | _ -> - ( value - |> StringMap.find_opt (key |> List.hd) - |> Fun.flip Option.bind (find_path (key |> List.tl)), - None ) + value + |> StringMap.find_opt (key |> List.hd) + |> Fun.flip Option.bind (find_path (key |> List.tl)) + in + let tag_meta_provider ~tag ~attributes ~required ~key = + match tag with + | Types.Type_Tag.Tag_Store _ -> ( + value + |> StringMap.find_opt (key |> List.hd) + |> Fun.flip Option.bind (find_path (key |> List.tl)) + |> function + | None -> state.tag_meta_provider ~tag ~attributes ~key ~required + | _ -> None) + | _ -> None in let state = State.make ~context:state.context ~mode:state.mode ~tag_meta:state.tag_meta - ~root_tag_data_provider:state.root_tag_data_provider ~tag_data_provider + ~root_tag_data_provider:state.root_tag_data_provider + ~tag_meta_provider + ~root_tag_meta_provider:state.root_tag_meta_provider state.declarations in store |> Types.Type_Store.body |> eval_expression ~state |> State.get_output @@ -317,13 +335,18 @@ module Tag_Store = struct in let is_singleton = store |> Types.Type_Store.is_singleton in let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true + in + let meta = + state.State.tag_meta_provider ~tag:(Tag_Store store) ~key ~attributes ~required in - let value, meta = + let data = state.State.tag_data_provider ~tag:(Tag_Store store) ~key ~attributes ~required in let output = - match value with + match data with | None -> Helpers.Value.null ~loc:tag.tag_loc () | Some { value_desc = Record value; _ } when is_singleton -> ( store |> eval_body ~name ~value ~eval_expression ~state |> function @@ -458,6 +481,8 @@ module Tag_Slot = struct ~tag_meta:state.tag_meta ~root_tag_data_provider:state.root_tag_data_provider ~tag_data_provider + ~root_tag_meta_provider:state.root_tag_meta_provider + ~tag_meta_provider:state.root_tag_meta_provider state.declarations in @@ -472,13 +497,16 @@ module Tag_Slot = struct in let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in - let slotted_elements, meta = + let meta = state.State.tag_meta_provider ~tag ~key ~attributes ~required in + let slotted_elements = match state.State.tag_data_provider ~tag ~key ~attributes ~required with - | None, meta -> ([||], meta) - | Some { value_desc = Array a; _ }, meta -> (a, meta) + | None -> [||] + | Some { value_desc = Array a; _ } -> a | _ -> Pinc_Diagnostics.error tag_value.tag_loc @@ -590,13 +618,14 @@ end module Tag_Record = struct let eval ~eval_expression ~state ~attributes ~of' t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true - in - let value, meta = - state.State.tag_data_provider ~tag:Tag_Record ~key ~attributes ~required + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true in + let meta = state.State.tag_meta_provider ~tag:Tag_Record ~key ~attributes ~required in + let data = state.State.tag_data_provider ~tag:Tag_Record ~key ~attributes ~required in let output, child_meta = - value + data |> Option.map (function | { value_desc = Record r; _ } -> r | { value_desc = _; value_loc } -> @@ -643,13 +672,14 @@ end module Tag_Array = struct let eval ~eval_expression ~state ~attributes ~of' t key = let required = - state.binding_identifier |> Option.map fst |> Option.value ~default:true - in - let value, meta = - state.State.tag_data_provider ~tag:Tag_Array ~key ~attributes ~required - in - let output, child_meta = - value + state.binding_identifier + |> (Option.map @@ fun v -> fst v = `Required) + |> Option.value ~default:true + in + let meta = state.State.tag_meta_provider ~tag:Tag_Array ~key ~attributes ~required in + let data = state.State.tag_data_provider ~tag:Tag_Array ~key ~attributes ~required in + let output, child_meta, template_meta = + data |> Option.map (function | { value_desc = Int i; _ } -> i | { value_desc = _; value_loc } -> @@ -664,9 +694,19 @@ module Tag_Array = struct Pinc_Diagnostics.error t.tag_loc "Attribute `of` is required on #Array." | Some children -> let state = { state with tag_path = key; tag_meta = [] } in + let template_meta = + let state = + children + |> eval_expression + ~state:{ state with binding_identifier = Some (`Optional, "0") } + in + match state.tag_meta with + | (_, meta) :: _ -> Some meta + | _ -> None + in let values, metas = List.init len (fun i -> - let binding_identifier = Some (false, string_of_int i) in + let binding_identifier = Some (`Required, string_of_int i) in let state = children |> eval_expression ~state:{ state with binding_identifier } @@ -682,16 +722,18 @@ module Tag_Array = struct in let value = values |> Helpers.Value.list ~loc:t.tag_loc in let meta = metas |> List.filter_map Fun.id in - (value, meta)) - |> Option.value ~default:(Helpers.Value.null ~loc:t.tag_loc (), []) + (value, meta, template_meta)) + |> Option.value ~default:(Helpers.Value.null ~loc:t.tag_loc (), [], None) in let meta = meta - |> Option.map - (Helpers.TagMeta.map @@ function - | `SubTagPlaceholder -> child_meta |> Helpers.TagMeta.array - | v -> v) + |> Fun.flip Option.bind + @@ Helpers.TagMeta.filter_map + @@ function + | `SubTagPlaceholder -> child_meta |> Helpers.TagMeta.array |> Option.some + | `TemplatePlaceholder -> template_meta + | v -> Some v in state diff --git a/lib/pinc_backend/Types.ml b/lib/pinc_backend/Types.ml index 894bf96..65aa373 100644 --- a/lib/pinc_backend/Types.ml +++ b/lib/pinc_backend/Types.ml @@ -39,12 +39,14 @@ end = and Type_State : sig type state = { - binding_identifier : (bool * string) option; + binding_identifier : ([ `Required | `Optional ] * string) option; declarations : Ast.t; output : Type_Value.value; environment : environment; tag_data_provider : Type_Tag.data_provider; root_tag_data_provider : Type_Tag.data_provider; + tag_meta_provider : Type_Tag.meta_provider; + root_tag_meta_provider : Type_Tag.meta_provider; tag_path : string list; tag_meta : (string * Type_Tag.meta) list; context : Type_Value.value StringMap.t; @@ -123,6 +125,7 @@ and Type_Tag : sig | `Array of meta list | `Record of (string * meta) list | `SubTagPlaceholder + | `TemplatePlaceholder ] type data_provider = @@ -130,7 +133,14 @@ and Type_Tag : sig attributes:Type_Value.value StringMap.t -> required:bool -> key:string list -> - Type_Value.value option * meta option + Type_Value.value option + + type meta_provider = + tag:kind -> + attributes:Type_Value.value StringMap.t -> + required:bool -> + key:string list -> + meta option end = Type_Tag