Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
ModuleParsing.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200let is_upper_char = function 'A' .. 'Z' -> true | _ -> false let is_libraryvendor_remaining_char = function | 'a' .. 'z' | '0' .. '9' -> true | _ -> false let is_libraryqualifier_remaining_char = function | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' -> true | _ -> false let is_libraryunit_remaining_char = function | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' -> true | _ -> false let is_standard_modulename_remaining_char = ModuleAssumptions.mlfront_module_charset_does_not_have_quote (); is_libraryunit_remaining_char type doubleunderscore_parser = | NoDoubleUnderscores | HasUnderscore | HasDoubleUnderscore let has_double_underscores s = let state = ref NoDoubleUnderscores in let exception Exit in begin try String.iter (fun c -> match (c, !state) with | '_', NoDoubleUnderscores -> state := HasUnderscore | '_', HasUnderscore -> state := HasDoubleUnderscore; raise Exit | _, _ -> state := NoDoubleUnderscores) s with Exit -> () end; !state = HasDoubleUnderscore type library_parser = | NotLibrary | LibraryOwnerFirst | LibraryOwnerSecond | LibraryOwnerRemaining | LibraryQualifierFirst | LibraryQualifierRemaining | LibraryUnitFirst | LibraryUnitRemaining let reserved_suffix = "__" let is_reserved s = String.ends_with ~suffix:reserved_suffix s let buf_str b = String.of_bytes (Buffer.to_bytes b) let parse_library s = let owner = Buffer.create (String.length s) in let qualifier = Buffer.create (String.length s) in let unit = Buffer.create (String.length s) in let state = ref LibraryOwnerFirst in String.iter (fun c -> match !state with | NotLibrary -> () | LibraryOwnerFirst when is_upper_char c -> Buffer.add_char owner c; state := LibraryOwnerSecond | LibraryOwnerFirst -> state := NotLibrary | LibraryOwnerSecond when is_libraryvendor_remaining_char c -> Buffer.add_char owner c; state := LibraryOwnerRemaining | LibraryOwnerSecond -> state := NotLibrary | LibraryOwnerRemaining when is_libraryvendor_remaining_char c -> Buffer.add_char owner c | LibraryOwnerRemaining when is_upper_char c -> Buffer.add_char qualifier c; state := LibraryQualifierFirst | LibraryOwnerRemaining -> state := NotLibrary | LibraryQualifierFirst when is_libraryqualifier_remaining_char c -> Buffer.add_char qualifier c; state := LibraryQualifierRemaining | LibraryQualifierFirst -> state := NotLibrary | LibraryQualifierRemaining when is_libraryqualifier_remaining_char c -> Buffer.add_char qualifier c | LibraryQualifierRemaining when '_' = c -> state := LibraryUnitFirst | LibraryQualifierRemaining -> state := NotLibrary | LibraryUnitFirst when is_upper_char c -> Buffer.add_char unit c; state := LibraryUnitRemaining | LibraryUnitFirst -> state := NotLibrary | LibraryUnitRemaining when is_libraryunit_remaining_char c -> Buffer.add_char unit c | LibraryUnitRemaining -> state := NotLibrary) s; ModuleAssumptions.mlfront_library_names_cannot_have_double_underscores (); if (not (is_reserved s)) && !state = LibraryUnitRemaining && not (has_double_underscores s) then Some (buf_str owner, buf_str qualifier, buf_str unit) else None let is_library s = Option.is_some (parse_library s) type module_parser = NotModule | ModuleOwnerFirst | ModuleOwnerRemaining let is_standard_namespace_term s = let state = ref ModuleOwnerFirst in String.iter (fun c -> match !state with | NotModule -> () | ModuleOwnerFirst when is_upper_char c -> state := ModuleOwnerRemaining | ModuleOwnerFirst -> state := NotModule | ModuleOwnerRemaining when is_standard_modulename_remaining_char c -> () | ModuleOwnerRemaining -> state := NotModule) s; ModuleAssumptions .mlfront_standard_namespace_terms_cannot_have_double_underscores (); (not (is_reserved s)) && !state = ModuleOwnerRemaining && (not (has_double_underscores s)) && not (is_library s) let signature_simple_name = "sig__" let is_signature_module = String.equal signature_simple_name let libopen_simple_name = "open__" let is_libopen_module = String.equal libopen_simple_name let proxy_suffix = "P__" let special_module_type s = if String.equal s signature_simple_name then Some `Signature else if String.equal s libopen_simple_name then Some `LibOpen else if String.ends_with ~suffix:proxy_suffix s then Some `Proxy else None let zero ~msg () = Error (`Msg msg) let validate_library libname = if is_library libname then Ok libname else let msg = Printf.sprintf "The first segment %S is not a library name." libname in zero ~msg () module InternalUse = struct let validate_standard_namespace_term_acc ~whole acc modname = match acc with | Error e -> Error e | Ok () -> if is_standard_namespace_term modname then Ok () else let msg = Printf.sprintf "The namespace term %S in %S is not a standard namespace term \ name." modname whole in zero ~msg () (** The character set for each namespace term in a ModuleId. *) let standard_namespace_term_char = is_standard_modulename_remaining_char let standard_namespace_term_uchar = fun u -> Uchar.is_char u && is_standard_modulename_remaining_char (Uchar.to_char u) (** The character set for a LibraryId. *) let library_id_char = is_libraryunit_remaining_char let library_id_uchar = fun u -> Uchar.is_char u && is_libraryunit_remaining_char (Uchar.to_char u) end let parse_library_and_namespace what s = let ( let* ) = Result.bind in let noun = match what with `PackageId -> "package" | `ModuleId -> "module" in match (what, String.split_on_char '.' s) with | _, [] -> zero ~msg:(Printf.sprintf "The %s id cannot be empty" noun) () | `ModuleId, [ _single ] -> let msg = Printf.sprintf "The %s id %S must at least include the library and one module \ segment" noun s in begin zero ~msg () end | _, library :: module_path -> let* library_id = validate_library library in let* () = List.fold_left (InternalUse.validate_standard_namespace_term_acc ~whole:s) (Ok ()) module_path in Ok (library_id, module_path)