package wax-lib

  1. Overview
  2. Docs
Libraries for Wax, a Rust-like syntax for WebAssembly

Install

dune-project
 Dependency

Authors

Maintainers

Sources

wax-v0.2.0.tbz
sha256=4361e1324b7754a4c08ab5b505df32061f3ce0cea60443fd0d3699e0fa796b32
sha512=fcc756d2f160ba90a9aa1131f2ab22ed7f45466ccd658c21cf9df6868a6aab0cee7f404719d698a379958802f9820398f2fe0685ecc4dda018ca4f653294e39b

doc/src/wax-lib.conversion/namespace.ml.html

Source file namespace.ml

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
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
module StringMap = Map.Make (String)

type t = {
  mutable existing_names : int StringMap.t;
  reserved : int StringMap.t;
      (* The reserved words seeded at creation, kept separately so [add'] can
         tell a reserved-word collision from a collision with another name. *)
  mutable locations : Wax_utils.Ast.location StringMap.t;
      (* The source location each name was claimed from (when one was given), so
         [add'] can point a conflict at the previous occurrence. *)
}

let build l = List.fold_left (fun m s -> StringMap.add s 1 m) StringMap.empty l

(* Only the Wax keywords are reserved. Intrinsics need no reservation: the
   free-function ones are spelled as [v128::]/[i64::] paths and every other is a
   receiver-based method, so no bare entity name can ever shadow one. *)
(* The Wax bare-word keywords. The single source shared by [from_wasm]'s
   reserved-name set (below), the editor's keyword completion
   ([Wax_format_js]), and the keyword-consistency test, which checks this list
   against the lexer (the source of truth) and the other keyword lists. *)
let reserved_words =
  [
    "as";
    "become";
    "br";
    "br_if";
    "br_on_cast";
    "br_on_cast_fail";
    "br_on_non_null";
    "br_on_null";
    "br_table";
    "catch";
    "const";
    "cont";
    "data";
    "dispatch";
    "do";
    "elem";
    "else";
    "fn";
    "describes";
    "descriptor";
    "inf";
    "if";
    "import";
    "is";
    "let";
    "loop";
    "match";
    "memory";
    "mut";
    "nan";
    "nop";
    "null";
    "pagesize";
    "on";
    "open";
    "rec";
    "return";
    "shared";
    "suspend";
    "table";
    "tag";
    "throw";
    "throw_ref";
    "try";
    "try_legacy";
    "type";
    "unreachable";
    "while";
  ]

let reserved = build reserved_words

(* A [$type] name may also not collide with a Wax built-in type name — the
   abstract heap types, the value types, the [atomic] intrinsic namespace —
   which a [type] declaration may not take (the typer's
   [Wax_lang.Typing.reserved_type_names], the single source). *)
let reserved_heap_types =
  StringMap.union
    (fun _ _ -> assert false)
    reserved
    (build Wax_lang.Typing.reserved_type_names)

let rec add_indexed ns x i =
  let y = Printf.sprintf "%s_%d" x i in
  if StringMap.mem y ns.existing_names then add_indexed ns x (i + 1)
  else (
    ns.existing_names <-
      ns.existing_names |> StringMap.add y 1 |> StringMap.add x i;
    y)

type outcome =
  | Available
  | Renamed of { reserved : bool; previous : Wax_utils.Ast.location option }

let record_location ns ?loc name =
  match loc with
  | Some loc -> ns.locations <- ns.locations |> StringMap.add name loc
  | None -> ()

let add' ?loc ns x =
  match StringMap.find_opt x ns.existing_names with
  | Some i ->
      let y = add_indexed ns x (i + 1) in
      let previous = StringMap.find_opt x ns.locations in
      record_location ns ?loc y;
      (y, Renamed { reserved = StringMap.mem x ns.reserved; previous })
  | None ->
      ns.existing_names <- ns.existing_names |> StringMap.add x 1;
      record_location ns ?loc x;
      (x, Available)

let add ns x = fst (add' ns x)
let is_reserved ns x = StringMap.mem x ns.reserved

let reserve ns x =
  if not (StringMap.mem x ns.existing_names) then
    ns.existing_names <- ns.existing_names |> StringMap.add x 1

let dup { existing_names; reserved; locations } =
  { existing_names; reserved; locations }

let make ?(kind = `Regular) () =
  let reserved =
    match kind with
    | `Regular -> reserved
    | `Label -> StringMap.empty
    | `Type -> reserved_heap_types
  in
  { existing_names = reserved; reserved; locations = StringMap.empty }