1
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
open Ast
module Origin_map = Map.Make (String)
type binding_origin =
| Builtin
| ImportedPackage of string
let metadata_key = "__tlang_internal_import_origins__"
let is_internal_key name =
name = metadata_key
let startup_rename_warning_message () =
String.concat "\n"
[ "Warning: package function names may be renamed to avoid silent conflicts."
; " - If an imported package conflicts with a built-in function, T keeps the built-in name"
; " and renames the imported function to <package>_<function> (for example, stats_mean)."
; " - If two imported user packages conflict, both functions are renamed to"
; " <package>_<function> (for example, alpha_filter and beta_filter)."
; "These renames prevent one package from silently overwriting another."
]
let origin_to_string = function
| Builtin -> "B"
| ImportedPackage pkg -> "P" ^ pkg
let origin_of_string s =
if s = "B" then Some Builtin
else
if String.length s > 1 && s.[0] = 'P' then
Some (ImportedPackage (String.sub s 1 (String.length s - 1)))
else
None
let get_origins (env : environment) =
match Env.find_opt metadata_key env with
| Some (VDict pairs) ->
List.fold_left
(fun acc (name, value) ->
match value with
| VString encoded -> (
match origin_of_string encoded with
| Some origin -> Origin_map.add name origin acc
| None -> acc)
| _ -> acc)
Origin_map.empty
pairs
| _ -> Origin_map.empty
let set_origins (env : environment) origins =
let encoded =
Origin_map.bindings origins
|> List.map (fun (name, origin) -> (name, VString (origin_to_string origin)))
in
Env.add metadata_key (VDict encoded) env
let find_origin env name =
Origin_map.find_opt name (get_origins env)
let set_origin env name origin =
let origins = get_origins env |> Origin_map.add name origin in
set_origins env origins
let remove_origin env name =
let origins = get_origins env |> Origin_map.remove name in
set_origins env origins
let mark_builtin_bindings env =
let origins =
Env.fold
(fun name _ acc ->
if name = metadata_key || Origin_map.mem name acc then acc
else Origin_map.add name Builtin acc)
env
(get_origins env)
in
set_origins env origins